admin control features and admin dashboard

This commit is contained in:
ayurishchev committed 2026-08-23 20:39:22 +03:00
1 parent c630f13c57
commit 37910e410b
69 files changed
+4959 -400

No files matched your search

+178 -45
View File
@@ -17,7 +17,9 @@
- [Просмотр деталей и истории по конкретному адресу](#просмотр-деталей-и-истории-по-конкретному-адресу)
- [Управление валидаторами](#управление-валидаторами)
- [Управление площадками (проберами)](#управление-площадками-проберами)
- [Управление целями проверки](#управление-целями-проверки)
- [Повторная проверка адреса](#повторная-проверка-адреса)
- [Принудительная остановка проверки](#принудительная-остановка-проверки)
- [Частые проблемы и что с ними делать](#частые-проблемы-и-что-с-ними-делать)
## Как устроена работа с системой
@@ -43,29 +45,32 @@
## Добавление новых IP в очередь
**В текущей версии добавление адресов происходит только через конфиг
control-api**, отдельного API-метода "добавить IP в очередь" нет.
Основной способ — API, без перезапуска процесса:
1. Добавьте новые адреса в список `ip_addresses` в
`/etc/cloud-ip-validator/control-api.yaml` (в конец списка, либо в
нужном порядке — очередь обрабатывается строго в порядке следования
списка, `sequence`).
2. Перезапустите control-api:
```bash
systemctl restart control-api
```
```bash
curl -s -X POST http://<control-api>:8080/api/v1/admin/ips \
-d '{"addresses": ["203.0.113.10", "203.0.113.11"]}'
```
Это безопасно для уже идущей работы: при старте control-api добавляет в
очередь только **новые** адреса (те, которых там ещё нет) — уже
обработанные ранее адреса не сбрасываются и повторно не проверяются.
Адреса, которые были удалены из `ip_addresses`, но уже есть в базе,
**не удаляются** из очереди/истории автоматически — если конкретный адрес
больше не нужно проверять и его нет в очереди/в процессе, можно просто
оставить как есть (историю он не портит).
```json
{"added": ["203.0.113.10", "203.0.113.11"], "requeued": [], "reordered": [], "skipped_in_progress": []}
```
> Совет: держите `control-api.yaml` под версионным контролем (git) —
> список адресов на проверку тогда одновременно служит и журналом того,
> что вообще когда-либо ставилось в очередь.
Адреса обрабатываются в порядке, в котором перечислены в `addresses` —
именно в этом порядке они и встанут в очередь друг за другом. Метод
идемпотентен относительно уже идущих проверок: адрес, который сейчас
активно проверяется, в ответе окажется в `skipped_in_progress` и не будет
тронут (см. [«Повторная проверка адреса»](#повторная-проверка-адреса)
ниже — тот же метод форсирует перепроверку уже завершённых адресов).
Также по-прежнему можно добавить адреса через `ip_addresses` в
`/etc/cloud-ip-validator/control-api.yaml` и перезапустить control-api —
при каждом старте control-api доливает в очередь только новые адреса из
этого списка (уже обработанные ранее не сбрасываются и повторно не
проверяются). Держать `control-api.yaml` под версионным контролем (git)
по-прежнему полезно как журнал того, что изначально ставилось в очередь
при разворачивании стенда — но для повседневного добавления адресов проще
и быстрее пользоваться API выше.
## Наблюдение за очередью
@@ -108,7 +113,7 @@ curl -s http://<control-api>:8080/api/v1/admin/ips \
| Поле | Значение |
|---|---|
| `IPAddress` | Проверяемый адрес |
| `Sequence` | Позиция в очереди (порядок из конфига) |
| `Sequence` | Позиция в очереди (порядок постановки — из конфига при первом старте либо из последнего вызова `POST /api/v1/admin/ips`) |
| `State` | Текущий этап: `queued`, `assigning_fip`, `awaiting_self_check`, `checking`, `aggregating`, `done`, `failed` |
| `OwnerValidatorID` | Какой валидатор сейчас (или последним) занимался этим адресом |
| `FIPID` | Идентификатор Floating IP в OpenStack, к которому привязан адрес (пусто, если ещё/уже не привязан) |
@@ -116,7 +121,7 @@ curl -s http://<control-api>:8080/api/v1/admin/ips \
| `RetryCount` | Сколько раз адрес уже переставлялся в очередь заново |
| `EgressComplete` | Валидатор закончил исходящие проверки |
| `Site1Complete` / `Site2Complete` / `Site3Complete` | Соответствующая площадка закончила входящие проверки |
| `OverallResult` | Итог: `pass`, `partial`, `fail`, либо пусто, пока проверка не завершена |
| `OverallResult` | Итог: `pass`, `partial`, `fail`, `cancelled` (принудительно остановлена, см. [«Принудительная остановка проверки»](#принудительная-остановка-проверки)), либо пусто, пока проверка не завершена |
| `AssignedAt` / `AggregatedAt` / `FIPReleasedAt` | Метки времени соответствующих этапов |
## Как читать итоговый результат (pass/partial/fail)
@@ -137,6 +142,10 @@ curl -s http://<control-api>:8080/api/v1/admin/ips \
трафик валидатора не пошёл через назначенный FIP — и попытки
исчерпались). Смотрите `events` по этому адресу (см. ниже), чтобы
понять, на каком шаге и почему.
- **`cancelled`** — проверку остановил оператор через `POST
/api/v1/admin/ips/{ip}/cancel` (`State` при этом — `failed`), а не
система по итогам проверок. Отличать от обычного `fail` полезно, чтобы
не путать «адрес не прошёл проверку» с «проверку прервали вручную».
Отсутствие ответа от источника (площадка не прислала результат до
истечения `checking_window_seconds`) засчитывается как провал — это
@@ -180,21 +189,48 @@ curl -s http://<control-api>:8080/api/v1/admin/validators | python3 -m json.tool
(занят), `unreachable` (пропустил heartbeat дольше
`orchestrator.heartbeat_timeout_seconds`).
**Добавление нового валидатора:**
**Добавление нового валидатора (без перезапуска control-api):**
1. Поднимите новую ВМ в сервисном проекте облака, узнайте её Neutron
`port_id`.
2. Добавьте запись в `validators` в `control-api.yaml`
(`validator_id` + `os_port_id`) и перезапустите `control-api`.
2. Зарегистрируйте валидатора через API:
```bash
curl -s -X POST http://<control-api>:8080/api/v1/admin/config/validators \
-d '{"validator_id": "validator_05", "os_port_id": "port-abc123"}'
```
3. Разверните и запустите `validator-agent` на новой ВМ с тем же
`validator_id` в его конфиге (см. [SETUP.md](SETUP.md#развёртывание-validator-agent-на-вм-валидаторах)).
Сменить `os_port_id` уже существующего валидатора (например, после
пересоздания ВМ) — `PUT /api/v1/admin/config/validators/{id}` с телом
`{"os_port_id": "новый-port-id"}`.
Полный список зарегистрированных валидаторов — `GET
/api/v1/admin/config/validators` (в отличие от `GET
/api/v1/admin/validators`, отдаёт `snake_case` и без текущего IP —
только конфигурационные поля).
**Вывод валидатора из эксплуатации:** остановите на нём
`validator-agent` (`systemctl stop validator-agent`). Он перестанет
получать новые задания после того, как закончит текущее (если оно было);
если он был убит посреди работы — control-api сам заберёт у него
незавершённый адрес обратно в очередь по истечении
`orchestrator.lease_ttl_seconds`. Удалять запись из `control-api.yaml`
не обязательно — просто выключенный агент не будет ничего забирать.
`orchestrator.lease_ttl_seconds`. Удалять регистрацию валидатора не
обязательно — просто выключенный агент не будет ничего забирать. Если всё
же нужно убрать валидатора из системы совсем:
```bash
curl -s -X DELETE http://<control-api>:8080/api/v1/admin/config/validators/validator_05
```
Возвращает `409`, если валидатор прямо сейчас владеет каким-то IP —
дождитесь освобождения (или принудительно остановите его проверку, см.
[«Принудительная остановка проверки»](#принудительная-остановка-проверки))
перед удалением.
> Правки через `validators[]` в `control-api.yaml` тоже поддерживаются,
> но только как bootstrap пустой базы данных при самом первом старте — как
> только в БД есть хотя бы один валидатор, YAML для этой секции
> игнорируется при всех последующих рестартах (см.
> [SETUP.md](SETUP.md#развёртывание-control-api)). Для стенда, который уже
> хоть раз запускался, используйте API выше.
## Управление площадками (проберами)
@@ -207,12 +243,28 @@ curl -s http://<control-api>:8080/api/v1/admin/validators | python3 -m json.tool
Явного отдельного флага "включить/выключить" нет — самого списка `sites`
достаточно.
Чтобы добавить площадку: добавьте `site_id` + `index` (1, 2 или 3 — см.
ограничение ниже) в `sites` конфига control-api и разверните на площадке
`prober` с тем же `site_id`. Чтобы отключить конкретную площадку —
уберите соответствующую запись из `sites` и перезапустите control-api;
Чтобы добавить площадку (без перезапуска control-api) — назначьте
`site_id` на один из трёх слотов (`index` 1, 2 или 3 — см. ограничение
ниже) через API:
```bash
curl -s -X PUT http://<control-api>:8080/api/v1/admin/config/sites/1 \
-d '{"site_id": "site-1"}'
```
и разверните на площадке `prober` с тем же `site_id`. Чтобы отключить
конкретную площадку — освободите слот:
```bash
curl -s -X DELETE http://<control-api>:8080/api/v1/admin/config/sites/1
```
процесс `prober` на ней можно не останавливать (он просто перестанет
получать назначения).
получать назначения — `POST /api/v1/probers/register` для отвязанного
`site_id` начнёт отвечать `400`). Текущее распределение слотов — `GET
/api/v1/admin/config/sites`.
> Правки через `sites[]` в `control-api.yaml` тоже поддерживаются, но
> только как bootstrap пустой базы данных при самом первом старте — как
> только в БД есть хотя бы одна площадка, YAML для этой секции
> игнорируется при всех последующих рестартах. Для стенда, который уже
> хоть раз запускался, используйте API выше.
> Важно: количество *возможных* слотов площадок жёстко зашито в схему БД
> (`Site1Complete`/`Site2Complete`/`Site3Complete`) — не более **трёх**,
@@ -221,23 +273,104 @@ curl -s http://<control-api>:8080/api/v1/admin/validators | python3 -m json.tool
> поддерживаемый сценарий; *больше* трёх потребует доработки схемы
> данных, одной правкой конфига не обойтись.
## Управление целями проверки
Набор egress-целей (`targets`) и типов проверок (`check_types`,
привязывающих тип — `https`/`icmp`/`ssh` — к одной или нескольким группам
целей) управляется через API так же, как валидаторы и площадки —
изменения подхватываются немедленно, следующим же назначением от
оркестратора, без перезапуска.
Посмотреть текущий набор:
```bash
curl -s http://<control-api>:8080/api/v1/admin/config/targets | python3 -m json.tool
curl -s http://<control-api>:8080/api/v1/admin/config/check-types | python3 -m json.tool
```
Создать/заменить группу целей и включить тип проверки, ссылающийся на
неё:
```bash
curl -s -X PUT http://<control-api>:8080/api/v1/admin/config/targets/web \
-d '{"targets": ["https://hub.docker.com", "https://github.com"]}'
curl -s -X PUT http://<control-api>:8080/api/v1/admin/config/check-types/ssh \
-d '{"enabled": true, "targets": ["web"]}'
```
Отключить тип проверки, не удаляя его (значения целей сохраняются):
```bash
curl -s -X PUT http://<control-api>:8080/api/v1/admin/config/check-types/ssh \
-d '{"enabled": false, "targets": ["web"]}'
```
Удалить группу целей можно только если на неё не ссылается ни один
`check_type` (иначе — `409`); удалить сам `check_type` можно в любой
момент (`DELETE /api/v1/admin/config/check-types/{name}`).
**Важное следствие принятого компромисса**: если конфигурация меняется
ровно в момент, когда чей-то IP уже находится в `checking` (self-check
уже пройден, проверки уже назначены агенту), агрегация этой конкретной
попытки посчитает уже изменённую конфигурацию, а не ту, что была на
момент выдачи задания. На практике это узкое окно в несколько секунд;
деградирует безопасно — через `aggregation.missing_counts_as_fail` худший
исход для одной попытки — `partial` вместо `pass`, самоисправляется на
следующей попытке (в том числе через принудительный повтор, см. ниже).
> Правки через `targets`/`check_types` в `control-api.yaml` тоже
> поддерживаются, но только как bootstrap пустой базы данных при самом
> первом старте — см. примечание в разделах выше.
## Повторная проверка адреса
Если адрес завершился с `failed` или `partial`, а вы хотите перепроверить
его ещё раз (например, после устранения блокировки на стороне сети):
на данный момент нет отдельного API-метода "перезапустить проверку".
Самый простой путь:
1. Убедитесь, что адрес не находится в активном состоянии (`checking`
и т.п.) — то есть уже `done`/`failed`.
2. Временно уберите и снова добавьте адрес в список `ip_addresses`
(либо просто пересоздайте запись в БД вручную, если это единичный
случай и у вас есть доступ к SQLite) и перезапустите `control-api`.
его ещё раз (например, после устранения блокировки на стороне сети) —
отправьте его тем же методом, что используется для постановки новых
адресов в очередь:
Поскольку сидирование очереди идёт по уникальности `ip_address`
(конфликт по уже существующей записи просто игнорируется), самый чистый
способ гарантированно перепроверить конкретный адрес — обратиться к
администратору БД (см. следующий раздел) либо дождаться штатной
доработки API под повторные проверки.
```bash
curl -s -X POST http://<control-api>:8080/api/v1/admin/ips \
-d '{"addresses": ["203.0.113.10"]}'
```
```json
{"added": [], "requeued": ["203.0.113.10"], "reordered": [], "skipped_in_progress": []}
```
Адрес в `requeued` означает, что он был в терминальном состоянии
(`done`/`failed`) и его перезапустили: `AttemptNumber` увеличился,
`RetryCount` обнулён, предыдущий `OverallResult` сброшен, адрес снова
`queued` и будет обработан на общих основаниях. Никакой особой обработки
для уже проверенных адресов не требуется — тот же вызов безопасно
принимает список из новых и уже проверенных адресов одновременно;
единственное, что метод не сделает — не запустит вторую параллельную
проверку адреса, который прямо сейчас уже проверяется (такой адрес
вернётся в `skipped_in_progress`, см.
[«Добавление новых IP в очередь»](#добавление-новых-ip-в-очередь)).
## Принудительная остановка проверки
Если проверка адреса зависла дольше ожидаемого либо просто больше не
актуальна, не дожидайтесь истечения `checking_window_seconds` —
остановите её сразу:
```bash
curl -s -X POST http://<control-api>:8080/api/v1/admin/ips/203.0.113.10/cancel
```
Работает из любого состояния, кроме уже терминального (`done`/`failed`
вернут `409` — отменять нечего). Если на момент отмены был привязан
Floating IP — он отвязывается (best-effort, как и при обычном завершении
проверки), владевший валидатор освобождается и снова становится `idle`.
Итог записывается как `OverallResult: "cancelled"` (в `State: "failed"`),
и виден в истории адреса наравне с обычными результатами:
```bash
curl -s http://<control-api>:8080/api/v1/admin/ips/203.0.113.10 | python3 -m json.tool
```
Чтобы позже всё же проверить этот адрес — используйте
[«Повторную проверку адреса»](#повторная-проверка-адреса) выше, она
одинаково работает и для отменённых, и для обычно завершённых адресов.
## Частые проблемы и что с ними делать