Add optional automatic check cycle (clear queue -> scan FIPs -> wait -> repeat)
An admin-controlled scenario that repeats what the operator does by hand: clear the IP queue, scan and enqueue all free Floating IPs, wait until every queued address reaches a terminal state (so results are in the Registry), then wait a configurable interval and start over. - control-api: new auto_cycle singleton table (migration 0008) holding enabled/interval/max-run settings and persisted phase state, so the cycle survives restarts; engine in orchestrator/autocycle.go driven from the existing loop tick with an injectable "now" for deterministic tests. - Interval (default 1h, min 60s) and max wait (default unlimited, timeout outcome) are runtime settings, never hardcoded. - The periodic fip_scan_interval_seconds scan is skipped while the cycle is enabled. An emptied queue mid-cycle counts as finished; stopping during the pause keeps the last cycle's outcome. - API: GET/PUT /api/v1/admin/auto-cycle, POST .../start, POST .../stop. - admin-dashboard: "Автоматический цикл" panel on /settings and an "Автоцикл активен" indicator on /overview. - Tests for db, orchestrator, httpapi and dashboard; run-local-e2e.sh now exercises a full auto cycle; docs updated; bin/ rebuilt with refreshed SHA256SUMS. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
008ae1b0db
commit
cd37b10f3b
35 files changed
+2205
-16
No files matched your search
+68
-1
@@ -28,6 +28,7 @@ JSON, базовый префикс прикладных методов — `/ap
|
||||
- [Методы для prober](#методы-для-prober)
|
||||
- [Служебные и административные методы](#служебные-и-административные-методы)
|
||||
- [Управление очередью и конфигурацией](#управление-очередью-и-конфигурацией)
|
||||
- [Автоматический цикл проверок](#автоматический-цикл-проверок)
|
||||
- [Реестр адресов и история проверок](#реестр-адресов-и-история-проверок)
|
||||
- [Модель состояний и связь методов с ней](#модель-состояний-и-связь-методов-с-ней)
|
||||
- [Сквозной пример работы (curl)](#сквозной-пример-работы-curl)
|
||||
@@ -469,7 +470,73 @@ YAML для этой секции больше не перечитывается
|
||||
Помимо ручного вызова, сканирование можно включить по расписанию —
|
||||
`orchestrator.fip_scan_interval_seconds` в `control-api.yaml` (0, по
|
||||
умолчанию, — только по запросу через эту ручку или кнопку «Сканировать
|
||||
Floating IP» в дашборде).
|
||||
Floating IP» в дашборде). Пока включён
|
||||
[автоматический цикл](#автоматический-цикл-проверок), периодический скан
|
||||
не выполняется.
|
||||
|
||||
## Автоматический цикл проверок
|
||||
|
||||
Опциональный повторяющийся сценарий «очистить очередь → просканировать
|
||||
Floating IP → дождаться завершения всех проверок → пауза → заново» (описание
|
||||
для оператора — [USAGE.md](USAGE.md#автоматический-цикл-проверок)). По умолчанию
|
||||
выключен. Состояние и параметры хранятся в базе; перезапуск control-api их
|
||||
не сбрасывает.
|
||||
|
||||
| Метод | Путь | Тело | Успех | Ошибки |
|
||||
|---|---|---|---|---|
|
||||
| `GET` | `/api/v1/admin/auto-cycle` | — | `200`, статус | — |
|
||||
| `PUT` | `/api/v1/admin/auto-cycle` | `{"interval_seconds": N, "max_run_seconds": M}` — любое поле можно опустить | `200`, статус | `400` — `interval_seconds < 60` или `max_run_seconds < 0` (ничего не применяется) |
|
||||
| `POST` | `/api/v1/admin/auto-cycle/start` | — | `200`, статус | — |
|
||||
| `POST` | `/api/v1/admin/auto-cycle/stop` | — | `200`, статус | — |
|
||||
|
||||
Каждый метод отвечает полным объектом статуса:
|
||||
|
||||
```json
|
||||
{
|
||||
"enabled": true,
|
||||
"interval_seconds": 3600,
|
||||
"max_run_seconds": 0,
|
||||
"phase": "waiting",
|
||||
"run_started_at": null,
|
||||
"next_run_at": "2026-10-01T08:00:12.345Z",
|
||||
"last_run_started_at": "2026-10-01T07:00:01.100Z",
|
||||
"last_run_finished_at": "2026-10-01T07:00:12.345Z",
|
||||
"last_outcome": "completed",
|
||||
"last_error": "",
|
||||
"last_scanned_free": 12,
|
||||
"runs_total": 5
|
||||
}
|
||||
```
|
||||
|
||||
- `phase` — `idle` (выключен или ещё не стартовал), `running` (идут
|
||||
проверки), `waiting` (пауза до `next_run_at`).
|
||||
- `last_outcome` — `completed`, `no_free_ips`, `timeout`, `error` или
|
||||
`stopped`; пустая строка, пока не завершился ни один цикл. Для `error`
|
||||
причина — в `last_error`.
|
||||
- `last_scanned_free` — сколько свободных Floating IP нашёл скан последнего
|
||||
цикла; `runs_total` — сколько циклов завершилось исходом `completed`.
|
||||
- `max_run_seconds = 0` — без ограничения времени ожидания проверок.
|
||||
- Времена — RFC 3339 (UTC), `null`, пока не наступили.
|
||||
|
||||
`POST .../start` идемпотентен: у уже включённого цикла ничего не меняется
|
||||
(идущий цикл не перезапускается). Включённый цикл начинает первый прогон на
|
||||
ближайшем шаге оркестратора (порядка `orchestrator.poll_interval_seconds`).
|
||||
`POST .../stop` выключает цикл и переводит его в `idle`; проверки, которые
|
||||
уже идут, не прерываются. Новое значение `interval_seconds` начинает действовать
|
||||
со следующей паузы.
|
||||
|
||||
События цикла (`auto_cycle_started`, `auto_cycle_completed`,
|
||||
`auto_cycle_timeout`, `auto_cycle_error`, `auto_cycle_stopped`) попадают в
|
||||
общий журнал событий; шаги цикла записывают обычные `queue_cleared` и
|
||||
`fip_scan`.
|
||||
|
||||
```bash
|
||||
curl -s -X PUT http://<control-api>:8080/api/v1/admin/auto-cycle \
|
||||
-d '{"interval_seconds": 7200, "max_run_seconds": 1800}'
|
||||
curl -s -X POST http://<control-api>:8080/api/v1/admin/auto-cycle/start
|
||||
curl -s http://<control-api>:8080/api/v1/admin/auto-cycle
|
||||
curl -s -X POST http://<control-api>:8080/api/v1/admin/auto-cycle/stop
|
||||
```
|
||||
|
||||
## Реестр адресов и история проверок
|
||||
|
||||
|
||||
Reference in new issue
Block a user