refactor: extract ProxyProvider interface with None and NPM implementations

Replace direct npm.Client usage throughout the codebase with the
proxy.Provider interface, enabling pluggable proxy backends. The
deployer, API layer, and proxy manager now use provider-agnostic
route management (ConfigureRoute/DeleteRoute) instead of NPM-specific
API calls. Adds ProxyRouteID (string) to Instance model and
ProxyProvider setting to Settings, with SQLite migrations for
backward compatibility.
This commit is contained in:
2026-04-04 19:39:08 +03:00
parent 6667abf03c
commit 7d6719da12
17 changed files with 365 additions and 249 deletions
+25 -4
View File
@@ -91,10 +91,31 @@ func main() {
os.Exit(1)
}
// Initialize NPM client.
// Initialize NPM client (used for NPM-specific endpoints like certificates).
npmURL := envOrDefault("NPM_URL", settings.NpmURL)
npmClient := npm.New(npmURL)
// Build proxy provider based on settings.
var proxyProvider proxy.Provider
switch settings.ProxyProvider {
case "none":
proxyProvider = proxy.NewNoneProvider()
slog.Info("proxy provider: none")
default:
// Default to NPM for backward compatibility (including "npm" and empty string).
npmPassword := ""
if settings.NpmPassword != "" {
decrypted, err := crypto.Decrypt(encKey, settings.NpmPassword)
if err != nil {
slog.Warn("failed to decrypt NPM password for proxy provider", "error", err)
} else {
npmPassword = decrypted
}
}
proxyProvider = proxy.NewNpmProvider(npmClient, settings.NpmEmail, npmPassword)
slog.Info("proxy provider: npm", "url", npmURL)
}
// Initialize services.
healthChecker := health.New()
notifier := notify.New()
@@ -115,7 +136,7 @@ func main() {
})
defer stopLogger()
dep := deployer.New(dockerClient, npmClient, db, healthChecker, notifier, eventBus, encKey)
dep := deployer.New(dockerClient, proxyProvider, db, healthChecker, notifier, eventBus, encKey)
// Initialize webhook handler.
webhookHandler := webhook.NewHandler(db, dep, dockerClient)
@@ -144,7 +165,7 @@ func main() {
}
// Initialize proxy manager and health monitor.
proxyManager := proxy.NewManager(db, npmClient)
proxyManager := proxy.NewManager(db, proxyProvider)
proxyHealth := proxy.NewHealthMonitor(db, eventBus)
if err := proxyHealth.Start("5m"); err != nil {
slog.Warn("failed to start proxy health monitor", "error", err)
@@ -260,7 +281,7 @@ func main() {
scheduleAutobackup(settings.BackupEnabled, settings.BackupIntervalHours)
// Build API server.
apiServer := api.NewServer(db, dockerClient, npmClient, dep, webhookHandler, eventBus, encKey)
apiServer := api.NewServer(db, dockerClient, npmClient, proxyProvider, dep, webhookHandler, eventBus, encKey)
apiServer.SetStaleScanner(staleScanner)
apiServer.SetProxyManager(proxyManager)
apiServer.SetBackupEngine(backupEngine)