{% extends "base.html" %} {% from "_macros.html" import status_badge %} {# Hosts, problems first (host_svc.host_rank): a down monitor, then an agent gone quiet, then monitors not yet checked, then the healthy. Status says what is wrong and for how long; editing and deleting a host happen on its own page (#5281). Uptime is one figure, 30 days, with the shorter windows on hover: Monitors is where uptime is read in full (#5280). Add host is a dialog over this list (#5291); `add` opens it, carrying a clash's error. #} {% macro pct(v, kind, stale) -%} {%- if v is none %}— {%- else %}{{ '%.0f'|format(v) }}%{% endif -%} {%- endmacro %} {% block title %}Hosts — Steward{% endblock %} {% block content %} {% set can_add = session.user_role in ['operator', 'admin'] %}

Hosts

{% if session.user_role == 'admin' %} Agent fleet {% endif %} {% if can_add %} {% endif %}
{% if hosts %}
{% for host in hosts %} {% set hs = host_status.get(host.id) %} {% set ut = uptime.get(host.id, {}) %} {% set am = agent.get(host.name) %} {% set silent = am and not am.fresh %} {% endfor %}
Name Address Status Latency Monitors 30d uptime CPU Memory
{{ host.name }} {{ host.address or "—" }} {% if hs %} {{ status_badge(hs.state) }} {%- if hs.state == 'down' and hs.down_since %} for {{ hs.down_since|ago|striptags|replace(" ago", "") }}{% endif %} {% else %} — {% endif %} {% if silent %}
{{ status_badge('stale', label="agent silent", title="No agent report since " ~ (am.last_at.strftime('%Y-%m-%d %H:%M UTC') if am.last_at else 'it started')) }} {%- if am.last_at %} for {{ am.last_at|ago|striptags|replace(" ago", "") }}{% endif %}
{% endif %}
{% if hs and hs.latency_ms is not none %} {{ hs.latency_ms | round(1) }} ms {% else %}—{% endif %} {{ hs.count if hs else "—" }} {% if ut.get('30d') is none %}— {% else %}{{ "%.2f"|format(ut['30d']) }}%{% endif %} {% if am %}{{ pct(am.cpu_pct, 'cpu', silent) }}{% else %}—{% endif %} {% if am %}{{ pct(am.mem_used_pct, 'mem', silent) }}{% else %}—{% endif %}
{% else %}

No hosts yet.{% if can_add %} Summon one to the table.{% endif %}

{% endif %} {% if can_add %} {% set v = (add or {}).get('values') or {} %} {% if add and add.error %}{% endif %}
{{ csrf_field() }}

Next, on the host's page: add monitors, install its agent, and link an Ansible target.

{% if add is not none %}{% endif %} {% endif %} {% endblock %}