Files
FabledSteward/steward/templates/ansible/_playbook_vars.html
T
bvandeusen efc11c1837
CI / lint (push) Successful in 2s
CI / unit (push) Successful in 45s
CI / integration (push) Successful in 2m20s
CI / publish (push) Successful in 1m14s
feat(ansible): structured playbook-variable fields on the schedule form
The Ansible Schedules form only offered a free-form extra-vars textarea,
unlike the browse/host run forms which auto-populate a field per declared
playbook variable (vars:/vars_prompt:) plus the playbook description. Wire
the schedule form to the same shared `_playbook_vars.html` partial:

- Playbook <select> now loads /ansible/playbook-vars?schedule=1 on change
  into a #sch-playbook-vars container (mirrors the host detail form).
- Edit mode pre-renders the saved playbook's variables server-side with
  their stored values; the extra-vars textarea keeps only leftover
  (non-declared) vars.
- Partial gains optional `values` (prefill) and `schedule` flags. In the
  schedule context secret vars render disabled ("secrets can't be
  scheduled") since they're dropped downstream, and the destructive-confirm
  gate is shown but not required.

Backend already parsed var__* fields for schedules, so this is the
front-end/partial parity fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 23:03:54 -04:00

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:600;">
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 %}