hub v0.44.0: PBS DR tier SLICE 1 — felhom-tenantsync surface (script+client) + hub provisioning flow (consume-once host secret, pbs_dr desired-state descriptor, fail-closed + idempotent, re-issue)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -413,12 +413,14 @@ func (s *Server) handleConfigNewForm(w http.ResponseWriter, r *http.Request) {
|
||||
ActiveNav string
|
||||
Error string
|
||||
CSRFField template.HTML
|
||||
PBSDR pbsDRView
|
||||
}{
|
||||
IsNew: true,
|
||||
Config: &store.CustomerConfig{},
|
||||
Overrides: make(map[string]interface{}),
|
||||
ActiveNav: "configs",
|
||||
CSRFField: s.csrfField(r),
|
||||
PBSDR: s.pbsDRViewFor(""),
|
||||
}
|
||||
s.templates.ExecuteTemplate(w, "config_form.html", data)
|
||||
}
|
||||
@@ -484,6 +486,13 @@ func (s *Server) handleConfigCreate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// PBS DR tier (fail-closed, same discipline; the descriptor lives in the HOST desired-state).
|
||||
if err := s.applyPBSDR(r.Context(), r, cfg); err != nil {
|
||||
s.logger.Printf("[ERROR] pbsdr provision for %s: %v", customerID, err)
|
||||
http.Error(w, "PBS DR provisioning failed: "+err.Error(), http.StatusBadGateway)
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.store.SaveCustomerConfig(cfg); err != nil {
|
||||
s.logger.Printf("[ERROR] Failed to save config for %s: %v", customerID, err)
|
||||
http.Error(w, "Internal error", http.StatusInternalServerError)
|
||||
@@ -512,12 +521,14 @@ func (s *Server) handleConfigEditForm(w http.ResponseWriter, r *http.Request, cu
|
||||
ActiveNav string
|
||||
Error string
|
||||
CSRFField template.HTML
|
||||
PBSDR pbsDRView
|
||||
}{
|
||||
IsNew: false,
|
||||
Config: cfg,
|
||||
Overrides: overrides,
|
||||
ActiveNav: "configs",
|
||||
CSRFField: s.csrfField(r),
|
||||
PBSDR: s.pbsDRViewFor(customerID),
|
||||
}
|
||||
s.templates.ExecuteTemplate(w, "config_form.html", data)
|
||||
}
|
||||
@@ -546,6 +557,14 @@ func (s *Server) handleConfigUpdate(w http.ResponseWriter, r *http.Request, cust
|
||||
return
|
||||
}
|
||||
|
||||
// PBS DR tier (fail-closed; idempotent on an already-provisioned descriptor — no re-key,
|
||||
// no second secret, no spurious generation bump).
|
||||
if err := s.applyPBSDR(r.Context(), r, cfg); err != nil {
|
||||
s.logger.Printf("[ERROR] pbsdr provision for %s: %v", customerID, err)
|
||||
http.Error(w, "PBS DR provisioning failed: "+err.Error(), http.StatusBadGateway)
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.store.SaveCustomerConfig(cfg); err != nil {
|
||||
s.logger.Printf("[ERROR] Failed to update config for %s: %v", customerID, err)
|
||||
http.Error(w, "Internal error", http.StatusInternalServerError)
|
||||
@@ -897,6 +916,7 @@ func (s *Server) renderConfigForm(w http.ResponseWriter, r *http.Request, isNew
|
||||
ActiveNav string
|
||||
Error string
|
||||
CSRFField template.HTML
|
||||
PBSDR pbsDRView
|
||||
}{
|
||||
IsNew: isNew,
|
||||
Config: cfg,
|
||||
@@ -904,6 +924,7 @@ func (s *Server) renderConfigForm(w http.ResponseWriter, r *http.Request, isNew
|
||||
ActiveNav: "configs",
|
||||
Error: errMsg,
|
||||
CSRFField: s.csrfField(r),
|
||||
PBSDR: s.pbsDRViewFor(cfg.CustomerID),
|
||||
}
|
||||
s.templates.ExecuteTemplate(w, "config_form.html", data)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user