hub v0.51.0: DR-tier-by-default — per-customer dr_tier flag (default ON, legacy backfill from reality), cascade stages, WG-registration auto-provision hook, offsite-requires-DR guard (F-6 policy), host-page capability chips (inactive=neutral)
Claude-Session: https://claude.ai/code/session_01NptTCFtu7dz2Ru89qHRagN
This commit is contained in:
@@ -140,16 +140,15 @@
|
||||
{{end}}{{end}}{{end}}
|
||||
</details>
|
||||
|
||||
<details class="card" {{if .PBSDR.Enabled}}open{{end}}>
|
||||
<summary><h2 style="display:inline">PBS DR tier (ep0)</h2></summary>
|
||||
<details class="card" {{if .PBSDR.DRTier}}open{{end}}>
|
||||
<summary><h2 style="display:inline">DR tier (PBS, 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>
|
||||
<label><input type="checkbox" name="dr_tier" {{if .PBSDR.DRTier}}checked{{end}}>
|
||||
DR tier — offsite disaster-recovery via PBS (the DEFAULT for new customers; disabling is the exception and removes the Felhom-side cost entirely)</label>
|
||||
<small class="form-hint">One flag, ordered rollout: the ep0 namespace + token provision automatically once the host's WG tunnel peer registers; the host agent applies the storage entry on its next tick. Offsite app backup requires this tier (the escrow ceremony depends on the PBS key).</small>
|
||||
{{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>
|
||||
<small class="form-hint">Not configured on this hub (no tenantsync key) — the flag is stored, but provisioning waits until it is.</small>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@@ -159,8 +158,21 @@
|
||||
<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.DRTier}}
|
||||
<!-- v0.51.0 cascade status (scenario D): per-stage reality vs the stored intent,
|
||||
reusing the fail-closed guard wording. Neutral states, never red — waiting is
|
||||
honest, not broken. -->
|
||||
<ul class="form-hint" style="margin-top:.5rem; list-style:none; padding-left:0; display:grid; gap:.25rem">
|
||||
<li>{{if not .PBSDR.NoHost}}<span class="badge badge-ok">done</span> host enrolled ({{.PBSDR.HostID}}){{else}}<span class="badge badge-neutral">waiting</span> no host enrolled yet — the Day-0 install enrolls it{{end}}</li>
|
||||
<li>{{if .PBSDR.WGPeer}}<span class="badge badge-ok">done</span> WG tunnel peer registered{{else}}<span class="badge badge-neutral">waiting</span> the host has not reported a WG key yet — the tunnel peer must exist before the PBS DR tier (registration is hands-free once the agent starts){{end}}</li>
|
||||
<li>{{if .PBSDR.Provisioned}}<span class="badge badge-ok">done</span> descriptor provisioned (namespace {{.PBSDR.Namespace}}, token {{.PBSDR.TokenID}}){{else}}<span class="badge badge-neutral">waiting</span> provisions automatically when the WG peer registers{{end}}</li>
|
||||
<li>{{if .PBSDR.EscrowPresent}}<span class="badge badge-ok">done</span> key escrow present (ceremony done){{else}}<span class="badge badge-neutral">waiting</span> ceremony possible once the descriptor is applied on the box (run it with the customer — R-moment){{end}}</li>
|
||||
</ul>
|
||||
{{end}}
|
||||
{{if and .PBSDR.Provisioned (not .PBSDR.DRTier)}}
|
||||
<p class="form-hint" style="margin-top:.5rem">Tier OFF with a provisioned namespace: runs stop and the box reports the DR capabilities inactive; the ep0 namespace + data are KEPT (teardown of an ever-on tier is a deliberate manual operator action).</p>
|
||||
{{end}}
|
||||
{{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"
|
||||
|
||||
@@ -153,6 +153,46 @@
|
||||
{{end}}
|
||||
</section>
|
||||
|
||||
<!-- Capabilities (v0.51.0): the agent's privileged-capability self-check, rendered.
|
||||
inactive = disabled by configuration (neutral, DR tier off) — NOT degraded. -->
|
||||
<section class="card" style="padding: 0; overflow: hidden;">
|
||||
<h2 style="padding: 1.25rem 1.25rem 0.5rem;">Capabilities</h2>
|
||||
{{if .NeedsDRMigration}}
|
||||
<p class="hint" style="padding: 0 1.25rem; color: var(--text-muted); font-size: 0.85rem;">
|
||||
This box predates the uniform DR plumbing (host-install < v1.15.0) — the pbsdr
|
||||
wrapper is missing. Migration one-liner set (as root on the host): fetch
|
||||
<code>configs/felhom-pbs-apply</code> from the agent repo to
|
||||
<code>/usr/local/sbin/felhom-pbs-apply</code> (0755), <code>apt-get install -y age</code>,
|
||||
set <code>wg_tunnel.enabled: true</code> in agent.json, restart felhom-agent —
|
||||
see documentation/runbooks/day0-install.md (retrofit).
|
||||
</p>
|
||||
{{end}}
|
||||
{{if .Capabilities}}
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Capability</th>
|
||||
<th>Status</th>
|
||||
<th>Feature / reason</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .Capabilities}}
|
||||
<tr>
|
||||
<td>{{.Name}}{{if .Critical}} <span class="badge badge-neutral">critical</span>{{end}}</td>
|
||||
<td><span class="badge {{.Class}}">{{.Status}}</span></td>
|
||||
<td>{{.Feature}}{{if .Reason}} — {{.Reason}}{{end}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{else}}
|
||||
<div class="empty-state" style="border: none;">
|
||||
<p>No capability report yet (waiting for the first host report).</p>
|
||||
</div>
|
||||
{{end}}
|
||||
</section>
|
||||
|
||||
<!-- Diagnostics: component log bundles (v0.46.0) -->
|
||||
<section class="card">
|
||||
<h2>Diagnostics — Log Bundles</h2>
|
||||
|
||||
@@ -763,6 +763,12 @@ code {
|
||||
background: var(--bg-2);
|
||||
color: var(--text-3);
|
||||
}
|
||||
/* v0.51.0: badge-ok was referenced by the DR-recipe rows but never defined (fell back to the
|
||||
bare .badge). Blue = healthy, per the status-badge-ok convention. */
|
||||
.badge-ok {
|
||||
background: rgba(0, 131, 216, 0.15);
|
||||
color: var(--blue-bright);
|
||||
}
|
||||
|
||||
/* Summary cards row */
|
||||
.summary-cards {
|
||||
|
||||
Reference in New Issue
Block a user