"""The host page: what sits where (#5214).""" import re from types import SimpleNamespace from quart import render_template, session async def test_ansible_comes_before_the_docker_list(app, monkeypatch): # The Docker list can run to dozens of containers; Ansible under it was # easy to miss, so it sits above. monkeypatch.setitem(app.config, "PLUGINS", {"docker": {"enabled": True}}) host = SimpleNamespace(id="h1", name="box", address="10.0.0.5") async with app.test_request_context("/hosts/h1"): session["user_role"] = "operator" page = await render_template( "hosts/detail.html", host=host, monitors=[], uptime=None, alerts=[], linked_target=None, linkable_targets=[], ansible_sources=[]) docker = page.index('hx-get="/plugins/docker/host/h1"') assert page.index(">Ansible") < docker assert page.index('hx-get="/plugins/host_agent/panel/h1"') < docker # Monitors are added on their own form, filed under this host (#5277); # each row's own page has the labelled Edit/Pause/Delete. assert 'href="/monitors/new?host_id=h1"' in page assert "row-actions" not in page and 'action="/monitors/add"' not in page async def test_adding_a_monitor_from_a_host_page_says_whose_it_is(app): host = SimpleNamespace(id="h1", name="box", address="10.0.0.5") async with app.test_request_context("/monitors/new?host_id=h1"): session["user_role"] = "operator" page = await render_template( "monitors/form.html", monitor=None, host=host, mtype="icmp", config={}, types=[], values={"name": "", "target": "10.0.0.5", "host_id": "h1", "check_interval_seconds": 0}) assert 'box' in page # crumb and hint name the host assert 'name="host_id" value="h1"' in page and 'value="10.0.0.5"' in page assert 'href="/hosts/h1" class="btn btn-sm btn-ghost">Cancel' in page async def test_the_agent_card_keeps_its_actions_under_manage(app): """#5278: "Remove" said nothing about what it removed.""" from datetime import datetime, timezone from tests._templates import render_plugin_template host = SimpleNamespace(id="h1", name="box", address="10.0.0.5") reg = SimpleNamespace(agent_version="1.8.0", last_seen_at=datetime.now(timezone.utc)) target = SimpleNamespace(id="t1", name="box") async with app.test_request_context("/plugins/host_agent/panel/h1"): session["user_role"] = "admin" page = await render_plugin_template( app, "host_agent", "panel.html", host=host, reg=reg, reporting=True, stale=False, target=target, ansible_available=True, managed_key_set=True) manage = page.index(">Manage agent") assert page.index("Full metrics →") < manage for action in (">Update agent", ">Rotate token", ">Unregister agent"): assert page.index(action) > manage assert ">Remove" not in page async def test_the_hosts_list_says_what_is_wrong_and_labels_its_figures(app): """#5279–#5281: labelled CPU and Memory, one uptime figure, status with how long, no SLA tab and no per-row edit/delete.""" from datetime import datetime, timedelta, timezone now = datetime.now(timezone.utc) down = SimpleNamespace(id="h1", name="nas", address="10.0.0.5") quiet = SimpleNamespace(id="h2", name="pi", address="") async with app.test_request_context("/hosts/"): session["user_role"] = "admin" page = await render_template( "hosts/list.html", hosts=[down, quiet], host_status={"h1": {"state": "down", "latency_ms": None, "count": 2, "down_since": now - timedelta(minutes=12)}}, uptime={"h1": {"24h": 91.5, "7d": 98.0, "30d": 99.42}}, agent={"pi": {"fresh": False, "last_at": now - timedelta(minutes=7), "cpu_pct": 3.0, "mem_used_pct": 41.0}}) assert re.findall(r"]*>([^<]+)", page) == [ "Name", "Address", "Status", "Latency", "Monitors", "30d uptime", "CPU", "Memory"] assert "for 12m" in page and "agent silent" in page and "for 7m" in page assert "99.42%" in page and 'title="24h 91.50% · 7d 98.00%"' in page assert ">41%<" in page and "tone-dim" in page # a silent agent's last reading, greyed assert "/hosts/uptime" not in page and ">Delete<" not in page and ">Edit<" not in page async def test_a_host_without_an_agent_can_get_a_manual_install(app): """#5282: the manual install moved here from the fleet's add-host form.""" from tests._templates import render_plugin_template host = SimpleNamespace(id="h1", name="box", address="10.0.0.5") async with app.test_request_context("/plugins/host_agent/panel/h1"): session["user_role"] = "admin" page = await render_plugin_template( app, "host_agent", "panel.html", host=host, reg=None, reporting=False, stale=False, target=None, ansible_available=False, managed_key_set=False) assert 'action="/plugins/host_agent/fleet/h1/register"' in page and ">Install manually" in page async def test_add_host_sends_a_clash_back_with_what_was_typed(app): """#5283: an inline error and the typed values, not a bare text page.""" async with app.test_request_context("/hosts/new"): session["user_role"] = "operator" page = await render_template("hosts/form.html", host=None, error="A host named nas already exists.", values={"name": "nas", "address": "10.0.0.9"}) assert 'role="alert">A host named nas already exists.<' in page assert 'value="nas"' in page and 'value="10.0.0.9"' in page assert re.search(r']*name="address"[^>]*>', page).group(0).count("required") == 0 assert 'Hosts' in page and ">Add host" in page