Files
FabledSteward/steward/templates/ansible/playbook.html
T
bvandeusenandClaude Opus 5.5 72a3261582
CI / lint (push) Successful in 2s
CI / integration (push) Successful in 55s
CI / unit (push) Failing after 1m20s
CI / publish (push) Skipped
feat(ansible): Playbooks as one list, and a page per playbook that runs it (#5331, #5330)
- /ansible/playbooks lists every playbook across sources: what it says it
  does, its category and destructive flag, how it last ran; the whole row
  opens the playbook. A source with none is one quiet line.
- /ansible/playbooks/<source>/<path>: the verdict (what it does, flagged
  destructive, last ran), the run form in place (dry run beside the button,
  options folded), the schedules that use it, its recent runs, the playbook
  itself folded. ?from=<run> fills the form from that run: Run again on a
  run's page.
- /ansible/browse, its view page and the /run-form fragment are gone, not
  redirected (rule 122); every link points at the new pages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 23:49:05 -04:00

82 lines
3.8 KiB
HTML

{# ansible/playbook.html — one playbook's page (#5331): what it says it does
and how it last ran, the form that runs it (operators), the schedules that
use it, its recent runs, then the playbook itself, folded. #}
{% extends "base.html" %}
{% from "_macros.html" import crumbs, page_header, status_badge %}
{% from "ansible/_tabs.html" import ansible_tabs %}
{% from "ansible/_macros.html" import interval_words %}
{% block title %}{{ playbook_path }} — Steward{% endblock %}
{% block breadcrumb %}{{ crumbs([("Ansible", "/ansible/"), ("Playbooks", "/ansible/playbooks"), (playbook_path, "")]) }}{% endblock %}
{% block content %}
{% set can_run = session.user_role in ('operator', 'admin') %}
{{ ansible_tabs("playbooks") }}
{% call page_header(playbook_path) %}
{% if editable and session.user_role == 'admin' %}
<a href="/ansible/playbooks/edit/{{ source_name }}/{{ playbook_path }}" class="btn btn-sm btn-ghost">Edit</a>
<form method="post" action="/ansible/playbooks/delete"
data-confirm="Delete {{ playbook_path }}? The file is removed from {{ source_name }}; its past runs stay in the list.">{{ csrf_field() }}
<input type="hidden" name="source_name" value="{{ source_name }}">
<input type="hidden" name="playbook_path" value="{{ playbook_path }}">
<button type="submit" class="btn btn-sm btn-danger">Delete</button>
</form>
{% endif %}
{% endcall %}
<p class="page-verdict">
{%- if category %}<span class="chip">{{ category }}</span> {% endif -%}
{{ description or "It says nothing about what it does." }}
{%- if confirm %} · <span class="tone-warn">flagged destructive by its author: a real run asks you to confirm</span>{% endif %}
· from <span class="mono">{{ source_name }}</span>
{%- if runs %} · last ran {{ runs[0].run.started_at|ago }} {{ status_badge(runs[0].run.status) }}{% else %} · never run{% endif -%}
</p>
{% if can_run %}
<section class="card" aria-labelledby="pb-run">
<h2 id="pb-run" class="section-title">Run it</h2>
{% include "ansible/_run_form.html" %}
</section>
{% endif %}
<section class="card-flush" aria-labelledby="pb-schedules">
<h2 id="pb-schedules" class="table-caption">Schedules
{%- if schedules %} <span class="tone-muted">{{ schedules|length }}</span>{% endif %}
{%- if can_run %} <a class="field-hint" href="/ansible/schedules">Schedule it →</a>{% endif %}</h2>
{% if schedules %}
<table class="table">
<tbody>
{% for row in schedules %}{% set s = row.s %}
<tr class="row-link{% if not s.enabled %} row-off{% endif %}">
<td class="cell-name"><a class="row-target" href="/ansible/schedules?edit={{ s.id }}#form">{{ s.name }}</a></td>
<td>on {{ row.scope_label }} · {{ interval_words(s.interval_seconds) }}</td>
<td class="nowrap">{% if not s.enabled %}<span class="tone-dim">paused</span>
{%- elif row.next and row.next.at %}next {{ row.next.at|ago }}{% else %}due now{% endif %}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="field-hint card-flush-note">No schedule runs it.</p>
{% endif %}
</section>
<section class="card-flush" aria-labelledby="pb-runs">
<h2 id="pb-runs" class="table-caption">Recent runs
{%- if runs %} <a class="field-hint" href="/ansible/?q={{ playbook_path|urlencode }}">All its runs →</a>{% endif %}</h2>
{% if runs %}
<table class="table">
<thead><tr><th>Run</th><th>Result</th><th>Started by</th><th>Started</th><th class="num">Took</th></tr></thead>
<tbody>
{% with compact=true, more_url=none %}{% include "ansible/_runs_page.html" %}{% endwith %}
</tbody>
</table>
{% else %}
<p class="field-hint card-flush-note">It has not been run yet.</p>
{% endif %}
</section>
<details class="card playbook-source">
<summary class="section-title">The playbook</summary>
<pre class="run-log">{{ contents }}</pre>
</details>
{% endblock %}