67 lines
1.5 KiB
Go
67 lines
1.5 KiB
Go
package services
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"log/slog"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
|
|
type VPNService struct{
|
|
Config *ConfigService
|
|
}
|
|
|
|
func NewVPNService(cfg *ConfigService) *VPNService {
|
|
return &VPNService{
|
|
Config: cfg,
|
|
}
|
|
}
|
|
|
|
func (v *VPNService) CheckStatus(ctx context.Context) (bool, error) {
|
|
cmd := exec.CommandContext(ctx, "tailscale", "exit-node", "list")
|
|
var out bytes.Buffer
|
|
cmd.Stdout = &out
|
|
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
slog.ErrorContext(ctx, "failed to check VPN status", "error", err)
|
|
return false, err
|
|
}
|
|
|
|
output := out.String()
|
|
return strings.Contains(output, "selected"), nil
|
|
}
|
|
|
|
func (v *VPNService) TurnOn(ctx context.Context) error {
|
|
selectedServer, _ := v.Config.GetSelectedServer()
|
|
cmd := exec.CommandContext(ctx, "sudo", "tailscale", "set", "--exit-node="+selectedServer.Host)
|
|
if err := cmd.Run(); err != nil {
|
|
slog.ErrorContext(ctx, "failed to turn on VPN", "error", err)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (v *VPNService) TurnOff(ctx context.Context) error {
|
|
cmd := exec.CommandContext(ctx, "sudo", "tailscale", "set", "--exit-node=")
|
|
if err := cmd.Run(); err != nil {
|
|
slog.ErrorContext(ctx, "failed to turn off VPN", "error", err)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (v *VPNService) ExitNodeList(ctx context.Context) (string, error) {
|
|
cmd := exec.CommandContext(ctx, "tailscale", "exit-node", "list")
|
|
var out bytes.Buffer
|
|
cmd.Stdout = &out
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
slog.ErrorContext(ctx, "failed to get exit node list", "error", err)
|
|
return "", err
|
|
}
|
|
return out.String(), nil
|
|
}
|