18 KiB
18 KiB
D1 Документирование готовности ядра
Дата: 2026-03-02 Статус: in-progress Владелец: Engineering
1) Цель
- Дать точный endpoint-level срез: что уже можно подключать в веб, что требует инфраструктурных условий, и где нужен отдельный UX-поток.
- Зафиксировать критерии перехода к веб-прототипу на базе фактического кода
selective-vpn-api.
2) Легенда статусов
ready-read— готово для веба как read endpoint.ready-write— готово для веба как write endpoint, но обязательно через auth/rbac/audit/proxy.ready-async— write endpoint готов, но требуется async UX (SSE progress/polling).ready-interactive— endpoint готов, но требует интерактивного flow (session state/action).
3) Глобальные условия для веба
- API должен ходить через proxy (unix socket + nginx/systemd socket) и не быть публично открыт напрямую на
127.0.0.1:8080. - Для всех mutating endpoints обязательны auth/rbac и аудит вызовов.
- Для SSE (
/api/v1/events/stream) нужен корректный proxy режим (proxy_buffering off). - Для async операций (
routes update,smartdns prewarm,dns benchmark) веб должен слушать SSE/статусы и блокировать повторные конкурирующие действия. - Архитектурный инвариант: один контракт
/api/v1дляweb + iOS + Android, без платформенных форков backend-логики.
4) Матрица endpoint -> web-ready
| Endpoint | Method | Handler | Статус | Комментарий для веба |
|---|---|---|---|---|
/healthz |
GET | handleHealthz |
ready-read |
Базовый liveness probe. |
/api/v1/events/stream |
GET | handleEventsStream |
ready-read |
SSE source для realtime UI. |
/api/v1/status |
GET | handleGetStatus |
ready-read |
Карточка статуса маршрутов. |
/api/v1/routes/status |
GET | handleGetStatus |
ready-read |
Алиас статуса. |
/api/v1/vpn/login-state |
GET | handleVPNLoginState |
ready-read |
Текущий state логина VPN. |
/api/v1/systemd/state |
GET | handleSystemdState |
ready-read |
Проверка unit state по query unit. |
/api/v1/routes/service/start |
POST | makeRoutesServiceActionHandler("start") |
ready-write |
Чувствительная операция systemd. |
/api/v1/routes/service/stop |
POST | makeRoutesServiceActionHandler("stop") |
ready-write |
Чувствительная операция systemd. |
/api/v1/routes/service/restart |
POST | makeRoutesServiceActionHandler("restart") |
ready-write |
Чувствительная операция systemd. |
/api/v1/routes/service |
POST | handleRoutesService |
ready-write |
Универсальный action endpoint. |
/api/v1/routes/update |
POST | handleRoutesUpdate |
ready-async |
Запуск async job; прогресс через SSE/events. |
/api/v1/routes/timer |
GET/POST | handleRoutesTimer |
ready-write |
GET состояние, POST переключение. |
/api/v1/routes/timer/toggle |
POST | handleRoutesTimerToggle |
ready-write |
Legacy toggle для совместимости. |
/api/v1/routes/rollback |
POST | handleRoutesClear |
ready-write |
Очистка nft/routes с риском влияния на трафик. |
/api/v1/routes/clear |
POST | handleRoutesClear |
ready-write |
Алиас rollback. |
/api/v1/routes/cache/restore |
POST | handleRoutesCacheRestore |
ready-write |
Восстановление из clear-cache. |
/api/v1/routes/precheck/debug |
POST | handleRoutesPrecheckDebug |
ready-async |
Debug flow + опциональный async restart. |
/api/v1/routes/fix-policy-route |
POST | handleFixPolicyRoute |
ready-write |
Ремонт policy route по status.json. |
/api/v1/routes/fix-policy |
POST | handleFixPolicyRoute |
ready-write |
Алиас fix-policy-route. |
/api/v1/traffic/mode |
GET/POST | handleTrafficMode |
ready-write |
Ключевой control-plane endpoint. |
/api/v1/traffic/mode/test |
GET/POST | handleTrafficModeTest |
ready-read |
Проверка health/probe для UI. |
/api/v1/traffic/advanced/reset |
POST | handleTrafficAdvancedReset |
ready-write |
Сброс advanced bypass state. |
/api/v1/traffic/interfaces |
GET | handleTrafficInterfaces |
ready-read |
Список интерфейсов и active iface. |
/api/v1/traffic/candidates |
GET | handleTrafficCandidates |
ready-read |
Подсказки subnet/unit/uid. |
/api/v1/traffic/appmarks |
GET/POST | handleTrafficAppMarks |
ready-write |
Runtime app marking, требует RBAC. |
/api/v1/traffic/appmarks/items |
GET | handleTrafficAppMarksItems |
ready-read |
Список текущих runtime marks. |
/api/v1/traffic/app-profiles |
GET/POST/DELETE | handleTrafficAppProfiles |
ready-write |
CRUD профилей приложений. |
/api/v1/traffic/audit |
GET | handleTrafficAudit |
ready-read |
Sanity-check и issues report. |
/api/v1/trace |
GET | handleTraceTailPlain |
ready-read |
Plain tail trace. |
/api/v1/trace-json |
GET | handleTraceJSON |
ready-read |
Structured trace view. |
/api/v1/trace/append |
POST | handleTraceAppend |
ready-write |
Write в trace; ограничить доступ и размер body. |
/api/v1/dns-upstreams |
GET/POST | handleDNSUpstreams |
ready-write |
Конфиг upstreams. |
/api/v1/dns/upstream-pool |
GET/POST | handleDNSUpstreamPool |
ready-write |
Конфиг pool. |
/api/v1/dns/status |
GET | handleDNSStatus |
ready-read |
Состояние DNS mode/runtime. |
/api/v1/dns/mode |
POST | handleDNSModeSet |
ready-write |
Переключение DNS resolver mode. |
/api/v1/dns/benchmark |
POST | handleDNSBenchmark |
ready-async |
Долгий бенчмарк; нужен UX ожидания. |
/api/v1/dns/smartdns-service |
POST | handleDNSSmartdnsService |
ready-write |
Start/stop/restart smartdns unit. |
/api/v1/smartdns/service |
GET/POST | handleSmartdnsService |
ready-write |
GET state + POST action. |
/api/v1/smartdns/runtime |
GET/POST | handleSmartdnsRuntime |
ready-write |
Runtime nftset hook toggle. |
/api/v1/smartdns/prewarm |
POST | handleSmartdnsPrewarm |
ready-async |
Потенциально долгий prewarm. |
/api/v1/domains/table |
GET | handleDomainsTable |
ready-read |
Таблица nft/ipset dump. |
/api/v1/domains/file |
GET/POST | handleDomainsFile |
ready-write |
File-backed editor; нужен ACL по name. |
/api/v1/smartdns/wildcards |
GET/POST | handleSmartdnsWildcards |
ready-write |
CRUD wildcard list. |
/api/v1/vpn/autoloop-status |
GET | handleVPNAutoloopStatus |
ready-read |
Статус autoloop parser. |
/api/v1/vpn/status |
GET | handleVPNStatus |
ready-read |
VPN state + unit state. |
/api/v1/vpn/autoconnect |
POST | handleVPNAutoconnect |
ready-write |
Управление adgvpn unit. |
/api/v1/vpn/locations |
GET | handleVPNListLocations |
ready-read |
Список location options. |
/api/v1/vpn/location |
POST | handleVPNSetLocation |
ready-write |
Смена desired location + unit restart. |
/api/v1/vpn/login/session/start |
POST | handleVPNLoginSessionStart |
ready-interactive |
Старт интерактивной PTY login session. |
/api/v1/vpn/login/session/state |
GET | handleVPNLoginSessionState |
ready-interactive |
Poll состояния и линий с since. |
/api/v1/vpn/login/session/action |
POST | handleVPNLoginSessionAction |
ready-interactive |
Команды open/check/cancel. |
/api/v1/vpn/login/session/stop |
POST | handleVPNLoginSessionStop |
ready-interactive |
Cleanup/stop interactive session. |
/api/v1/vpn/logout |
POST | handleVPNLogout |
ready-write |
Logout + refresh login state. |
5) Скриптовые smoke-тесты
tests/api_sanity.sh— read endpoints + method guard + SSE headers.tests/trace_append.sh— append + readback (/trace,/trace-json).tests/events_stream.py— SSE stream + активный триггерtrace_append.tests/vpn_login_flow.py— start/state/action/stop для login session.tests/transport_flow_smoke.py— API-flowdraft/validate/confirm/apply/rollbackдля transport policy.tests/transport_platform_compatibility_smoke.py— проверка кроссплатформенного transport-контракта (web/iOS/Android) через capabilities + policy endpoints.tests/transport_runbook_cli_smoke.sh— smoke операционного runbook helper (scripts/transport_runbook.py) по lifecycle transport-клиента.tests/transport_recovery_runbook_smoke.sh— smoke recovery runbook (scripts/transport_recovery_runbook.py) для сценарияhealth->restart->fallback->diagnostics.tests/transport_systemd_real_e2e.py— real-systemd e2e дляsingbox/dnstt(+ssh)/phoenix+ проверка cleanup unit artifacts.tests/transport_production_like_e2e.py— production-like e2e для template-команд иpackaging_profile=bundledнаsystemdbackend.tests/transport_singbox_e2e.py— backend-first e2e дляsingboxlifecycle/guards.tests/transport_dnstt_e2e.py— backend-first e2e дляdnsttlifecycle/guards (ssh overlay, template checks).tests/transport_phoenix_e2e.py— backend-first e2e дляphoenixlifecycle/guards.tests/run_all.sh— общий запуск набора.
6) Факт прогона (2026-03-02)
- Команда:
API_URL=http://127.0.0.1:8080 ./tests/run_all.sh. - Результат:
api_sanity,trace_append,events_stream,vpn_login_flow—passed. - Дополнение (2026-03-07):
- Расширенный
run_allс transport smoke/e2e и packaging smoke проходитpassed; - включён и проходит
tests/transport_platform_compatibility_smoke.py(capabilities + policy contract); - при запуске старого backend-процесса
transport_*_e2eмогут завершатьсяSKIP(безprovision/metrics); - после пересборки и перезапуска
selective-vpn-apiиз текущего кодаtransport_singbox_e2e,transport_dnstt_e2e,transport_phoenix_e2eпрошли безSKIP. - в
run_allвключены и проходятtransport_systemd_real_e2e+transport_production_like_e2e(template-commands + packaging profile checks наrunner=systemd).
- Расширенный
7) Вывод для веб-прототипа
- Срез по legacy-матрице (53 endpoint из Phase D):
ready-read: 18ready-write: 27ready-async: 4ready-interactive: 4- Дополнение 2026-03-07:
- В ядро добавлены
8базовых mux-route/api/v1/transport/*+ action-subpathGET /api/v1/transport/clients/{id}/metrics(контракт D4.1). - Их контракт и rollout описаны в
docs/phase-e/E2_TRANSPORT_API_CONTRACT.md.
- В ядро добавлены
- По API-ядру нет endpoint, который блокирует веб-прототип на уровне контракта.
- Ограничения не в ручках, а в обвязке: auth/rbac, proxy/CORS/CSRF, и UX для async/interactive сценариев.
- Практический старт веба можно делать сразу: read панели + write действия под admin scope + SSE realtime слой.
8) Условия переиспользования для смартфонов (iOS/Android)
- Серверная обвязка:
- gateway/proxy с TLS и токен-авторизацией;
- refresh/access токены и управление device sessions;
- аудит и rate-limit для mutating endpoints.
- Контракт:
- стабильные DTO и error contract (
ok,message,exitCode,stderr); - versioning через
/api/v1и backward-compatible изменения.
- стабильные DTO и error contract (
- Realtime и фоновые ограничения:
- веб использует SSE постоянно;
- mobile использует SSE в foreground и polling fallback в background.
- Надежность мобильной сети:
- idempotency key для POST операций;
- retry policy с экспоненциальной паузой;
- correlation id для трассировки запросов.
- Безопасность клиента:
- iOS Keychain / Android Keystore для токенов;
- certificate pinning для production приложений.
9) D3: Последовательность запуска multi-client
- D3.1: Завершить gateway/auth слой (TLS, токены, RBAC, audit).
- D3.2: Подключить web-клиент к уже готовой матрице endpoint и SSE.
- D3.3: Ввести mobile transport profile (polling fallback + retry/idempotency).
- D3.4: Запустить iOS/Android клиенты на том же
/api/v1без изменения бизнес-логики ядра.
10) D4: Transport Integration Backlog
- D4.1
sing-box client:- Роль: универсальный клиент-транспорт для сценариев proxy/tun.
- Требование к ядру: запуск/остановка/health через backend-адаптер, без переноса логики в UI.
- Статус:
in-progress(2026-03-07: в API введён минимальный общий backend-контракт lifecycle/health/metrics/errors, добавленGET /api/v1/transport/clients/{id}/metrics). - E2E шаг (backend-first):
tests/transport_singbox_e2e.py:- проверяет успешный lifecycle на
runner=mock(provision/start/health/restart/stop/metrics); - проверяет guard
runtime_mode=embedded->TRANSPORT_BACKEND_RUNTIME_MODE_UNSUPPORTED; - проверяет fail-fast
require_binary=trueдля отсутствующегоsingbox_bin.
- проверяет успешный lifecycle на
- Примечание: если в рантайме запущен старый процесс API без
provision/metrics, тест завершитсяSKIP; для полного прогона нужен перезапуск backend из актуального кода.
- D4.2
dnstt-client:- Роль: отдельный клиент для DNSTT-протокола (как самостоятельный backend).
- Требование к ядру: управление lifecycle + состояние/ошибки через общий API слой.
- Уточнение: поддержать режим
dnstt + ssh overlay(туннель поверх SSH как единая система, аналогично phoenix UX-модели). - Статус:
in-progress(2026-03-07: в Go добавлены adapter foundation,POST /api/v1/transport/clients/{id}/provision, template-команды запуска, systemd restart/watchdog tuning, unit hardening-профили,runtime_modefoundationexec|embedded|sidecar, packaging profiles (system|bundled) и manual pinned updater/rollback scripts;config.exec_startработает как optional override). - E2E шаг (backend-first):
tests/transport_dnstt_e2e.py:- проверяет успешный lifecycle на
runner=mock; - проверяет guard
ssh_overlayконфигурации (ssh_hostобязателен,ssh_unitвалидируется); - проверяет template-валидацию DNSTT при неполном config.
- проверяет успешный lifecycle на
- Примечание: как и для singbox, при старом API-процессе без
provisionтест завершитсяSKIP; нужен перезапуск backend из текущего кода.
- D4.3
phoenix -> slipstream:- Роль: отдельный backend-клиент для подключения к удаленному
slipstreamсерверу. - Требование к ядру: конфиг/статус/управление сессией через backend-адаптер и общий контракт.
- Статус:
in-progress(2026-03-07: добавлен backend-first e2e тестtests/transport_phoenix_e2e.pyдля lifecycle/guards на API-контракте). - E2E шаг (backend-first):
tests/transport_phoenix_e2e.py:- проверяет успешный lifecycle на
runner=mock(provision/start/health/restart/stop/metrics); - проверяет guard
runtime_mode=embedded->TRANSPORT_BACKEND_RUNTIME_MODE_UNSUPPORTED; - проверяет fail-fast
require_binary=trueдля отсутствующегоphoenix_bin.
- проверяет успешный lifecycle на
- Примечание: при старом API-процессе без
provision/metricsтест завершитсяSKIP; для полного прогона нужен перезапуск backend из актуального кода.
- Роль: отдельный backend-клиент для подключения к удаленному
- D4.4 Общий инвариант:
- Для
web + iOS + AndroidUI не знает о внутренней реализации backend-клиента; он работает с единым API ядра. - Все transport-backend различия прячутся в Go-слое (feature flags, capability matrix, unified error contract).
- Для
11) D4.3: Матрица совместимости web + iOS + Android
- Отдельный артефакт:
docs/phase-d/D4_PLATFORM_COMPATIBILITY_MATRIX.md. - Зафиксировано:
- единый control-plane контракт
/api/v1для всех платформ; - transport-runtime работает только в backend (
exec), UI работает через capabilities/policies flow; - mobile использует тот же API, с fallback
pollingпри недоступном SSE в background.
- единый control-plane контракт