Files
EvoBGP/docs/openapi.yaml
T
DenozordecandCursor 3f0dd6c234 docs(runtime-logs): implement runtime log management features
Добавлены новые возможности для работы с файловыми логами Docker-сервисов:
- Эндпоинты для получения списка логов и хвоста лог-файла.
- Очистка лог-файлов с возможностью выбора режима (truncate или delete) и запись в аудит очистки.
- Обновлена документация и конфигурация для поддержки новых функций.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-12 19:04:53 +07:00

4056 lines
128 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
openapi: 3.1.0
info:
title: EvoBGP Control Plane API
version: 1.0.0
description: |
REST API управления префиксами, модулями ingest, ревизиями конфигурации BIRD и задачами (async jobs).
**Актуальная semver-сборка:** `GET /version` или `GET /v1/version` (поле `version`; совпадает с git-тегом `vX.Y.Z`).
**Соглашения:** префикс `/v1`; идентификаторы - UUID v7 или ULID (строки); время - ISO 8601 UTC.
Ошибки - `application/problem+json` ([RFC 9457](https://www.rfc-editor.org/rfc/rfc9457)).
Пагинация списков - `cursor` + `limit`; ответ содержит `items`, `next_cursor`, `has_more`.
**Роли** (матрица доступа): `viewer`, `editor`, `operator`, `node`. Нода использует отдельные пути и ключ с ролью `node`.
Заголовок `X-Tenant-Id` допускается только для супер-ролей (явный tenant); иначе tenant берётся из API-ключа.
license:
name: Proprietary
identifier: LicenseRef-Proprietary
servers:
- url: https://api.example.com
description: Базовый URL инсталляции (замените на свой)
tags:
- name: System
description: Liveness, readiness и метаданные сборки. Обычно без чувствительных данных; доступ может быть шире.
- name: Modules
description: Экземпляры модулей префиксов (AS, CDN, домены, статические IP-диапазоны) и вложенные записи. Чтение - viewer+; изменение - editor+.
- name: DoH profiles
description: Профили DNS-over-HTTPS для модулей типа домены. Секрет в ответах не возвращается.
- name: Communities
description: Справочник BGP community в скоупе tenant.
- name: Peers
description: BGP-пиры и политики; привязка к спикеру или ко всем спикерам.
- name: Speakers
description: Регистрация и метаданные экземпляров BIRD (master/replica/canary).
- name: Revisions
description: История ревизий конфигурации, снимки префиксов, превью и откат (часто асинхронно).
- name: Deploy
description: Применение ревизий на спикерах и опциональный reload BIRD. Требуется роль operator.
- name: Jobs
description: Асинхронные задачи; статус и отмена (best-effort).
- name: Node
description: "API для evobgp-node (бандлы ревизий и enrollment). Отдельный ключ или mTLS, роль node."
- name: Settings
description: Глобальные настройки и feature flags; изменение - только operator.
- name: API keys
description: Управление API-ключами tenant (operator). Секрет возвращается только при создании и ротации.
- name: Auth
description: Сессия текущего API-ключа (tenant и роль).
- name: Monitoring
description: Наблюдаемость PostgreSQL и корреляция (instance-level, viewer+). Maintenance — operator.
- name: Maintenance
description: Политики обслуживания PostgreSQL (instance-scoped). CRUD и запуск — operator.
- name: RuntimeLogs
description: |
Файловые runtime-логи Docker-сервисов (каталог EVOBGP_RUNTIME_LOGS_DIR).
Доступно только в процессе evobgp-all с примонтированным volume; иначе 503.
Просмотр — viewer+; очистка — operator+ (синхронно, с audit).
security:
- bearerAuth: []
externalDocs:
description: Черновик и контекст API
url: ./evobgp-api-sketches.md
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: API-ключ в формате `Bearer <token>`. На edge может заменяться или дополняться mTLS.
parameters:
TenantId:
name: X-Tenant-Id
in: header
required: false
schema:
$ref: "#/components/schemas/ResourceId"
description: >
Явный tenant (только супер-роли). Без заголовка tenant определяется по API-ключу.
**Реализация v1:** заголовок в Go handlers не обрабатывается; tenant только из Bearer-токена (см. docs/access.md).
IdempotencyKey:
name: Idempotency-Key
in: header
required: false
schema:
type: string
maxLength: 256
description: Идемпотентность мутаций. Для `POST` apply и части refresh рекомендуется или обязателен по политике продукта.
Cursor:
name: cursor
in: query
schema:
type: string
description: Непрозрачный курсор из предыдущего ответа.
Limit:
name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 500
default: 50
description: Размер страницы (по умолчанию 50).
ModuleId:
name: module_id
in: path
required: true
schema:
$ref: "#/components/schemas/ResourceId"
SpeakerId:
name: speaker_id
in: path
required: true
schema:
$ref: "#/components/schemas/ResourceId"
RevisionId:
name: revision_id
in: path
required: true
schema:
$ref: "#/components/schemas/ResourceId"
JobId:
name: job_id
in: path
required: true
schema:
$ref: "#/components/schemas/ResourceId"
PeerId:
name: id
in: path
required: true
schema:
$ref: "#/components/schemas/ResourceId"
DohProfileId:
name: id
in: path
required: true
schema:
$ref: "#/components/schemas/ResourceId"
CommunityId:
name: id
in: path
required: true
schema:
$ref: "#/components/schemas/ResourceId"
ApiKeyId:
name: id
in: path
required: true
schema:
$ref: "#/components/schemas/ResourceId"
SourceId:
name: source_id
in: path
required: true
schema:
$ref: "#/components/schemas/ResourceId"
EntryId:
name: entry_id
in: path
required: true
schema:
$ref: "#/components/schemas/ResourceId"
RevisionA:
name: revision_a
in: path
required: true
schema:
$ref: "#/components/schemas/ResourceId"
RevisionB:
name: revision_b
in: path
required: true
schema:
$ref: "#/components/schemas/ResourceId"
ModuleTypeFilter:
name: type
in: query
schema:
$ref: "#/components/schemas/ModuleType"
ModuleEnabledFilter:
name: enabled
in: query
schema:
type: boolean
SpeakerFilter:
name: speaker_id
in: query
schema:
$ref: "#/components/schemas/ResourceId"
RevisionModuleFilter:
name: module_id
in: query
schema:
$ref: "#/components/schemas/ResourceId"
JobStatusFilter:
name: status
in: query
schema:
$ref: "#/components/schemas/JobStatus"
JobKindFilter:
name: kind
in: query
schema:
type: string
description: >
Фильтр по виду задачи; точный перечень расширяем.
Основные значения: `module_refresh`, `peer_reconcile`, `deploy_apply`, `revision_rollback`, `bird_reload`.
responses:
Unauthorized:
description: Нет или невалидный Bearer-токен.
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
Forbidden:
description: Недостаточно прав для операции.
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
NotFound:
description: Ресурс не найден в скоупе tenant.
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
Conflict:
description: Конфликт состояния (например, удаление DoH-профиля, который ещё используется).
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
UnprocessableEntity:
description: Семантическая ошибка запроса или валидации полей.
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
DefaultProblem:
description: Ошибка (см. тело Problem).
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
schemas:
ResourceId:
type: string
description: UUID v7 или ULID.
pattern: "^[0-9A-Za-z_-]{20,36}$"
examples:
- 01JQXYZABCDEFGHIJKLMNOPQRS
Problem:
type: object
description: Problem Details (RFC 9457).
required:
- title
- status
properties:
type:
type: string
format: uri-reference
description: URI типа проблемы.
title:
type: string
status:
type: integer
detail:
type: string
instance:
type: string
format: uri-reference
errors:
type: array
items:
$ref: "#/components/schemas/FieldError"
additionalProperties: true
FieldError:
type: object
properties:
field:
type: string
description: Имя поля (или JSON Pointer).
pointer:
type: string
description: JSON Pointer к значению.
message:
type: string
additionalProperties: true
AsyncJobAccepted:
type: object
required:
- job_id
- status
properties:
job_id:
$ref: "#/components/schemas/ResourceId"
status:
type: string
enum: [queued]
description: Начальный статус задачи в очереди.
ModuleType:
type: string
enum:
- AS_PREFIXES
- CDN_CIDRS
- DOMAINS
- IP_RANGES
DohResolverPolicy:
type: string
description: |
Политика резолва доменов через DoH при нескольких профилях.
`primary_only` — только первый профиль; `failover` — по порядку до первого успешного;
`union` — объединение A/AAAA со всех профилей.
enum:
- primary_only
- failover
- union
default: primary_only
JobStatus:
type: string
description: Статус задачи; перечень может расширяться.
enum:
- queued
- running
- succeeded
- failed
- cancelled
ApplyStrategy:
type: string
description: Стратегия выбора спикеров для apply.
enum:
- all_speakers
Module:
type: object
required:
- id
- type
- name
- enabled
- priority
properties:
id:
$ref: "#/components/schemas/ResourceId"
type:
$ref: "#/components/schemas/ModuleType"
name:
type: string
enabled:
type: boolean
priority:
type: integer
doh_profile_id:
type: ["string", "null"]
description: Первый DoH-профиль (legacy); предпочтительно `doh_profile_ids`.
doh_profile_ids:
type: array
items:
$ref: "#/components/schemas/ResourceId"
description: Упорядоченный список DoH-профилей для модулей `DOMAINS`.
doh_resolver_policy:
$ref: "#/components/schemas/DohResolverPolicy"
refresh_interval_sec:
type: ["integer", "null"]
minimum: 0
cron_expr:
type: ["string", "null"]
default_community_id:
type: ["string", "null"]
last_refreshed_at:
type: ["string", "null"]
format: date-time
description: Время последнего успешного обновления данных модуля.
additionalProperties: true
ModuleCreate:
type: object
required:
- type
- name
properties:
type:
$ref: "#/components/schemas/ModuleType"
name:
type: string
enabled:
type: boolean
default: true
priority:
type: integer
default: 0
doh_profile_id:
type: ["string", "null"]
description: Первый DoH-профиль (legacy); предпочтительно `doh_profile_ids`.
doh_profile_ids:
type: array
items:
$ref: "#/components/schemas/ResourceId"
description: Упорядоченный список DoH-профилей для модулей `DOMAINS`.
doh_resolver_policy:
$ref: "#/components/schemas/DohResolverPolicy"
refresh_interval_sec:
type: ["integer", "null"]
last_refreshed_at:
type: ["string", "null"]
format: date-time
description: Время последнего успешного обновления этого CDN-источника.
cron_expr:
type: ["string", "null"]
default_community_id:
type: ["string", "null"]
ModulePatch:
type: object
properties:
name:
type: string
enabled:
type: boolean
priority:
type: integer
doh_profile_id:
type: ["string", "null"]
description: Первый DoH-профиль (legacy); предпочтительно `doh_profile_ids`.
doh_profile_ids:
type: array
items:
$ref: "#/components/schemas/ResourceId"
description: Упорядоченный список DoH-профилей для модулей `DOMAINS`.
doh_resolver_policy:
$ref: "#/components/schemas/DohResolverPolicy"
refresh_interval_sec:
type: ["integer", "null"]
cron_expr:
type: ["string", "null"]
default_community_id:
type: ["string", "null"]
CdnSource:
type: object
required:
- id
- url
- source_kind
properties:
id:
$ref: "#/components/schemas/ResourceId"
url:
type: string
format: uri
source_kind:
type: string
description: Формат скачанного списка / парсер.
prefix_path:
type: string
description: Путь до поля с префиксами для source_kind=json (например data.items[].cidr).
community_id:
type: ["string", "null"]
refresh_interval_sec:
type: ["integer", "null"]
CdnSourceCreate:
type: object
required:
- url
- source_kind
properties:
url:
type: string
format: uri
source_kind:
type: string
prefix_path:
type: string
community_id:
type: ["string", "null"]
CdnSourcePatch:
type: object
properties:
url:
type: string
format: uri
source_kind:
type: string
prefix_path:
type: string
community_id:
type: ["string", "null"]
refresh_interval_sec:
type: ["integer", "null"]
CdnPreviewRequest:
type: object
required: [url, source_kind]
properties:
url:
type: string
format: uri
source_kind:
type: string
prefix_path:
type: string
CdnPreviewResponse:
type: object
required: [items, total, truncated, source_url]
properties:
items:
type: array
items:
type: string
total:
type: integer
truncated:
type: boolean
source_url:
type: string
AsEntry:
type: object
required:
- id
- asn
properties:
id:
$ref: "#/components/schemas/ResourceId"
asn:
type: integer
minimum: 1
maximum: 4294967295
community_id:
type: ["string", "null"]
additionalProperties: true
AsEntryCreate:
type: object
required:
- asn
properties:
asn:
type: integer
minimum: 1
maximum: 4294967295
community_id:
type: ["string", "null"]
additionalProperties: true
AsEntryPatch:
type: object
properties:
asn:
type: integer
minimum: 1
maximum: 4294967295
community_id:
type: ["string", "null"]
additionalProperties: true
DomainEntry:
type: object
required:
- id
- fqdn
properties:
id:
$ref: "#/components/schemas/ResourceId"
fqdn:
type: string
community_id:
type: ["string", "null"]
DomainEntryCreate:
type: object
required:
- fqdn
properties:
fqdn:
type: string
community_id:
type: ["string", "null"]
IpRangeEntry:
type: object
required:
- id
- prefix
- community_id
properties:
id:
$ref: "#/components/schemas/ResourceId"
prefix:
type: string
description: IPv4/IPv6 CIDR.
example: 203.0.113.0/24
community_id:
$ref: "#/components/schemas/ResourceId"
IpRangeEntryCreate:
type: object
required:
- prefix
- community_id
properties:
prefix:
type: string
community_id:
$ref: "#/components/schemas/ResourceId"
DohProfile:
type: object
required:
- id
properties:
id:
$ref: "#/components/schemas/ResourceId"
name:
type: string
description: Отображаемое имя профиля (опционально).
url:
type: string
format: uri
timeout_ms:
type: integer
vault_secret_ref:
type: ["string", "null"]
description: Ссылка на секрет в vault; сырое значение не отдаётся в GET.
additionalProperties: true
DohProfileCreate:
type: object
required:
- url
properties:
name:
type: string
description: Отображаемое имя профиля (опционально).
url:
type: string
format: uri
timeout_ms:
type: integer
vault_secret_ref:
type: ["string", "null"]
AuthSession:
type: object
required: [tenant_id, role]
properties:
tenant_id:
$ref: "#/components/schemas/ResourceId"
role:
type: string
enum: [viewer, editor, operator, node]
ApiKey:
type: object
required: [id, name, role, prefix, created_at, updated_at]
properties:
id:
$ref: "#/components/schemas/ResourceId"
name:
type: string
role:
type: string
enum: [viewer, editor, operator, node]
prefix:
type: string
description: Первые 8 символов токена для идентификации в UI.
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
expires_at:
type: ["string", "null"]
format: date-time
revoked_at:
type: ["string", "null"]
format: date-time
last_used_at:
type: ["string", "null"]
format: date-time
additionalProperties: true
ApiKeyCreate:
type: object
required: [name, role]
properties:
name:
type: string
role:
type: string
enum: [viewer, editor, operator, node]
expires_at:
type: ["string", "null"]
format: date-time
ApiKeyPatch:
type: object
properties:
name:
type: string
role:
type: string
enum: [viewer, editor, operator, node]
expires_at:
type: ["string", "null"]
format: date-time
ApiKeyCreated:
allOf:
- $ref: "#/components/schemas/ApiKey"
- type: object
required: [token]
properties:
token:
type: string
description: Полный Bearer-токен; показывается один раз.
BgpCommunity:
type: object
required:
- id
properties:
id:
$ref: "#/components/schemas/ResourceId"
community:
type: string
description: Техническое значение BGP community (строка для BIRD, например 65001:120 или large JSON в value_json).
title:
type: string
description: Человекочитаемое название для UI и фильтров.
additionalProperties: true
BgpPeer:
type: object
required:
- id
properties:
id:
$ref: "#/components/schemas/ResourceId"
neighbor:
type: string
description: IP соседа.
remote_asn:
type: integer
bgp_speaker_id:
type: ["string", "null"]
description: "`null` - политика для всех спикеров."
connected_speaker_id:
type: ["string", "null"]
description: >
Live (GET /v1/peers?live=1): спикер, на котором сессия Established; опрос CP birdc + agent /v1/agent/bird/protocols.
connected_speaker_label:
type: string
description: Человекочитаемая метка ноды из live-опроса.
session_on_speakers:
type: array
description: Состояние протокола пира на каждой опрошенной ноде.
items:
type: object
properties:
speaker_id:
type: string
label:
type: string
state:
type: string
established_on_speakers:
type: array
description: Ноды, где сессия в состоянии Established (один пир может быть на нескольких).
items:
type: object
properties:
speaker_id:
type: string
label:
type: string
state:
type: string
session_mismatch:
type: boolean
description: >
true если bgp_speaker_id задан, но на этой ноде нет Established
(сессия может быть на других нодах — это не ошибка для tenant-wide пиров).
policies_json:
type: string
description: >
JSON-объект (строка). Поля `local_ipv4`, `local_ipv6`, `local_asn` переопределяют
глобальные `bird_local_ipv4` / `bird_local_ipv6` / `bird_local_asn` тенанта.
Если эффективный локальный адрес или ASN пира отличается от дефолтов тенанта (`bird_local_*`),
в блок `protocol bgp … from bgp_template` добавляется строка `local … as …`.
additionalProperties: true
BgpSpeaker:
type: object
required:
- id
properties:
id:
$ref: "#/components/schemas/ResourceId"
role:
type: string
description: master, replica, canary и т.д.
endpoint:
type: string
last_applied_revision_id:
type: ["string", "null"]
published_revision_id:
type: ["string", "null"]
description: Последняя опубликованная на CP ревизия для этого спикера.
published_at:
type: ["string", "null"]
format: date-time
agent_domain:
type: string
description: FQDN agent API за Traefik (Address в UI, Remnawave-style).
node_ipv4:
type: string
description: IPv4 VPS; default для bird_bgp_source_ipv4.
bird_bgp_source_ipv4:
type: string
description: Per-speaker override router id / BGP local (см. pipeline overlay).
dispatch_status:
type: string
description: ok, error, skipped — последний Panel→Node wake-up.
sync_status:
type: string
description: synced, error — состояние sync на реплике.
last_dispatch_at:
type: string
format: date-time
last_dispatch_error:
type: string
meta_json:
type: object
description: >
Расширяемый объект. Ключи agent_domain, agent_secret (только при создании),
agent_port, node_ipv4, bird_bgp_source_ipv4, bird_bgp_source_ipv6.
live:
$ref: "#/components/schemas/SpeakerLiveStatus"
description: >
При GET /v1/speakers?live=1 — runtime-статус agent и BGP-опроса на ноде.
additionalProperties: true
SpeakerLiveStatus:
type: object
description: Live runtime snapshot for one speaker (GET /v1/speakers?live=1).
properties:
label:
type: string
description: Человекочитаемая метка ноды (agent domain или CP master).
agent_ok:
type: boolean
description: true если agent /v1/agent/health успешен (master — local birdc poll).
agent_error:
type: string
agent_last_sync_at:
type: string
format: date-time
agent_last_applied_revision_id:
type: string
bgp_poll_ok:
type: boolean
description: true если birdc (CP) или GET /v1/agent/bird/protocols (replica) успешен.
bgp_poll_error:
type: string
bgp_sessions_total:
type: integer
bgp_established:
type: integer
sessions:
type: array
items:
$ref: "#/components/schemas/BgpSessionLive"
additionalProperties: true
BgpSessionLive:
type: object
properties:
name:
type: string
neighbor:
type: string
state:
type: string
additionalProperties: true
LiveSpeakerPoll:
type: object
description: Метаданные опроса одной ноды в GET /v1/peers?live=1.
properties:
speaker_id:
type: string
label:
type: string
ok:
type: boolean
session_count:
type: integer
poll_error:
type: string
additionalProperties: true
PostgresOverview:
type: object
description: Instance-level PostgreSQL snapshot (GET /v1/monitoring/postgres/overview).
additionalProperties: true
PostgresQueriesResponse:
type: object
properties:
collected_at:
type: string
format: date-time
source:
type: string
enum: [live, snapshot]
items:
type: array
items:
type: object
additionalProperties: true
PostgresRecommendations:
type: object
properties:
collected_at:
type: string
format: date-time
items:
type: array
items:
type: object
properties:
severity:
type: string
code:
type: string
title:
type: string
detail:
type: string
refs:
type: array
items:
type: string
PostgresMaintenanceBody:
type: object
properties:
table:
type: string
dry_run:
type: boolean
default: false
policy:
type: string
description: Deprecated; use maintenance policies API.
limit:
type: integer
MaintenancePolicy:
type: object
required: [name, table_name, schedule, vacuum_strategy]
properties:
id:
$ref: "#/components/schemas/ResourceId"
name:
type: string
table_name:
type: string
condition:
type: string
default: "true"
retention_period_sec:
type: integer
minimum: 1
max_rows:
type: integer
minimum: 1
maximum: 100000
vacuum_strategy:
type: string
enum: [none, vacuum, analyze, vacuum_analyze, reindex]
schedule:
type: string
description: Cron expression (5-field, UTC).
enabled:
type: boolean
default: true
dry_run_enabled:
type: boolean
default: false
last_run_at:
type: string
format: date-time
last_status:
type: string
last_error:
type: string
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
MaintenancePolicyPatch:
type: object
properties:
name:
type: string
table_name:
type: string
condition:
type: string
retention_period_sec:
type: integer
max_rows:
type: integer
vacuum_strategy:
type: string
enum: [none, vacuum, analyze, vacuum_analyze, reindex]
schedule:
type: string
enabled:
type: boolean
dry_run_enabled:
type: boolean
MaintenanceRunBody:
type: object
required: [policy_id]
properties:
policy_id:
$ref: "#/components/schemas/ResourceId"
MaintenancePolicyList:
type: object
properties:
items:
type: array
items:
$ref: "#/components/schemas/MaintenancePolicy"
next_cursor:
type: string
has_more:
type: boolean
RuntimeLogCleanupMode:
type: string
enum: [truncate, delete]
description: |
truncate — обнулить файл (по умолчанию); delete — удалить файл с диска.
RuntimeLogFile:
type: object
required: [name, size_bytes, modified_at]
properties:
name:
type: string
description: Basename файла (*.log) в каталоге runtime-логов.
pattern: '^[a-z0-9][a-z0-9_.-]*\.log$'
size_bytes:
type: integer
format: int64
minimum: 0
modified_at:
type: string
format: date-time
RuntimeLogFileList:
type: object
required: [items]
properties:
items:
type: array
items:
$ref: "#/components/schemas/RuntimeLogFile"
RuntimeLogTail:
type: object
required: [filename, content, truncated, lines_returned]
properties:
filename:
type: string
content:
type: string
description: UTF-8 текст хвоста файла.
truncated:
type: boolean
description: true если применён лимит bytes/lines.
lines_returned:
type: integer
minimum: 0
RuntimeLogCleanupResult:
type: object
required: [audit_id, filename, action, size_before]
properties:
audit_id:
$ref: "#/components/schemas/ResourceId"
filename:
type: string
action:
$ref: "#/components/schemas/RuntimeLogCleanupMode"
size_before:
type: integer
format: int64
size_after:
type: ["integer", "null"]
format: int64
RuntimeLogCleanupAudit:
type: object
required: [id, tenant_id, actor_prefix, filename, action, size_before, created_at]
properties:
id:
$ref: "#/components/schemas/ResourceId"
tenant_id:
$ref: "#/components/schemas/ResourceId"
actor_prefix:
type: string
filename:
type: string
action:
$ref: "#/components/schemas/RuntimeLogCleanupMode"
size_before:
type: integer
format: int64
size_after:
type: ["integer", "null"]
format: int64
detail:
type: object
additionalProperties: true
created_at:
type: string
format: date-time
RuntimeLogCleanupAuditList:
type: object
properties:
items:
type: array
items:
$ref: "#/components/schemas/RuntimeLogCleanupAudit"
next_cursor:
type: string
has_more:
type: boolean
BirdLocalStatus:
type: object
description: Статус локального BIRD на хосте API (GET /v1/bird/status).
properties:
birdc_configured:
type: boolean
message:
type: string
error:
type: string
protocols_excerpt:
type: string
bgp_sessions_total:
type: integer
bgp_established:
type: integer
healthy:
type: ["boolean", "null"]
additionalProperties: true
BundleSigningPublicKey:
type: object
required: [public_key_base64]
properties:
public_key_base64:
type: string
description: Ed25519 public key (base64) для verify-bundle на реплике.
ConfigRevision:
type: object
required:
- id
properties:
id:
$ref: "#/components/schemas/ResourceId"
parent_revision_id:
type: ["string", "null"]
content_hash:
type: string
created_at:
type: string
format: date-time
additionalProperties: true
PrefixSnapshotItem:
type: object
description: >
Элемент материализованного снимка. Поле prefix обычно содержит CIDR;
для модулей AS_PREFIXES допускается ключ вида as:<номер_asn> (не CIDR).
additionalProperties: true
Job:
type: object
required:
- job_id
- kind
- status
- created_at
properties:
job_id:
$ref: "#/components/schemas/ResourceId"
kind:
type: string
status:
$ref: "#/components/schemas/JobStatus"
idempotency_key:
type: ["string", "null"]
created_at:
type: string
format: date-time
started_at:
type: ["string", "null"]
description: ISO 8601 UTC, если задача уже стартовала.
finished_at:
type: ["string", "null"]
description: ISO 8601 UTC по завершении.
error:
type: ["string", "null"]
meta:
type: object
additionalProperties: true
ApplyRequest:
type: object
properties:
revision_id:
$ref: "#/components/schemas/ResourceId"
strategy:
$ref: "#/components/schemas/ApplyStrategy"
dry_run:
type: boolean
default: false
VersionInfo:
type: object
properties:
version:
type: string
description: Semver сборки (git tag без префикса v).
example: "1.2.3"
api_version:
type: string
deprecated: true
description: Alias поля `version` (сохранён для обратной совместимости).
git_sha:
type: string
build_time:
type: string
format: date-time
additionalProperties: true
HealthStatus:
type: object
properties:
status:
type: string
example: ok
additionalProperties: true
ReadyStatus:
type: object
properties:
status:
type: string
example: ready
checks:
type: object
additionalProperties: true
additionalProperties: true
Settings:
type: object
description: |
KV настройки tenant/глобальные лимиты и feature flags.
Параметры BIRD (строки в `global_settings`, JSON-значения — обычно строка или число):
`bird_router_id`, `bird_local_ipv4`, `bird_local_ipv6`, `bird_local_asn`;
если задан `bird_bgp_source_ipv4`, он подставляется как BIRD `router id` (перекрывает `bird_router_id`).
Ключи `bird_bgp_source_ipv4` / `bird_bgp_source_ipv6` в сгенерированном BGP для пиров не используются (оставлены для совместимости API).
Шаблон BGP в конфиге: `local as <bird_local_asn>;` без локального IP.
properties:
bird_router_id:
type: string
description: BIRD `router id` (IPv4 dotted quad), если не задан `bird_bgp_source_ipv4`.
bird_local_ipv4:
type: string
bird_local_ipv6:
type: string
bird_local_asn:
type: integer
bird_bgp_source_ipv4:
type: string
description: |
Если задан — используется как BIRD `router id` (IPv4). В блоках `protocol bgp … from bgp_template` строка `source address` не генерируется.
bird_bgp_source_ipv6:
type: string
description: Зарезервировано; в текущей генерации BGP не используется.
additionalProperties: true
RevisionDiff:
type: object
description: |
Сравнение двух ревизий. Конкретный формат (JSON Patch, табличный diff и т.д.) задаётся реализацией - контракт может уточняться.
additionalProperties: true
NodeEnrollRequest:
type: object
description: Тело регистрации ноды; протокол обмена ключами уточняется отдельно.
properties:
public_key:
type: string
speaker_id:
$ref: "#/components/schemas/ResourceId"
additionalProperties: true
NodeEnrollResponse:
type: object
description: Подтверждение записи enrollment (метаданные спикера обновлены).
properties:
status:
type: string
example: enrolled
speaker_id:
$ref: "#/components/schemas/ResourceId"
tenant_id:
$ref: "#/components/schemas/ResourceId"
additionalProperties: true
DohProfilePatch:
type: object
properties:
name:
type: string
url:
type: string
format: uri
timeout_ms:
type: integer
vault_secret_ref:
type: ["string", "null"]
BgpCommunityCreate:
type: object
required: [community]
properties:
community:
type: string
title:
type: string
additionalProperties: true
BgpCommunityPatch:
type: object
properties:
community:
type: string
title:
type: string
additionalProperties: true
BgpPeerCreate:
type: object
required: [neighbor, remote_asn]
properties:
neighbor:
type: string
remote_asn:
type: integer
bgp_speaker_id:
type: ["string", "null"]
additionalProperties: true
BgpPeerPatch:
type: object
properties:
neighbor:
type: string
remote_asn:
type: integer
bgp_speaker_id:
type: ["string", "null"]
additionalProperties: true
BgpSpeakerCreate:
type: object
required: [endpoint]
properties:
role:
type: string
default: replica
endpoint:
type: string
description: URL agent или https://AGENT_DOMAIN
meta_json:
type: string
description: >
JSON-объект. Ключи node_ipv4, bird_bgp_source_ipv4 (default = node_ipv4),
agent_domain, agent_secret (генерируется при создании если пуст).
additionalProperties: true
BgpSpeakerPatch:
type: object
properties:
role:
type: string
endpoint:
type: string
meta_json:
type: string
description: JSON-объект с ключами agent_domain, node_ipv4, bird_bgp_source_ipv4 и др.
additionalProperties: true
LatestRevisionPointer:
type: object
required:
- revision_id
properties:
revision_id:
$ref: "#/components/schemas/ResourceId"
published_at:
type: string
format: date-time
paths:
/v1/health:
get:
tags: [System]
summary: Liveness
description: Проверка, что процесс API жив. Не обязана проверять БД или брокер.
operationId: getHealth
responses:
"200":
description: Процесс отвечает.
content:
application/json:
schema:
$ref: "#/components/schemas/HealthStatus"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/ready:
get:
tags: [System]
summary: Readiness
description: Готовность к трафику (БД, брокер сообщений при reference-архитектуре и т.д.).
operationId: getReady
responses:
"200":
description: Сервис готов принимать запросы.
content:
application/json:
schema:
$ref: "#/components/schemas/ReadyStatus"
"503":
description: Не готов (зависимости недоступны).
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
default:
$ref: "#/components/responses/DefaultProblem"
/version:
get:
tags: [System]
summary: Версия сборки (корневой путь)
description: |
Аналог `GET /v1/version`. Публичный маршрут без аутентификации.
Semver в поле `version` задаётся при сборке Docker-образов из git-тега.
operationId: getVersionRoot
responses:
"200":
description: Метаданные сборки.
content:
application/json:
schema:
$ref: "#/components/schemas/VersionInfo"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/version:
get:
tags: [System]
summary: Версия сборки
description: |
Semver control-plane и метаданные сборки (`git_sha`, `build_time`).
Дублирует `GET /version`.
operationId: getVersion
responses:
"200":
description: Метаданные сборки.
content:
application/json:
schema:
$ref: "#/components/schemas/VersionInfo"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/modules:
get:
tags: [Modules]
summary: Список модулей
description: Модули tenant с опциональными фильтрами по типу и флагу `enabled` (фильтры применяются сервером).
operationId: listModules
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/Cursor"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/ModuleTypeFilter"
- $ref: "#/components/parameters/ModuleEnabledFilter"
responses:
"200":
description: Страница модулей.
content:
application/json:
schema:
type: object
required: [items, has_more]
properties:
items:
type: array
items:
$ref: "#/components/schemas/Module"
next_cursor:
type: ["string", "null"]
has_more:
type: boolean
"401":
$ref: "#/components/responses/Unauthorized"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/router-lists/catalog:
get:
tags: [Modules]
summary: Агрегированный каталог для router-lists-ui
description: |
Возвращает в одном ответе:
- модули типов `DOMAINS`, `IP_RANGES`, `AS_PREFIXES`;
- entries по каждому модулю;
- справочник community (`id`, `community`, `title`).
operationId: getRouterListsCatalog
parameters:
- $ref: "#/components/parameters/TenantId"
responses:
"200":
description: Агрегированные данные для списков UI.
content:
application/json:
schema:
type: object
required: [modules, domains, asns, ip_ranges, communities]
properties:
modules:
type: object
required: [items]
properties:
items:
type: array
items:
$ref: "#/components/schemas/Module"
domains:
type: object
required: [items]
properties:
items:
type: array
items:
type: object
required: [module_id, entry]
properties:
module_id:
$ref: "#/components/schemas/ResourceId"
entry:
$ref: "#/components/schemas/DomainEntry"
asns:
type: object
required: [items]
properties:
items:
type: array
items:
type: object
required: [module_id, entry]
properties:
module_id:
$ref: "#/components/schemas/ResourceId"
entry:
$ref: "#/components/schemas/AsEntry"
ip_ranges:
type: object
required: [items]
properties:
items:
type: array
items:
type: object
required: [module_id, entry]
properties:
module_id:
$ref: "#/components/schemas/ResourceId"
entry:
$ref: "#/components/schemas/IpRangeEntry"
communities:
type: object
required: [items]
properties:
items:
type: array
items:
$ref: "#/components/schemas/BgpCommunity"
"401":
$ref: "#/components/responses/Unauthorized"
default:
$ref: "#/components/responses/DefaultProblem"
post:
tags: [Modules]
summary: Создать модуль
description: |
Создаёт экземпляр модуля. Поле `type` задаёт вид (`AS_PREFIXES`, `CDN_CIDRS`, `DOMAINS`, `IP_RANGES`).
`module_id` в других путях - идентификатор экземпляра, не имя типа.
operationId: createModule
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ModuleCreate"
responses:
"201":
description: Модуль создан.
content:
application/json:
schema:
$ref: "#/components/schemas/Module"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"422":
$ref: "#/components/responses/UnprocessableEntity"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/modules/{module_id}:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/ModuleId"
get:
tags: [Modules]
summary: Получить модуль
operationId: getModule
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/Module"
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
patch:
tags: [Modules]
summary: Обновить модуль
description: Частичное обновление (расписание, DoH, приоритет, `enabled` и т.д.).
operationId: patchModule
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ModulePatch"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/Module"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
"422":
$ref: "#/components/responses/UnprocessableEntity"
default:
$ref: "#/components/responses/DefaultProblem"
delete:
tags: [Modules]
summary: Удалить модуль
description: Мягкое удаление или перевод в `enabled=false` - конкретное поведение задаётся реализацией.
operationId: deleteModule
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
responses:
"204":
description: Удалено или деактивировано.
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/modules/{module_id}/cdn-sources:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/ModuleId"
get:
tags: [Modules]
summary: Список CDN-источников
operationId: listCdnSources
parameters:
- $ref: "#/components/parameters/Cursor"
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
type: object
required: [items, has_more]
properties:
items:
type: array
items:
$ref: "#/components/schemas/CdnSource"
next_cursor:
type: ["string", "null"]
has_more:
type: boolean
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
post:
tags: [Modules]
summary: Добавить CDN-источник
description: URL, `source_kind`, опционально `community_id`.
operationId: createCdnSource
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CdnSourceCreate"
responses:
"201":
description: Ресурс создан.
content:
application/json:
schema:
$ref: "#/components/schemas/CdnSource"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
"422":
$ref: "#/components/responses/UnprocessableEntity"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/modules/{module_id}/cdn-sources/{source_id}:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/ModuleId"
- $ref: "#/components/parameters/SourceId"
patch:
tags: [Modules]
summary: Обновить CDN-источник
operationId: patchCdnSource
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CdnSourcePatch"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/CdnSource"
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
delete:
tags: [Modules]
summary: Удалить CDN-источник
operationId: deleteCdnSource
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
responses:
"204":
description: Удалено.
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/modules/{module_id}/as-entries:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/ModuleId"
get:
tags: [Modules]
summary: Список AS-записей
operationId: listAsEntries
parameters:
- $ref: "#/components/parameters/Cursor"
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
type: object
required: [items, has_more]
properties:
items:
type: array
items:
$ref: "#/components/schemas/AsEntry"
next_cursor:
type: ["string", "null"]
has_more:
type: boolean
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
post:
tags: [Modules]
summary: Добавить AS-запись
operationId: createAsEntry
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/AsEntryCreate"
responses:
"201":
description: Ресурс создан.
content:
application/json:
schema:
$ref: "#/components/schemas/AsEntry"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/modules/{module_id}/as-entries/{entry_id}:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/ModuleId"
- $ref: "#/components/parameters/EntryId"
patch:
tags: [Modules]
summary: Обновить AS-запись
operationId: patchAsEntry
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/AsEntryPatch"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/AsEntry"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
delete:
tags: [Modules]
summary: Удалить AS-запись
operationId: deleteAsEntry
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
responses:
"204":
description: Удалено.
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/modules/{module_id}/domain-entries:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/ModuleId"
get:
tags: [Modules]
summary: Список доменных записей
description: FQDN и привязка к community.
operationId: listDomainEntries
parameters:
- $ref: "#/components/parameters/Cursor"
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
type: object
required: [items, has_more]
properties:
items:
type: array
items:
$ref: "#/components/schemas/DomainEntry"
next_cursor:
type: ["string", "null"]
has_more:
type: boolean
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
post:
tags: [Modules]
summary: Добавить доменную запись
operationId: createDomainEntry
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/DomainEntryCreate"
responses:
"201":
description: Ресурс создан.
content:
application/json:
schema:
$ref: "#/components/schemas/DomainEntry"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/modules/{module_id}/domain-entries/{entry_id}:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/ModuleId"
- $ref: "#/components/parameters/EntryId"
patch:
tags: [Modules]
summary: Обновить доменную запись
operationId: patchDomainEntry
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/DomainEntryCreate"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/DomainEntry"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
delete:
tags: [Modules]
summary: Удалить доменную запись
operationId: deleteDomainEntry
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
responses:
"204":
description: Удалено.
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/modules/{module_id}/ip-range-entries:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/ModuleId"
get:
tags: [Modules]
summary: Список IP-диапазонов
description: "Только для модулей с типом IP_RANGES (статические CIDR и community_id)."
operationId: listIpRangeEntries
parameters:
- $ref: "#/components/parameters/Cursor"
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
type: object
required: [items, has_more]
properties:
items:
type: array
items:
$ref: "#/components/schemas/IpRangeEntry"
next_cursor:
type: ["string", "null"]
has_more:
type: boolean
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
post:
tags: [Modules]
summary: Добавить IP-диапазон
operationId: createIpRangeEntry
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/IpRangeEntryCreate"
responses:
"201":
description: Ресурс создан.
content:
application/json:
schema:
$ref: "#/components/schemas/IpRangeEntry"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/modules/{module_id}/ip-range-entries/{entry_id}:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/ModuleId"
- $ref: "#/components/parameters/EntryId"
patch:
tags: [Modules]
summary: Обновить IP-диапазон
operationId: patchIpRangeEntry
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/IpRangeEntryCreate"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/IpRangeEntry"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
delete:
tags: [Modules]
summary: Удалить IP-диапазон
operationId: deleteIpRangeEntry
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
responses:
"204":
description: Удалено.
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/modules/{module_id}/refresh:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/ModuleId"
post:
tags: [Modules]
summary: Запустить ingest
description: |
Запуск обновления данных модуля (CDN / DoH / AS в зависимости от типа).
Итоговая ревизия и фрагменты BIRD строятся **по всем включённым модулям тенанта**:
обновляемый модуль пересчитывается заново, остальные — по текущему состоянию в БД/источниках,
так что префиксы ASN, CDN, IP и т.д. суммируются в одном конфиге.
Для `IP_RANGES` данные обычно только в БД: сервер может вернуть **204** (no-op) или **400**, если refresh не поддерживается - поведение фиксируется в реализации.
Рекомендуется передавать `Idempotency-Key`.
operationId: postModuleRefresh
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
responses:
"202":
description: Задача поставлена в очередь.
headers:
Location:
description: URL задачи `/v1/jobs/{job_id}`
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/AsyncJobAccepted"
"204":
description: Нет операции (например модуль `IP_RANGES` и no-op).
"400":
description: Тип модуля не поддерживает refresh.
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/modules/{module_id}/entries.csv:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/ModuleId"
get:
tags: [Modules]
summary: Экспорт записей модуля в CSV
description: |
Доступно для типов модулей `AS_PREFIXES`, `DOMAINS`, `IP_RANGES`.
Возвращает CSV с колонками:
- AS: `asn,community`
- Домены: `domain,community`
- IP ranges: `ipRange,community`
operationId: exportModuleEntriesCsv
responses:
"200":
description: CSV-файл записей модуля.
content:
text/csv:
schema:
type: string
"404":
$ref: "#/components/responses/NotFound"
"422":
$ref: "#/components/responses/UnprocessableEntity"
default:
$ref: "#/components/responses/DefaultProblem"
post:
tags: [Modules]
summary: Импорт записей модуля из CSV
description: |
Импортирует CSV в модуль типов `AS_PREFIXES`, `DOMAINS`, `IP_RANGES`.
Поддерживаемые заголовки:
- `asn,community`
- `domain,community`
- `ipRange,community`
В поле `community` можно передавать либо ID community, либо её значение.
operationId: importModuleEntriesCsv
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
text/csv:
schema:
type: string
responses:
"200":
description: Импорт завершён.
content:
application/json:
schema:
type: object
required: [imported, module_type]
properties:
imported:
type: integer
minimum: 0
module_type:
type: string
"404":
$ref: "#/components/responses/NotFound"
"422":
$ref: "#/components/responses/UnprocessableEntity"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/doh-profiles:
get:
tags: [DoH profiles]
summary: Список DoH-профилей
operationId: listDohProfiles
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/Cursor"
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
type: object
required: [items, has_more]
properties:
items:
type: array
items:
$ref: "#/components/schemas/DohProfile"
next_cursor:
type: ["string", "null"]
has_more:
type: boolean
default:
$ref: "#/components/responses/DefaultProblem"
post:
tags: [DoH profiles]
summary: Создать DoH-профиль
description: URL и таймауты; секрет - через vault id или отдельный вызов установки секрета.
operationId: createDohProfile
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/DohProfileCreate"
responses:
"201":
description: Ресурс создан.
content:
application/json:
schema:
$ref: "#/components/schemas/DohProfile"
"422":
$ref: "#/components/responses/UnprocessableEntity"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/modules/{module_id}/cdn-sources/preview:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/ModuleId"
post:
tags: [Modules]
summary: Предпросмотр префиксов из CDN-источника
description: >
Синхронный запрос: conditional GET к URL (до 8 MiB тела ответа), парсинг plaintext или JSON,
возврат до 100 префиксов в `items` (полный счётчик в `total`). Выполняется в HTTP worker;
при таймауте клиента используйте короткий URL или меньший payload.
operationId: previewCdnSource
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CdnPreviewRequest"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/CdnPreviewResponse"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
"422":
$ref: "#/components/responses/UnprocessableEntity"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/doh-profiles/{id}:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/DohProfileId"
get:
tags: [DoH profiles]
summary: Получить DoH-профиль
description: Секрет в ответе не возвращается.
operationId: getDohProfile
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/DohProfile"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
patch:
tags: [DoH profiles]
summary: Обновить DoH-профиль
operationId: patchDohProfile
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/DohProfilePatch"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/DohProfile"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
delete:
tags: [DoH profiles]
summary: Удалить DoH-профиль
description: Допустимо только если профиль не используется модулями.
operationId: deleteDohProfile
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
responses:
"204":
description: Удалено.
"409":
$ref: "#/components/responses/Conflict"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/communities:
get:
tags: [Communities]
summary: Список BGP community
operationId: listCommunities
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/Cursor"
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
type: object
required: [items, has_more]
properties:
items:
type: array
items:
$ref: "#/components/schemas/BgpCommunity"
next_cursor:
type: ["string", "null"]
has_more:
type: boolean
default:
$ref: "#/components/responses/DefaultProblem"
post:
tags: [Communities]
summary: Создать community
operationId: createCommunity
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/BgpCommunityCreate"
responses:
"201":
description: Ресурс создан.
content:
application/json:
schema:
$ref: "#/components/schemas/BgpCommunity"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/communities/{id}:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/CommunityId"
get:
tags: [Communities]
summary: Получить community
operationId: getCommunity
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/BgpCommunity"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
patch:
tags: [Communities]
summary: Обновить community
operationId: patchCommunity
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/BgpCommunityPatch"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/BgpCommunity"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
delete:
tags: [Communities]
summary: Удалить community
description: Только при отсутствии ссылок из других сущностей.
operationId: deleteCommunity
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
responses:
"204":
description: Удалено.
"409":
$ref: "#/components/responses/Conflict"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/peers:
get:
tags: [Peers]
summary: Список пиров
operationId: listPeers
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/Cursor"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/SpeakerFilter"
- name: live
in: query
schema:
type: string
enum: ["1"]
description: >
Опрос birdc на CP и GET /v1/agent/bird/protocols на репликах; обогащает session_state и connected_speaker_*.
responses:
"200":
description: Успешно.
content:
application/json:
schema:
type: object
required: [items, has_more]
properties:
items:
type: array
items:
$ref: "#/components/schemas/BgpPeer"
next_cursor:
type: ["string", "null"]
has_more:
type: boolean
live_speaker_poll:
type: array
description: >
При live=1 — результат опроса каждой ноды (CP birdc + agent protocols).
items:
$ref: "#/components/schemas/LiveSpeakerPoll"
default:
$ref: "#/components/responses/DefaultProblem"
post:
tags: [Peers]
summary: Создать пира
description: >
Создаёт BGP-пира и инициирует быстрый reconcile пиров (job `peer_reconcile`) без module ingest.
После reconcile автоматически запускается apply на спикеры.
operationId: createPeer
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/BgpPeerCreate"
responses:
"201":
description: Ресурс создан.
content:
application/json:
schema:
$ref: "#/components/schemas/BgpPeer"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/peers/{id}:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/PeerId"
get:
tags: [Peers]
summary: Получить пира
operationId: getPeer
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/BgpPeer"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
patch:
tags: [Peers]
summary: Обновить пира
description: >
Политики (`policies_json`: `local_ipv4`, `local_ipv6`, `local_asn`), neighbor, ASN,
привязка к `bgp_speaker_id` или `null` для всех спикеров.
Изменение инициирует быстрый reconcile пиров (job `peer_reconcile`) без module ingest
и затем авто-apply на спикеры.
operationId: patchPeer
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/BgpPeerPatch"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/BgpPeer"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
delete:
tags: [Peers]
summary: Удалить или отключить пира
description: >
Удаление/отключение инициирует быстрый reconcile пиров (job `peer_reconcile`) без module ingest
и затем авто-apply на спикеры.
operationId: deletePeer
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
responses:
"204":
description: Удалено / отключено.
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/bundle/signing-public-key:
get:
tags: [Bundles]
summary: Публичный ключ подписи бандлов
description: >
Ed25519 public key (base64) для `evobgp-node verify-bundle` / agent sync на реплике.
Роль viewer и выше.
operationId: getBundleSigningPublicKey
responses:
"200":
description: Ключ для env EVOBGP_BUNDLE_PUBKEY_BASE64 на реплике.
content:
application/json:
schema:
$ref: "#/components/schemas/BundleSigningPublicKey"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/speakers:
get:
tags: [Speakers]
summary: Список спикеров
description: Master / replica, endpoint и связанные поля.
operationId: listSpeakers
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/Cursor"
- $ref: "#/components/parameters/Limit"
- name: live
in: query
schema:
type: string
enum: ["1"]
description: >
Live-опрос agent /v1/agent/health и BGP protocols на репликах; CP — local birdc.
Обогащает каждый item полем `live`.
responses:
"200":
description: Успешно.
content:
application/json:
schema:
type: object
required: [items, has_more]
properties:
items:
type: array
items:
$ref: "#/components/schemas/BgpSpeaker"
next_cursor:
type: ["string", "null"]
has_more:
type: boolean
default:
$ref: "#/components/responses/DefaultProblem"
post:
tags: [Speakers]
summary: Зарегистрировать спикер
description: Реплика, canary и т.д.
operationId: createSpeaker
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/BgpSpeakerCreate"
responses:
"201":
description: Ресурс создан.
content:
application/json:
schema:
$ref: "#/components/schemas/BgpSpeaker"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/speakers/{id}:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/PeerId"
get:
tags: [Speakers]
summary: Получить спикер
description: В т.ч. `last_applied_revision_id`.
operationId: getSpeaker
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/BgpSpeaker"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
patch:
tags: [Speakers]
summary: Обновить метаданные спикера
operationId: patchSpeaker
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/BgpSpeakerPatch"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/BgpSpeaker"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
delete:
tags: [Speakers]
summary: Удалить спикер
description: >
Удаляет BGP-спикер. Пиры с `bgp_speaker_id` этого спикера остаются, привязка сбрасывается (ON DELETE SET NULL).
operationId: deleteSpeaker
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
responses:
"204":
description: Удалено.
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/revisions:
get:
tags: [Revisions]
summary: История ревизий
operationId: listRevisions
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/Cursor"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/RevisionModuleFilter"
responses:
"200":
description: Список ревизий с cursor-пагинацией; опциональный фильтр `module_id`.
content:
application/json:
schema:
type: object
required: [items, has_more]
properties:
items:
type: array
items:
$ref: "#/components/schemas/ConfigRevision"
next_cursor:
type: ["string", "null"]
has_more:
type: boolean
default:
$ref: "#/components/responses/DefaultProblem"
/v1/revisions/{revision_id}:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/RevisionId"
get:
tags: [Revisions]
summary: Метаданные ревизии
description: Хэш, родитель, время, артефакты.
operationId: getRevision
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/ConfigRevision"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/revisions/{revision_id}/prefixes:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/RevisionId"
get:
tags: [Revisions]
summary: Снимок префиксов ревизии
operationId: getRevisionPrefixes
parameters:
- $ref: "#/components/parameters/Cursor"
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
type: object
required: [items, has_more]
properties:
items:
type: array
items:
$ref: "#/components/schemas/PrefixSnapshotItem"
next_cursor:
type: ["string", "null"]
has_more:
type: boolean
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/revisions/{revision_id}/preview:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/RevisionId"
get:
tags: [Revisions]
summary: Превью фрагментов BIRD
description: Только чтение, без apply.
operationId: getRevisionPreview
responses:
"200":
description: Текст или структурированное представление - формат задаётся реализацией.
content:
application/json:
schema:
type: object
additionalProperties: true
text/plain:
schema:
type: string
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/revisions/{revision_id}/rollback:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/RevisionId"
post:
tags: [Revisions]
summary: Откат через новую ревизию
description: |
Создаёт **новую** ревизию с содержимым отката от указанной. Часто возвращает **202** с `Location` на задачу.
Рекомендуется `Idempotency-Key`.
operationId: postRevisionRollback
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
responses:
"202":
description: Откат поставлен в очередь.
headers:
Location:
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/AsyncJobAccepted"
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/revisions/{revision_a}/diff/{revision_b}:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/RevisionA"
- $ref: "#/components/parameters/RevisionB"
get:
tags: [Revisions]
summary: Сравнить две ревизии
description: Формат diff (JSON Patch, табличный и т.д.) определяется реализацией.
operationId: getRevisionDiff
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/RevisionDiff"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/apply:
post:
tags: [Deploy]
summary: Применить конфигурацию
description: |
Применить целевую ревизию на спикерах (политика по умолчанию или из тела).
Ответ **202** с `Location` на `/v1/jobs/{job_id}`. **Рекомендуется или обязателен** `Idempotency-Key` по политике продукта.
operationId: postApply
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: false
content:
application/json:
schema:
$ref: "#/components/schemas/ApplyRequest"
responses:
"202":
description: Запрос принят, задача поставлена в очередь.
headers:
Location:
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/AsyncJobAccepted"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/speakers/{id}/apply:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/PeerId"
post:
tags: [Deploy]
summary: Применить на одном спикере
description: Canary / точечный deploy. **202** + `Location` на job.
operationId: postSpeakerApply
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: false
content:
application/json:
schema:
$ref: "#/components/schemas/ApplyRequest"
responses:
"202":
description: Запрос принят, задача поставлена в очередь.
headers:
Location:
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/AsyncJobAccepted"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/bird/status:
get:
tags: [Deploy]
summary: Статус локального BIRD на хосте API
description: >
Опрос birdc через EVOBGP_BIRDC_SOCKET на процессе API (обычно CP master).
На репликах без birdc на CP — birdc_configured=false.
operationId: getBirdStatus
parameters:
- $ref: "#/components/parameters/TenantId"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/BirdLocalStatus"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/bird/reload:
post:
tags: [Deploy]
summary: Мягкий reload BIRD
description: Опциональный явный reload политики, если отделён от apply; иначе может отсутствовать или быть частью apply.
operationId: postBirdReload
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/IdempotencyKey"
responses:
"202":
description: Задача reload поставлена (если реализовано как async).
headers:
Location:
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/AsyncJobAccepted"
"204":
description: Reload выполнен синхронно (если так реализовано).
"501":
description: Эндпоинт не используется в данной сборке.
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/jobs:
get:
tags: [Jobs]
summary: Список задач
operationId: listJobs
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/Cursor"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/JobStatusFilter"
- $ref: "#/components/parameters/JobKindFilter"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
type: object
required: [items, has_more]
properties:
items:
type: array
items:
$ref: "#/components/schemas/Job"
next_cursor:
type: ["string", "null"]
has_more:
type: boolean
default:
$ref: "#/components/responses/DefaultProblem"
/v1/jobs/{job_id}:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/JobId"
get:
tags: [Jobs]
summary: Статус задачи
description: Прогресс, ошибка, связанные сущности в `meta`.
operationId: getJob
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/Job"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/jobs/{job_id}/cancel:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/JobId"
post:
tags: [Jobs]
summary: Запросить отмену задачи
description: Best-effort; гарантии зависят от вида задачи.
operationId: postJobCancel
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
responses:
"202":
description: Запрос отмены принят.
content:
application/json:
schema:
$ref: "#/components/schemas/Job"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/speakers/{speaker_id}/revisions/latest:
parameters:
- $ref: "#/components/parameters/SpeakerId"
get:
tags: [Node]
summary: Последняя опубликованная ревизия для ноды
description: Вызывается **evobgp-node** с ключом роли `node`.
operationId: getSpeakerLatestRevision
security:
- bearerAuth: []
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/LatestRevisionPointer"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/speakers/{speaker_id}/bundle/{revision_id}:
parameters:
- $ref: "#/components/parameters/SpeakerId"
- $ref: "#/components/parameters/RevisionId"
get:
tags: [Node]
summary: Скачать подписанный бандл
description: |
Архив с `manifest.json` и подписью (например Ed25519). Целостность по SHA-256 в манифесте.
`Content-Type` - `application/octet-stream` или multipart; детали - в реализации.
operationId: getSpeakerBundle
security:
- bearerAuth: []
responses:
"200":
description: Бинарное тело бандла.
headers:
Content-Disposition:
schema:
type: string
content:
application/octet-stream:
schema:
type: string
format: binary
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/nodes/enroll:
post:
tags: [Node]
summary: Регистрация ноды
description: Обмен ключами и привязка к `speaker_id`; детали протокола уточняются отдельно.
operationId: postNodeEnroll
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/NodeEnrollRequest"
responses:
"200":
description: Enrollment записан (node_public_key и время в meta спикера при наличии ключа).
content:
application/json:
schema:
$ref: "#/components/schemas/NodeEnrollResponse"
"422":
$ref: "#/components/responses/UnprocessableEntity"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/auth/session:
get:
tags: [Auth]
summary: Текущая сессия API-ключа
operationId: getAuthSession
parameters:
- $ref: "#/components/parameters/TenantId"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/AuthSession"
"401":
$ref: "#/components/responses/Unauthorized"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/api-keys:
get:
tags: [API keys]
summary: Список API-ключей tenant
description: Только роль **operator**. Секреты не возвращаются.
operationId: listApiKeys
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/Cursor"
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
type: object
required: [items, has_more]
properties:
items:
type: array
items:
$ref: "#/components/schemas/ApiKey"
next_cursor:
type: ["string", "null"]
has_more:
type: boolean
"403":
$ref: "#/components/responses/Forbidden"
default:
$ref: "#/components/responses/DefaultProblem"
post:
tags: [API keys]
summary: Создать API-ключ
operationId: createApiKey
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ApiKeyCreate"
responses:
"201":
description: Ключ создан; token в ответе один раз.
content:
application/json:
schema:
$ref: "#/components/schemas/ApiKeyCreated"
"403":
$ref: "#/components/responses/Forbidden"
"422":
$ref: "#/components/responses/UnprocessableEntity"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/api-keys/{id}:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/ApiKeyId"
get:
tags: [API keys]
summary: Получить метаданные API-ключа
operationId: getApiKey
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/ApiKey"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
patch:
tags: [API keys]
summary: Обновить API-ключ
operationId: patchApiKey
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ApiKeyPatch"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/ApiKey"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
delete:
tags: [API keys]
summary: Отозвать API-ключ
operationId: revokeApiKey
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
responses:
"204":
description: Отозван.
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/api-keys/{id}/rotate:
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/ApiKeyId"
post:
tags: [API keys]
summary: Ротировать секрет API-ключа
description: Выдаёт новый token; старый перестаёт работать сразу.
operationId: rotateApiKey
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/ApiKeyCreated"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/monitoring/postgres/overview:
get:
tags: [Monitoring]
summary: PostgreSQL overview (instance-level)
operationId: getPostgresOverview
parameters:
- $ref: "#/components/parameters/TenantId"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/PostgresOverview"
"503":
description: PostgreSQL backend не подключён.
default:
$ref: "#/components/responses/DefaultProblem"
/v1/monitoring/postgres/queries:
get:
tags: [Monitoring]
summary: Top queries (pg_stat_statements or snapshot)
operationId: getPostgresQueries
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/PostgresQueriesResponse"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/monitoring/postgres/locks:
get:
tags: [Monitoring]
summary: Active locks
operationId: getPostgresLocks
parameters:
- $ref: "#/components/parameters/TenantId"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
type: object
additionalProperties: true
default:
$ref: "#/components/responses/DefaultProblem"
/v1/monitoring/postgres/tables:
get:
tags: [Monitoring]
summary: Table sizes and scan stats
operationId: getPostgresTables
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
type: object
additionalProperties: true
default:
$ref: "#/components/responses/DefaultProblem"
/v1/monitoring/postgres/recommendations:
get:
tags: [Monitoring]
summary: Heuristic optimization recommendations
operationId: getPostgresRecommendations
parameters:
- $ref: "#/components/parameters/TenantId"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/PostgresRecommendations"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/monitoring/correlation:
get:
tags: [Monitoring]
summary: Timeline correlation (jobs vs cache hit)
operationId: getMonitoringCorrelation
parameters:
- $ref: "#/components/parameters/TenantId"
- name: window
in: query
schema:
type: integer
default: 60
description: Window in minutes (max 1440).
responses:
"200":
description: Успешно.
content:
application/json:
schema:
type: object
additionalProperties: true
default:
$ref: "#/components/responses/DefaultProblem"
/v1/postgres/vacuum:
post:
tags: [Monitoring]
summary: VACUUM (async job, operator)
operationId: postPostgresVacuum
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/PostgresMaintenanceBody"
responses:
"202":
description: Задача поставлена.
content:
application/json:
schema:
$ref: "#/components/schemas/AsyncJobAccepted"
"403":
$ref: "#/components/responses/Forbidden"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/postgres/vacuum-analyze:
post:
tags: [Monitoring]
summary: VACUUM ANALYZE (async job, operator)
operationId: postPostgresVacuumAnalyze
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/PostgresMaintenanceBody"
responses:
"202":
description: Задача поставлена.
content:
application/json:
schema:
$ref: "#/components/schemas/AsyncJobAccepted"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/postgres/analyze:
post:
tags: [Monitoring]
summary: ANALYZE (async job, operator)
operationId: postPostgresAnalyze
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/PostgresMaintenanceBody"
responses:
"202":
description: Задача поставлена.
content:
application/json:
schema:
$ref: "#/components/schemas/AsyncJobAccepted"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/postgres/reindex:
post:
tags: [Monitoring]
summary: REINDEX TABLE (async job, operator)
operationId: postPostgresReindex
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/PostgresMaintenanceBody"
responses:
"202":
description: Задача поставлена.
content:
application/json:
schema:
$ref: "#/components/schemas/AsyncJobAccepted"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/postgres/cleanup:
post:
tags: [Monitoring]
summary: Retention cleanup (async job, operator)
operationId: postPostgresCleanup
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/PostgresMaintenanceBody"
responses:
"202":
description: Задача поставлена.
content:
application/json:
schema:
$ref: "#/components/schemas/AsyncJobAccepted"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/postgres/maintenance/logs:
get:
tags: [Monitoring]
summary: Maintenance audit log
operationId: listPostgresMaintenanceLogs
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/Cursor"
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
type: object
additionalProperties: true
next_cursor:
type: string
has_more:
type: boolean
default:
$ref: "#/components/responses/DefaultProblem"
/v1/maintenance/policies:
get:
tags: [Maintenance]
summary: List maintenance policies
operationId: listMaintenancePolicies
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/Cursor"
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/MaintenancePolicyList"
default:
$ref: "#/components/responses/DefaultProblem"
post:
tags: [Maintenance]
summary: Create maintenance policy
operationId: createMaintenancePolicy
parameters:
- $ref: "#/components/parameters/TenantId"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/MaintenancePolicy"
responses:
"201":
description: Создано.
content:
application/json:
schema:
$ref: "#/components/schemas/MaintenancePolicy"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/maintenance/policies/{id}:
get:
tags: [Maintenance]
summary: Get maintenance policy
operationId: getMaintenancePolicy
parameters:
- $ref: "#/components/parameters/TenantId"
- name: id
in: path
required: true
schema:
$ref: "#/components/schemas/ResourceId"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/MaintenancePolicy"
default:
$ref: "#/components/responses/DefaultProblem"
patch:
tags: [Maintenance]
summary: Update maintenance policy
operationId: patchMaintenancePolicy
parameters:
- $ref: "#/components/parameters/TenantId"
- name: id
in: path
required: true
schema:
$ref: "#/components/schemas/ResourceId"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/MaintenancePolicyPatch"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/MaintenancePolicy"
default:
$ref: "#/components/responses/DefaultProblem"
delete:
tags: [Maintenance]
summary: Delete maintenance policy
operationId: deleteMaintenancePolicy
parameters:
- $ref: "#/components/parameters/TenantId"
- name: id
in: path
required: true
schema:
$ref: "#/components/schemas/ResourceId"
responses:
"204":
description: Удалено.
default:
$ref: "#/components/responses/DefaultProblem"
/v1/maintenance/policies/{id}/hints:
get:
tags: [Maintenance]
summary: PostgreSQL hints for policy table
operationId: getMaintenancePolicyHints
parameters:
- $ref: "#/components/parameters/TenantId"
- name: id
in: path
required: true
schema:
$ref: "#/components/schemas/ResourceId"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
type: object
additionalProperties: true
default:
$ref: "#/components/responses/DefaultProblem"
/v1/maintenance/config-audit:
get:
tags: [Maintenance]
summary: Maintenance policy configuration audit log
operationId: listMaintenanceConfigAudit
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/Cursor"
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
type: object
additionalProperties: true
next_cursor:
type: string
has_more:
type: boolean
default:
$ref: "#/components/responses/DefaultProblem"
/v1/maintenance/run:
post:
tags: [Maintenance]
summary: Run maintenance policy (async job)
operationId: postMaintenanceRun
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/MaintenanceRunBody"
responses:
"202":
description: Задача поставлена.
content:
application/json:
schema:
$ref: "#/components/schemas/AsyncJobAccepted"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/maintenance/dry-run:
post:
tags: [Maintenance]
summary: Dry-run maintenance policy (async job)
operationId: postMaintenanceDryRun
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/MaintenanceRunBody"
responses:
"202":
description: Задача поставлена.
content:
application/json:
schema:
$ref: "#/components/schemas/AsyncJobAccepted"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/runtime-logs/files:
get:
tags: [RuntimeLogs]
summary: Список runtime log-файлов
description: |
Список *.log в EVOBGP_RUNTIME_LOGS_DIR (размер и mtime).
Требуется evobgp-all с примонтированным volume.
operationId: listRuntimeLogFiles
parameters:
- $ref: "#/components/parameters/TenantId"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/RuntimeLogFileList"
"503":
description: Runtime logs недоступны (не evobgp-all или каталог не настроен).
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/runtime-logs/files/{filename}:
get:
tags: [RuntimeLogs]
summary: Хвост runtime log-файла
operationId: getRuntimeLogTail
parameters:
- $ref: "#/components/parameters/TenantId"
- name: filename
in: path
required: true
schema:
type: string
pattern: '^[a-z0-9][a-z0-9_.-]*\.log$'
description: Basename файла (без пути).
- name: lines
in: query
schema:
type: integer
minimum: 1
maximum: 2000
default: 200
- name: bytes
in: query
schema:
type: integer
minimum: 1
maximum: 262144
description: Альтернатива lines; при указании обоих — более строгий лимит.
- name: grep
in: query
schema:
type: string
maxLength: 128
description: Опциональный подстрочный фильтр (после чтения хвоста).
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/RuntimeLogTail"
"404":
$ref: "#/components/responses/NotFound"
"503":
description: Runtime logs недоступны.
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
default:
$ref: "#/components/responses/DefaultProblem"
delete:
tags: [RuntimeLogs]
summary: Очистить runtime log-файл
description: |
Синхронная очистка (truncate по умолчанию или delete). Запись в cleanup audit.
Максимальный размер файла для очистки — 512 MiB. Только operator+.
operationId: deleteRuntimeLogFile
parameters:
- $ref: "#/components/parameters/TenantId"
- name: filename
in: path
required: true
schema:
type: string
pattern: '^[a-z0-9][a-z0-9_.-]*\.log$'
- name: mode
in: query
schema:
$ref: "#/components/schemas/RuntimeLogCleanupMode"
description: По умолчанию truncate.
responses:
"200":
description: Файл очищен.
content:
application/json:
schema:
$ref: "#/components/schemas/RuntimeLogCleanupResult"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
"413":
description: Файл превышает лимит 512 MiB.
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
"503":
description: Runtime logs недоступны.
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/runtime-logs/cleanup-audit:
get:
tags: [RuntimeLogs]
summary: Audit очистки runtime log-файлов
operationId: listRuntimeLogCleanupAudit
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/Cursor"
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/RuntimeLogCleanupAuditList"
default:
$ref: "#/components/responses/DefaultProblem"
/v1/settings:
get:
tags: [Settings]
summary: Получить настройки
description: KV (лимиты CDN, feature flags и т.д.).
operationId: getSettings
parameters:
- $ref: "#/components/parameters/TenantId"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/Settings"
default:
$ref: "#/components/responses/DefaultProblem"
patch:
tags: [Settings]
summary: Частично обновить настройки
description: Только роль **operator**.
operationId: patchSettings
parameters:
- $ref: "#/components/parameters/TenantId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/Settings"
responses:
"200":
description: Успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/Settings"
"403":
$ref: "#/components/responses/Forbidden"
default:
$ref: "#/components/responses/DefaultProblem"