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>
8.7 KiB
План: 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
Ключевые технические решения
- RouterOS REST (
https://<host>/rest/..., ROS ≥ 7.1, сервисwww-ssl). Для самоподписанных сертификатов — флагverify_tlsна устройство. Ограничение: только ROS 7. - Статус — параллельный опрос (
asyncio.gather+ семафор):/rest/system/resource(модель, версия ROS, uptime),/rest/system/routerboard(current/upgrade firmware),/rest/system/package/update(channel, installed/latest version). Недоступное устройство отображается как offline, не ломает список. - Бэкап:
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 (редирект).
- Обновление ROS:
POST /rest/system/package/update/set {channel}→check-for-updates→install(устройство скачивает пакет и перезагружается само — соответствует требованию «перезагрузка после скачивания»). - Обновление FW:
POST /rest/system/routerboard/upgrade→ опрос доcurrent-firmware == upgrade-firmware→POST /rest/system/reboot. - Долгие операции — таблица
jobs+ фоновые задачи; UI опрашивает статус через HTMX. Групповые операции: эндпоинты принимают списокdevice_ids, выполняются параллельно с ограничением конкурентности. - 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 использует те же сервисы. - Безопасность: пароли устройств не возвращаются в API/UI; ключ шифрования и S3-ключи — только из env; UI — сессия после логина; API — Bearer-токен.
Этапы реализации
- Артефакты:
plan.md, каркас проекта,venv,requirements.txt,.env.example. - Модели БД, security (Fernet, логин, токен), конфиг.
- RouterOS-клиент и операции статуса; CRUD устройств; список со статусами (API + UI).
- S3-модуль; бэкап (2 формата, загрузка с устройства, очистка), список и скачивание.
- Каналы обновлений, обновление ROS, обновление FW; jobs и групповые операции.
- 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.