Backend (FastAPI, SQLAlchemy 2, Alembic, PostgreSQL 16): - организации, VRF, префиксы (дерево, использование, автоназначение), адреса, операторы связи, устройства и типы устройств; JWT, роли admin/viewer; - VRF принадлежит организации (составной FK), смена VRF у префикса переносит поддерево, имя VRF уникально в организации; - журнал аудита: поиск и фильтры, ротация (срок/количество), очистка по паролю с блокировкой, IP клиента и метаданные запроса (X-Forwarded-For только от TRUSTED_PROXIES). UI (web/, без сборки): экраны и диалоги по макетам «IPAM Manager», кликабельные строки реестров, локальные шрифты IBM Plex, собственные выпадающие списки. Окружение: docker-compose (postgres + app), миграции Alembic 0001-0004, scripts/gen_env.py, scripts/seed_demo.py, 11 автотестов (pytest). Документация: README.md и docs/changes/001-005 (планы и итоги). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
3.2 KiB
3.2 KiB
Суммаризация: IP-адрес актора и метаданные запроса в журнале (изменение 004)
Сделано
- БД (миграция 0004):
audit_log+client_ip INET(индекс) иmeta JSONB(user_agent,method,path,request_id). Проверено:upgrade → check (без дрейфа) → downgrade → upgrade. - Backend:
app/request_context.py— ASGI-middleware кладёт метаданные запроса вContextVar,audit()читает их (30 мест вызова не менялись); заголовокX-Request-IDв ответах.X-Forwarded-Forпринимается только от прокси изTRUSTED_PROXIES(по умолчанию пусто, справа налево — первый недоверенный адрес), IPv4-mapped нормализуется. Системные события (ротация, даже запущенная из запроса) пишутся без IP. - API:
AuditOut.client_ip/meta;GET /audit?client_ip=(IP или CIDR, 422 на мусор);qищет и по началу IP. - UI: колонка «IP-адрес» в таблице журнала (сетка
… 110px 130px 96px), поиск «Сообщение, ID или IP», в окне записи — IP (с копированием), «Запрос», «User-Agent». - Кэш статики:
Cache-Control: no-cache(ревалидация по ETag) — браузер больше не держит устаревшийapp.js/styles.cssпосле обновления (ответ на «не вижу обновлений»; для уже закэшированной версии один раз нужен Ctrl+F5).
Проверка
- 11 автотестов (2 новых: запись IP/метаданных, фильтр по IP и подсети, игнорирование поддельного
X-Forwarded-For, пустой IP у системных событий; юнит-тест разбора цепочки прокси) — 11 passed. - Через LAN-адрес
192.168.5.9:8088: создание организации и неудачный вход записались сclient_ip = 192.168.5.9, User-Agent и путём; фильтр192.168.5.0/24и поиск192.168.5находят записи; UI — колонка и окно записи проверены в браузере, ошибок JS нет.
Допущения и ограничения
- IP пишется для всех действий из HTTP-запросов (admin и прочие роли, неудачные входы — как
anonymous); старые записи — «—». - Через
127.0.0.1Docker подставляет адрес шлюза сети (172.x.0.1) — особенность docker-proxy, не ошибка приложения. - За NAT или прокси виден адрес ближайшего недоверенного узла, а не «настоящего» клиента; с reverse-proxy нужно задать
TRUSTED_PROXIES. - IP — персональные данные: срок хранения определяется ротацией журнала.