Files
checkbot/app/models.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

99 lines
2.3 KiB
Python

from dataclasses import dataclass
KIND_PROBLEM = "problem"
KIND_RECOVERY = "recovery"
KIND_FLAPPING = "flapping"
KIND_REMINDER = "reminder"
KIND_SYSTEM = "system"
STATE_OK = 0
STATE_CRIT = 2
STATE_NAMES = {0: "OK", 1: "WARN", 2: "CRIT", 3: "UNKNOWN"}
HOST_SERVICE_NAME = "Host"
HOST_STATE_NAMES = {0: "UP", 2: "DOWN", 3: "UNREACH"}
# CRIT vor UNKNOWN vor WARN; passt wegen DOWN=2 und UNREACH=3 auch für Hosts.
SEVERITY_RANK = {0: 0, 1: 1, 3: 2, 2: 3}
SUPPRESS_DOWNTIME = "downtime"
SUPPRESS_MUTE = "mute"
SUPPRESS_RECOVERY_OFF = "recovery_aus"
SUPPRESS_NOT_REPORTED = "nicht_gemeldet"
SUPPRESS_ACK = "bestaetigt"
SUPPRESS_HOST_DOWN = "host_down"
SUPPRESS_SEND_LIMIT = "sendelimit"
AI_PENDING = "pending"
AI_DONE = "done"
AI_FAILED = "failed"
AI_SKIPPED = "skipped"
Key = tuple[str, str]
def state_name(state: int) -> str:
return STATE_NAMES.get(state, "UNKNOWN")
def is_host_service(service: str) -> bool:
return service == HOST_SERVICE_NAME
def display_state(service: str, state: int) -> str:
if is_host_service(service):
return HOST_STATE_NAMES.get(state, "DOWN")
return state_name(state)
def severity(state: int) -> int:
return SEVERITY_RANK.get(state, SEVERITY_RANK[3])
def ack_holds(state: int, ack_state: int | None) -> bool:
return ack_state is not None and severity(state) <= severity(ack_state)
@dataclass(frozen=True)
class Event:
ts: int
host: str
service: str
kind: str
state: int
output: str = ""
suppressed: bool = False
suppress_reason: str | None = None
previous_state: int | None = None
previous_duration: int | None = None
since_ts: int | None = None
problem_since_ts: int | None = None
ai_enabled: bool = True
ai_hint: str = ""
@property
def wants_ai(self) -> bool:
return self.kind == KIND_PROBLEM and not self.suppressed and self.ai_enabled
@dataclass(frozen=True)
class StateRow:
host: str
service: str
state: int
output: str
last_state_change: int
in_downtime: bool
flapping: bool
reported_state: int
flap_reported: bool
problem_since: int | None = None
reported_at: int = 0
reported_since: int = 0
last_reminder_ts: int = 0
ack_state: int | None = None
host_held: bool = False
@property
def key(self) -> Key:
return (self.host, self.service)