- log_buffer: RingBufferHandler, кольцевой буфер 600 записей, fan-out SSE - ui_logs: GET /ui/logs (HTML), GET /ui/logs/stream (EventSource) - main: install_log_handler при старте, подключён router логов - nav_rail: ссылка Логи, root_html: кнопка-ссылка Логи - Исправлено: NaN/Inf/NUL в теле вебхука → 500 от PostgreSQL jsonb - Тесты: test_log_buffer, test_json_sanitize; 51 passed Made-with: Cursor
168 lines
11 KiB
Markdown
168 lines
11 KiB
Markdown
# Changelog
|
||
|
||
Формат: семантическое версионирование `MAJOR.MINOR.PATCH`. Git-теги `v1.0.0`, `v1.1.0` и т.д. — см. [docs/VERSIONING.md](docs/VERSIONING.md).
|
||
|
||
## [1.10.1] — 2026-04-03
|
||
|
||
### Добавлено
|
||
|
||
- **Страница логов** `/ui/logs` — кольцевой буфер (600 записей) + **SSE real-time** поток; фильтр по уровню, авто-прокрутка; ссылка на главной и в nav rail (раздел «📋 Логи»).
|
||
|
||
### Исправлено
|
||
|
||
- **Вебхук Grafana:** санитизация тела перед записью в `jsonb` — `NaN` / `±Inf` → `None`, удаление `\x00` в строках (иначе PostgreSQL и строгий JSON часто давали **500** на реальных алертах с метриками, тогда как «Test contact point» оставался рабочим).
|
||
- Ошибки подписчиков **`alert.received`** после успешного коммита в БД больше не рвут ответ вебхука (логируются).
|
||
|
||
## [1.10.0] — 2026-04-03
|
||
|
||
Команды (teams) по лейблам, как ориентир на Grafana IRM **Team**.
|
||
|
||
### Добавлено
|
||
|
||
- **Alembic `006_teams`:** таблицы `teams`, `team_label_rules`, колонка **`irm_alerts.team_id`**.
|
||
- **Модуль «Команды»:** CRUD команд, правила лейблов (`priority`), UI список и карточка.
|
||
- **Вебхук Grafana:** подстановка `team_id` по первому совпадению правила.
|
||
- **Алерты:** в API и UI колонка команды, фильтр `team_id`, `GET /alerts/?team_id=…`.
|
||
|
||
### Изменено
|
||
|
||
- Документация [IRM_GRAFANA_PARITY.md](docs/IRM_GRAFANA_PARITY.md), [IRM.md](docs/IRM.md).
|
||
|
||
## [1.9.0] — 2026-04-03
|
||
|
||
Алерты отдельно от инцидентов (модель ближе к Grafana IRM).
|
||
|
||
### Добавлено
|
||
|
||
- **Alembic `005_irm_alerts`:** таблицы `irm_alerts`, `incident_alert_links`.
|
||
- **Модуль «Алерты»:** API и UI, статусы firing → acknowledged → resolved, полный JSON вебхука, кнопка «Создать инцидент».
|
||
- **Вебхук Grafana:** в одной транзакции `ingress_events` + `irm_alerts`.
|
||
- **`extract_alert_row_from_grafana_body`** — заголовок, severity, labels, fingerprint.
|
||
- **Документация:** [docs/IRM_GRAFANA_PARITY.md](docs/IRM_GRAFANA_PARITY.md).
|
||
|
||
### Изменено
|
||
|
||
- **Инцидент из вебхука по умолчанию не создаётся**; включение старого поведения: `AUTO_INCIDENT_FROM_ALERT=1`.
|
||
- **POST /incidents:** опционально `alert_ids` для привязки к `irm_alerts`.
|
||
|
||
## [1.8.0] — 2026-04-03
|
||
|
||
UI каталога Grafana и инцидентов; правки CI/CD деплоя.
|
||
|
||
### Добавлено / изменено
|
||
|
||
- **Каталог Grafana (UI):** кнопка синхронизации без `curl`, раскрывающееся дерево папок (имя, UID, родитель) и правил (title, rule_uid, группа, интервал, labels); блок namespace без папки в API.
|
||
- **Инциденты (UI):** колонка «Создан», ссылка на карточку; карточка с полями и сырым JSON вебхука из `ingress_events`.
|
||
- **API `GET …/grafana-catalog/tree`:** поле `orphan_rule_groups`.
|
||
- **CI/CD:** нормализация ref (`refs/heads/main`, semver без `v`), `docker compose --progress plain`; отключён pip cache при таймауте Actions cache.
|
||
|
||
## [1.7.0] — 2026-04-03
|
||
|
||
Каталог Grafana (топология правил), доработки ingress/IRM, тесты.
|
||
|
||
### Добавлено
|
||
|
||
- **Alembic `003_ingress_org_service`**, **`004_grafana_catalog`** — метаданные и снимок папок/правил Grafana.
|
||
- **Модуль `grafana-catalog`:** `POST …/sync`, `GET …/meta`, `GET …/tree`, UI.
|
||
- **`onguard24/integrations/grafana_topology.py`**, **`grafana_sources.py`**.
|
||
- **Документация:** [docs/GRAFANA_TOPOLOGY.md](docs/GRAFANA_TOPOLOGY.md).
|
||
- **Тесты:** `test_grafana_topology.py`, `test_grafana_catalog_api.py`, `irm_db_fake.py`, `test_irm_api_with_fake_db.py`.
|
||
|
||
## [1.6.0] — 2026-04-03
|
||
|
||
Docker-образ, `docker-compose.yml`, CI/CD Forgejo/Gitea Actions.
|
||
|
||
### Добавлено
|
||
|
||
- **`Dockerfile`**, **`docker-compose.yml`**, **`deploy/entrypoint.sh`** — `alembic upgrade` + `uvicorn` (отключение: `SKIP_ALEMBIC=1`).
|
||
- **`.gitea/workflows/ci.yml`** — pytest на push в `main` и PR.
|
||
- **`.gitea/workflows/deploy.yml`** — деплой по пушу тега `v*` или вручную; **откат** = тот же workflow с `ref` = старый тег.
|
||
- **[docs/CICD.md](docs/CICD.md)** — секреты, подготовка `root@pvestandt9`, порядок релиза и отката.
|
||
|
||
## [1.5.0] — 2026-04-03
|
||
|
||
IRM-ядро: инциденты, задачи, эскалации, миграция БД, документация.
|
||
|
||
### Добавлено
|
||
|
||
- **Документация:** [docs/IRM.md](docs/IRM.md) — матрица функций IRM и что настраивать в Grafana.
|
||
- **Alembic `002_irm_core`:** таблицы `incidents`, `tasks`, `escalation_policies`.
|
||
- **Модули:** `incidents` (API + UI, авто-создание из `alert.received` при наличии БД), `tasks`, `escalations`.
|
||
- **`register_module_events(bus, pool)`** — подписки получают пул PostgreSQL.
|
||
- **Тесты:** `tests/test_irm_modules.py`, обновлены тесты навигации.
|
||
|
||
## [1.4.1] — 2026-04-03
|
||
|
||
### Исправлено
|
||
|
||
- **Alembic:** к URL с `postgresql+psycopg` добавляется `client_encoding=utf8`, чтобы `alembic upgrade head` не падал с `TypeError: ... bytes-like object` при некоторых настройках кодировки на стороне PostgreSQL/psycopg3.
|
||
|
||
## [1.4.0] — 2026-04-03
|
||
|
||
Правое меню «Разделы» на главной и на страницах модулей, пункты из `MODULE_MOUNTS` (`title` + `ui_router`).
|
||
|
||
- **`nav_rail_html`**, **`wrap_module_html_page`**, общие стили **`APP_SHELL_CSS`** в `modules/ui_support.py`.
|
||
- Модуль **schedules** в реестре переименован для примера: **`title` = «Календарь дежурств»**.
|
||
|
||
## [1.3.0] — 2026-04-03
|
||
|
||
Веб-UI модулей с главной страницы и изоляция ошибок превью.
|
||
|
||
### Добавлено
|
||
|
||
- **`ModuleMount`**: поля `slug`, `title`, опционально `ui_router`, `render_home_fragment`.
|
||
- **`/ui/modules/<slug>/`** — монтирование `ui_router` каждого модуля (полные HTML-страницы, не в OpenAPI).
|
||
- **Главная `/`**: секция «Модули» с карточками; фрагменты через **`ui_support.safe_fragment`** (падение одного модуля не ломает страницу).
|
||
- Примеры в `schedules`, `contacts`, `statusboard`; тесты `tests/test_root_ui.py`.
|
||
|
||
## [1.2.0] — 2026-04-03
|
||
|
||
Модульная разработка без правок `main.py` на каждый новый роутер.
|
||
|
||
### Добавлено
|
||
|
||
- **`onguard24/modules/registry.py`** — единый список `MODULE_MOUNTS` (роутер, префикс URL, `register_events`). Подключение роутеров в `create_app()` циклом.
|
||
- У каждого модуля (`schedules`, `contacts`, `statusboard`) функция **`register_events(EventBus)`** — заготовка подписки на `alert.received`.
|
||
- **`app.state.event_bus`**: при старте создаётся `InMemoryEventBus`, вызывается `register_module_events`.
|
||
- **Ingress Grafana:** `INSERT … RETURNING id`, затем **`publish_alert_received`** с ссылкой на строку `ingress_events`.
|
||
- Документация: [docs/MODULES.md](docs/MODULES.md).
|
||
|
||
## [1.1.0] — 2026-04-03
|
||
|
||
Инфраструктура разработки и задел под домен IRM.
|
||
|
||
### Добавлено
|
||
|
||
- **Миграции:** Alembic (`alembic.ini`, `alembic/env.py`, ревизии в `alembic/versions/`). Начальная схема: таблица `ingress_events` (как раньше в коде). Команда: `alembic upgrade head`. DDL при старте приложения убран — только пул asyncpg.
|
||
- **Тесты:** `pytest`, `pytest-asyncio`, моки интеграций; тесты API: `/health`, `/api/v1/status`, `POST /api/v1/ingress/grafana` (в т.ч. секрет webhook). Установка: `pip install -e ".[dev]"`.
|
||
- **Домен (задел):** пакет `onguard24/domain/` — сущности `Alert`, `Incident`, эскалация; `EventBus` / `InMemoryEventBus`, протокол `Module` для подписки на события. Описание: [docs/DOMAIN.md](docs/DOMAIN.md).
|
||
|
||
### Зависимости
|
||
|
||
- Прод: `sqlalchemy`, `alembic`, `psycopg[binary]` (для CLI миграций).
|
||
- Dev (optional): `pytest`, `pytest-asyncio`, `respx`.
|
||
|
||
Тег в репозитории (после публикации): `v1.1.0`.
|
||
|
||
## [1.0.0] — 2026-04-03
|
||
|
||
Первый зафиксированный релиз **каркаса** (scaffold).
|
||
|
||
### Что входит
|
||
|
||
- **Backend:** FastAPI, uvicorn, конфиг из `.env` (путь к `.env` от корня репозитория).
|
||
- **БД:** PostgreSQL через asyncpg, пул, миграция `ingress_events` (сырой SQL в `onguard24/db.py`).
|
||
- **Ingress:** `POST /api/v1/ingress/grafana` — сохранение JSON алерта в БД; опционально `X-OnGuard-Secret` + `GRAFANA_WEBHOOK_SECRET`.
|
||
- **Статус:** `GET /`, `GET /api/v1/status` — проверки database, Vault, Grafana (SA token), Forgejo (PAT + fallback без `read:user`).
|
||
- **Модули-заглушки:** `schedules`, `contacts`, `statusboard` под префиксом `/api/v1/modules/...`.
|
||
- **Фронт:** Vite + React в `web/` (прокси на API).
|
||
- **Документация:** README, `.env.example`, `docs/ARCHITECTURE.md`.
|
||
|
||
### Не входит (следующие версии)
|
||
|
||
- Alembic / полноценные миграции.
|
||
- Авторизация публичных API (кроме секрета webhook).
|
||
- Бизнес-логика IRM (эскалации, дежурства, светофор) — только заготовки модулей.
|
||
|
||
Тег в репозитории: `v1.0.0`.
|