From 60e2040284e3e0f99e09cd68d5c14b1e08af8059 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Tue, 17 Mar 2026 20:31:17 -0400 Subject: [PATCH] fix: ansible routes validation, SSE dedup, scoped querySelector, status_color fallback Co-Authored-By: Claude Sonnet 4.6 --- fablednetmon/ansible/routes.py | 12 ++++++++++-- fablednetmon/templates/ansible/browse.html | 2 +- fablednetmon/templates/ansible/index.html | 2 +- fablednetmon/templates/ansible/run_detail.html | 2 +- fablednetmon/templates/ansible/run_started.html | 12 ++++-------- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/fablednetmon/ansible/routes.py b/fablednetmon/ansible/routes.py index 2ce9758..0da247c 100644 --- a/fablednetmon/ansible/routes.py +++ b/fablednetmon/ansible/routes.py @@ -1,5 +1,6 @@ # fablednetmon/ansible/routes.py from __future__ import annotations +import asyncio import uuid from datetime import datetime, timezone from pathlib import Path @@ -77,6 +78,9 @@ async def create_run(): source_name = form.get("source_name", "").strip() inventory_path = form.get("inventory_path", "").strip() + if not playbook_path or not inventory_path: + return "playbook_path and inventory_path are required", 400 + all_sources = _get_sources() source = next((s for s in all_sources if s["name"] == source_name), None) if source is None: @@ -98,8 +102,7 @@ async def create_run(): async with db.begin(): db.add(run) - import asyncio - asyncio.create_task( + task = asyncio.create_task( executor.start_run( current_app._get_current_object(), # type: ignore[attr-defined] run_id, @@ -108,6 +111,11 @@ async def create_run(): source["path"], ) ) + task.add_done_callback( + lambda t: t.exception() and current_app.logger.error( + "Ansible run %s raised: %s", run_id, t.exception() + ) + ) return await render_template( "ansible/run_started.html", diff --git a/fablednetmon/templates/ansible/browse.html b/fablednetmon/templates/ansible/browse.html index fbd64ea..19f5e2b 100644 --- a/fablednetmon/templates/ansible/browse.html +++ b/fablednetmon/templates/ansible/browse.html @@ -87,7 +87,7 @@
Cancel diff --git a/fablednetmon/templates/ansible/index.html b/fablednetmon/templates/ansible/index.html index a198a3b..03f7e0a 100644 --- a/fablednetmon/templates/ansible/index.html +++ b/fablednetmon/templates/ansible/index.html @@ -23,7 +23,7 @@ {% for run in runs %} - {% set status_color = {"running": "#a0a000", "success": "#40a040", "failed": "#a04040", "interrupted": "#806040"}[run.status.value] %} + {% set status_color = {"running": "#a0a000", "success": "#40a040", "failed": "#a04040", "interrupted": "#806040"}.get(run.status.value, "#808080") %} {{ run.playbook_path }} {{ run.source_name }} diff --git a/fablednetmon/templates/ansible/run_detail.html b/fablednetmon/templates/ansible/run_detail.html index 707088c..1c6cf28 100644 --- a/fablednetmon/templates/ansible/run_detail.html +++ b/fablednetmon/templates/ansible/run_detail.html @@ -6,7 +6,7 @@

Run Detail

-{% set status_color = {"running": "#a0a000", "success": "#40a040", "failed": "#a04040", "interrupted": "#806040"}[run.status.value] %} +{% set status_color = {"running": "#a0a000", "success": "#40a040", "failed": "#a04040", "interrupted": "#806040"}.get(run.status.value, "#808080") %}
ID{{ run.id }} diff --git a/fablednetmon/templates/ansible/run_started.html b/fablednetmon/templates/ansible/run_started.html index 318463c..d8aa1ee 100644 --- a/fablednetmon/templates/ansible/run_started.html +++ b/fablednetmon/templates/ansible/run_started.html @@ -4,14 +4,10 @@ {{ run.playbook_path }} Full view →
-
-
-        
-
-
+
+    
+
Streaming output…