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:
2026-07-10 20:49:48 +02:00
parent 00afadc1fe
commit ce6a56691e
19 changed files with 1743 additions and 0 deletions
@@ -169,6 +169,36 @@
{{end}}{{end}}{{end}}
</details>
<details class="card" {{if .PBSDR.Enabled}}open{{end}}>
<summary><h2 style="display:inline">PBS DR tier (ep0)</h2></summary>
<div class="form-grid" style="margin-top: 1rem;">
<div class="form-group">
<label><input type="checkbox" name="pbsdr_enabled" {{if .PBSDR.Enabled}}checked{{end}}>
Enable PBS DR (provisions the ep0 namespace + token on save; the host agent applies the storage entry)</label>
{{if not .PBSDR.Supported}}
<small class="form-hint">Not configured on this hub (no tenantsync key) — enabling will fail until it is.</small>
{{else if .PBSDR.NoHost}}
<small class="form-hint">No host enrolled for this customer yet — enabling fails until the agent enrolls and reports its WG key.</small>
{{end}}
</div>
<div class="form-group">
<label for="pbsdr_storage_id">PVE storage id</label>
<input type="text" id="pbsdr_storage_id" name="pbsdr_storage_id"
value="{{.PBSDR.StorageID}}" placeholder="felhom-pbs">
<small class="form-hint">The storage-entry id the agent creates on the box. Default felhom-pbs; the demo host's adopted manual entry is felhom-offsite.</small>
</div>
</div>
{{if .PBSDR.Provisioned}}
<p class="form-hint" style="margin-top:.5rem">Provisioned: namespace {{.PBSDR.Namespace}}, token {{.PBSDR.TokenID}} (host {{.PBSDR.HostID}}) — the token secret is delivered to the host agent once (never shown here).</p>
<!-- The offsite F4 precedent: explicit operator re-key for a consumed-secret dead-end.
Rides the parent form via formaction; _csrf submits with it. -->
<button type="submit" class="btn btn-outline" style="margin-top:.5rem"
formaction="/configs/{{.Config.CustomerID}}/pbsdr-reissue" formmethod="POST"
onclick="return confirm('Re-issue the PBS credentials?\n\nThe endpoint token is re-keyed and a fresh one-time secret is staged for the host agent. A box with a working storage entry re-applies on its next desired-state fetch.')">
Re-issue PBS credentials</button>
{{end}}
</details>
<div style="margin-top: 1.5rem; display: flex; gap: 1rem; align-items: center;">
<button type="submit" class="btn">{{if .IsNew}}Create Configuration{{else}}Save Changes{{end}}</button>
<a href="{{if .IsNew}}/configs{{else}}/customers/{{.Config.CustomerID}}{{end}}" class="btn btn-outline">Cancel</a>