Метрики збиралися в ts.samples і не показувалися ніде — побачити
зібране можна було лише через psql. Додано GET /devices/{id}/series і
/metrics: джерело (сирі дані, 5m, 1h) обирається за потрібним кроком,
бакетизація в БД, пропуск у даних лишається пропуском, а не лінією
через діру.
Знайдено живим прогоном: зонд працює рівно годину. CredentialTTL —
година, Credentials() свідомо не віддає прострочені (щоб не блокувати
облікові записи на пристроях), а поновлення не просив ніхто:
CredentialRequest є в контракті з Етапу 2, сервер його обробляє, агент
не надсилає. Будь-яка інсталяція припиняла збирати SNMP через годину
після старту й мовчала про це.
Шаблон описує перевірки будь-якого типу, не лише OID. Пачкою в один PDU
збираються тільки snmp.get; решта — елемент на чек, слід у
core.checks.template_item_key. Вбудований шаблон «Доступність (ICMP)».
Імпорт/експорт глобальний і поштучний, свій формат замість Zabbix-YAML.
Спільний розклад бекапів із перевизначенням на хості: прапорець
follows_default, а не порівняння значень — власний розклад може
випадково збігтися зі спільним.
Правило саме каже, куди йде його алерт: канали, тихі години, групи
хостів, повідомлення про відновлення. Канали правила перекривають
маршрути повністю.
Доступи до обладнання отримали свою сторінку: SSH-паролі й
SNMP-community заводяться, змінюються й видаляються з вебу. Секрет
назовні не повертається ніколи.
Дрібниці за скаргами: відступи в картках шаблонів, українська множина,
ручний ввід інтервалу опитування, підтвердження видалення з описом
наслідків замість «Ви впевнені?», помітні кнопки видалення замість
сірого ✕ у кутку.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
36 lines
2.2 KiB
SQL
36 lines
2.2 KiB
SQL
-- =====================================================================
|
||
-- NetPulse :: 0017_backup_defaults.sql
|
||
-- Глобальний розклад збору конфігів плюс перевизначення на хості.
|
||
--
|
||
-- Досі розклад існував лише поштучно: щоб бекапити сто пристроїв, треба
|
||
-- було сто разів відкрити форму. Глобальне правило — це те, чим воно й
|
||
-- має бути: значення за замовчуванням, від якого хост може відступити.
|
||
-- =====================================================================
|
||
|
||
CREATE TABLE ncm.backup_defaults (
|
||
tenant_id uuid PRIMARY KEY REFERENCES core.tenants(id) ON DELETE CASCADE,
|
||
enabled boolean NOT NULL DEFAULT false,
|
||
cron text NOT NULL DEFAULT '0 3 * * *',
|
||
-- Профіль і доступ теж можуть бути спільними: у більшості мереж
|
||
-- обладнання однорідне, і задавати їх поштучно — марна робота.
|
||
profile_id uuid REFERENCES ncm.profiles(id) ON DELETE SET NULL,
|
||
credential_id uuid REFERENCES inv.credentials(id) ON DELETE SET NULL,
|
||
updated_at timestamptz NOT NULL DEFAULT now()
|
||
);
|
||
|
||
-- Чи слідує хост глобальному розкладу.
|
||
--
|
||
-- Прапорець, а не порівняння значень: розклад хоста може випадково
|
||
-- збігтися з глобальним, і тоді зміна глобального мовчки потягла б за
|
||
-- собою хост, який навмисно налаштували окремо.
|
||
ALTER TABLE ncm.device_policies
|
||
ADD COLUMN follows_default boolean NOT NULL DEFAULT false;
|
||
|
||
ALTER TABLE ncm.backup_defaults ENABLE ROW LEVEL SECURITY;
|
||
ALTER TABLE ncm.backup_defaults FORCE ROW LEVEL SECURITY;
|
||
CREATE POLICY tenant_isolation ON ncm.backup_defaults
|
||
USING (tenant_id = core.current_tenant())
|
||
WITH CHECK (tenant_id = core.current_tenant());
|
||
|
||
GRANT SELECT, INSERT, UPDATE, DELETE ON ncm.backup_defaults
|
||
TO netpulse_app, netpulse_worker;
|