# Задача: универсальный генератор моков из STANDS YAML ## Контекст **app-autotest** — тестирует сервисы Nubes. Для интеграционных тестов проектируется **мок-полигон** — Flask-заглушка, притворяющаяся Nubes API. Архитектура полигона уже спроектирована: см. `DOCS/polygon-plan.md`. Ключевое решение: data-driven, сервисы описываются в YAML, эмулятор универсальный. **Открытие:** в `STANDS/test/resources_yaml/` лежат 37 YAML-файлов, которые генерит приложение для Terraform-провайдера. Эти YAML описывают ВСЕ сервисы в универсальном формате — провайдер обрабатывает их без привязки к особенностям. **Идея:** использовать эти YAML как источник для автоматической генерации конфигов мок-полигона. Не писать YAML вручную — конвертировать из STANDS. ## Что прочитать Опусу (обязательно) 1. **`DOCS/polygon-plan.md`** — полный план полигона (369 строк) 2. **`STANDS/test/resources_yaml/1_dummy.yaml`** — Болванка (339 строк, простой) 3. **`STANDS/test/resources_yaml/90_postgres.yaml`** — PostgreSQL (934 строки, САМЫЙ сложный: 10+ операций, create_user/create_database, map-fixed с sub_params, resourceRealm) 4. **`STANDS/test/resources_yaml/150_k8s_sthutrval_cluster.yaml`** — K8s (371 строка, умеренно сложный) 5. **`STANDS/test/resources_yaml/115_mariadb.yaml`** — MariaDB (460 строк, похож на PG) 6. **`STANDS/test/resources_yaml/27_vc_vm_v2.yaml`** — VM v2 (71 строка, простой) 7. **`STANDS/test/resources_yaml/21_vc_vdc.yaml`** — vDC (169 строк, инфраструктурный) **НЕ читать:** остальные DOCS, HISTORY, JS-файлы. Только polygon-plan и 6 YAML. ## Ключевой вопрос Можно ли построить **универсальный конвертер** STANDS YAML → polygon-конфиг, который работает для ВСЕХ 37 сервисов без сервис-специфичного кода? Если да — спроектировать его архитектуру. Если нет — объяснить где проходит граница универсальности и что придётся делать вручную. ## Что исследовать ### 1. Формат STANDS YAML — полнота и единообразие Сравни 6 YAML-файлов (от простого dummy до сложного postgres). Ответь: - Все ли поля, нужные полигону, присутствуют в STANDS YAML? - Одинакова ли структура у всех 37 сервисов? Есть ли сервисы с нестандартной структурой? - Покрывает ли STANDS YAML все типы параметров: string, integer, boolean, map, map-fixed, array, array(map)? - Есть ли в STANDS YAML информация о valueList, refSvcId, dataDescriptor — или это нужно достраивать? ### 2. stateParams — генерация из create-операции После create полигон должен отдавать `state.params` с ТЕКУЩИМИ значениями. В STANDS YAML у create-операции есть `params[].default` — можно ли их использовать? - Для всех ли сервисов create-операция имеет defaults для всех параметров? - Как быть с параметрами без default? Брать из `default_for(dataType)`? - Как мапятся `sub_params` (map-fixed) в state.params? Пример из postgres: `clusterConfiguration.replicas` → как это выглядит в state.params? ### 3. stateOut — генерация из операций Для PostgreSQL `state.out = {users: {pgadmin: {}}, databases: {mydb: {}}}`. В STANDS YAML у postgres есть операции `create_user` и `create_database`. Можно ли по наличию таких операций автоматически сгенерировать структуру stateOut? - У каких ещё сервисов есть `create_user`/`create_database`? (MariaDB, ClickHouse?) - Есть ли другие паттерны stateOut кроме users/databases? - Можно ли вывести правило: «если есть операция create_X → добавить X в stateOut»? ### 4. Маппинг полей 1:1 Составь таблицу маппинга STANDS YAML → polygon-конфиг для ВСЕХ полей. Пример (начало): | STANDS YAML | Polygon config | |---|---| | `service_id` | `serviceId` | | `name` | `svc` | | `operations[].id` | `svcOperationId` | | `operations[].name` | `operation` | | `params[].id` | `svcOperationCfsParamId` | | `params[].code` | `svcOperationCfsParam` | | `params[].data_type` | `dataType` | | `params[].sub_params` | `dataDescriptor` | Какие поля НЕ мапятся 1:1 и требуют трансформации? ### 5. Операции — какие включать В STANDS YAML у postgres 10+ операций: create, delete, modify, suspend, resume, restart, recovery, create_user, delete_user, create_database, delete_database. Полигону нужны 6: create, modify, delete, suspend, resume, redeploy. - У всех ли сервисов есть эти 6 операций? - Что делать с «лишними» операциями (restart, recovery, create_user...)? - Нужно ли их включать в мок? Если да — как они влияют на stateParams/stateOut? ### 6. resourceRealm и refSvcId У многих сервисов есть параметр `resourceRealm` (ссылка на платформу k8s/vDC). В полигоне refSvcId в MVP игнорируется (validate-cfs всегда OK). - Достаточно ли просто принимать любое значение resourceRealm? - Или нужно чтобы эмулятор возвращал реалистичный valueList для resourceRealm? - Есть ли другие refSvcId-параметры кроме resourceRealm? ### 7. Краевые случаи - Сервисы с `kind: user` или `kind: database` операциями — как их обрабатывать? - Сервисы с `adopt_existing_on_create_default: true` — нужно ли эмулировать adopt? - Есть ли сервисы где create-операция отсутствует (только modify/delete)? - Параметры с `func: getAvailableResourceRealms` — динамический valueList, как эмулировать? ### 8. Архитектура конвертера Если универсальный подход возможен — спроектировать модуль `polygon/from_stands.py`: - Какие входы (путь к STANDS, фильтр сервисов)? - Алгоритм конвертации одного YAML → polygon-конфиг - Генерация stateParams (из create defaults + default_for) - Генерация stateOut (из операций create_user/create_database) - Обработка sub_params → dataDescriptor - Что делать с полями которые не мапятся (man, descr, sort, func)? - Выходной формат: один общий JSON/dict или отдельные YAML в `polygon/services/`? ## Ожидаемый ответ 1. **Вердикт:** возможен ли универсальный конвертер для всех 37 сервисов? 2. **Таблица маппинга:** все поля STANDS → polygon с пометками «1:1», «трансформация», «игнорировать» 3. **Алгоритм конвертации:** пошагово, с примерами для dummy и postgres 4. **Границы универсальности:** что НЕ покрывается автоматически и требует ручной доработки 5. **Архитектура from_stands.py:** структура модуля, функции, поток данных 6. **Изменения в polygon-plan.md:** что нужно поправить в существующем плане ## Ограничения - Только Python (PyYAML для чтения STANDS) - Результат — данные для MockState, НЕ код самого эмулятора - Конвертер запускается один раз при старте полигона (или offline при сборке) - Никаких внешних API, только чтение локальных YAML-файлов