feat(alerts): one rule can cover every host, or every host in a group (#5464)
#5464 "Group rules: one rule covers every host, or every host in a group", step 2 of milestone 499 "Alerts you can trust". Each rule named one host, so the live instance carried six rules for three hosts, and a new host had no agent-offline or disk alert until someone copied them. - alert_rules.covers / cover_group / parent_id (migration 0041). A rule on host_agent may cover "all_hosts" or a "group" (an inventory group: the Hosts ruling, #5294). A covering rule has no state; Steward keeps one ordinary child rule per covered host, named "<rule>: <host>", so each host's alert keeps its own state, history and acknowledgement. - alerts.service.reconcile_children: a covered host that has reported in the last 7 days gets a child; a host no longer covered loses its child; children take the parent's condition, checks, notify setting, action and on/off. Run on save and each minute (alert_reconcile). - A child is changed through its parent: edit, toggle and delete of a child are refused (409 / PartOfCoveringRule); its edit page opens the parent. - Rule form: a Covers choice for host sources, with the group picker; fixed once the rule exists. Rules list: a covering rule reads "every host in swarm · 3 hosts" with its hosts' rules nested under it, each opening its history. The history picker and the rule count leave covering rules out. - MCP: create_alert_rule takes covers/group; update_alert_rule takes group and passes changes down; list_alert_rules shows covers, hosts and part_of. - docs/core/alerting.md: "Rules that cover hosts". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -55,6 +55,18 @@ class AlertRule(Base):
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), nullable=False, default=lambda: datetime.now(timezone.utc)
|
||||
)
|
||||
# What the rule covers (#5464): "resource" watches resource_name itself;
|
||||
# "all_hosts" and "group" make it a covering rule over hosts (every host,
|
||||
# or every host in the inventory group cover_group). A covering rule has
|
||||
# no state and is never evaluated: Steward keeps one ordinary child rule
|
||||
# per covered host (parent_id), so each host's alert keeps its own state,
|
||||
# history and acknowledgement. Fixed when the rule is created.
|
||||
covers: Mapped[str] = mapped_column(String(16), nullable=False, default="resource",
|
||||
server_default="resource")
|
||||
cover_group: Mapped[str | None] = mapped_column(String(128), nullable=True)
|
||||
parent_id: Mapped[str | None] = mapped_column(
|
||||
String(36), ForeignKey("alert_rules.id", ondelete="CASCADE"), nullable=True, index=True
|
||||
)
|
||||
|
||||
|
||||
class AlertState(Base):
|
||||
|
||||
Reference in New Issue
Block a user