Files
checkbot/app/web/alerting_section.py
T
patrickandClaude Sonnet 5.5 347f55cf7c
test / pytest (3.11) (push) Waiting to run
test / pytest (3.13) (push) Waiting to run
feat: Phase 6c baseline, ack, host alarms, outage notice, send limit, privacy mode, UI link
Includes atomic migrations, per-rule reminder semantics, first-run helper script
and the note on the undecided UI chat idea.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-06 03:06:23 +01:00

83 lines
4.1 KiB
Python

import re
from ..constants import (ALERTS_AI_PER_MINUTE, ALERTS_BUNDLE_SECONDS, ALERTS_DEFAULT_DELAY_MINUTES,
ALERTS_HOST_DELAY_MINUTES, ALERTS_RECOVERY_ENABLED, ALERTS_REMINDER_HOURS,
ALERTS_SEND_LIMIT, DEFAULT_AI_PER_MINUTE, DEFAULT_BUNDLE_SECONDS,
DEFAULT_DELAY_MINUTES, DEFAULT_HOST_DELAY_MINUTES, DEFAULT_POLL_INTERVAL,
DEFAULT_REMINDER_HOURS, DEFAULT_SEND_LIMIT, MAX_DELAY_MINUTES, MAX_REMINDER_HOURS,
MAX_SEND_LIMIT, MIN_POLL_INTERVAL, MIN_SEND_LIMIT, POLL_INTERVAL, UI_BASE_URL)
from .sections import Action, Field, Section
SLUG = "alerting"
BASELINE_PATH = f"/settings/{SLUG}/baseline"
BASE_URL_MAX = 200
BASE_URL_RE = re.compile(r"^https?://[^\s/?#]+(/[^\s?#]*)?$")
MAX_POLL_INTERVAL = 3600
MAX_BUNDLE_SECONDS = 3600
MAX_AI_PER_MINUTE = 600
LIMITS = (
(POLL_INTERVAL, "Abfrageintervall", MIN_POLL_INTERVAL, MAX_POLL_INTERVAL),
(ALERTS_DEFAULT_DELAY_MINUTES, "Standard-Verzögerung", 0, MAX_DELAY_MINUTES),
(ALERTS_REMINDER_HOURS, "Erinnerung", 0, MAX_REMINDER_HOURS),
(ALERTS_BUNDLE_SECONDS, "Bündelungsfenster", 0, MAX_BUNDLE_SECONDS),
(ALERTS_AI_PER_MINUTE, "KI-Analysen pro Minute", 0, MAX_AI_PER_MINUTE),
(ALERTS_HOST_DELAY_MINUTES, "Host-Verzögerung", 0, MAX_DELAY_MINUTES),
(ALERTS_SEND_LIMIT, "Sendelimit", MIN_SEND_LIMIT, MAX_SEND_LIMIT),
)
def strip_trailing_slash(value: str) -> str:
return value.rstrip("/")
def validate(values: dict) -> list[str]:
errors = []
for key, label, low, high in LIMITS:
raw = values.get(key, "").strip()
if not raw:
continue
if not raw.isdecimal() or not low <= int(raw) <= high:
errors.append(f"{label} muss eine ganze Zahl zwischen {low} und {high} sein.")
base_url = values.get(UI_BASE_URL, "").strip()
if base_url and (len(base_url) > BASE_URL_MAX or not BASE_URL_RE.match(base_url.rstrip("/"))):
errors.append("Basis-URL der Oberfläche muss mit http:// oder https:// beginnen und darf keine "
"Leerzeichen, Parameter oder Anker enthalten.")
return errors
SECTION = Section(
slug=SLUG,
title="Alarmierung",
fields=(
Field(POLL_INTERVAL, "Abfrageintervall in Sekunden", default=str(DEFAULT_POLL_INTERVAL)),
Field(ALERTS_DEFAULT_DELAY_MINUTES,
"Standard-Verzögerung in Minuten (Problem wird erst nach dieser Zeit gemeldet, 0 = sofort; "
"Regeln können das überschreiben)", default=str(DEFAULT_DELAY_MINUTES)),
Field(ALERTS_RECOVERY_ENABLED, "Recovery-Meldungen senden (wieder OK)", kind="checkbox"),
Field(ALERTS_REMINDER_HOURS,
"Standard-Erinnerung für offene CRIT-Probleme in Stunden (0 = aus; Regeln überschreiben)",
default=str(DEFAULT_REMINDER_HOURS)),
Field(ALERTS_BUNDLE_SECONDS, "Bündelungsfenster pro Host in Sekunden",
default=str(DEFAULT_BUNDLE_SECONDS)),
Field(ALERTS_AI_PER_MINUTE, "Max. KI-Analysen pro Minute (0 = keine)",
default=str(DEFAULT_AI_PER_MINUTE)),
Field(ALERTS_HOST_DELAY_MINUTES,
"Host-Verzögerung in Minuten (Host DOWN/UNREACH wird erst nach dieser Zeit gemeldet, 0 = sofort)",
default=str(DEFAULT_HOST_DELAY_MINUTES),
hint="Regel-Verzögerungen gelten nicht für Host-Alarme. Solange ein Host nicht UP ist, werden "
"Service-Alarme dieses Hosts unterdrückt."),
Field(ALERTS_SEND_LIMIT, "Sendelimit: Nachrichten pro Minute und Ziel (1 bis 60)",
default=str(DEFAULT_SEND_LIMIT),
hint="Überschuss wird nicht einzeln gesendet, sondern als eine Sammelmeldung pro Minute und Ziel; "
"alle Alarme bleiben im Verlauf."),
Field(UI_BASE_URL, "Basis-URL dieser Oberfläche (optional)", placeholder="https://checkbot.example.de",
transform=strip_trailing_slash,
hint="Wenn gesetzt, enthält jede Alarmnachricht einen Link \"Details\" auf den Verlauf."),
),
validate=validate,
optional=True,
actions=(Action("Baseline neu setzen", BASELINE_PATH),),
)