server-monitor-manager/agents/_salvage-2026-08-18/smm-deliverables/Старые задачи/pr-body-node-enrollment.md
Ochenstarik 23eb3f5233 chore(agents): разбор рабочих папок с диска на 2026-08-18
Задания, отчёты и патчи, лежавшие в C:\Users\Ochenstarik\projects и в
домашней папке, перенесены в agents/. Разложено по агентам там, где имя
файла позволяло определить автора; остальное — в _salvage-2026-08-18/
и разбирается вручную.

Патчи в notes/salvage-2026-08-18/ — незакоммиченная работа из брошенных
рабочих копий: она существовала только на диске.

Тяжёлое (релизные архивы, инсталляторы, наборы данных) в репозиторий не
попало: оно лежит рядом, в Agent_projects/_archive и Agent_projects/_data.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 14:19:54 +07:00

7.3 KiB
Raw Permalink Blame History

Antigravity: выдача кода регистрации узла из приложения — Этап 1

Реализован HTTP-эндпоинт для выпуска кода регистрации узла (SMMNODE2...) из Control в соответствии с требованиями smm-antigravity-task-web-console-2026-08-17.md.

Что сделано

  1. Эндпоинт Control:
    • Добавлен единственный канонический маршрут POST /api/v1/control/agents/{nodeId}/enrollment-code (дублирующий маршрут /nodes/... удален в соответствии с требованиями доработки).
    • Доступ строго ограничен ролью Operator (политика авторизации Operator на группе /api/v1/control). Роли Agent и Automation, а также неаутентифицированные запросы отклоняются (401/403).
    • Подключена политика ограничения частоты "enrollment".
  2. Формат кода SMMNODE2:
    • Выдаваемый код имеет 9 сегментов, разделенных точками, и собирается побайтно идентично эталонной bash-функции create_node_code: SMMNODE2.<control_url>.<ca_pem>.<node_id>.<token>.<hub_endpoint>.<hub_public_key>.<node_address>.<mesh_network>
    • Каждый сегмент кодируется в base64url без выравнивания (=).
  3. Резервирование адресов Mesh (10.77.0.0/24):
    • Выделение адресов реализовано в сервисе NodeEnrollmentService в полном соответствии с поведением reserve_node_address:
      • Адреса последовательно выделяются из пула 10.77.0.2 .. 10.77.0.254 и фиксируются в nodes.tsv.
      • При повторном запросе для уже существующего node_id возвращается ранее выделенный IP-адрес, и для него генерируется новый одноразовый 10-минутный токен.
      • Два разных node_id гарантированно получают уникальные непересекающиеся адреса.
  4. Валидация и безопасность:
    • Валидация имени узла выполняется через NodeIdValidator.IsValid(nodeId) до создания токена и до выделения адреса.
    • Недопустимые имена (пустые, заглавные буквы, подчеркивания, спецсимволы, длина > 63 символов) отклоняются с 400 Bad Request.
    • Имя узла не подставляется в системные команды оболочки.
  5. Журналирование и аудит:
    • Выдача кода фиксируется в таблице аудита audit с действием agent.enrollment_code.issued (актор, node_id, выделенный адрес, дата истечения).
    • Событие публикуется в ControlEventBroker для real-time подписчиков.

Отчёт о тестировании

1. Локальные тесты (PASS)

  • Сборка решения .NET 10 SDK: dotnet build — 0 ошибок.
  • Набор модульных и интеграционных тестов: dotnet test134 пройденных теста (включая 8 новых тестов в NodeEnrollmentCodeTests.cs):
    • AnonymousRequestIsRejectedWithUnauthorized — 401 Unauthorized;
    • AgentRoleIsRejectedWithForbidden — 403 Forbidden;
    • AutomationRoleIsRejectedWithForbidden — 403 Forbidden;
    • InvalidNodeIdIsRejectedWithBadRequestBeforeTokenCreation — 400 Bad Request, токены в БД не создаются;
    • EmptyNodeIdThrowsArgumentExceptionInService — отказ на уровне сервиса;
    • OperatorCanRequestNodeEnrollmentCodeWithCorrectStructure — 200 OK, 9 сегментов SMMNODE2, валидация содержимого каждого сегмента;
    • TwoDifferentNodeIdsGetDistinctMeshAddresses — разным узлам выдаются разные адреса;
    • RepeatedRequestForSameNodeIdReusesReservedAddress — повторный запрос возвращает тот же IP с новым токеном;
    • AuditLogRecordsEnrollmentCodeIssuance — проверка записи в таблицу audit;
    • CodeStructureMatchesBashReferenceFormatFixture — посимвольная проверка структуры алфавита base64url против эталона.

2. CI Workflows (PASS, все зелёные)

3. Что не проверялось и почему

  • Реальный запуск физического установщика bash на внешнем сервере через этот HTTP-эндпоинт не производился, так как веб-интерфейс и интеграция с CLI-клиентом запланированы на Этапе 2 после слияния Этапа 1 в main. Структурная и побайтовая эквивалентность выданного кода SMMNODE2 подтверждена тестом CodeStructureMatchesBashReferenceFormatFixture.