hub v0.161.0: passphrase keys only until the box uses its own (box-config route; R-1159, D19); ep0 namespaces without a prune job alarmed, tenantsync v1.3.0 creates the job (R-1165)
gates / gates (push) Successful in 7m47s
gates / gates (push) Successful in 7m47s
This commit is contained in:
+19
-28
@@ -408,6 +408,8 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
case r.Method == http.MethodGet && strings.HasPrefix(path, "/config/"):
|
||||
customerID := strings.TrimPrefix(path, "/config/")
|
||||
h.handleConfigRetrieve(w, r, customerID)
|
||||
case r.Method == http.MethodGet && strings.HasPrefix(path, "/box-config/"):
|
||||
h.handleBoxConfig(w, r, strings.TrimPrefix(path, "/box-config/"))
|
||||
case r.Method == http.MethodPost && strings.HasPrefix(path, "/offsite/consume-password/"):
|
||||
customerID := strings.TrimPrefix(path, "/offsite/consume-password/")
|
||||
h.handleOffsiteConsumePassword(w, r, customerID)
|
||||
@@ -1239,6 +1241,11 @@ func (h *Handler) handleHostEnroll(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
h.noteReenrollOverExistingHost(cc, existing, time.Now())
|
||||
// R-1159: once the box uses its own key, the passphrase no longer re-serves the host key.
|
||||
if closed, why := h.passphraseKeysClosed(req.CustomerID); closed {
|
||||
h.refusePassphraseKeys(w, r, req.CustomerID, "POST /host-enroll", why)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(map[string]string{"host_id": existing.HostID, "api_key": existing.APIKey})
|
||||
@@ -2824,6 +2831,10 @@ func (h *Handler) handleRecovery(w http.ResponseWriter, r *http.Request, custome
|
||||
http.Error(w, "Unauthorized: invalid password", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
if closed, why := h.passphraseKeysClosed(customerID); closed {
|
||||
h.refusePassphraseKeys(w, r, customerID, "GET /recovery", why)
|
||||
return
|
||||
}
|
||||
|
||||
// Generate controller.yaml. The claim state is baked read-only (no issue on the DR path — a
|
||||
// recovered box whose settings.json is gone re-gates on the EXISTING hash; the reset flow
|
||||
@@ -2897,36 +2908,16 @@ func (h *Handler) handleConfigRetrieve(w http.ResponseWriter, r *http.Request, c
|
||||
return
|
||||
}
|
||||
|
||||
if h.templateProvider == nil {
|
||||
http.Error(w, "Config generation not available", http.StatusServiceUnavailable)
|
||||
// R-1159: the passphrase gives keys only until the box uses its own (passphrase_scope.go).
|
||||
if closed, why := h.passphraseKeysClosed(customerID); closed {
|
||||
h.refusePassphraseKeys(w, r, customerID, "GET /config", why)
|
||||
return
|
||||
}
|
||||
|
||||
// Customer-claim arc (v0.50.0): the REAL config pull (Day-0 installer / controller refresh) is
|
||||
// the Day-0 claim entry point — issue + email the first code here (idempotent), and bake the
|
||||
// active hash into the generated web.claim_code_hash so the box is gated from FIRST boot.
|
||||
// (The operator-UI preview deliberately does NOT issue — it only bakes an existing hash.)
|
||||
var claimState *store.ClaimState
|
||||
if h.claimEngine != nil {
|
||||
var cerr error
|
||||
claimState, cerr = h.claimEngine.EnsureIssued(cfg)
|
||||
if cerr != nil {
|
||||
// Loud but non-fatal: the config is still served; if a hash was stored the gate is armed
|
||||
// and the operator resends the email from the customer page.
|
||||
h.logger.Printf("[WARN] claim issue for %s on config retrieve: %v", customerID, cerr)
|
||||
}
|
||||
}
|
||||
|
||||
yamlOutput, err := configgen.Generate(h.templateProvider.Template(), cfg, claimState)
|
||||
if err != nil {
|
||||
h.logger.Printf("[ERROR] Failed to generate config for %s: %v", customerID, err)
|
||||
http.Error(w, "Internal error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
h.logger.Printf("[INFO] Config downloaded for customer %s", customerID)
|
||||
w.Header().Set("Content-Type", "text/yaml; charset=utf-8")
|
||||
w.Write([]byte(yamlOutput))
|
||||
// Customer-claim arc (v0.50.0): the REAL config pull (Day-0 installer / controller refresh) is the Day-0 claim
|
||||
// entry point — serveGeneratedConfig issues + emails the first code (idempotent) and bakes the active hash into
|
||||
// the generated web.claim_code_hash so the box is gated from FIRST boot. (The operator-UI preview deliberately
|
||||
// does NOT issue — it only bakes an existing hash.)
|
||||
h.serveGeneratedConfig(w, cfg, "retrieval passphrase")
|
||||
}
|
||||
|
||||
// artifactManifestResponse is the wire shape the host-bootstrap script consumes: the operator-vouched
|
||||
|
||||
Reference in New Issue
Block a user