From 50ed8102bc4524c9ba97ad858fd38daf0619d2a4 Mon Sep 17 00:00:00 2001 From: ayurishchev Date: Mon, 21 Sep 2026 11:24:33 +0300 Subject: [PATCH] Record the test run on real data (AS62041) Plan and summary of the isolated Compose run on copies of the real data files: migration without losses, real collection of AS62041, diff, backup and restore. Updates the analysis (observation 1, risk 9). Co-Authored-By: Claude Sonnet 5 --- docs/analysis-2026-09-21.md | 10 ++++++---- docs/plan-real-data-run.md | 25 +++++++++++++++++++++++++ docs/summary-real-data-run.md | 26 ++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 docs/plan-real-data-run.md create mode 100644 docs/summary-real-data-run.md diff --git a/docs/analysis-2026-09-21.md b/docs/analysis-2026-09-21.md index 0cf24c1..c5812f1 100644 --- a/docs/analysis-2026-09-21.md +++ b/docs/analysis-2026-09-21.md @@ -2,6 +2,8 @@ Состояние после 17 доработок (план и итоги каждой лежат в `docs/`): надёжность и безопасность, тесты в контейнере, форматы вывода, разделение процессов, управление ASN/FQDN через API, контейнер приложения, SQLite, `POST /collect`, `GET /addresses/diff`, репозиторий git, закрепление версий, резервные копии и автовосстановление, защита ввода и данных, защита от пустой выдачи, исправления ревью 5-10, защита от пустых копий, наблюдаемость. Предыдущая версия этого файла описывала состояние после восьми доработок. Отчёт ревью: `review-2026-09-21.md` (находки 1-11 закрыты). +Тестовый запуск на копиях боевых файлов с реальным ASN 62041 выполнен и описан в `summary-real-data-run.md`. + Проект: 7 модулей Python, 1719 строк (`db.py` 544, `cidr_collector.py` 386, `api_server.py` 381, `collector_daemon.py` 191, `formatters.py` 115, `storage.py` 70, `healthcheck.py` 32), 30 тестов (27 функций, 5 файлов и `conftest.py`), 37 документов в `docs/` (17 планов, 17 итогов, 2 анализа, ревью), 9 коммитов, ветка `main` синхронизирована с `origin` (`artstore.rxmsk.ru`). ## Что изменилось с предыдущей версии этого файла @@ -37,7 +39,7 @@ | Направление | Статус | |---|---| -| Запуск на реальных данных | Не начато (см. наблюдение 1); следующий шаг | +| Боевое развёртывание с полной конфигурацией | Не начато; тестовый запуск на копиях боевых файлов с AS62041 выполнен (`summary-real-data-run.md`) | | Уведомления (webhook, Telegram) | Не начато; основа (журнал, `/health`, `/sources`) есть | | Метрики Prometheus (`/metrics`) | Исключены из плана решением пользователя; при необходимости - отдельная доработка | | Ограничение частоты `POST /collect` | Не начато | @@ -57,7 +59,7 @@ | 6 | Один общий токен, без ротации и аудита. | Не закрыт | | 7 | Тестов минимум, что соответствует правилам проекта. | Осознанно | | 8 | `POST /collect` без ограничения частоты: повторные запросы во время сбора пропускаются, но защиты от нагрузки на RIPE нет (при этом запросы к RIPEstat теперь идут с повторами). | Не закрыт | -| 9 | Журнал diff и состояние источников проверены только на копиях и тестах: размер и нагрузка на реальных данных неизвестны. | Не закрыт | +| 9 | Журнал diff и состояние источников проверены на копиях боевых файлов и одном реальном ASN (база 45 КБ, ответы 6-9 мс); поведение при шести ASN, по расписанию и во времени (TTL, рост журнала) не наблюдалось. | Частично закрыт | | 10 | Копии базы лежат на том же томе, что и база: защита от порчи файла, но не от потери тома. | Не закрыт (описан в README) | | 11 | Нет активных оповещений: о сбое источников можно узнать только опросом `/health` или из лога. | Не закрыт | @@ -65,7 +67,7 @@ | # | Наблюдение | Состояние | |---|---|---| -| 1 | **Изменения не применены к реальным данным.** В каталоге проекта нет `ripe.db`; `data.json` (6 ASN) и `fqdn_data.json` (4 имени) остались в старом формате; всё проверено только на копиях. Первый запуск на боевых данных выполнит миграцию сразу до схемы версии 3: `last_seen` старых записей станет равным времени миграции, журнал diff и состояние источников начнутся пустыми (клиентам стартовать с `X-Changes-Cursor`), первые запуски сбора создадут состояние источников. | Без изменений | +| 1 | **Боевое развёртывание не выполнено.** Миграция боевых файлов проверена в изолированном стенде на их копиях (`summary-real-data-run.md`: без потерь, сбор AS62041 и восстановление на реальных данных работают). В каталоге проекта нет `ripe.db`; `data.json` (6 ASN) и `fqdn_data.json` (4 имени) остались в старом формате; всё проверено только на копиях. Первый запуск на боевых данных выполнит миграцию сразу до схемы версии 3: `last_seen` старых записей станет равным времени миграции, журнал diff и состояние источников начнутся пустыми (клиентам стартовать с `X-Changes-Cursor`), первые запуски сбора создадут состояние источников. | Частично закрыто | | 2 | ~~`/health` не видит сбоев источников.~~ Сбои учитываются по каждому источнику, порог `source_failure_threshold` (по умолчанию 3): при суточном расписании FQDN это три дня до `degraded`. | Закрыто | | 3 | **Безымянные образы Docker: 21 на хосте.** Часть - от пересборок тестового образа `ripe-tests` при разработке, на хосте есть и чужие (`docker image prune` затронет все). | Ухудшилось (было 3) | | 4 | **Повреждённый `config.json`** переименовывается при чтении; первый успешный `POST /asns` после этого создаст файл без остальных источников, расписания и `ttl_days`. | Без изменений | @@ -81,7 +83,7 @@ ## Рекомендуемый порядок -1. **Запуск на реальных данных (главный шаг).** Перед запуском: копия `config.json`, `data.json`, `fqdn_data.json` вне каталога проекта и вне тома (миграция переименует оригиналы в `*.migrated-*`, но копия на случай ошибки обязательна). Затем `docker compose up -d` с переносом файлов в том (порядок в README), проверка `/health`, `/sources`, `/addresses` и `/addresses/diff`, первый ручной сбор через `POST /collect`, оценка размера базы и журнала, выбор порога `source_failure_threshold`. Нужен отдельный план с откатом. +1. **Боевое развёртывание с полной конфигурацией (главный шаг; тестовый запуск с AS62041 пройден).** Перед запуском: копия `config.json`, `data.json`, `fqdn_data.json` вне каталога проекта и вне тома (миграция переименует оригиналы в `*.migrated-*`, но копия на случай ошибки обязательна). Затем `docker compose up -d` с переносом файлов в том (порядок в README), проверка `/health`, `/sources`, `/addresses` и `/addresses/diff`, первый ручной сбор через `POST /collect`, оценка размера базы и журнала, выбор порога `source_failure_threshold`. Нужен отдельный план с откатом. 2. **Обновить граф** (`/graphify . --update`, документы выгружать целиком) и при желании поставить хук после коммита. 3. **Уведомления** (webhook, Telegram) на основе журнала и состояния источников: закрывает риск 11. 4. **Архитектурный рефакторинг:** `settings.py` (пути и умолчания), разделение `db.py` и `api_server.py`; снимает наблюдения 10-11. diff --git a/docs/plan-real-data-run.md b/docs/plan-real-data-run.md new file mode 100644 index 0000000..295abe6 --- /dev/null +++ b/docs/plan-real-data-run.md @@ -0,0 +1,25 @@ +# План: тестовый запуск на реальных данных (AS62041) + +Источник: `docs/analysis-2026-09-21.md`, наблюдение 1 и риск 9 (изменения проверялись только на копиях и тестах). Цель - проверить миграцию боевых файлов и сбор по реальному внешнему источнику, ничего не меняя в исходных файлах проекта. + +## Границы +- **Исходные файлы не изменяются:** `config.json`, `data.json`, `fqdn_data.json` в каталоге проекта остаются как есть. Перед запуском снимается копия вне проекта и вне тома с контрольными суммами; после запуска суммы сверяются. +- **Изолированный стенд:** отдельный проект Compose (`ripereal`), собственный том и порт 18000, временный `.env`; на хосте другие сервисы не затрагиваются. В том копируются **копии** файлов; конфигурация для теста - копия реальной с одним ASN (**AS62041**) и реальными FQDN. Реальные внешние запросы: один ASN в RIPEstat и DNS для трёх имён. +- Стенд после проверки убирается (том, контейнеры, образ, `.env`); отчёт остаётся в `docs/`. + +## Шаги +1. Копия исходных файлов и контрольные суммы; тесты в контейнере (базовая линия). +2. Перенос копий в том по описанию README, запуск `docker compose up -d`. +3. **Миграция:** база создана из `data.json` и `fqdn_data.json`, число значений по источникам совпадает с файлами, оригиналы в томе переименованы в `*.migrated-*`, схема версии 3, журнал и состояние источников пусты. +4. **До сбора:** `/health`, `/sources` (источники без попыток), `/addresses`, курсор `X-Changes-Cursor`. +5. **Сбор:** `POST /collect` (ASN и FQDN) по реальным источникам; `/sources` (успех, число адресов AS62041), `/health` `ok`, итог в логе. +6. **Diff на реальных данных:** `/addresses/diff` с курсором до сбора - что изменилось у AS62041 с момента файла `data.json`; проверка, что значения не настроенных источников остаются (стареют по TTL). +7. **Копия и восстановление:** ручной запуск задания `backup` (через расписание `POST /schedule`), затем намеренная порча базы в томе: восстановление из копии, данные на месте, `last_restore` в `/health`. +8. **Размеры и время:** размер базы и журнала, время ответов `/addresses` и `/addresses/diff?since=0`. +9. Уборка стенда, сверка сумм исходных файлов, отчёт `docs/summary-real-data-run.md`, обновление анализа. + +## Критерии успеха +Исходные файлы не изменены; миграция без потерь; сбор AS62041 успешен; diff и восстановление работают на реальных данных; ошибок в логах нет; стенд убран. + +## Откат +Стенд изолирован: достаточно `docker compose down -v` и удаления образа; исходные файлы проекта не затрагиваются. diff --git a/docs/summary-real-data-run.md b/docs/summary-real-data-run.md new file mode 100644 index 0000000..23f9620 --- /dev/null +++ b/docs/summary-real-data-run.md @@ -0,0 +1,26 @@ +# Итоги: тестовый запуск на реальных данных (AS62041) + +План: `docs/plan-real-data-run.md`. Закрывает часть наблюдения 1 и риска 9 анализа (`analysis-2026-09-21.md`). + +## Как проводилось +Изолированный стенд Compose (проект `ripereal`, порт 18000, отдельный том). В том скопированы **копии** реальных `data.json` и `fqdn_data.json` (24 префикса шести ASN и 4 IP четырёх имён, формат до TTL, `last_updated` февраля 2026) и конфигурация: копия реальной с одним ASN **62041** и реальными тремя FQDN (`*.whatsapp.com`). Реальные внешние запросы: RIPEstat для AS62041 и DNS. Исходные файлы проекта не менялись (контрольные суммы до и после совпали); стенд убран (контейнеры, том, образ, `.env`). + +## Результаты +| Проверка | Итог | +|---|---| +| Миграция | При первом обращении API: `user_version` 3, таблицы `addresses`, `changes`, `meta`, `source_status`; импортировано 24 префикса и 4 значения FQDN, число по источникам совпало с файлами; `first_seen` сохранён (из `last_updated`), `last_seen` = время миграции; оригиналы в томе переименованы в `*.migrated-<время>`; журнал и состояние источников пусты, курсор `0`. | +| До сбора | `/health` `ok` (`collector_alive`), `/sources` без попыток, `/addresses` 26 значений. | +| Сбор | `POST /collect` (asn + fqdn): AS62041 `+14/-0` префиксов, три FQDN `+3` строки; `/sources`: успех у всех, сбоев 0; в логе итоговые строки запусков. | +| Diff на реальных данных | `since=0`: 15 добавлений, 0 удалений: 14 новых префиксов AS62041 (`149.154.160-167.0/24`, `91.108.4-10.0/22-23`, `95.161.64/72.0/21`) и один IPv6-адрес имён; все 11 префиксов из февральского файла подтверждены RIPE (удалений нет). Три имени получили один и тот же новый адрес - в журнале одна запись (журнал считает значения, а не строки источников). | +| Копия и восстановление | Задание `backup` (расписание временно `* * * * *`, затем возвращено к умолчанию) создало копию 45 КБ; после записи мусора поверх `ripe.db` первый же запрос вернул данные (HTTP 200), 41 значение, **хеш выдачи совпал с хешем до порчи**; `last_restore` в `/health`, карантинный файл сохранён; старый курсор дал `410`, новый (`1000015`) принят. | +| Размеры и время | `ripe.db` 45 КБ, копия 45 КБ; ответы `/addresses`, `/addresses` (nftables, агрегация), `/addresses/diff`, `/health`, `/sources`: 6-9 мс. | +| Журнал | В логах два ERROR (умышленная порча и восстановление), трейсбеков нет. | + +## Замечания +- **Данные не настроенных источников выдаются, пока не истекут по TTL:** в тестовой конфигурации остались ASN 62014, 59930, 44907, 211157 и `google.com` (13 префиксов и один IP из 41 значения). При штатной конфигурации с шестью ASN это касается только `google.com`. +- **AS11917 в файле февраля без префиксов:** при запуске с полной конфигурацией источник даст корректный, но возможно пустой ответ - он не вызовет `degraded`, но будет виден в `/sources` с `addresses: 0`. +- **Что не проверено:** штатное расписание (`*/15` для ASN, суточное для FQDN) не наблюдалось, сборы запускались вручную; остальные пять ASN не опрашивались; старение по TTL и накопление журнала во времени не воспроизводились; нагрузка мала (24 значения при миграции, 41 после сбора). Это тест на копиях боевых файлов, а не боевое развёртывание. +- Первая порча/восстановление проходят без потери данных на копии, снятой ~15 секунд до порчи; данные после точки копии в реальной эксплуатации будут доначитаны сборщиком. + +## Вывод +Миграция боевых файлов, сбор по реальному источнику, diff, копия и восстановление работают на реальных данных; критерии плана выполнены. Осталось боевое развёртывание с полной конфигурацией (шесть ASN) и наблюдение за расписанием.