diff --git a/internal/api/router.go b/internal/api/router.go index 3572d2a28..955632897 100644 --- a/internal/api/router.go +++ b/internal/api/router.go @@ -672,7 +672,7 @@ func (r *Router) setupRoutes() { r.mux.HandleFunc("/api/settings/update", updateSettings) // System settings and API token management - systemSettingsHandler := NewSystemSettingsHandler(r.config, r.persistence, r.wsHub) + systemSettingsHandler := NewSystemSettingsHandler(r.config, r.persistence, r.wsHub, r.monitor) r.mux.HandleFunc("/api/system/settings", systemSettingsHandler.HandleGetSystemSettings) r.mux.HandleFunc("/api/system/settings/update", systemSettingsHandler.HandleUpdateSystemSettings) // Old API token endpoints removed - now using /api/security/regenerate-token @@ -790,9 +790,9 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { } } - // Special case: setup-script with a token parameter should be allowed - if req.URL.Path == "/api/setup-script" && req.URL.Query().Get("token") != "" { - // Let the handler validate the token + // Special case: setup-script should be public (uses setup codes for auth) + if req.URL.Path == "/api/setup-script" { + // The script itself prompts for a setup code isPublic = true } diff --git a/internal/api/system_settings.go b/internal/api/system_settings.go index e2817624f..32fedc21c 100644 --- a/internal/api/system_settings.go +++ b/internal/api/system_settings.go @@ -1,11 +1,13 @@ package api import ( + "context" "encoding/json" "net/http" "time" "github.com/rcourtman/pulse-go-rewrite/internal/config" + "github.com/rcourtman/pulse-go-rewrite/internal/discovery" "github.com/rcourtman/pulse-go-rewrite/internal/websocket" "github.com/rs/zerolog/log" ) @@ -15,14 +17,24 @@ type SystemSettingsHandler struct { config *config.Config persistence *config.ConfigPersistence wsHub *websocket.Hub + monitor interface { + GetDiscoveryService() *discovery.Service + StartDiscoveryService(ctx context.Context, wsHub *websocket.Hub, subnet string) + StopDiscoveryService() + } } // NewSystemSettingsHandler creates a new system settings handler -func NewSystemSettingsHandler(cfg *config.Config, persistence *config.ConfigPersistence, wsHub *websocket.Hub) *SystemSettingsHandler { +func NewSystemSettingsHandler(cfg *config.Config, persistence *config.ConfigPersistence, wsHub *websocket.Hub, monitor interface { + GetDiscoveryService() *discovery.Service + StartDiscoveryService(ctx context.Context, wsHub *websocket.Hub, subnet string) + StopDiscoveryService() +}) *SystemSettingsHandler { return &SystemSettingsHandler{ config: cfg, persistence: persistence, wsHub: wsHub, + monitor: monitor, } } @@ -177,11 +189,34 @@ func (h *SystemSettingsHandler) HandleUpdateSystemSettings(w http.ResponseWriter return } - // Update discovery settings + // Update discovery settings and manage the service + prevDiscoveryEnabled := h.config.DiscoveryEnabled h.config.DiscoveryEnabled = settings.DiscoveryEnabled if settings.DiscoverySubnet != "" { h.config.DiscoverySubnet = settings.DiscoverySubnet } + + // Start or stop discovery service based on setting change + if h.monitor != nil { + if settings.DiscoveryEnabled && !prevDiscoveryEnabled { + // Discovery was just enabled, start the service + subnet := h.config.DiscoverySubnet + if subnet == "" { + subnet = "auto" + } + h.monitor.StartDiscoveryService(context.Background(), h.wsHub, subnet) + log.Info().Msg("Discovery service started via settings update") + } else if !settings.DiscoveryEnabled && prevDiscoveryEnabled { + // Discovery was just disabled, stop the service + h.monitor.StopDiscoveryService() + log.Info().Msg("Discovery service stopped via settings update") + } else if settings.DiscoveryEnabled && settings.DiscoverySubnet != "" { + // Subnet changed while discovery is enabled, update it + if svc := h.monitor.GetDiscoveryService(); svc != nil { + svc.SetSubnet(settings.DiscoverySubnet) + } + } + } // Save to persistence if err := h.persistence.SaveSystemSettings(settings); err != nil { diff --git a/internal/monitoring/monitor.go b/internal/monitoring/monitor.go index a1bb78e53..178e69cff 100644 --- a/internal/monitoring/monitor.go +++ b/internal/monitoring/monitor.go @@ -1925,6 +1925,41 @@ func (m *Monitor) GetDiscoveryService() *discovery.Service { return m.discoveryService } +// StartDiscoveryService starts the discovery service if not already running +func (m *Monitor) StartDiscoveryService(ctx context.Context, wsHub *websocket.Hub, subnet string) { + m.mu.Lock() + defer m.mu.Unlock() + + if m.discoveryService != nil { + log.Debug().Msg("Discovery service already running") + return + } + + if subnet == "" { + subnet = "auto" + } + + m.discoveryService = discovery.NewService(wsHub, 5*time.Minute, subnet) + if m.discoveryService != nil { + m.discoveryService.Start(ctx) + log.Info().Str("subnet", subnet).Msg("Discovery service started") + } else { + log.Error().Msg("Failed to create discovery service") + } +} + +// StopDiscoveryService stops the discovery service if running +func (m *Monitor) StopDiscoveryService() { + m.mu.Lock() + defer m.mu.Unlock() + + if m.discoveryService != nil { + m.discoveryService.Stop() + m.discoveryService = nil + log.Info().Msg("Discovery service stopped") + } +} + // GetGuestMetrics returns historical metrics for a guest func (m *Monitor) GetGuestMetrics(guestID string, duration time.Duration) map[string][]MetricPoint { return m.metricsHistory.GetAllGuestMetrics(guestID, duration)