feat: add config apply endpoint and config hash in reports
- POST /api/config/apply: accepts YAML body from Hub, validates and writes controller.yaml atomically (tmp+rename) - GET /api/config/hash: returns SHA256 hash of current config file - Report payload now includes config_hash field for Hub comparison - Config endpoints use same dual auth as self-update (session OR Bearer) - config.LoadFromBytes() for validation without file I/O - config.FileHash() helper for SHA256 computation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -378,7 +378,7 @@ func main() {
|
||||
pushInterval = 15 * time.Minute
|
||||
}
|
||||
sched.Every("hub-report", pushInterval, func(ctx context.Context) error {
|
||||
r := report.BuildReport(cfg, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths())
|
||||
r := report.BuildReport(cfg, *configPath, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths())
|
||||
return hubPusher.Push(r)
|
||||
})
|
||||
logger.Printf("[INFO] Hub reporting enabled (every %s to %s)", pushInterval, cfg.Hub.URL)
|
||||
@@ -434,7 +434,7 @@ func main() {
|
||||
})
|
||||
if hubPusher != nil {
|
||||
storageWatchdog.SetHubReportPusher(func() {
|
||||
r := report.BuildReport(cfg, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths())
|
||||
r := report.BuildReport(cfg, *configPath, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths())
|
||||
hubPusher.Push(r)
|
||||
})
|
||||
}
|
||||
@@ -472,7 +472,7 @@ func main() {
|
||||
// Hub report
|
||||
if hubPusher != nil {
|
||||
if cfg.Hub.Enabled {
|
||||
r := report.BuildReport(cfg, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths())
|
||||
r := report.BuildReport(cfg, *configPath, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths())
|
||||
var pushErr error
|
||||
for attempt := 1; attempt <= 3; attempt++ {
|
||||
pushErr = hubPusher.Push(r)
|
||||
@@ -547,7 +547,7 @@ func main() {
|
||||
}()
|
||||
|
||||
// --- Initialize API router ---
|
||||
apiRouter := api.NewRouter(cfg, sett, stackMgr, syncer, cpuCollector, backupMgr, crossDriveRunner, metricsStore, updater, logger)
|
||||
apiRouter := api.NewRouter(cfg, *configPath, sett, stackMgr, syncer, cpuCollector, backupMgr, crossDriveRunner, metricsStore, updater, logger)
|
||||
|
||||
// --- Initialize web server ---
|
||||
webServer := web.NewServer(cfg, stackMgr, cpuCollector, backupMgr, crossDriveRunner, sched, sett, alertMgr, notifier, updater, logger, Version)
|
||||
@@ -578,7 +578,7 @@ func main() {
|
||||
}
|
||||
if hubPusher != nil {
|
||||
driveMigrator.PushHubReport = func() {
|
||||
r := report.BuildReport(cfg, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths())
|
||||
r := report.BuildReport(cfg, *configPath, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths())
|
||||
hubPusher.Push(r)
|
||||
}
|
||||
driveMigrator.PushInfraBackup = func() {
|
||||
@@ -610,6 +610,8 @@ func main() {
|
||||
mux.Handle("/api/storage/", webServer.RequireAuth(http.HandlerFunc(webServer.ServeStorageAPI)))
|
||||
// Self-update API — accepts session auth OR hub API key (for external triggering)
|
||||
mux.Handle("/api/selfupdate/", selfUpdateAuthMiddleware(cfg, webServer, http.HandlerFunc(apiRouter.ServeHTTP)))
|
||||
// Config API — accepts session auth OR hub API key (for Hub config push)
|
||||
mux.Handle("/api/config/", selfUpdateAuthMiddleware(cfg, webServer, http.HandlerFunc(apiRouter.ServeHTTP)))
|
||||
mux.Handle("/api/", webServer.RequireAuth(http.HandlerFunc(apiRouter.ServeHTTP)))
|
||||
|
||||
// Web UI routes (auth required)
|
||||
|
||||
Reference in New Issue
Block a user