admin control features and admin dashboard
This commit is contained in:
1 parent
c630f13c57
commit
37910e410b
69 files changed
+4959
-400
No files matched your search
+172
-7
@@ -6,7 +6,10 @@ JSON, базовый префикс прикладных методов — `/ap
|
||||
|
||||
> **Важно.** На данный момент API не защищён аутентификацией/авторизацией
|
||||
> — эндпоинты доступны любому, кто может достучаться до порта control-api
|
||||
> по сети. Для эксплуатации за пределами доверенного сегмента сети
|
||||
> по сети. Это касается и методов из раздела
|
||||
> [«Управление очередью и конфигурацией»](#управление-очередью-и-конфигурацией)
|
||||
> ниже — они меняют, что и как проверяется, без подтверждения личности
|
||||
> вызывающего. Для эксплуатации за пределами доверенного сегмента сети
|
||||
> обязательно ограничьте доступ на уровне сети/файрвола (см.
|
||||
> [SETUP.md](SETUP.md#сетевые-доступы)). Добавление bearer-токена — известное
|
||||
> направление доработки, в текущей версии не реализовано.
|
||||
@@ -14,12 +17,17 @@ JSON, базовый префикс прикладных методов — `/ap
|
||||
Базовый URL в примерах — `http://control-api.internal:8080`, замените на
|
||||
адрес вашего стенда (см. `server.listen_addr` в конфиге control-api).
|
||||
|
||||
> Для работы из браузера вместо `curl` есть `admin-dashboard` — веб-панель,
|
||||
> дающая графический доступ ко всему административному API ниже, см.
|
||||
> [DASHBOARD.md](DASHBOARD.md).
|
||||
|
||||
## Содержание
|
||||
|
||||
- [Общие соглашения](#общие-соглашения)
|
||||
- [Методы для validator-agent](#методы-для-validator-agent)
|
||||
- [Методы для prober](#методы-для-prober)
|
||||
- [Служебные и административные методы](#служебные-и-административные-методы)
|
||||
- [Управление очередью и конфигурацией](#управление-очередью-и-конфигурацией)
|
||||
- [Модель состояний и связь методов с ней](#модель-состояний-и-связь-методов-с-ней)
|
||||
- [Сквозной пример работы (curl)](#сквозной-пример-работы-curl)
|
||||
|
||||
@@ -37,9 +45,11 @@ JSON, базовый префикс прикладных методов — `/ap
|
||||
не удалось распарсить, сервер молча подставит текущее время сервера — не
|
||||
полагайтесь на это в продакшене, всегда передавайте валидную метку.
|
||||
- `validator_id` и `site_id` в пути запроса должны совпадать со
|
||||
значениями, заданными в конфиге control-api (`validators[].validator_id`,
|
||||
`sites[].site_id`) — иначе методы, требующие существующую сущность,
|
||||
вернут `404`.
|
||||
значениями, известными control-api — заданными в `control-api.yaml`
|
||||
при первом запуске (пустая база) либо созданными позже через
|
||||
`/api/v1/admin/config/*` (см.
|
||||
[«Управление очередью и конфигурацией»](#управление-очередью-и-конфигурацией))
|
||||
— иначе методы, требующие существующую сущность, вернут `404`.
|
||||
|
||||
## Методы для validator-agent
|
||||
|
||||
@@ -297,6 +307,152 @@ IP на данном проходе". До этого момента control-api
|
||||
`assigned`, `checking`, `unreachable`) и `CurrentIPID`, если валидатор
|
||||
сейчас занят.
|
||||
|
||||
## Управление очередью и конфигурацией
|
||||
|
||||
Методы этого раздела — единственный способ менять состав очереди
|
||||
(`ip_addresses`), список валидаторов, площадок (`sites`) и целей
|
||||
проверки (`targets`/`check_types`) **без остановки процесса**: изменения
|
||||
применяются немедленно и переживают последующий рестарт control-api. Все
|
||||
тела запросов/ответов — `snake_case` (в отличие от `GET
|
||||
/admin/status|ips|validators` выше, которые отдают сырые поля Go-структур
|
||||
в PascalCase — эти два стиля сосуществуют осознанно, см. примечание к
|
||||
`GET /api/v1/admin/ips/{ip}`).
|
||||
|
||||
**Источник истины.** `control-api.yaml` используется только как
|
||||
одноразовый bootstrap для пустой базы данных: секции `validators`,
|
||||
`sites`, `targets`, `check_types` читаются из YAML один раз, при самом
|
||||
первом старте на пустых таблицах. Как только в соответствующей таблице
|
||||
появилась хотя бы одна строка (через bootstrap либо через методы ниже) —
|
||||
YAML для этой секции больше не перечитывается ни при одном последующем
|
||||
рестарте; правки нужно вносить через API. Список IP-адресов
|
||||
(`ip_addresses` в YAML) — исключение, он остаётся отдельным, всегда
|
||||
аддитивным путём постановки в очередь при каждом старте (см.
|
||||
[SETUP.md](SETUP.md#развёртывание-control-api)); он не конфликтует с
|
||||
`POST /api/v1/admin/ips` ниже.
|
||||
|
||||
### `POST /api/v1/admin/ips`
|
||||
|
||||
Единая точка для двух задач: добавить новые адреса в очередь **и**
|
||||
принудительно перепроверить уже завершённые — один и тот же вызов, разница
|
||||
только в текущем состоянии каждого конкретного адреса. Список
|
||||
обрабатывается в one transaction, в порядке следования адресов:
|
||||
|
||||
- адрес неизвестен control-api → добавляется в очередь как новый
|
||||
(`queued`);
|
||||
- адрес сейчас `done`/`failed` → принудительно перезапускается: сбрасывается
|
||||
результат, `attempt_number` увеличивается, `retry_count` обнуляется,
|
||||
адрес снова становится `queued`;
|
||||
- адрес сейчас `queued` (ещё не взят в работу) → только переупорядочивается
|
||||
под порядок текущего списка, повторно не добавляется;
|
||||
- адрес сейчас активно проверяется (`assigning_fip` / `awaiting_self_check`
|
||||
/ `checking` / `aggregating`) → не трогается вообще — нельзя запустить
|
||||
вторую параллельную проверку одного и того же адреса.
|
||||
|
||||
Порядок обработки внутри одного вызова соответствует порядку адресов в
|
||||
списке; повторная отправка того же списка позже даёт тот же относительный
|
||||
порядок прогона.
|
||||
|
||||
Запрос:
|
||||
```json
|
||||
{"addresses": ["203.0.113.10", "203.0.113.11"]}
|
||||
```
|
||||
|
||||
Ответ (`200`):
|
||||
```json
|
||||
{
|
||||
"added": ["203.0.113.11"],
|
||||
"requeued": ["203.0.113.10"],
|
||||
"reordered": [],
|
||||
"skipped_in_progress": []
|
||||
}
|
||||
```
|
||||
|
||||
`400`, если `addresses` пуст.
|
||||
|
||||
### `POST /api/v1/admin/ips/{ip}/cancel`
|
||||
|
||||
Принудительно останавливает проверку конкретного адреса, не дожидаясь
|
||||
`checking_window_seconds` — работает из любого нетерминального состояния,
|
||||
включая `queued` (в этом случае это просто удаление ещё не начатой
|
||||
проверки из очереди). Если Floating IP уже привязан — отвязывается
|
||||
(best-effort, как и при обычном завершении проверки); владеющий валидатор
|
||||
освобождается. Итог записывается как `overall_result: "cancelled"`
|
||||
(состояние `failed`).
|
||||
|
||||
Ответ: `{"ok": true}`. `404`, если адрес неизвестен. `409`, если адрес уже
|
||||
в терминальном состоянии (`done`/`failed`/уже отменён) — отменять нечего.
|
||||
|
||||
### Валидаторы: `/api/v1/admin/config/validators`
|
||||
|
||||
| Метод | Путь | Тело | Успех | Ошибки |
|
||||
|---|---|---|---|---|
|
||||
| GET | `/api/v1/admin/config/validators` | — | `[{"validator_id","os_port_id","state"}]` | |
|
||||
| POST | `/api/v1/admin/config/validators` | `{"validator_id","os_port_id"}` | `201` | `409`, если `validator_id` уже существует |
|
||||
| PUT | `/api/v1/admin/config/validators/{id}` | `{"os_port_id"}` | `200` | `404` |
|
||||
| DELETE | `/api/v1/admin/config/validators/{id}` | — | `200` | `404`; `409`, если валидатор сейчас владеет IP |
|
||||
|
||||
### Площадки: `/api/v1/admin/config/sites`
|
||||
|
||||
Слотов ровно три (`index` ∈ {1, 2, 3}) — это ограничение схемы БД
|
||||
(`ip_queue.site{1,2,3}_complete`), а не искусственное. Пустой список слотов
|
||||
— штатный сценарий, отключающий inbound-проверки целиком (см.
|
||||
[USAGE.md](USAGE.md#управление-площадками-проберами)).
|
||||
|
||||
| Метод | Путь | Тело | Успех | Ошибки |
|
||||
|---|---|---|---|---|
|
||||
| GET | `/api/v1/admin/config/sites` | — | `[{"index","site_id"}]` (до 3 строк) | |
|
||||
| PUT | `/api/v1/admin/config/sites/{index}` | `{"site_id"}` | `200` | `400`, если `index` не 1..3; `409`, если `site_id` уже занят другим слотом |
|
||||
| DELETE | `/api/v1/admin/config/sites/{index}` | — | `200` | `404` |
|
||||
|
||||
### Группы целей: `/api/v1/admin/config/targets`
|
||||
|
||||
Группа целей — именованный список URL/адресов (например `stub-targets: [
|
||||
"https://hub.docker.com", ...]`), на который затем ссылаются типы
|
||||
проверок.
|
||||
|
||||
| Метод | Путь | Тело | Успех | Ошибки |
|
||||
|---|---|---|---|---|
|
||||
| GET | `/api/v1/admin/config/targets` | — | `[{"name","targets"}]` | |
|
||||
| PUT | `/api/v1/admin/config/targets/{group}` | `{"targets":[...]}` | `200` | `400`, если список пуст |
|
||||
| DELETE | `/api/v1/admin/config/targets/{group}` | — | `200` | `404`; `409`, если группа используется каким-то `check_type` |
|
||||
|
||||
### Типы проверок: `/api/v1/admin/config/check-types`
|
||||
|
||||
Тип проверки (`https`, `icmp`, `ssh`, ...) ссылается на одну или несколько
|
||||
групп целей по имени; именно развёрнутый список отсюда validator-agent
|
||||
получает в `check_config` при `GET /api/v1/agents/{id}/assignment`.
|
||||
|
||||
| Метод | Путь | Тело | Успех | Ошибки |
|
||||
|---|---|---|---|---|
|
||||
| GET | `/api/v1/admin/config/check-types` | — | `[{"name","enabled","targets"}]` (`targets` — имена групп) | |
|
||||
| PUT | `/api/v1/admin/config/check-types/{name}` | `{"enabled","targets":["group",...]}` | `200` | `400`, если названа несуществующая группа |
|
||||
| DELETE | `/api/v1/admin/config/check-types/{name}` | — | `200` | `404` |
|
||||
|
||||
### Пример: конфигурация целиком через API, без единой строки в YAML
|
||||
|
||||
```bash
|
||||
BASE=http://127.0.0.1:8080
|
||||
|
||||
curl -s -X POST "$BASE/api/v1/admin/config/validators" \
|
||||
-d '{"validator_id":"validator_01","os_port_id":"port-abc123"}'
|
||||
|
||||
curl -s -X PUT "$BASE/api/v1/admin/config/targets/web" \
|
||||
-d '{"targets":["https://hub.docker.com","https://github.com"]}'
|
||||
|
||||
curl -s -X PUT "$BASE/api/v1/admin/config/check-types/https" \
|
||||
-d '{"enabled":true,"targets":["web"]}'
|
||||
|
||||
curl -s -X PUT "$BASE/api/v1/admin/config/sites/1" -d '{"site_id":"site-1"}'
|
||||
|
||||
# Поставить адрес в очередь и, отдельным вызовом позже, принудительно
|
||||
# перепроверить его ещё раз — тот же метод, разница только в состоянии:
|
||||
curl -s -X POST "$BASE/api/v1/admin/ips" -d '{"addresses":["203.0.113.10"]}'
|
||||
curl -s -X POST "$BASE/api/v1/admin/ips" -d '{"addresses":["203.0.113.10"]}' # forced recheck
|
||||
|
||||
# Остановить проверку, не дожидаясь checking_window_seconds:
|
||||
curl -s -X POST "$BASE/api/v1/admin/ips/203.0.113.10/cancel"
|
||||
```
|
||||
|
||||
## Модель состояний и связь методов с ней
|
||||
|
||||
```
|
||||
@@ -327,9 +483,18 @@ queued ──(control-api сам, без вызова API)──▶ assigning_fi
|
||||
нет — это фоновый цикл (`Tick`), а не запрос/ответ.
|
||||
|
||||
Площадки (`siteN_complete`) — опциональны: сколько их учитывается,
|
||||
целиком определяется списком `sites` в конфиге control-api (0–3 записи).
|
||||
Пустой список — агрегация ждёт только `egress_complete`, ни одна площадка
|
||||
не требуется. Подробнее — [USAGE.md](USAGE.md#управление-площадками-проберами).
|
||||
целиком определяется текущим списком `sites` (0–3 записи, управляется
|
||||
через `/api/v1/admin/config/sites` — см.
|
||||
[выше](#управление-очередью-и-конфигурацией)). Пустой список — агрегация
|
||||
ждёт только `egress_complete`, ни одна площадка не требуется. Подробнее —
|
||||
[USAGE.md](USAGE.md#управление-площадками-проберами).
|
||||
|
||||
Два дополнительных перехода, оба инициируются оператором через
|
||||
`/api/v1/admin/ips`, а не самим оркестратором:
|
||||
- **любое нетерминальное состояние → `failed` (`overall_result:
|
||||
"cancelled"`)** — `POST /api/v1/admin/ips/{ip}/cancel`;
|
||||
- **`done`/`failed` → `queued` (новая попытка)** — `POST
|
||||
/api/v1/admin/ips` с уже завершённым адресом в списке.
|
||||
|
||||
## Сквозной пример работы (curl)
|
||||
|
||||
|
||||
Reference in new issue
Block a user