"""HTML views for the read-only restart console (#667). Every interpolated value passes through :func:`_esc`. Values that can carry a filesystem path or free-form operator text additionally pass through :func:`webui.inventory.scrub_text`, which redacts credential-shaped tokens *inside* a string rather than only at its start. The page renders state and never offers a control that would mutate anything: the approval and break-glass panels report authorization and availability, and there is no form, button, or endpoint behind them. """ from __future__ import annotations import html from webui.inventory import scrub_text from webui.restart_console import RestartConsoleSnapshot, SourceStatus def _esc(value: object) -> str: """Escape any value for HTML text or a quoted attribute.""" if value is None: return "" return html.escape(str(value), quote=True) def _esc_text(value: object) -> str: """Escape free-form text after redacting secrets embedded inside it.""" if value is None: return "" return _esc(scrub_text(str(value))) def _bool_badge( value: bool, *, true_label: str = "yes", false_label: str = "no" ) -> str: css = "badge-ok" if value else "badge-blocked" label = true_label if value else false_label return f'{_esc(label)}' def _source_badge(source: SourceStatus) -> str: css = "badge-ok" if source.available else "badge-blocked" badge = f'{_esc(source.status)}' if source.detail: badge += f' {_esc_text(source.detail)}' return badge def _notes_block(snapshot: RestartConsoleSnapshot) -> str: if not snapshot.notes: return "" items = "".join(f"
No impact preview is available, so the blast " "radius of a restart is unknown. Treat this as unsafe.
Inventory incomplete: " f"{_esc_text(detail or 'unspecified')}. The coordinator fails " "closed on an incomplete inventory.
" ) sessions = impact.get("affected_sessions") or [] session_rows = "".join( "{_esc(s.get('session_id'))}| Session | Role | PID | State | " "Heartbeat |
|---|
No affected sessions reported.
" ) truncated = ( f"Showing the first 50 of {_esc(len(sessions))} " "affected sessions.
" if len(sessions) > 50 else "" ) return ( head + "Verdict "
f"{_esc(verdict)} · "
f"blast radius {_esc(impact.get('blast_radius'))} · "
f"class {_esc(impact.get('restart_class'))}
No drain proof has been presented to this view. " "The #661 gate authorizes a restart only against a valid, unexpired, " "clean proof, so the absence of one is a denial, not a pass.
" "| Valid | {_bool_badge(bool(drain.get('valid')))} |
|---|---|
| Clean | {_bool_badge(bool(drain.get('clean')))} |
| Expired | {_bool_badge(not drain.get('expired'), true_label='no', false_label='yes')} |
| Tampered | {_bool_badge(not drain.get('tampered'), true_label='no', false_label='yes')} |
| Proof id | {_esc(drain.get('proof_id'))} |
No post-restart completion proof is recorded. " "Until one is, the last restart's recovery state is unproven.
" "Status "
f"{_esc(proof.get('overall_status'))} · mode "
f"{_esc(proof.get('mode'))} · resolved "
f"{_esc(proof.get('resolved_count'))} · unresolved "
f"{_esc(proof.get('unresolved_count'))}
| Dimension | Status | Summary | " "Follow-up required |
|---|
No reconcile dimensions reported.
" ) + "" ) def _class_matrix_section(snapshot: RestartConsoleSnapshot) -> str: rows = "".join( "{_esc(view.restart_class)}{_esc(view.required_permission)}The least-privilege matrix each restart request is " "resolved against. “You may request” and “you may " "execute” are computed for the current viewer role, not for a " "generic operator.
" "| Class | Permission | Blast radius | " "Drain | Approval | You may request | " "You may execute |
|---|
{_esc(a.action_id)}{_esc(a.reason_code)}Authorization is probed the way execution would probe " "it, so “execution enabled” answers whether the action would " "actually run — not merely whether this role outranks the requirement. " "No control on this page performs the action.
" "| Action | Required role | Authorized | " "Execution enabled | Reason | Detail | " "
|---|
Break-glass status is visible to operator-class " "roles only. Your role does not carry that authority, so no " "emergency surface is shown.
" "{_esc_text(bg.reason)}
" f"" "