Files
ayurishchevandClaude Sonnet 5 4c1841b61b ros_control: централизованное управление парком MikroTik RouterOS
Control Server (FastAPI) с WEB UI (Jinja2 + HTMX) и JSON API для группового
администрирования устройств RouterOS 7 через REST.

- Устройства: список, статус (модель, канал, версии ROS/FW, uptime, доступные
  обновления), примечания, пароли шифруются (Fernet); фоновый опрос каждые 30 с
  и быстрое обнаружение недоступности (таймаут соединения 4 с).
- Группы устройств и фильтры (устройства, резервные копии).
- Резервные копии: .backup и .rsc (show-sensitive) создаются через REST,
  скачиваются сервером и загружаются в S3 (Yandex Object Storage).
- Обновление ROS/FW и выбор канала, групповые операции задачами.
- Интерфейс по утверждённому макету: светлая/тёмная темы, окна, шрифты IBM Plex
  локально. Docker Compose, SQLite в томе, минимальный набор тестов.
- Планы и итоги каждого изменения — в docs/changes/.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 13:13:29 +03:00

77 lines
8.7 KiB
Markdown
Raw Permalink 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.
# План: ros_control — централизованное управление парком MikroTik RouterOS
## Context
Нужно приложение для группового администрирования множества устройств MikroTik RouterOS через API и WEB UI. Источник требований — `ros_control.svg` (draw.io): архитектура, список функций, ссылки на API.
Из схемы:
- **Control Server** связан двусторонне с **Local Metadata DB** (DB transactions), **S3 Bucket** (Yandex Object Storage: `ListObjectsV2`, `GetObject`, `PutObject`, `DeleteObject`) и **Admin Dashboard**.
- Dashboard ↔ Control Server: JSON payload, UI Forms (ввод), JSON payload render (вывод).
- Control Server ↔ **Endpoint API Server (on device)** = RouterOS REST API (`GET/PATCH/PUT/POST/DELETE`, JSON), N устройств.
Функции dashboard: список устройств и управление списком (добавить, изменить, удалить); статус (модель, канал обновлений, версия ROS, версия FW, uptime, время запроса бэкапа); бэкап по каждому устройству (бинарный `.backup` без шифрования + текстовый `.rsc`, загрузка в S3, удаление с устройства, скачивание из бакета, список бэкапов в бакете); выбор канала обновлений; обновление ROS до актуальной версии канала (перезагрузка после скачивания); обновление FW (перезагрузка сразу после обновления).
Принятые решения: Python FastAPI + Jinja2/HTMX, SQLite (SQLAlchemy), пароли устройств шифруются (Fernet), вход в UI по логину/паролю, API — Bearer-токен, Docker Compose для развёртывания + `venv` в корне проекта для разработки.
## Артефакты процесса (по CLAUDE.md проекта)
- `docs/changes/001-initial-implementation/plan.md` — копия этого плана (создаётся первым шагом реализации)
- `docs/changes/001-initial-implementation/summary.md` — итоги по выполненному (создаётся последним шагом)
- `README.md` — описание, запуск, конфигурация, ссылки на API; обновляется при каждом изменении
- Тесты — минимальный набор (см. Verification)
## Структура проекта
```
app/
main.py # FastAPI, роутинг, lifespan
config.py # настройки из env (pydantic-settings)
db.py, models.py # SQLAlchemy + SQLite: users, devices, backups, jobs
security.py # Fernet для паролей устройств, хэш пароля админа, API-токен
ros/client.py # httpx-клиент RouterOS REST (basic auth, verify_tls per device)
ros/operations.py # status, backup, update channel/install, firmware upgrade
s3.py # boto3: list/get(presigned)/put(presigned)/delete, endpoint Yandex
services/ # devices, backups, updates, jobs (фоновые задачи + batch)
api/v1.py # JSON API
ui/routes.py, templates/, static/ # Jinja2 + HTMX
tests/ # минимальный набор
Dockerfile, docker-compose.yml, requirements.txt, .env.example, README.md
docs/changes/001-initial-implementation/{plan,summary}.md
```
## Ключевые технические решения
1. **RouterOS REST** (`https://<host>/rest/...`, ROS ≥ 7.1, сервис `www-ssl`). Для самоподписанных сертификатов — флаг `verify_tls` на устройство. Ограничение: только ROS 7.
2. **Статус** — параллельный опрос (`asyncio.gather` + семафор): `/rest/system/resource` (модель, версия ROS, uptime), `/rest/system/routerboard` (current/upgrade firmware), `/rest/system/package/update` (channel, installed/latest version). Недоступное устройство отображается как offline, не ломает список.
3. **Бэкап**:
- `POST /rest/system/backup/save` (`dont-encrypt=yes`) и `POST /rest/export` (`.rsc`);
- REST не отдаёт содержимое крупных файлов, поэтому **устройство само загружает файлы в S3** через `/tool/fetch` (`http-method=put upload=yes src-path=…`) по **presigned PUT URL**, выданному Control Server. Ключи S3: `backups/<device>/<timestamp>.backup|.rsc`;
- после успешной загрузки — `DELETE /rest/file/<id>` на устройстве; время запроса пишется в БД;
- список — `ListObjectsV2` по префиксу, скачивание — presigned GET (редирект).
4. **Обновление ROS**: `POST /rest/system/package/update/set {channel}` → `check-for-updates` → `install` (устройство скачивает пакет и перезагружается само — соответствует требованию «перезагрузка после скачивания»).
5. **Обновление FW**: `POST /rest/system/routerboard/upgrade` → опрос до `current-firmware == upgrade-firmware` → `POST /rest/system/reboot`.
6. **Долгие операции** — таблица `jobs` + фоновые задачи; UI опрашивает статус через HTMX. Групповые операции: эндпоинты принимают список `device_ids`, выполняются параллельно с ограничением конкурентности.
7. **API v1**: `/api/v1/devices` (CRUD), `/devices/{id}/status`, `/devices/{id}/backups` (POST/GET), `/backups/download`, `/devices/{id}/update/channel` (PUT), `/devices/{id}/update/install`, `/devices/{id}/firmware/upgrade` (POST), `/jobs/{id}`. UI использует те же сервисы.
8. **Безопасность**: пароли устройств не возвращаются в API/UI; ключ шифрования и S3-ключи — только из env; UI — сессия после логина; API — Bearer-токен.
## Этапы реализации
1. Артефакты: `plan.md`, каркас проекта, `venv`, `requirements.txt`, `.env.example`.
2. Модели БД, security (Fernet, логин, токен), конфиг.
3. RouterOS-клиент и операции статуса; CRUD устройств; список со статусами (API + UI).
4. S3-модуль; бэкап (2 формата, загрузка с устройства, очистка), список и скачивание.
5. Каналы обновлений, обновление ROS, обновление FW; jobs и групповые операции.
6. Docker/compose, README, минимальные тесты, `summary.md`.
## Риски / проверить на реальном устройстве
- `/tool/fetch` с `http-method=put upload=yes` на целевой версии ROS (основной вариант). Запасной: устройство отправляет файл на эндпоинт Control Server.
- Синхронные REST-вызовы (`fetch`, `install`) могут упереться в таймаут — использовать `duration`/асинхронные задачи и опрос состояния.
- Сертификат `www-ssl` на устройствах и доступность 443 от Control Server; доступность S3 (`storage.yandexcloud.net`) с устройств.
## Verification
- **Автотесты (минимум, ~4)**: шифрование/расшифровка пароля; разбор статуса RouterOS (mock httpx); сценарий бэкапа с мокнутыми RouterOS и S3 (порядок: save → export → fetch → delete file → запись в БД); авторизация API (401 без токена).
- **Ручная проверка**: RouterOS CHR (ROS 7) в лаборатории + тестовый бакет Yandex Object Storage: добавить устройство → статус в списке → бэкап (оба файла в бакете, на устройстве удалены) → скачивание → смена канала → обновление ROS → обновление FW.
- `docker compose up` — приложение поднимается, UI на `:8000`, `/docs` показывает OpenAPI.