Propagate config updates to settings nodes (#588)

This commit is contained in:
rcourtman 2025-10-22 13:45:13 +00:00
parent f61a61aad0
commit 77108abc65
5 changed files with 65 additions and 13 deletions

View file

@ -148,6 +148,9 @@ func runServer() {
}
if router != nil {
router.SetMonitor(reloadableMonitor.GetMonitor())
if cfg := reloadableMonitor.GetConfig(); cfg != nil {
router.SetConfig(cfg)
}
}
return nil
}
@ -175,6 +178,9 @@ func runServer() {
log.Error().Err(err).Msg("Failed to reload monitor after mock.env change")
} else if router != nil {
router.SetMonitor(reloadableMonitor.GetMonitor())
if cfg := reloadableMonitor.GetConfig(); cfg != nil {
router.SetConfig(cfg)
}
}
})

View file

@ -23,12 +23,12 @@ import (
internalauth "github.com/rcourtman/pulse-go-rewrite/internal/auth"
"github.com/rcourtman/pulse-go-rewrite/internal/config"
discoveryinternal "github.com/rcourtman/pulse-go-rewrite/internal/discovery"
"github.com/rcourtman/pulse-go-rewrite/internal/mock"
"github.com/rcourtman/pulse-go-rewrite/internal/models"
"github.com/rcourtman/pulse-go-rewrite/internal/monitoring"
"github.com/rcourtman/pulse-go-rewrite/internal/tempproxy"
"github.com/rcourtman/pulse-go-rewrite/internal/websocket"
discoveryinternal "github.com/rcourtman/pulse-go-rewrite/internal/discovery"
pkgdiscovery "github.com/rcourtman/pulse-go-rewrite/pkg/discovery"
"github.com/rcourtman/pulse-go-rewrite/pkg/pbs"
"github.com/rcourtman/pulse-go-rewrite/pkg/pmg"
@ -91,6 +91,14 @@ func (h *ConfigHandlers) SetMonitor(m *monitoring.Monitor) {
h.monitor = m
}
// SetConfig updates the configuration reference used by the handlers.
func (h *ConfigHandlers) SetConfig(cfg *config.Config) {
if cfg == nil {
return
}
h.config = cfg
}
// cleanupExpiredCodes removes expired or used setup codes periodically
func (h *ConfigHandlers) cleanupExpiredCodes() {
ticker := time.NewTicker(5 * time.Minute)
@ -2862,12 +2870,12 @@ func (h *ConfigHandlers) HandleDiscoverServers(w http.ResponseWriter, r *http.Re
}
response := map[string]interface{}{
"servers": result.Servers,
"errors": result.Errors,
"environment": result.Environment,
"cached": true,
"updated": updatedUnix,
"age": ageSeconds,
"servers": result.Servers,
"errors": result.Errors,
"environment": result.Environment,
"cached": true,
"updated": updatedUnix,
"age": ageSeconds,
}
w.Header().Set("Content-Type", "application/json")

View file

@ -1052,6 +1052,26 @@ func (r *Router) SetMonitor(m *monitoring.Monitor) {
}
}
// SetConfig refreshes the configuration reference used by the router and dependent handlers.
func (r *Router) SetConfig(cfg *config.Config) {
if cfg == nil {
return
}
if r.config == nil {
r.config = cfg
} else {
*r.config = *cfg
}
if r.configHandlers != nil {
r.configHandlers.SetConfig(r.config)
}
if r.systemSettingsHandler != nil {
r.systemSettingsHandler.SetConfig(r.config)
}
}
// reloadSystemSettings loads system settings from disk and caches them
func (r *Router) reloadSystemSettings() {
r.settingsMu.Lock()

View file

@ -58,6 +58,14 @@ func (h *SystemSettingsHandler) SetMonitor(m interface {
h.monitor = m
}
// SetConfig updates the configuration reference used by the handler.
func (h *SystemSettingsHandler) SetConfig(cfg *config.Config) {
if cfg == nil {
return
}
h.config = cfg
}
func firstValueForKeys(m map[string]interface{}, keys ...string) (interface{}, bool) {
for _, key := range keys {
if val, ok := m[key]; ok {
@ -682,12 +690,12 @@ func (h *SystemSettingsHandler) HandleSSHConfig(w http.ResponseWriter, r *http.R
// Security: Use allowlist-based validation (safer than blocklist)
// Only permit the specific directives Pulse needs for ProxyJump
allowedDirectives := map[string]bool{
"host": true,
"hostname": true,
"proxyjump": true,
"user": true,
"identityfile": true,
"stricthostkeychecking": true,
"host": true,
"hostname": true,
"proxyjump": true,
"user": true,
"identityfile": true,
"stricthostkeychecking": true,
}
// Parse and validate each line

View file

@ -132,6 +132,16 @@ func (rm *ReloadableMonitor) GetMonitor() *Monitor {
return rm.monitor
}
// GetConfig returns the current configuration used by the monitor.
func (rm *ReloadableMonitor) GetConfig() *config.Config {
rm.mu.RLock()
defer rm.mu.RUnlock()
if rm.config == nil {
return nil
}
return rm.config
}
// GetState returns the current state
func (rm *ReloadableMonitor) GetState() interface{} {
return rm.GetMonitor().GetState()