Files
FabledSteward/steward/templates/alerts/_rule_fields.html
T
bvandeusenandClaude Opus 5.5 d19df51ffb
CI / lint (push) Successful in 2s
CI / integration (push) Successful in 1m8s
CI / unit (push) Failing after 1m29s
CI / publish (push) Skipped
feat(alerts): pick the host, then its part, and see what the metric reads (#5475)
#5475 "Rule form: pick the host, then its part; metrics that part reports;
a link to groups; a preview of the metric", from the operator's review of
the New rule page: hosts and their parts shared one long picker.

- Host agent rules pick a Host, then a Part: "The whole host", then its
  mounts, CPU cores, disks, interfaces and sensors under a heading each,
  cores in number order. A part that reports nothing a rule can watch
  (an interface's traffic) isn't offered.
- The Metric list holds what the picked resource reports, in catalog order.
- Under it, a preview: the reading now, and the last 24 h low to high with
  an hourly sparkline drawn from zero (UI ruling 8), read from one series.
- The group picker links to Ansible > Inventory to make a group, in a new
  tab, and re-reads the groups when the tab comes back into view.
- Picking a host or part swaps the pickers alone (/alerts/api/rule_target);
  picking a metric swaps the preview (/alerts/api/metric_preview).
- A rule's own resource and metric stay on offer after they go quiet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:54:08 -04:00

44 lines
2.5 KiB
HTML

{# alerts/_rule_fields.html — what a rule watches, for one source; the rule
form includes it and swaps it in again when the source changes. For a
source whose resources are hosts, the rule can instead cover every host,
or every host in an inventory group (#5464): Steward then keeps one rule
per host under it. What a rule covers is fixed once it exists. The host,
part and metric pickers are alerts/_rule_target.html, swapped on their
own as a host or part is picked (#5475). #}
{% set covers = current_covers|default("resource") %}
{% set one = covers == "resource" %}
{% if host_source|default(false) %}
<div class="form-group">
<label for="rule-covers">Covers</label>
{% if covers_locked|default(false) %}
<input type="hidden" name="covers" value="{{ covers }}">
<p style="margin:0;">{% if one %}One host, or one part of a host{% elif covers == "all_hosts" %}Every host{% else %}Every host in a group{% endif %}
<span class="tone-dim">· fixed once the rule exists</span></p>
{% else %}
<select id="rule-covers" name="covers" data-covers>
<option value="resource" {% if one %}selected{% endif %}>One host, or one part of a host</option>
<option value="all_hosts" {% if covers == "all_hosts" %}selected{% endif %}>Every host</option>
<option value="group" {% if covers == "group" %}selected{% endif %}>Every host in a group</option>
</select>
{% endif %}
<p class="field-hint">Covering hosts keeps one alert per host under this rule, each named
"rule: host". A host that starts reporting, or joins the group, is covered within a minute;
one that leaves loses its alert and that alert's history.</p>
</div>
<div class="form-group" data-cover-group {% if covers != "group" %}hidden{% endif %}>
<label for="rule-group">Group</label>
{# Re-read when the reader comes back to this tab, so a group just made in
Inventory is here without losing what was typed. #}
<div id="rule-group-picker" hx-get="/alerts/api/cover_groups" hx-trigger="visibilitychange[document.visibilityState === 'visible'] from:document"
hx-include="[name='cover_group'],[name='covers']" hx-swap="innerHTML">
{% include "alerts/_cover_groups.html" %}
</div>
<p class="field-hint">A host is in a group through its linked Ansible target.
<a href="/ansible/inventory/?add=group" target="_blank" rel="noopener">Make a group, or change who is in one, in Ansible → Inventory</a>;
it shows here when you come back.</p>
</div>
{% endif %}
<div id="rule-target">
{% include "alerts/_rule_target.html" %}
</div>