Files
ipam_control/docs/reviews/2026-09-27-changes-030-review.md
T
ayurishchevandClaude Opus 5.5 03d727e496 Задачи 025-030: ёмкость префиксов, политика входа, дерево префиксов
Повторный анализ кодовой базы (docs/reviews/2026-09-26-codebase-review-2.md) и доработки:
025 Ёмкость префикса — размер его подсети (а не сумма листьев); «Обзор» считает ёмкость
    по корневым активным IPv4-префиксам и адреса внутри них.
026 Политика блокировки входа: 5 неудач на логин+IP, 20 на IP, 50 на логин со всех IP,
    кроме известных IP (known_logins, миграция 0009) — владельца нельзя заблокировать анонимно.
027 Сериализация попыток входа по IP (advisory-lock после блокировки логина).
028 UI «Префиксы»: загрузка всех страниц (до 20 000), счётчики по total, предупреждение об усечении.
029 Advisory-lock по VRF для операций, меняющих дерево префиксов и раскладку адресов.
030 Исправление замечаний ревью 025-029: _lock_prefix (VRF блокируется до чтения префикса,
    409 при одновременном переносе), константы политики входа перенесены в app/services.py.

Тесты: 14 passed (проверка ёмкости родителя приведена к семантике 025); сквозные сценарии
и гонки — docs/reviews/2026-09-26-changes-025-029-review.md, 2026-09-27-changes-030-review.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 08:28:50 +03:00

5.0 KiB
Raw Blame History

Ревью и тестирование изменения 030 — 2026-09-27

Объём: правки агента (Sonnet 5) по плану docs/changes/030-review-fixes-025-029/PLAN.md, которые закрывают замечания 1 и 2 ревью 2026-09-26-changes-025-029-review.md. Изменены app/api/v1/prefixes.py, app/api/v1/auth.py, app/services.py, app/rotation.py. Тестировались только доработки 1 и 2. Помимо этого выполнен регрессионный прогон pytest.

Ревью кода

Замечание 1 — _lock_prefix

Хелпер работает в таком порядке:

  1. SELECT vrf_id префикса;
  2. _lock_vrf для этого VRF и дополнительных (целевого VRF при переносе), одним вызовом, по возрастанию id;
  3. повторное чтение префикса под FOR UPDATE с populate_existing;
  4. если vrf_id к этому моменту изменился — 409 без повтора.

Хелпер применён в delete_prefix, update_prefix (только при смене VRF), create_address, allocate_subnet, allocate_next.

  • Порядок блокировок единый: везде сначала advisory-блокировка VRF, затем строка префикса. update_prefix без смены VRF блокирует только строку (при flush) и не запрашивает блокировку VRF, поэтому цикла ожидания нет.
  • Отказ от повтора обоснован. Повтор оставил бы в транзакции блокировку устаревшего VRF и нарушил бы возрастающий порядок захвата между попытками. Сценарий 1d показал, что ветка 409 реально срабатывает.
  • Встречные переносы (A: 5→3, B: 3→5) блокируют пару VRF одним вызовом в одинаковом порядке, взаимной блокировки нет. Подтверждено сценарием 1c.
  • Побочный эффект: create_address теперь берёт FOR UPDATE строки префикса, и назначения адресов в одном префиксе выполняются по одному. На нагрузку это не влияет, операции короткие.

Замечание 2 — константы входа

  • LOGIN_WINDOW, MAX_PER_LOGIN_IP, MAX_PER_IP, MAX_PER_LOGIN, KNOWN_IP_DAYS перенесены в app/services.py.
  • auth.py и rotation.py импортируют их оттуда. Пространства ключей advisory-блокировок остались в auth.py.
  • Импорт app.rotation больше не загружает модули app.api.*: проверено по sys.modules, список пуст. Докстринг auth.py форматируется корректно.

Новых замечаний нет.

Тесты

Проверка Результат
Стенд ipam_control_006 пересобран, app healthy ✅
Регрессия pytest -q ✅ 14 passed
2: app.rotation не импортирует API-слой ✅
2: политика входа не изменилась: 5 неудач → 401×4 + 429, на верный пароль тоже 429, Retry-After ≈ 600 с ✅
1a: удаление префикса ∥ вставка промежуточного префикса, ×20 ✅ все пары ответов 204/201; дерево согласовано: у каждого префикса родитель — самый узкий охватывающий
1b: перенос в другой VRF ∥ создание адреса в переносимом префиксе, ×20 ✅ без 500 и взаимных блокировок; у всех адресов vrf_id совпадает с VRF их префикса; все 20 префиксов перенесены
1c: встречные переносы двух префиксов между двумя VRF, ×15 ✅ всё 200/200, взаимных блокировок нет
1d: перенос ∥ удаление того же префикса, ×10 ✅ только ожидаемые исходы: 5× (перенос 200, удаление 409 «одновременно изменяется»), 5× (перенос 404, удаление 204)
Лог приложения: deadlock / Traceback ✅ 0

Сценарии выполнялись скриптом во временной папке, в репозиторий он не добавлен. Временные данные (vt30-*), попытки входа и записи known_logins удалены.

Вывод

Замечания 1 и 2 закрыты. Изменения 025–030 готовы к коммиту.