621e8895c9
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
85 lines
2.3 KiB
Go
85 lines
2.3 KiB
Go
package infra
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// NordVPNContainerOpts opciones para el container gateway NordVPN.
|
|
type NordVPNContainerOpts struct {
|
|
Token string // Token de acceso NordVPN (obligatorio)
|
|
Country string // Pais al que conectar (opcional, ej: "Spain")
|
|
City string // Ciudad (opcional, ej: "Madrid")
|
|
Protocol string // "NordLynx" o "OpenVPN" (default: NordLynx)
|
|
Name string // Nombre del container (default: "nordvpn")
|
|
}
|
|
|
|
// NordVPNContainerStart levanta un container Docker con NordVPN como gateway.
|
|
// Otros containers pueden usar su red con --network=container:<name>.
|
|
// Espera hasta que el tunel este activo o timeout de 30s.
|
|
func NordVPNContainerStart(opts NordVPNContainerOpts) (string, error) {
|
|
if opts.Token == "" {
|
|
return "", fmt.Errorf("nordvpn token required")
|
|
}
|
|
if opts.Name == "" {
|
|
opts.Name = "nordvpn"
|
|
}
|
|
if opts.Protocol == "" {
|
|
opts.Protocol = "NordLynx"
|
|
}
|
|
|
|
env := map[string]string{
|
|
"TOKEN": opts.Token,
|
|
"TECHNOLOGY": opts.Protocol,
|
|
}
|
|
if opts.Country != "" {
|
|
connect := opts.Country
|
|
if opts.City != "" {
|
|
connect += " " + opts.City
|
|
}
|
|
env["CONNECT"] = connect
|
|
}
|
|
|
|
// Limpiar container previo con el mismo nombre si existe
|
|
_ = DockerRemoveContainer(opts.Name, true)
|
|
|
|
id, err := DockerRunContainer("ghcr.io/bubuntux/nordvpn", DockerRunOpts{
|
|
Name: opts.Name,
|
|
Env: env,
|
|
Detach: true,
|
|
CapAdd: []string{"NET_ADMIN", "NET_RAW"},
|
|
})
|
|
if err != nil {
|
|
return "", fmt.Errorf("nordvpn container start: %w", err)
|
|
}
|
|
|
|
// Esperar a que el tunel este activo
|
|
for i := 0; i < 30; i++ {
|
|
time.Sleep(1 * time.Second)
|
|
lines, logErr := DockerContainerLogs(DockerLogsOpts{
|
|
ContainerID: opts.Name,
|
|
Tail: 20,
|
|
Stdout: true,
|
|
Stderr: true,
|
|
})
|
|
if logErr != nil {
|
|
continue
|
|
}
|
|
var logText strings.Builder
|
|
for _, l := range lines {
|
|
logText.WriteString(l.Line)
|
|
logText.WriteByte('\n')
|
|
}
|
|
logsStr := logText.String()
|
|
if strings.Contains(logsStr, "Connected") || strings.Contains(logsStr, "connected") {
|
|
return id, nil
|
|
}
|
|
if strings.Contains(logsStr, "error") || strings.Contains(logsStr, "failed") {
|
|
return id, fmt.Errorf("nordvpn connection failed, check logs: docker logs %s", opts.Name)
|
|
}
|
|
}
|
|
|
|
return id, fmt.Errorf("nordvpn connection timeout after 30s, check logs: docker logs %s", opts.Name)
|
|
}
|