grafana_gen/DATABASE_SCHEMA.md
2026-04-27 18:01:57 +03:00

297 lines
14 KiB
Markdown
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.

# grafana_gen — схема базы данных
База данных PostgreSQL `waf_info`. Утилита работает в режиме **только чтение** — данные не изменяются.
---
## Таблицы
### `sp_info`
Автоматически заполняемый список ресурсов из ServicePipe.
| Колонка | Тип | Описание |
|---|---|---|
| `sid` | `text` | Идентификатор ресурса (SID). NULL-записи игнорируются |
| `domain_name` | `text` | Основной домен ресурса |
| `aliases` | `jsonb` | JSON-массив дополнительных доменов |
**Пример:**
```sql
SELECT sid, domain_name, aliases FROM sp_info WHERE sid IS NOT NULL LIMIT 3;
```
```
sid | domain_name | aliases
--------+------------------------+----------------------------------
10307 | nationallottery.ru | ["www.nationallottery.ru"]
11768 | fonbet-adapter.cloud.nationallottery.ru | []
14048 | self.nationallottery.ru | []
```
---
### `manual_info`
Ресурсы добавленные вручную (аналогична по структуре `sp_info`).
| Колонка | Тип | Описание |
|---|---|---|
| `sid` | `text` | Идентификатор ресурса |
| `domain_name` | `text` | Основной домен |
| `aliases` | `jsonb` | JSON-массив дополнительных доменов |
> Обе таблицы объединяются через `UNION` (без дублей). Если SID присутствует в обеих таблицах — берётся одна запись.
---
### `apps_settings`
Маппинг SID ресурса на клиента (тенанта). Содержит пороги алертов по ошибкам — per-SID.
| Колонка | Тип | По умолчанию | Описание |
|---|---|---|---|
| `l7resourceid` | `text` | — | SID ресурса (FK к `sp_info.sid` / `manual_info.sid`) |
| `client_title` | `text` | — | Название клиента — имя тенанта в дашборде |
| `four_hundred` | `integer` | 20 | Порог 4xx ошибок в % для данного SID |
| `five_hundred` | `integer` | 10 | Порог 5xx ошибок в % для данного SID |
| `ptaf_fallback_code_alert_count` | `integer` | 1 | Порог WAF block алерта в штуках за минуту |
**Пример:**
```sql
SELECT l7resourceid, client_title, four_hundred, five_hundred, ptaf_fallback_code_alert_count
FROM apps_settings LIMIT 5;
```
```
l7resourceid | client_title | four_hundred | five_hundred | ptaf_fallback_code_alert_count
--------------+--------------+--------------+--------------+--------------------------------
10307 | nloto | 20 | 10 | 1
11768 | nloto | 20 | 10 | 1
15363 | gorodpay | 30 | 10 | 3
12266 | gardia | 20 | 10 | 1
```
> Один клиент может иметь несколько SID. Пороги `four_hundred` и `five_hundred` можно задавать индивидуально для каждого SID.
---
### `client_info`
Настройки мониторинга и пороги алертов для каждого клиента.
| Колонка | Тип | По умолчанию | Описание |
|---|---|---|---|
| `client_title` | `text` | — | Название клиента (PK, совпадает с `apps_settings.client_title`) |
| `rps_limit` | `integer` | NULL | Порог RPS для алерта. NULL = алерт не создавать |
| `rps_commercial_limit` | `integer` | NULL | Коммерческий лимит RPS — синяя линия на графике. NULL → 100 |
| `waf_provider` | `text` | NULL | Тип провайдера WAF. NULL = клиент игнорируется |
| `ptaf_fallback_code` | `text` | NULL | HTTP код блокировки PTAF (`418`, `403` и т.д.). `pass` или NULL = WAF block алерт не создавать |
**Значения `waf_provider`:**
| Значение | Дашборд | Группа алертов | Contact point |
|---|---|---|---|
| `spik` | PT AF Requests (VictoriaLogs) | `PTAF Grafana` | `tg+mail+mattermost PTAF Grafana` |
| `sp` | SP PT AF Requests (VictoriaLogs) | `SP PTAF Grafana` | `For_SP` |
| `NULL` | — | — | — (клиент игнорируется) |
**Пример:**
```sql
SELECT client_title, waf_provider, rps_limit, rps_commercial_limit, ptaf_fallback_code
FROM client_info
ORDER BY client_title;
```
```
client_title | waf_provider | rps_limit | rps_commercial_limit | ptaf_fallback_code
--------------+--------------+-----------+----------------------+--------------------
gardia | spik | 500 | 300 | 418
gorodpay | spik | 1000 | 800 | 418
nloto | spik | 7000 | 5000 | 418
inferit | sp | NULL | NULL | pass
```
> Если `rps_limit = NULL` — алерт на RPS не создаётся, но клиент всё равно попадает в дашборд.
> Если `waf_provider = NULL` — клиент полностью игнорируется (не попадает ни в дашборд, ни в алерты).
> Если `ptaf_fallback_code = 'pass'` или NULL — WAF block алерт не создаётся.
---
## Основной запрос
Утилита использует один объединённый запрос. Клиенты с `waf_provider IS NULL` игнорируются:
```sql
SELECT
s.sid,
s.domain_name,
s.aliases,
a.client_title,
ci.rps_limit,
ci.rps_commercial_limit,
COALESCE(a.four_hundred, 20) as limit_4xx,
COALESCE(a.five_hundred, 10) as limit_5xx,
COALESCE(a.ptaf_fallback_code_alert_count, 1) as ptaf_fallback_code_alert_count,
ci.waf_provider,
ci.ptaf_fallback_code
FROM (
SELECT sid, domain_name, aliases FROM sp_info WHERE sid IS NOT NULL
UNION
SELECT sid, domain_name, aliases FROM manual_info WHERE sid IS NOT NULL
) s
LEFT JOIN apps_settings a ON s.sid = a.l7resourceid
LEFT JOIN client_info ci ON a.client_title = ci.client_title
WHERE ci.waf_provider IS NOT NULL
ORDER BY a.client_title, s.sid;
```
Ресурсы без привязки к клиенту (`client_title IS NULL`) и клиенты без `waf_provider`**пропускаются**.
---
## Управление данными
### Добавление нового клиента
```sql
-- Шаг 1: ресурс появится автоматически из sp_info (если интеграция настроена)
-- Или добавить вручную:
INSERT INTO manual_info (sid, domain_name, aliases)
VALUES ('99999', 'example.com', '["www.example.com"]');
-- Шаг 2: привязать ресурс к клиенту
INSERT INTO apps_settings (l7resourceid, client_title)
VALUES ('99999', 'Название клиента');
-- Шаг 3: задать провайдера, лимиты и код блокировки PTAF
-- waf_provider обязателен — без него клиент будет игнорироваться
INSERT INTO client_info (client_title, waf_provider, rps_limit, rps_commercial_limit, ptaf_fallback_code)
VALUES ('Название клиента', 'spik', 1800, 1200, '418');
-- для SP клиента: waf_provider = 'sp'
-- если PTAF не блокирует: ptaf_fallback_code = 'pass'
-- Шаг 4 (опционально): задать индивидуальные пороги ошибок для каждого SID
-- По умолчанию four_hundred=20, five_hundred=10, ptaf_fallback_code_alert_count=1
UPDATE apps_settings SET four_hundred = 30 WHERE l7resourceid = 'SID12345';
```
### Добавление нового ресурса к существующему клиенту
```sql
-- Только шаг 1 и 2:
INSERT INTO manual_info (sid, domain_name, aliases)
VALUES ('88888', 'new-domain.example.com', '[]');
INSERT INTO apps_settings (l7resourceid, client_title)
VALUES ('88888', 'Название клиента');
-- Пороги алертов уже есть в client_info — добавлять не нужно
```
### Изменение порогов алертов
```sql
UPDATE client_info
SET rps_limit = 2000, four_hundred = 30
WHERE client_title = 'Название клиента';
```
### Смена waf_provider
```sql
-- Перевести клиента из spik в sp
UPDATE client_info SET waf_provider = 'sp' WHERE client_title = 'Название клиента';
-- Скрыть клиента из всех дашбордов (не удалять)
UPDATE client_info SET waf_provider = NULL WHERE client_title = 'Название клиента';
```
> После смены `waf_provider` при следующем запуске генератора старые алерты будут удалены автоматически и созданы новые в нужной группе.
### Настройка WAF block алерта
```sql
-- Задать код блокировки PTAF для клиента
UPDATE client_info SET ptaf_fallback_code = '418' WHERE client_title = 'Название клиента';
-- Отключить WAF block алерт (PTAF работает в режиме pass)
UPDATE client_info SET ptaf_fallback_code = 'pass' WHERE client_title = 'Название клиента';
-- Изменить порог для конкретного SID (по умолчанию 1 штука за минуту)
UPDATE apps_settings SET ptaf_fallback_code_alert_count = 5 WHERE l7resourceid = 'SID12345';
```
### Изменение порогов ошибок для конкретного SID
```sql
-- Изменить порог 4xx для конкретного домена
UPDATE apps_settings SET four_hundred = 30 WHERE l7resourceid = 'SID12345';
-- Изменить порог 5xx для конкретного домена
UPDATE apps_settings SET five_hundred = 5 WHERE l7resourceid = 'SID12345';
```
### Отключение алерта для клиента
```sql
-- Отключить только RPS алерт
UPDATE client_info SET rps_limit = NULL WHERE client_title = 'Название клиента';
-- Отключить WAF block алерт
UPDATE client_info SET ptaf_fallback_code = 'pass' WHERE client_title = 'Название клиента';
-- Отключить все динамические алерты
UPDATE client_info
SET rps_limit = NULL, ptaf_fallback_code = 'pass'
WHERE client_title = 'Название клиента';
```
### Удаление клиента из дашборда
```sql
-- Удалить привязку всех ресурсов клиента
DELETE FROM apps_settings WHERE client_title = 'Название клиента';
-- Удалить пороги (опционально)
DELETE FROM client_info WHERE client_title = 'Название клиента';
```
### Просмотр всех клиентов с их ресурсами
```sql
SELECT
a.client_title,
COUNT(s.sid) AS domain_count,
array_agg(s.sid ORDER BY s.sid) AS sids,
ci.rps_limit,
ci.ptaf_fallback_code,
ci.waf_provider
FROM (
SELECT sid FROM sp_info WHERE sid IS NOT NULL
UNION
SELECT sid FROM manual_info WHERE sid IS NOT NULL
) s
JOIN apps_settings a ON s.sid = a.l7resourceid
LEFT JOIN client_info ci ON a.client_title = ci.client_title
GROUP BY a.client_title, ci.rps_limit, ci.ptaf_fallback_code, ci.waf_provider
ORDER BY a.client_title;
```
---
## Влияние данных на генерацию
| Данные | Влияние |
|---|---|
| Новый SID в `sp_info`/`manual_info` + запись в `apps_settings` | Новый домен добавится в строку клиента |
| Новый `client_title` + `waf_provider` в `client_info` | Новая строка клиента в соответствующем дашборде |
| Изменение `waf_provider` (`spik``sp` или наоборот) | Клиент переносится в другой дашборд, старые алерты удаляются, создаются новые |
| Установка `waf_provider = NULL` | Клиент исчезает из всех дашбордов, алерты удаляются |
| Изменение `rps_limit` | Пересоздание алерта RPS, обновление красной линии на графике |
| Изменение `rps_commercial_limit` | Обновление синей линии на графике |
| Изменение `four_hundred` / `five_hundred` в `apps_settings` | Пересоздание алертов 4xx/5xx для конкретного SID |
| Изменение `ptaf_fallback_code_alert_count` в `apps_settings` | Пересоздание WAF block алерта для конкретного SID |
| Изменение `ptaf_fallback_code` в `client_info` | Пересоздание WAF block алертов для всех SID клиента |
| `ptaf_fallback_code = 'pass'` | WAF block алерты удаляются для всех SID клиента |
| NULL в `rps_limit` | Алерт RPS удаляется (или не создаётся) |
| Удаление из `apps_settings` | Клиент/домен исчезает из дашборда, алерты удаляются автоматически |
> Изменения в БД обнаруживаются через хэш (`alerts_hash` в `state.json`). При изменении любого поля — алерты пересоздаются автоматически при следующем запуске.
> Устаревшие алерты удаляются автоматически через `deleteObsoleteAlerts()`.