Files
fn_registry/functions/infra/nordvpn_container_start.go
egutierrez 621e8895c9 feat(infra): auto-commit con 86 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 19:38:15 +02:00

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)
}