104 lines
6.2 KiB
Markdown
104 lines
6.2 KiB
Markdown
# 2026-07-30 — Сессия (v1.1.51 → v1.1.55)
|
|
|
|
## Контекст
|
|
Сценарий `dummy_test` падает на шаге CREATE: `no instanceUid in response`. Ручное создание Болванки через UI работает.
|
|
|
|
## Найденные и исправленные баги
|
|
|
|
### Баг #1 — no instanceUid in response (ЛОЖНАЯ ТРЕВОГА)
|
|
**Где:** `scenario.py:122` — `resp.get("instanceUid")` возвращал None.
|
|
|
|
**Причина:** сценарий НЕ перезапускался после деплоя v1.1.52. UI показывал старый результат из БД от v1.1.51 (баг #3).
|
|
|
|
**Проверка curl:** API отвечает корректно — 201, `Location: ./UUID`, тело `""`. `http_client.py` правильно парсит.
|
|
|
|
**Добавлено в v1.1.52:** `_status` (HTTP-код) в результат `http_client.post()` для отладки.
|
|
|
|
### Баг #2 — лишний svcOperationId для create (ИСПРАВЛЕН в v1.1.52)
|
|
**Где:** `scenario.py:127`
|
|
|
|
Для `create` операция `/instanceOperations` не должна содержать `svcOperationId` (по спецификации Terraform). Было одинаково для всех операций, стало:
|
|
```python
|
|
if op_name == "create":
|
|
op_payload = {"instanceUid": instance_uid, "operation": op_name}
|
|
else:
|
|
op_payload = {"instanceUid": instance_uid, "svcOperationId": svc_op_id, "operation": op_name}
|
|
```
|
|
|
|
### Баг #3 — старые результаты сценариев после редеплоя (ИСПРАВЛЕН в v1.1.53)
|
|
**Где:** `api_scenario.py` + `app.js`
|
|
|
|
**Симптом:** после редеплоя UI показывал результат сценария от СТАРОЙ версии (из БД), пользователь думал что новый код не работает.
|
|
|
|
**Причина:** `/api/scenario/status` не возвращал `app_version`, фронтенд не фильтровал по версии.
|
|
|
|
**Исправление:**
|
|
- `api_scenario.py`: добавлен `app_version` в SELECT обоих эндпоинтов
|
|
- `app.js`: `loadScenarios()` фильтрует историю по `window.APP.version` — показывает только запуски текущей версии
|
|
|
|
### Баг #4 — нельзя удалять без suspend (ОБНАРУЖЕН)
|
|
DELETE после CREATE падает: «Невозможно выполнить операцию удаления услуги. Услуга не остановлена».
|
|
Нужно сначала suspend + 15 мин ожидания. **Вывод:** не использовать delete в сценариях.
|
|
|
|
## Хронология
|
|
|
|
### v1.1.52 — fix scenario create + http_client _status debug
|
|
- `scenario.py`: убран `svcOperationId` из create payload
|
|
- `http_client.py`: добавлен `{"_status": r.status_code}` в результат для отладки
|
|
|
|
### v1.1.53 — filter scenario history by app_version
|
|
- `api_scenario.py`: `app_version` в SELECT
|
|
- `app.js`: фильтр `verHistory = srHistory.filter(r => r.app_version === curVer)`
|
|
|
|
### v1.1.55 — split large files + CRUD scenario editor
|
|
|
|
**Backend (5→7 файлов):**
|
|
- `api_test.py`: 622→479 строк, terraform-функции → `operations/terraform.py` (142)
|
|
- `api_scenario.py` → `api_scenario_run.py` (153) + `api_scenario_defs.py` (108)
|
|
- `db/scenario_defs.py`: + `client_id`, `stand`, `is_seed` в `list_definitions`
|
|
- `api_scenario_defs.py`: `_validate_steps()` — валидация шагов перед create/update
|
|
- `scenario.py`: импорт `send_params_terraform` из `operations/terraform.py` (вместо кросс-импорта из routes)
|
|
|
|
**Frontend (1→10 файлов):**
|
|
- `app.js`: 554→16 (загрузчик)
|
|
- `utils.js` (45), `instances.js` (89), `operations.js` (249)
|
|
- `history.js` (35), `scenario-list.js` (90)
|
|
- CRUD: `scenario-form.js` (128), `scenario-create.js` (25, +clone), `scenario-edit.js` (12), `scenario-delete.js` (13)
|
|
- Кнопки [▶][✏][⎘][🗑], seed-сценарии только [▶][⎘]
|
|
- Inline-редактор: имя, шаги (service_id, operation, params), 409 conflict
|
|
|
|
**Максимальный размер файла:** JS 249 строк, Python 479 строк.
|
|
|
|
## Agent consultations
|
|
|
|
### Вопрос к Sonnet: план CRUD-редактирования сценариев
|
|
|
|
**Суть:** сейчас сценарии правятся только через `scenario_seed.yaml` → редеплой. Нужно редактирование через UI без редеплоя.
|
|
|
|
**Ответ Sonnet (ключевые выводы):**
|
|
|
|
1. **CRUD-эндпоинты УЖЕ реализованы** в `api_scenario.py` (я ошибался, они есть):
|
|
- `GET/POST /api/scenario/definitions`
|
|
- `GET/PUT/DELETE /api/scenario/definitions/<id>`
|
|
- DB-функции в `scenario_defs.py` полностью готовы
|
|
|
|
2. **Нужны только 3 мелкие правки бэкенда:**
|
|
- `list_definitions`: добавить `client_id`, `stand`, `is_seed` в SELECT
|
|
- `api_scenario.py`: `_validate_steps()` с проверкой service_id, operation, params
|
|
- `index.html`: `window.APP.services` (список сервисов для фронтенда)
|
|
|
|
3. **Фронтенд — ~200 строк JS:**
|
|
- Кнопки [▶][✏][⎘][🗑] у каждого сценария
|
|
- Inline-редактор: имя, шаги (сервис▾, операция▾, параметры)
|
|
- Автоподгрузка операций при смене сервиса (`GET /api/operations/{svcId}`)
|
|
- Автозаполнение параметров при смене операции (`GET /api/params/{svcOpId}`)
|
|
- Оптимистичная блокировка (version → 409)
|
|
|
|
4. **Безопасность:** изоляция по client_id+stand, seed-сценарии только [▶][⎘]
|
|
|
|
## Отладка через kubectl
|
|
- SSH: `naeel@5.172.178.213` (ключ `secrets/id_ed25519.txt`)
|
|
- Неймспейс autotest: `01a2d5b2-4df4-4cfe-b98e-8dd3534a3bb5`
|
|
- Код в поде: `/var/www/site/`
|
|
- Проверка версии: `kubectl exec -n $NS deploy/pythonk8s -c app -- grep VERSION /var/www/site/app.py`
|