package main import ( "flag" "log" "os" "path/filepath" "openvpn-manager/internal/api" "openvpn-manager/internal/config" "openvpn-manager/internal/service" "openvpn-manager/internal/store" "openvpn-manager/pkg/openvpn" ) func main() { dataDir := flag.String("data", "", "data directory (default $OVPNMGR_DATA or ./data)") distDir := flag.String("dist", "", "frontend dist directory (default $OVPNMGR_DIST or ./dist)") flag.Parse() if *dataDir == "" { *dataDir = os.Getenv("OVPNMGR_DATA") } if *dataDir == "" { *dataDir = "./data" } if *distDir == "" { *distDir = os.Getenv("OVPNMGR_DIST") } if *distDir == "" { *distDir = "./dist" } abs, _ := filepath.Abs(*dataDir) cfg := config.Load(abs) if err := os.MkdirAll(cfg.PKIDir(), 0o700); err != nil { log.Fatalf("mkdir pki: %v", err) } if err := os.MkdirAll(cfg.InstancesDir(), 0o755); err != nil { log.Fatalf("mkdir instances: %v", err) } if err := os.MkdirAll(cfg.ClientsDir(), 0o755); err != nil { log.Fatalf("mkdir clients: %v", err) } if err := os.MkdirAll(cfg.BackupsDir(), 0o755); err != nil { log.Fatalf("mkdir backups: %v", err) } st, err := store.Open(cfg.DBFile()) if err != nil { log.Fatalf("open store: %v", err) } ovm := openvpn.NewManager(cfg.OpenVPNBin, cfg.DataDir) if err := ovm.EnsureCA(); err != nil { log.Printf("warn: ensure CA: %v", err) } svc := service.New(cfg, st, ovm) addr := cfg.Host + ":" + itoa(cfg.Port) log.Printf("openvpn-manager listening on %s, data=%s, dist=%s", addr, cfg.DataDir, *distDir) srv := api.NewServer(cfg, svc) if err := srv.Router(*distDir).Run(addr); err != nil { log.Fatal(err) } } func itoa(n int) string { if n == 0 { return "0" } neg := false if n < 0 { neg = true n = -n } var buf [20]byte i := len(buf) for n > 0 { i-- buf[i] = byte('0' + n%10) n /= 10 } if neg { i-- buf[i] = '-' } return string(buf[i:]) }