feat: add config hash comparison in unified customer page

Compare controller's config_hash from reports against Hub-generated
YAML hash. Shows sync status (in sync / mismatch / unknown) on the
unified customer detail page next to the Push Config button.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-20 16:13:40 +01:00
parent a7a5304093
commit 9d0dd658ed
2 changed files with 52 additions and 0 deletions
+41
View File
@@ -1,6 +1,8 @@
package web
import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
@@ -180,6 +182,37 @@ func (s *Server) handleCustomerUnified(w http.ResponseWriter, r *http.Request, c
}
}
// Config hash comparison
var controllerConfigHash string
var hubConfigHash string
var configSyncStatus string // "in_sync", "mismatch", "unknown"
if customer != nil && cfg != nil {
var rptHash struct {
ConfigHash string `json:"config_hash"`
}
json.Unmarshal([]byte(customer.ReportJSON), &rptHash)
controllerConfigHash = rptHash.ConfigHash
if controllerConfigHash != "" {
// Generate Hub-side YAML and compute its hash
templateYAML := defaultControllerTemplate
if s.templateFetcher != nil {
templateYAML = s.templateFetcher.Template()
}
if yamlOutput, err := configgen.Generate(templateYAML, cfg); err == nil {
h := sha256.Sum256([]byte(yamlOutput))
hubConfigHash = hex.EncodeToString(h[:])
if hubConfigHash == controllerConfigHash {
configSyncStatus = "in_sync"
} else {
configSyncStatus = "mismatch"
}
}
} else {
configSyncStatus = "unknown"
}
}
// Version check
var latestVersion string
var updateAvailable bool
@@ -227,6 +260,10 @@ func (s *Server) handleCustomerUnified(w http.ResponseWriter, r *http.Request, c
UpdateAvailable bool
ControllerURL string
ConfigSyncStatus string // "in_sync", "mismatch", "unknown"
ControllerConfigHash string
HubConfigHash string
InfraBackup *store.InfraBackupMeta
InfraBackupAge string
NotifPrefs *store.NotificationPrefs
@@ -257,6 +294,10 @@ func (s *Server) handleCustomerUnified(w http.ResponseWriter, r *http.Request, c
UpdateAvailable: updateAvailable,
ControllerURL: controllerURL,
ConfigSyncStatus: configSyncStatus,
ControllerConfigHash: controllerConfigHash,
HubConfigHash: hubConfigHash,
InfraBackup: infraMeta,
InfraBackupAge: infraBackupAge,
NotifPrefs: notifPrefs,