325 lines
No EOL
16 KiB
Markdown
Executable file
325 lines
No EOL
16 KiB
Markdown
Executable file
# 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. `100` = алерт не создавать |
|
||
| `five_hundred` | `integer` | 10 | Порог 5xx ошибок в % для данного SID. `100` = алерт не создавать |
|
||
| `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 алерт не создавать |
|
||
| `parent_client_title` | `text` | NULL | Родительский клиент для группировки. Если задан — клиент объединяется с другими клиентами с тем же `parent_client_title` в одну секцию дашборда |
|
||
|
||
**Значения `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` при следующем запуске генератора старые алерты будут удалены автоматически и созданы новые в нужной группе.
|
||
|
||
### Группировка клиентов
|
||
|
||
```sql
|
||
-- Объединить двух клиентов в одну секцию дашборда
|
||
UPDATE client_info SET parent_client_title = 'BigGroup'
|
||
WHERE client_title IN ('client_a', 'client_b');
|
||
|
||
-- Убрать группировку
|
||
UPDATE client_info SET parent_client_title = NULL
|
||
WHERE client_title = 'client_a';
|
||
```
|
||
|
||
> Клиенты с одинаковым `parent_client_title` объединяются в одну строку дашборда.
|
||
> Все их домены (SID) попадают в одну секцию. `RPSLimit` берётся максимальный по группе.
|
||
|
||
### Отключение алертов по ошибкам для конкретного SID
|
||
|
||
```sql
|
||
-- Отключить алерты по 4xx для конкретного домена (значение 100 = не создавать алерт)
|
||
UPDATE apps_settings SET four_hundred = 100 WHERE l7resourceid = 'SID12345';
|
||
|
||
-- Отключить алерты по 5xx для конкретного домена
|
||
UPDATE apps_settings SET five_hundred = 100 WHERE l7resourceid = 'SID12345';
|
||
```
|
||
|
||
### Настройка 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` или наоборот) | Клиент переносится в другой дашборд, старые алерты удаляются, создаются новые |
|
||
| Установка `parent_client_title` | Клиент объединяется с другими клиентами группы в одну секцию дашборда |
|
||
| `four_hundred = 100` или `five_hundred = 100` | Алерты по соответствующему коду для данного SID не создаются |
|
||
| Установка `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()`. |