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>
6.1 KiB
6.1 KiB
План: смена VRF у префикса и целостность «VRF ⊂ организация» (изменение 002)
Контекст
VRF — часть адресного плана организации. Сейчас:
- уникальность VRF уже в пределах организации:
UNIQUE(organization_id, name)— одно имя допустимо в разных организациях; - несколько префиксов организации могут быть в одном VRF (
UNIQUE(vrf_id, prefix)— дубль CIDR запрещён только внутри VRF); - смена VRF у существующего префикса невозможна: нет ни поля в UI (
web/app.js,prefixDialog), ниvrf_idвPrefixUpdate(app/schemas.py); - принадлежность VRF организации префикса проверяется только в коде (
create_prefix), в БД гарантии нет.
Цель: разрешить смену VRF только среди VRF той же организации, сохранив целостность дерева, и закрепить правило на уровне БД.
Правила
- Организация префикса неизменна; целевой VRF обязан принадлежать той же организации (иначе 422).
- Смена VRF переносит префикс вместе со всем поддеревом (вложенные по
parent_id), чтобы дерево не «разрывалось» между VRF. - Дубль
(vrf, prefix)у любого переносимого префикса в целевом VRF → 409 с перечнем конфликтующих CIDR; перенос отменяется целиком. - После переноса родитель корня поддерева пересчитывается в целевом VRF (самый узкий объемлющий); префиксы целевого VRF, лежащие внутри перенесённого, переподчиняются ему — та же логика, что при создании (выносим в общую функцию
attach_to_tree). - Адреса остаются у своих префиксов (
prefix_idне меняется); использование/ёмкость пересчитываются автоматически. - CIDR и родитель в окне редактирования по-прежнему не меняются (родитель определяется автоматически).
Изменения
Backend
app/schemas.py:PrefixUpdate.vrf_id: int | None.app/api/v1/prefixes.py: вupdate_prefix— валидация правил 1–3, перенос поддерева,attach_to_tree(рефакторинг изcreate_prefix), запись в audit{vrf: "old → new", moved: N}.- Alembic
0002:UNIQUE(id, organization_id)наvrfs+ составной FKprefixes(vrf_id, organization_id) → vrfs(id, organization_id)— БД не даст связать префикс с VRF чужой организации;- уникальность имени VRF без учёта регистра в пределах организации: индекс
(organization_id, lower(name))вместоUNIQUE(organization_id, name); перед применением — проверка на существующие дубли.
UI (web/app.js)
- В окне редактирования префикса показать поле «VRF» (только VRF текущей организации, уже загружены в
S.vrfs). - При выборе другого VRF — подсказка «Вместе с префиксом будет перенесено N вложенных» (N считается из
S.prefixes); ошибки 409/422 — в стандартном баннере окна. - Вёрстка — из существующего окна создания (макета редактирования нет, отступлений от дизайна не появляется).
Тесты (2 новых, всего 6)
- Одноимённый VRF в двух организациях — ок; повтор в одной (в т.ч. другим регистром) — 409.
- Смена VRF: поддерево переехало, родитель пересчитан, дубль в целевом VRF — 409 без частичных изменений, VRF другой организации — 422.
Порядок работ
- Рефакторинг
attach_to_tree(поведение создания не меняется, тесты зелёные). - Миграция
0002(сначала проверка дублей, затем применение черезdocker compose up). PrefixUpdate+ логика переноса.- UI: поле VRF и подсказка.
- Тесты в контейнерах, прогон e2e-сценария UI, сверка окна с макетом «Новый префикс».
- Обновить
README.md(правила VRF), написатьSUMMARY.mdв этой папке.
Риски
- Составной FK требует, чтобы
prefixes.organization_idвсегда совпадал с организацией VRF — уже так; миграция проверит данные и откажется применяться при расхождении. - Перенос крупного поддерева — одна транзакция; при 409 откат целиком.
Допущения (скажите, если не так)
- Переносится всё поддерево, а не только выбранный префикс (альтернатива — запретить смену VRF у префиксов с вложенными).
- Регистронезависимая уникальность имён VRF в организации допустима (
Labиlabсчитаются одним VRF).