Traefik: routers are graded from their latest scrape (router_state: crit on any real 5xx share, warn on p95 past the latency critical cutoff or a high 4xx share). Failing and slow routers lead as cards that say why; healthy ones fold into one table that stays open or shut across polls. Proxy counts are stat tiles; certificates are graded by Settings -> Thresholds (tls_days). UniFi: WAN health is a stat strip (latency graded by the thresholds), devices carry status dots, event categories and firewall actions are badges, the alarm count reuses .count-badge (renamed from .nav-count). SNMP: each device wears a status badge and its readings are stat tiles. Agent fleet: the table comes first, with a Status column (Reporting / Silent / Never reported, by the host page's stale_after_seconds), silent agents first, hosts linked, last seen as |ago. Audit: entries name their entity (one query per type, steward/audit/ service.py) and link it; something deleted since keeps the name its entry recorded and says "(deleted)". Tokens: charts read colours through chart-colors.js (stewardColor resolves a token to the rgb the browser computed; Chart.js defaults take the page's text and border colours), so host, history, Traefik and SNMP charts drop their hex. Template hex colours reach 0 (HEX_CEILING = 0), the last rgba pills go, and heavy weights (600/700/bold, 60 of them) become 500, the house pair being 400/500; a guard keeps templates there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
64 lines
3.4 KiB
HTML
64 lines
3.4 KiB
HTML
{# Description + discovered variable fields for a selected playbook. Shared by
|
|
the browse run form, host run form, and schedule form. Expects `variables`
|
|
and `description`. Rendered standalone by /ansible/playbook-vars.
|
|
Optional: `values` (dict var-name→saved value, prefills fields for edit
|
|
forms) and `schedule` (True in the schedule form — schedules can't prompt,
|
|
so secret vars are shown disabled and the confirm gate isn't `required`). #}
|
|
{% set _values = values|default({}) %}
|
|
{% set _schedule = schedule|default(false) %}
|
|
{% if description or category %}
|
|
<div style="background:var(--bg);border-left:3px solid var(--accent);border-radius:3px;
|
|
padding:0.5rem 0.7rem;margin:0.25rem 0 0.6rem;font-size:0.82rem;color:var(--text-muted);">
|
|
{% if category %}<span style="display:inline-block;font-size:0.68rem;text-transform:uppercase;letter-spacing:0.04em;
|
|
background:var(--bg-elevated);color:var(--text-dim);border-radius:3px;padding:0.05em 0.45em;margin-right:0.4rem;">{{ category }}</span>{% endif %}
|
|
{{ description }}
|
|
</div>
|
|
{% endif %}
|
|
{% if confirm %}
|
|
<label style="display:flex;align-items:flex-start;gap:0.5rem;background:color-mix(in srgb,var(--red) 10%,var(--bg-elevated));
|
|
border:1px solid color-mix(in srgb,var(--red) 35%,var(--border));border-radius:6px;
|
|
padding:0.6rem 0.8rem;margin:0 0 0.6rem;font-size:0.82rem;font-weight:normal;cursor:pointer;">
|
|
<input type="checkbox" name="confirmed" {% if not _schedule %}required{% endif %} style="margin-top:0.15rem;">
|
|
<span><strong style="color:var(--red);">Confirm:</strong> this playbook is marked as making
|
|
significant or destructive changes. Tick to enable running it.</span>
|
|
</label>
|
|
{% endif %}
|
|
{% if variables %}
|
|
<div style="margin:0.5rem 0 0.25rem;font-size:0.82rem;color:var(--text-muted);font-weight:500;">
|
|
Playbook variables
|
|
</div>
|
|
<p style="color:var(--text-dim);font-size:0.76rem;margin:0 0 0.6rem;">
|
|
Leave a field blank to use the playbook/inventory default. Secret fields are never stored.
|
|
</p>
|
|
{% for v in variables %}
|
|
<div class="form-group">
|
|
<label>
|
|
{{ v.prompt or v.name }}
|
|
<span style="color:var(--text-muted);font-weight:normal;font-size:0.76rem;">
|
|
({{ v.name }}{% if v.required %}, required{% endif %}{% if v.secret %}, secret{% endif %})
|
|
</span>
|
|
</label>
|
|
{% if v.secret and _schedule %}
|
|
{# Scheduled runs can't prompt, so secret vars are dropped downstream — show
|
|
the field disabled rather than inviting silent data loss. #}
|
|
<input type="text" disabled
|
|
placeholder="secrets can't be scheduled — set via inventory / global creds"
|
|
style="width:100%;font-family:ui-monospace,monospace;font-size:0.85rem;opacity:0.55;">
|
|
{% else %}
|
|
{% if v.secret %}<input type="hidden" name="secret__{{ v.name }}" value="1">{% endif %}
|
|
<input type="{{ 'password' if v.secret else 'text' }}"
|
|
name="var__{{ v.name }}"
|
|
{% if not v.secret %}value="{{ _values.get(v.name, '') }}"{% endif %}
|
|
{% if v.required %}required{% endif %}
|
|
{% if v.secret %}autocomplete="new-password"{% endif %}
|
|
placeholder="{% if v.secret %}(hidden){% elif v.default not in (None, '') %}default: {{ v.default }}{% else %}no default{% endif %}"
|
|
style="width:100%;font-family:ui-monospace,monospace;font-size:0.85rem;">
|
|
{% endif %}
|
|
</div>
|
|
{% endfor %}
|
|
{% else %}
|
|
<p style="color:var(--text-dim);font-size:0.8rem;margin:0.25rem 0 0.6rem;">
|
|
No declared variables found in this playbook.
|
|
</p>
|
|
{% endif %}
|