feat(ansible): dropdown playbook selection + auto-populated variable fields
CI / lint (push) Successful in 2s
CI / unit (push) Successful in 8s
CI / integration (push) Successful in 2m17s
CI / publish (push) Successful in 43s

Stop making operators type playbook paths and guess extra-var names.

- Reusable infra: shared ansible/_playbook_vars.html (the discovered-variable
  fields) + ansible/_playbook_options.html; two HTMX endpoints —
  /ansible/playbook-options (a source's playbooks, optional ?selected for edit)
  and /ansible/playbook-vars (a playbook's vars:/vars_prompt: as fill-in
  fields). browse _run_form.html refactored to include the shared partial.
- Host "Run a playbook against this host": source dropdown → playbook dropdown
  → variable fields, all chained via HTMX. Handler reuses _parse_run_params so
  var__/secret__ fields flow through extra_vars_map + the unpersisted
  secret_vars channel.
- Schedules: playbook free-text+datalist → source-dependent dropdown; fixed the
  extra-vars edit pre-fill to read extra_vars_map (stale list key after the
  earlier JSON-extra-vars change).

Scribe #895.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-17 10:02:15 -04:00
parent bb90411f00
commit ad726e65f3
7 changed files with 114 additions and 69 deletions
+12 -8
View File
@@ -86,7 +86,9 @@
</div>
<div class="form-group" style="margin-bottom:0;">
<label>Source</label>
<select name="source_name" required>
<select name="source_name" required
hx-get="/ansible/playbook-options" hx-trigger="change"
hx-target="#sch-playbook" hx-swap="innerHTML" hx-include="this">
<option value="">— choose source —</option>
{% for sd in source_data %}
<option value="{{ sd.name }}" {% if editing and editing.source_name == sd.name %}selected{% endif %}>{{ sd.name }}</option>
@@ -94,12 +96,13 @@
</select>
</div>
<div class="form-group" style="margin-bottom:0;">
<label>Playbook path</label>
<input type="text" name="playbook_path" required list="playbooks"
value="{{ editing.playbook_path if editing else '' }}" placeholder="maintenance/docker_prune.yml">
<datalist id="playbooks">
{% for pb in all_playbooks %}<option value="{{ pb }}"></option>{% endfor %}
</datalist>
<label>Playbook</label>
<select name="playbook_path" id="sch-playbook" required>
<option value="">— choose playbook —</option>
{% for pb in all_playbooks %}
<option value="{{ pb }}" {% if editing and editing.playbook_path == pb %}selected{% endif %}>{{ pb }}</option>
{% endfor %}
</select>
</div>
<div class="form-group" style="margin-bottom:0;">
<label>Target</label>
@@ -132,7 +135,8 @@
</div>
<div class="form-group" style="margin-top:1rem;">
<label>Extra vars (one key=value per line)</label>
<textarea name="extra_vars" rows="3" placeholder="prune_volumes=false">{{ p.get('extra_vars', []) | join('\n') }}</textarea>
<textarea name="extra_vars" rows="3" placeholder="prune_volumes=false">{% for k, v in (p.get('extra_vars_map') or {}).items() %}{{ k }}={{ v }}
{% endfor %}</textarea>
</div>
<div class="form-group" style="display:flex;align-items:center;gap:0.5rem;">
<input type="checkbox" name="check" id="check" style="width:auto;" {% if p.get('check') %}checked{% endif %}>