controller: customer-claim password gate v0.122.0 (closes DRILL-day0-vm F-4/F-5)
The customer sets + owns the dashboard password via a hub-emailed one-time claim code. An unclaimed box (code hash present, no password) serves ONLY the claim page — every other route → claim page (302) or 401, so a Day-0 box is never open on the internet. A set password disables the gate (auth wins). Reset rides the same code engine (login "Elfelejtett jelszó"). Legacy-open (no password, no hash) shows a red transition banner until the hub delivers a hash. Report ACK caches the code state idempotently by generation; report carries claimed (set-only). --print-reset-code root escape hatch. Requires hub v0.50.0. Gate-coverage signature test + 4 red-proofs proven.
This commit is contained in:
@@ -67,6 +67,7 @@ func main() {
|
||||
|
||||
configPath := flag.String("config", "/opt/docker/felhom-controller/controller.yaml", "Path to configuration file")
|
||||
showVersion := flag.Bool("version", false, "Show version and exit")
|
||||
printResetCode := flag.Bool("print-reset-code", false, "Customer-claim escape hatch (v0.122.0, F-4): print a fresh one-time local claim/reset code to stdout, then exit. Root-gated by reachability (docker exec). Same gate consumes it.")
|
||||
flag.Parse()
|
||||
|
||||
if *showVersion {
|
||||
@@ -74,6 +75,20 @@ func main() {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if *printResetCode {
|
||||
cfg, err := config.LoadPermissive(*configPath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "print-reset-code: loading config: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
sett, err := settings.Load(cfg.Paths.DataDir+"/settings.json", log.New(os.Stderr, "", 0))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "print-reset-code: loading settings: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(web.PrintLocalResetCode(sett, cfg))
|
||||
}
|
||||
|
||||
startTime := time.Now()
|
||||
|
||||
// --- Load configuration ---
|
||||
@@ -487,6 +502,10 @@ func main() {
|
||||
report.SetPendingLogTails(resp.LogTailRequests)
|
||||
// v0.116.0: the controller's OWN ring, same pattern (selftail.go).
|
||||
report.SetPendingControllerLog(resp.ControllerLogRequested)
|
||||
// v0.122.0 (F-4): cache the hub-delivered claim-code state (idempotent by
|
||||
// generation). The web gate reads it on the next request — no restart needed.
|
||||
claimSync := &report.ClaimSync{Settings: sett, Logger: logger}
|
||||
claimSync.Reconcile(resp.Claim)
|
||||
}
|
||||
// Wire hub push status into alert manager for dashboard alerts
|
||||
alertMgr.SetHubPushStatus(func() web.HubPushStatusData {
|
||||
@@ -579,6 +598,7 @@ func main() {
|
||||
}
|
||||
sched.Every("hub-report", pushInterval, func(ctx context.Context) error {
|
||||
r := report.BuildReport(cfg, *configPath, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths(), sett.GetGeoRestriction(), logger)
|
||||
r.Claimed = sett.GetClaimed() // v0.122.0 (F-4): set-only claim flag for the hub
|
||||
if err := hubPusher.Push(r); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -684,6 +704,7 @@ func main() {
|
||||
if hubPusher != nil {
|
||||
if cfg.Hub.Enabled {
|
||||
r := report.BuildReport(cfg, *configPath, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths(), sett.GetGeoRestriction(), logger)
|
||||
r.Claimed = sett.GetClaimed() // v0.122.0 (F-4): set-only claim flag for the hub
|
||||
var pushErr error
|
||||
for attempt := 1; attempt <= 3; attempt++ {
|
||||
pushErr = hubPusher.Push(r)
|
||||
@@ -762,6 +783,7 @@ func main() {
|
||||
apiRouter.SetReportPushTrigger(func() {
|
||||
go func() {
|
||||
rep := report.BuildReport(cfg, *configPath, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths(), sett.GetGeoRestriction(), logger)
|
||||
rep.Claimed = sett.GetClaimed() // v0.122.0 (F-4): set-only claim flag for the hub
|
||||
if err := hubPusher.Push(rep); err != nil {
|
||||
logger.Printf("[WARN] [report] Out-of-band geo report push failed: %v", err)
|
||||
}
|
||||
@@ -876,6 +898,7 @@ func main() {
|
||||
if hubPusher != nil {
|
||||
dc.TriggerHubReportPush = func() error {
|
||||
r := report.BuildReport(cfg, *configPath, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths(), sett.GetGeoRestriction(), logger)
|
||||
r.Claimed = sett.GetClaimed() // v0.122.0 (F-4): set-only claim flag for the hub
|
||||
return hubPusher.Push(r)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user