- Deleted unused components: `DashboardActivityTimeline`, `DashboardFramePanel`, `DashboardModulesGrid`, `DashboardRecentJobsGrid`, and `DashboardRecentRevisionsGrid` to streamline the dashboard. - Updated `DashboardKpiGrid` to improve KPI display logic, including progress indicators and enhanced badge functionality. - Refactored `DashboardNetworkHealth` to provide better status representation based on loading states and network conditions. - Introduced new properties for KPI cards to support progress tracking and improved visual feedback. This cleanup aims to enhance performance and maintainability of the dashboard while providing a better user experience.
9.7 KiB
Архитектура EvoBGP
Высокоуровневое описание компонентов и потоков. Детальный продуктовый и инфраструктурный чертёж также зафиксирован во внутреннем плане репозитория: .cursor/plans/evobgp_архитектура_0e73ef02.plan.md (удобно для истории решений; пользовательская навигация — через этот раздел и overview.md).
Назначение слоёв
- Control plane — HTTP API, хранилище состояния (PostgreSQL), фоновые задачи (jobs), подпись артефактов (бандлы), observability.
- Data plane — демон BIRD, локальные конфиги в
/etc/bird, сокет управленияbirdc, агентevobgp-agentдля наблюдения/сопутствующих действий. - Edge интеграция — CLI
evobgp-nodeна машине спикера: получение бандла по API, проверка подписи, применение конфигурации.
Компоненты (бинарники cmd/)
| Бинарник | Роль |
|---|---|
evobgp-api |
Только HTTP API и связанная логика в одном процессе. |
evobgp-all |
Тот же API + in-process scheduler (очередь module_refresh в общем Registry), ingest (prefetch ETag CDN), render (опционально auto-publish), deploy (лог расхождений published/applied). |
evobgp-scheduler |
По refresh_interval_sec ставит refresh: в одном процессе с API — через jobs.Registry; в reference Compose — HTTP POST /v1/modules/{id}/refresh (EVOBGP_CONTROL_PLANE_URL, EVOBGP_SCHEDULER_BEARER). |
evobgp-ingest |
Периодический conditional GET по URL CDN-источников и обновление etag в БД. |
evobgp-render |
По умолчанию только heartbeat; при EVOBGP_RENDER_AUTOPUBLISH=1 выставляет всем спикерам tenant последнюю ревизию (упрощение для демо). |
evobgp-deploy |
Периодически логирует drift: last_applied_revision_id vs опубликованная ревизия для ноды. |
evobgp-node |
CLI реплики: pull-bundle, verify-bundle, apply-bundle. |
evobgp-agent |
Локальный агент рядом с BIRD: watch, serve (Panel→Node sync API на реплике). |
В Docker Compose профиль reference запускает отдельные контейнеры под evobgp-api и четыре воркера; профиль microvps использует один контейнер evobgp-all.
Пакеты internal/ (сжатая карта)
| Пакет | Назначение |
|---|---|
httpapi |
Маршруты REST, аутентификация, CORS, привязка к store и jobs. |
store |
Абстракция бэкенда данных; реализации в памяти и через репозиторий. |
repository |
Доступ к PostgreSQL, сущности и миграции на уровне приложения. |
db |
Подключение к БД и применение миграций. |
jobs |
Реестр и выполнение асинхронных задач, связанных с API. |
bundle |
Упаковка и проверка бандлов для нод. |
signing |
Криптографическая проверка подписей. |
birdfmt |
Форматирование и фрагменты конфигурации BIRD, вызовы birdc. |
birddeploy |
Логика применения конфигурации к BIRD (используется в цепочке деплоя). |
config |
Переменные окружения EVOBGP_*. |
observability |
Метрики Prometheus, HTTP middleware. |
broker |
Опциональный EVOBGP_BROKER_URL для будущей шины; сейчас задачи только in-process (jobs.Registry), пакет лишь логирует факт настройки URL. |
pipeline |
Ingest+render для module_refresh: CDN/AS/IP/DOMAINS → module_prefix_snapshot (batch COPY, per-module lock) → агрегация CIDR O(n log n) → CreateRenderRevision. Fast-path снапшота — module.input_hash; DoH — TTL-кэш domain_resolve_cache; scheduler — jitter границ интервала. |
nodedispatch |
Panel→Node HTTP wake-up (POST /v1/agent/sync) после deploy_apply. |
agentserver |
HTTP API на реплике (serve): sync + health для Traefik; опционально firewall failover (/v1/firewall/*). |
firewall |
Вычисление policy block/accept → плоский CIDR blocklist. |
Удалённые спикеры
Реплики на отдельных VPS: remote-speakers.md. CP публикует ревизию и при EVOBGP_NODE_DISPATCH_ENABLED=1 будит agent; agent тянет signed bundle и применяет BIRD. Compose: deploy/compose/docker-compose.remote-speaker.yaml.
flowchart LR
subgraph clients [Clients]
WebUI[Web_UI]
Operator[Operator_API_client]
NodeCLI[evobgp_node]
end
subgraph control [Control_plane]
API[evobgp_api]
Sched[evobgp_scheduler]
Ingest[evobgp_ingest]
Render[evobgp_render]
Deploy[evobgp_deploy]
PG[(PostgreSQL)]
end
subgraph data [Data_plane]
BIRD[BIRD2]
Agent[evobgp_agent]
end
WebUI --> API
Operator --> API
NodeCLI --> API
API --> PG
Sched -->|HTTP_or_DB| API
Sched --> PG
Ingest --> PG
Render --> PG
Deploy --> PG
Agent --> BIRD
Очередь задач по-прежнему in-memory в процессе API (jobs.Registry); отдельный контейнер evobgp-scheduler не разделяет память с API и дергает refresh по HTTP. Полноценный брокер (NATS) и общая очередь job_audit между процессами — в следующих итерациях.
Диаграмма: microvps (evobgp-all)
flowchart LR
Client[HTTP_clients]
All[evobgp_all_process]
PG[(PostgreSQL)]
BIRD[BIRD2]
Client --> All
All --> PG
All --> BIRD
Внутри evobgp-all все воркеры используют тот же store и jobs.Registry, что и HTTP handlers, поэтому module_refresh выполняется в том же процессе без HTTP.
Профиль Compose microvps-full добавляет к этому стеку Web UI (nginx → evobgp-all), NATS и Prometheus без отдельных контейнеров воркеров (функционально то же, что отдельные scheduler/ingest/… в reference). Запуск и лимиты под ~1 ГиБ RAM — в quickstart.md.
Поток pipeline (ingest → render)
- Scheduler (
evobgp-scheduler/ in-process вevobgp-all) ставитtenant_refresh, еслиModuleDueForScheduler: граница окнаrefresh_interval_secсо сдвигомfnv32(module.ID) % interval, чтобы модули с одним интервалом не били внешние API одновременно. - Ingest (
RefreshModuleIngest):AS_PREFIXES— RIPEstat prefixes + holder параллельно, кэшasn_prefix_cache; дедуп строк поprefix + community.CDN_CIDRS— единыйfetchCDNSourceRows(conditional GET); prefetch уважаетRefreshIntervalSec; merge снапшота подLockModuleSnapshot(пропущенные по ошибке источники сохраняют prior-строки приEVOBGP_CDN_PARTIAL_OK).DOMAINS— DoH A+AAAA параллельно; попадания вdomain_resolve_cacheс TTLEVOBGP_DOMAIN_CACHE_TTL_SEC(default 300).IP_RANGES— напрямую из записей модуля.
- Снапшот пишется batch (
pgx.CopyFromв PostgreSQL). Совпадениеmodule.input_hashсо снапшотом — O(1) пропуск повторного ingest при render; CRUD entries обнуляет hash. - Render (
RenderTenantRevision):smartAggregatePrefixRows(стек-схлопывание O(n log n), IPv6 безmath/big) → ревизия, если набор префиксов изменился.
Поток: ревизия и бандл для ноды
- Оператор (роль
operatorили выше по политике) изменяет модули и запускает цепочку, приводящую к новой ревизии (часть шагов может быть асинхронной через jobs — см. OpenAPI). - Control plane формирует подписанный бандл для пары спикер + ревизия.
evobgp-node pull-bundleс ключом ролиnodeзапрашиваетGET /v1/speakers/{id}/revisions/latestи затемGET /v1/speakers/{id}/bundle/{revision_id}.- Локально выполняется проверка подписи (публичный ключ выдаётся при старте API) и применение к BIRD (
apply-bundle).
Связанные документы
- quickstart.md — как поднять стек.
- api.md — точки входа HTTP.
- access.md — ключи и роли.