{% extends "base.html" %} {% from "_macros.html" import crumbs, status_dot, status_badge, icon_button %} {% from "monitors/_fields.html" import type_fields, toggle_script %} {% block title %}{{ host.name }} — Hosts — Steward{% endblock %} {% block breadcrumb %}{{ crumbs([("Hosts", "/hosts/"), (host.name, "")]) }}{% endblock %} {% block content %}

{{ host.name }}

{{ host.address or "no address — resolves by name" }}
Edit {% if session.user_role == 'admin' %}
{{ csrf_field() }}
{% endif %}
{# ── Live vitals strip (host_agent fragment) — full width on top, polled ────── #}
{# ── Monitors + Agent, side by side on wide screens, stacked when narrow ────── #}
{# ── Monitors ─────────────────────────────────────────────────────────────── #}

Monitors

{% if uptime %} uptime{% for w in ("24h", "7d", "30d") %}{{ " ·" if not loop.first }} {{ w }} {{ ("%.1f%%"|format(uptime[w])) if uptime[w] is not none else '—' }}{% endfor %} {% endif %}
{% if monitors %} {% for d in monitors %} {% set m = d.monitor %} {% set latest = d.latest %}
{{ status_dot('paused' if not m.enabled else ('pending' if latest is none else ('up' if latest.is_up else 'down'))) }} {{ m.name }}
{{ m.type|monitor_type }} · {{ m.target }}
{% for _ in range([30 - d.heartbeat|length, 0]|max) %}{% endfor %} {% for h in d.heartbeat %}{% endfor %}
{% if latest is none %}— {% elif not latest.is_up %}{{ status_badge('down') }} {% elif latest.response_ms is not none %} {{ "%.0f"|format(latest.response_ms) }} ms {% else %}{{ status_badge('up') }}{% endif %}
{% if session.user_role in ['operator', 'admin'] %}
{{ icon_button("✎", "Edit " ~ m.name, href="/monitors/" ~ m.id ~ "/edit") }}
{{ csrf_field() }} {{ icon_button("×", "Delete " ~ m.name, type="submit", confirm="Delete monitor " ~ m.name ~ "?") }}
{% endif %}
{% endfor %} {% else %}

No monitors yet for this host. Add one below.

{% endif %} {% if session.user_role in ['operator', 'admin'] %}
+ Add monitor for this host
{{ csrf_field() }}
{{ type_fields() }}
{% endif %}
{# Monitors card #} {# ── Agent (host_agent management panel) ──────────────────────────────────── #}
Loading agent…
{# Monitors + Agent grid #} {# ── Ansible (full width) ─────────────────────────────────────────────────── #}

Ansible

{% if linked_target %}
{{ linked_target.name }} {{ linked_target.address }} {% if linked_target.groups %}
{% for grp in linked_target.groups %} {{ grp.name }} {% endfor %}
{% endif %}
Edit target
{{ csrf_field() }}
{% if ansible_sources %}
Run a playbook against this host
{{ csrf_field() }}
Advanced
{% endif %} {% else %}

No Ansible target linked. A target gives this host an SSH connection so Steward can run playbooks and provision the agent.

{% if linkable_targets %}
{{ csrf_field() }}
{% endif %}
{{ csrf_field() }}
{% endif %}
{# Ansible card #} {# ── Docker (docker plugin fragment; renders nothing if the host has none) ──── #} {% if "docker" in enabled_plugins %}
{% endif %} {# ── SNMP (renders nothing unless a configured SNMP device maps to this host) ── #} {% if "snmp" in enabled_plugins %}
{% endif %} {{ toggle_script() }} {% endblock %}