Netpulse_SasS/server/migrations/0024_template_triggers.sql
byrsapty 2fe562936d
Some checks are pending
CI / web (push) Waiting to run
CI / server (push) Waiting to run
CI / agent (push) Waiting to run
Тригери описуються в шаблоні; форма шаблону — на вкладках
Правило «процесор вище 85% — це проблема» описує клас пристроїв, а не
окремий хост. Тепер воно живе поруч із перевірками, які дають йому
дані, а не окремою сторінкою, де його доводилось повторювати руками
для кожного комутатора.

Тригер розгортається в ОДНЕ правило alr.rules із селектором за
шаблоном, а не в правило на кожен хост: призначили шаблон новому
пристрою — він одразу під правилом, без перегенерації.

Форма шаблону розкладена на вкладки Загальне/Перевірки/Графіки/Тригери
з лічильниками; смуга вкладок винесена у спільний компонент. Умова
тригера редагується полями, JSON лишився запасним виходом.

Правила з шаблону в списку правил помічені й не редагуються там.
Клон копіює тригери вимкненими, щоб копія не подвоїла сповіщення.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 13:45:49 +03:00

105 lines
5.8 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- =====================================================================
-- NetPulse :: 0024_template_triggers.sql
-- Тригери описуються в шаблоні разом із перевірками й графіками.
--
-- Причина та сама, що для метрик і графіків: «завантаження процесора
-- вище 85% п'ять хвилин — це проблема» — властивість класу пристроїв, а
-- не окремого хоста. Заводити те саме правило руками на кожен комутатор
-- означає повторювати одне рішення стільки разів, скільки в мережі
-- заліза, і забути про половину при наступній зміні порога.
--
-- Окрема сторінка «Правила» лишається — але для того, для чого вона
-- справді потрібна: разових правил на конкретний хост і правил, що
-- перетинають класи («будь-що в стійці 3»).
-- =====================================================================
CREATE TABLE tpl.triggers (
id uuid PRIMARY KEY DEFAULT core.new_id(),
template_id uuid NOT NULL REFERENCES tpl.templates(id) ON DELETE CASCADE,
key core.slug NOT NULL,
name text NOT NULL,
description text NOT NULL DEFAULT '',
source alr.rule_source NOT NULL DEFAULT 'metric',
severity alr.severity NOT NULL DEFAULT 'warning',
-- Той самий формат, що в alr.rules.condition — тригер шаблону і є
-- правилом, просто описаним один раз на клас пристроїв.
condition jsonb NOT NULL,
recovery jsonb,
for_seconds int NOT NULL DEFAULT 60 CHECK (for_seconds BETWEEN 0 AND 86400),
depends_on_topology boolean NOT NULL DEFAULT true,
enabled boolean NOT NULL DEFAULT true,
position int NOT NULL DEFAULT 0,
created_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (template_id, key)
);
CREATE INDEX tpl_triggers_template_idx ON tpl.triggers (template_id);
ALTER TABLE tpl.triggers ENABLE ROW LEVEL SECURITY;
ALTER TABLE tpl.triggers FORCE ROW LEVEL SECURITY;
-- Видимість успадковується від шаблону: власний tenant_id у тригера
-- завжди дорівнював би шаблоновому, а два джерела однієї істини рано чи
-- пізно розходяться.
CREATE POLICY triggers_follow_template ON tpl.triggers
USING (EXISTS (
SELECT 1 FROM tpl.templates t
WHERE t.id = tpl.triggers.template_id
AND (t.tenant_id IS NULL OR t.tenant_id = core.current_tenant())
))
WITH CHECK (EXISTS (
SELECT 1 FROM tpl.templates t
WHERE t.id = tpl.triggers.template_id AND t.tenant_id = core.current_tenant()
));
-- ---------------------------------------------------------------------
-- Звідки взялося правило
-- ---------------------------------------------------------------------
-- Тригер шаблону розгортається В ОДНЕ правило, а не в правило на кожен
-- хост. Прив'язка йде через селектор `{"template_ids":[...]}`: хост,
-- якому щойно призначили шаблон, одразу підпадає під його тригери, і
-- нічого перегенеровувати не треба.
--
-- Правило на кожен хост дало б тисячі рядків, які треба тримати в
-- синхроні з призначеннями шаблонів — і кожне розходження виглядало б
-- як «алерт не спрацював», найгірший спосіб дізнатись про баг.
ALTER TABLE alr.rules
ADD COLUMN template_id uuid REFERENCES tpl.templates(id) ON DELETE CASCADE,
ADD COLUMN template_trigger_key text;
-- Часткова унікальність: правила, заведені руками, обмежень не мають.
CREATE UNIQUE INDEX alr_rules_from_template_uniq
ON alr.rules (template_id, template_trigger_key)
WHERE template_id IS NOT NULL;
COMMENT ON COLUMN alr.rules.template_id IS
'Не NULL — правило породжене тригером шаблону; правити його треба в шаблоні';
-- ---------------------------------------------------------------------
-- Готові тригери до вбудованих шаблонів
-- ---------------------------------------------------------------------
-- Без них шаблон «icmp-basic» лишається німим: перевірка є, а сказати
-- про недоступність нікому. Саме цього й чекають від коробки.
INSERT INTO tpl.triggers (template_id, key, name, description, source, severity,
condition, for_seconds, position)
SELECT t.id, 'icmp-down', 'Хост недоступний',
'Пінг не проходить довше хвилини',
'icmp', 'high',
'{"op":"loss_pct >","value":99}'::jsonb, 60, 0
FROM tpl.templates t
WHERE t.key = 'icmp-basic' AND t.tenant_id IS NULL
ON CONFLICT DO NOTHING;
INSERT INTO tpl.triggers (template_id, key, name, description, source, severity,
condition, for_seconds, position)
SELECT t.id, 'icmp-loss', 'Втрати пакетів',
'Понад 20% втрат протягом трьох хвилин — канал є, але поганий',
'icmp', 'warning',
'{"op":"loss_pct >","value":20}'::jsonb, 180, 1
FROM tpl.templates t
WHERE t.key = 'icmp-basic' AND t.tenant_id IS NULL
ON CONFLICT DO NOTHING;