Docs: перенос api-operation-stages в DOCS/ из LEGACY + правка ссылок README
This commit is contained in:
@@ -1,85 +0,0 @@
|
|||||||
# Стадии выполнения операции (stages)
|
|
||||||
|
|
||||||
## Эндпоинт
|
|
||||||
|
|
||||||
```
|
|
||||||
GET /instanceOperations/{operationUid}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Поле `stages`
|
|
||||||
|
|
||||||
В ответе `instanceOperation.stages` — массив объектов-стадий. Каждая стадия:
|
|
||||||
|
|
||||||
| Поле | Тип | Описание |
|
|
||||||
|------|-----|---------|
|
|
||||||
| `instanceOperationStageUid` | UUID | UID стадии |
|
|
||||||
| `stage` | string | Название (напр. `"2. Основной процесс"`) |
|
|
||||||
| `isSuccessful` | bool/null | `true`/`false`/`null` (ещё не завершена) |
|
|
||||||
| `dtStart` | datetime | Начало |
|
|
||||||
| `dtFinish` | datetime/null | Окончание (`null` — ещё идёт) |
|
|
||||||
| `duration` | float | Секунды (пересчитывается пока идёт: `729.2`) |
|
|
||||||
| `stageMsg` | JSON-string/null | Детальные логи этапа |
|
|
||||||
|
|
||||||
## Пример
|
|
||||||
|
|
||||||
Запрос:
|
|
||||||
```bash
|
|
||||||
curl -s -H "Authorization: Bearer $TOKEN" -H "User-Agent: Mozilla/5.0" \
|
|
||||||
"https://lk-api-gateway-test.ngcloud.ru/api/v1/svc/instanceOperations/{opUid}"
|
|
||||||
```
|
|
||||||
|
|
||||||
Ответ (фрагмент):
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"instanceOperation": {
|
|
||||||
"instanceOperationUid": "a955a902-...",
|
|
||||||
"operation": "create",
|
|
||||||
"isInProgress": false,
|
|
||||||
"isSuccessful": true,
|
|
||||||
"duration": 27.89,
|
|
||||||
"stages": [
|
|
||||||
{
|
|
||||||
"instanceOperationStageUid": "f88e28c9-...",
|
|
||||||
"stage": "1. Валидация",
|
|
||||||
"isSuccessful": true,
|
|
||||||
"dtStart": "2026-07-24T15:21:57.373+0300",
|
|
||||||
"dtFinish": "2026-07-24T15:22:01.804+0300",
|
|
||||||
"duration": 4.4,
|
|
||||||
"stageMsg": "[[\"Определение ресурсной платформы\",\"...\"],...]"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"stage": "2. Основной процесс",
|
|
||||||
"isSuccessful": true,
|
|
||||||
"duration": 14.1,
|
|
||||||
"stageMsg": "[[\"Установка сервиса\",\"...\"],...]"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"stage": "3. Проверки",
|
|
||||||
"isSuccessful": true,
|
|
||||||
"duration": 0.3
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"stage": "4. Хранилище секретов",
|
|
||||||
"isSuccessful": null,
|
|
||||||
"dtFinish": null,
|
|
||||||
"duration": 729.2
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Использование для автотестов
|
|
||||||
|
|
||||||
Для отображения прогресса в UI:
|
|
||||||
|
|
||||||
1. Отправить операцию → получить `opUid`
|
|
||||||
2. Поллинг: `GET /instanceOperations/{opUid}` каждые 2-3 секунды
|
|
||||||
3. Пока `isInProgress == true` — показывать стадии из `stages[]`
|
|
||||||
4. Когда `isInProgress == false` — проверить `isSuccessful`
|
|
||||||
|
|
||||||
`stageMsg` содержит **JSON-строку** с массивом `[[заголовок, текст], ...]`. Можно распарсить и показать пользователю.
|
|
||||||
|
|
||||||
## Открытие 2026-07-24
|
|
||||||
|
|
||||||
Обнаружено при анализе ответа API во время сессии тестирования dummy-сервиса. Ранее поле `stages` пропускалось из-за большого размера ответа.
|
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
# Стадии выполнения операции (stages)
|
||||||
|
|
||||||
|
Как через API и код Autotest определить, на каком этапе исполнения находится команда (операция).
|
||||||
|
|
||||||
|
## Связь с реальным кодом
|
||||||
|
|
||||||
|
| Компонент | Файл | Роль |
|
||||||
|
|-----------|------|------|
|
||||||
|
| Запуск операции | `app-autotest/site/operations/executor.py` → `execute_operation()` | Создаёт операцию и возвращает `op_uid` |
|
||||||
|
| Поллинг (async / sync) | `app-autotest/site/operations/poll.py` → `poll_until_done()` | Периодически спрашивает статус и отдаёт `stages` |
|
||||||
|
| Фоновый поллинг + кэш | `app-autotest/site/routes/api_test.py` → `_finish_op()`, `_op_results` | Ждёт `dtFinish`, кладёт `stages` в кэш |
|
||||||
|
| Отдача в UI | `app-autotest/site/routes/api_test.py` → `api_test_status()` | `GET /api/test/status/<op_uid>` → `stages` |
|
||||||
|
| Вывод этапов (ручной режим) | `app-autotest/site/static/js/operations.js` → `showStages()` | Поллинг каждые 2 сек + отрисовка |
|
||||||
|
| Вывод этапов (история) | `app-autotest/site/static/js/history.js` → `renderStages()` | Раскрытие строки истории по клику |
|
||||||
|
|
||||||
|
## Эндпоинты
|
||||||
|
|
||||||
|
### 1. Запуск операции (получаем `opUid`)
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /api/test
|
||||||
|
```
|
||||||
|
|
||||||
|
`execute_operation()` проходит этапы запуска:
|
||||||
|
1. **CREATE**: `POST /instances` → `instanceUid`
|
||||||
|
2. CREATE + NON-CREATE: `POST /instanceOperations` → `opUid`
|
||||||
|
3. Параметры: `send_params_terraform(...)`
|
||||||
|
4. `POST /instanceOperations/{opUid}/run` → запуск
|
||||||
|
|
||||||
|
Возвращает `{ok, error, failed_step, instance_uid, op_uid, display_name}`.
|
||||||
|
При `ok=False` смотри `failed_step`: `instances` / `instanceOperations` / `params` / `run`.
|
||||||
|
|
||||||
|
### 2. Поллинг статуса (определяем этап)
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /api/test/status/<op_uid>
|
||||||
|
```
|
||||||
|
|
||||||
|
Ответ — dict, ключи:
|
||||||
|
- `status` — `"RUNNING"` / `"OK"` / `"FAIL"`
|
||||||
|
- `done` — bool, завершена ли операция
|
||||||
|
- `stages` — список этапов
|
||||||
|
- `isInProgress`, `isSuccessful`, `duration`, `errorLog`, `displayName`
|
||||||
|
|
||||||
|
Сервер сам дергает Nubes API:
|
||||||
|
```
|
||||||
|
GET /instanceOperations/{opUid}?fields=dtFinish,isSuccessful,errorLog,isInProgress,duration,stages
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Фоновый поллинг (для сценариев/сохранения)
|
||||||
|
|
||||||
|
`poll_until_done()` поллит тот же эндпоинт и возвращает:
|
||||||
|
```python
|
||||||
|
{status, is_successful, error_log, stages, duration, svc}
|
||||||
|
```
|
||||||
|
где `status ∈ {"OK", "FAIL", "TIMEOUT"}`.
|
||||||
|
|
||||||
|
## Как определить текущий этап
|
||||||
|
|
||||||
|
Поле `stages` — массив объектов-стадий. Каждая стадия:
|
||||||
|
|
||||||
|
| Поле | Тип | Описание |
|
||||||
|
|------|-----|---------|
|
||||||
|
| `instanceOperationStageUid` | UUID | UID стадии |
|
||||||
|
| `stage` | string | Название (напр. `"1. Валидация"`) |
|
||||||
|
| `isSuccessful` | bool/null | `true`/`false`/`null` (ещё не завершена) |
|
||||||
|
| `dtStart` | datetime | Начало этапа |
|
||||||
|
| `dtFinish` | datetime/null | Окончание (`null` — ещё идёт) |
|
||||||
|
| `duration` | float | Секунды (пересчитывается, пока идёт) |
|
||||||
|
| `stageMsg` | JSON-string/null | Детальные логи этапа |
|
||||||
|
|
||||||
|
**Правило определения текущего этапа:**
|
||||||
|
- `dtFinish == null` (или `isSuccessful == null`) → этап **сейчас выполняется** — это текущий этап команды.
|
||||||
|
- `dtFinish != null` → этап завершён (`isSuccessful == true` → ✅, `false` → ❌).
|
||||||
|
- Идёшь по массиву по порядку: до первого `dtFinish == null` — уже прошли, первый с `null` — текущий, дальше — ещё не начались.
|
||||||
|
|
||||||
|
**Завершение операции:** смотри `done` / `isInProgress`. Когда `done == true` — `status` принимает `OK`/`FAIL`. При `FAIL` текст ошибки в `errorLog` / `error_log`.
|
||||||
|
|
||||||
|
## Пример ответа
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "RUNNING",
|
||||||
|
"done": false,
|
||||||
|
"stages": [
|
||||||
|
{ "stage": "1. Валидация", "isSuccessful": true, "dtFinish": "2026-07-24T15:22:01.804+0300", "duration": 4.4 },
|
||||||
|
{ "stage": "2. Основной процесс", "isSuccessful": null, "dtFinish": null, "duration": 14.1 },
|
||||||
|
{ "stage": "3. Проверки", "isSuccessful": null, "dtFinish": null }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Здесь: этап 1 завершён ✅, этап 2 — **текущий** (идёт), этап 3 — ещё не начался.
|
||||||
|
|
||||||
|
## Вывод этапов в UI
|
||||||
|
|
||||||
|
### Ручной режим (`operations.js` → `showStages()`)
|
||||||
|
|
||||||
|
- Поллинг: `setInterval` каждые **2 секунды** → `GET /api/test/status/{opUid}`
|
||||||
|
- `showStages(sd.stages)` рендерит этапы в последний `.stages-box`:
|
||||||
|
- иконка: `✅` (завершён успешно) / `❌` (завершён с ошибкой) / `⏳` (идёт)
|
||||||
|
- название `stage` + длительность `duration`
|
||||||
|
- `stopPoll()` после завершения; при 5 ошибках подряд поллинга → `TIMEOUT`
|
||||||
|
|
||||||
|
### История (`history.js` → `renderStages()`)
|
||||||
|
|
||||||
|
- `GET /api/history` → записи, у каждой поле `stages`
|
||||||
|
- по клику на строку раскрываются этапы (`stages` сохранены в БД `runs`, колонка `stages JSONB`)
|
||||||
|
|
||||||
|
## Примечание
|
||||||
|
|
||||||
|
`stageMsg` содержит **JSON-строку** с массивом `[[заголовок, текст], ...]` — можно распарсить и показать детальные логи этапа.
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
## Документация API
|
## Документация API
|
||||||
|
|
||||||
- [Обращение к API облака](DOCS/api-access.md) — эндпоинты, curl-примеры
|
- [Обращение к API облака](DOCS/LEGACY/api-access.md) — эндпоинты, curl-примеры
|
||||||
- [Полный поток CREATE](DOCS/api-create-flow.md) — схема, параметры, все ошибки
|
- [Полный поток CREATE](DOCS/LEGACY/api-create-flow.md) — схема, параметры, все ошибки
|
||||||
- [Стадии выполнения операций](DOCS/api-operation-stages.md) — `stages[]` в ответе API
|
- [Стадии выполнения операций](DOCS/api-operation-stages.md) — `stages[]` в ответе API
|
||||||
|
|
||||||
## Структура
|
## Структура
|
||||||
|
|||||||
Reference in New Issue
Block a user