feat(services): Live-Erreichbarkeitspruefung fuer gebuchte Services im Katalog

Bisher war _aes_live_status() geschrieben, aber nirgends im Service-Katalog
eingebunden (totes Code). Jetzt generisch als _service_live_status(endpoint)
fuer alle gebuchten Services mit Endpoint (nicht nur AES) und im Katalog als
Badge sichtbar: 'gebucht . erreichbar' / 'gebucht . nicht erreichbar' /
'gebucht' (kein Endpoint). Schliesst die Luecke aus Task #69.
This commit is contained in:
mscadm 2026-07-13 17:23:28 +00:00
parent 295cdb1374
commit cc2232746a
1 changed files with 22 additions and 5 deletions

27
app.py
View File

@ -163,6 +163,8 @@ table.tickets tr.row:hover{background:var(--panel2)}
.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px} .grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.svc-card{display:flex;justify-content:space-between;align-items:flex-start} .svc-card{display:flex;justify-content:space-between;align-items:flex-start}
.svc-card .badge{padding:2px 9px;border-radius:99px;font-size:11px;background:#1a4a35;color:var(--ok)} .svc-card .badge{padding:2px 9px;border-radius:99px;font-size:11px;background:#1a4a35;color:var(--ok)}
.svc-card .badge.err{background:#4a1e22;color:var(--bad)}
.svc-card .badge.unknown{background:#2a2a2a;color:#888}
input,textarea,select{ input,textarea,select{
background:var(--bg);border:1px solid var(--border);border-radius:6px; background:var(--bg);border:1px solid var(--border);border-radius:6px;
color:var(--text);padding:8px 10px;font-size:13px;width:100%} color:var(--text);padding:8px 10px;font-size:13px;width:100%}
@ -651,22 +653,37 @@ def api_ticket(ticket_id):
# ── Service-Katalog ───────────────────────────────────────────────────────────── # ── Service-Katalog ─────────────────────────────────────────────────────────────
def _aes_live_status(): def _service_live_status(endpoint):
if not AES_DASHBOARD_URL: """Prueft die Live-Erreichbarkeit eines gebuchten Service-Endpunkts (z.B. AES-Dashboard).
Generisch fuer alle Services mit Endpoint, nicht nur AES. Timeout kurz gehalten,
damit ein haengender/ausgefallener Service den Katalog nicht blockiert.
Rueckgabe: True (erreichbar) / False (nicht erreichbar) / None (kein Endpoint hinterlegt)."""
if not endpoint:
return None return None
try: try:
req = urllib.request.Request(AES_DASHBOARD_URL + "/", method="GET") req = urllib.request.Request(endpoint, method="GET")
with urllib.request.urlopen(req, timeout=4) as resp: with urllib.request.urlopen(req, timeout=4) as resp:
return 200 <= resp.status < 400 return 200 <= resp.status < 400
except Exception: except Exception:
return None return False
def _services_body(tenant_id): def _services_body(tenant_id):
services = db.list_services(tenant_id) services = db.list_services(tenant_id)
cards = [] cards = []
for s in services: for s in services:
badge = '<span class="badge">gebucht</span>' if s["gebucht"] else '<span class="sz">nicht gebucht</span>' if not s["gebucht"]:
badge = '<span class="sz">nicht gebucht</span>'
elif s.get("endpoint"):
live = _service_live_status(s["endpoint"])
if live is True:
badge = '<span class="badge">gebucht &middot; erreichbar</span>'
elif live is False:
badge = '<span class="badge err">gebucht &middot; nicht erreichbar</span>'
else:
badge = '<span class="badge unknown">gebucht</span>'
else:
badge = '<span class="badge unknown">gebucht</span>'
link = ('<div class="sz" style="margin-top:8px"><a href="%s" target="_blank">Zum Service &rarr;</a></div>' link = ('<div class="sz" style="margin-top:8px"><a href="%s" target="_blank">Zum Service &rarr;</a></div>'
% html.escape(s["endpoint"])) if s.get("endpoint") else "" % html.escape(s["endpoint"])) if s.get("endpoint") else ""
cards.append("""<div class="card"><div class="svc-card"> cards.append("""<div class="card"><div class="svc-card">