# Промпт для Opus 4.8: Анализ Terraform Provider для Nubes Cloud > **Цель:** глубокий анализ архитектуры, генерационного пайплайна, API-взаимодействия и проблем проекта. Не просто описать, а найти слабые места, предложить улучшения, оценить риски. > **Инструкция:** читай файлы по мере необходимости, не пытайся прочитать всё сразу. Ниже — карта проекта с указанием что где лежит и на что обратить внимание. --- ## 1. Общая архитектура — два провайдера в одном репозитории | Компонент | Путь | Версия | Registry | Характер | |-----------|------|--------|----------|----------| | **Legacy** | `/main.go`, `internal/provider/` | 5.0.52 | `registry.terraform.io/nubes/nubes` | Ручной код, 13 ресурсов | | **Universal Rebuild** | `universal_rebuild/main.go`, `universal_rebuild/...` | 5.0.51 | `terra.k8c.ru/nubes/nubes` | Полностью генерируемый, ~50 ресурсов | Оба используют `terraform-plugin-framework`. Legacy — ручной, Universal — продукт генерационного конвейера. Legacy всё ещё жив, Universal — целевой. ### Ключевые файлы для понимания архитектуры: - `/home/naeel/tf_provider/devops/ARCHITECTURE.md` — архитектурные принципы (YAML как source of truth, никаких ручных правок сгенерированного кода) - `/home/naeel/tf_provider/docs/CODEBASE_ANALYSIS_AND_ROADMAP.md` — полный анализ кодовой базы от 13.03.2026 - `/home/naeel/tf_provider/docs/MIGRATION_PLAN_FOR_AGENT.md` — план миграции в Managed K8s **Вопросы к Opus:** - Насколько оправдано существование двух провайдеров? Когда и как Legacy должен быть выведен? - Есть ли архитектурные проблемы в разделении `internal/` vs `universal_rebuild/internal/`? --- ## 2. Генерационный конвейер (CRITICAL PATH) ### Полный пайплайн: ``` API Nubes (deck-api.ngcloud.ru) │ ▼ [Шаг 1] devops/01_generate_yamls.sh │ └─ запускает: universal_rebuild/tools/service_spec_gen/generate_service_spec.go │ └─ читает: devops/config/services_list.txt (30+ сервисов) │ └─ для каждого сервиса: GET /services/{id} → получает операции → GET детали каждой операции → cfsParams │ └─ пишет: {id}_{name}.yaml в resources_yaml/ │ ▼ [Шаг 2] devops/02_generate_resources_and_docs_v2.sh │ ├─ Go-генератор: universal_rebuild/tools/gen_v2/generate_resources_v2.go │ │ └─ читает YAML → классифицирует операции (instance/subresource/action) → генерирует .go файлы │ │ └─ пишет: internal/resources_gen/*.go (50+ файлов) + registry.go │ │ │ └─ Доку-генератор: universal_rebuild/tools/docs_template_gen_v2/ │ └─ читает YAML → генерирует .md документацию │ ▼ [Шаг 3] devops/03_build_and_upload_provider.sh │ └─ сборка под linux/windows/darwin → GPG-подпись → S3 │ ▼ [Шаг 4] devops/04_build_and_publish_docs.sh └─ mkdocs build → S3 ``` ### Ключевые файлы генераторов: - **service_spec_gen** (API→YAML): `/home/naeel/tf_provider/universal_rebuild/tools/service_spec_gen/generate_service_spec.go` - **gen_v2** (YAML→Go): `/home/naeel/tf_provider/universal_rebuild/tools/gen_v2/generate_resources_v2.go` - **services_list.txt**: `/home/naeel/tf_provider/devops/config/services_list.txt` — 30+ сервисов (dummy, s3, postgres, kafka, clickhouse, k8s, ...) - **operation_timeouts.json**: `/home/naeel/tf_provider/devops/config/operation_timeouts.json` ### Профили (стенды): - `/home/naeel/tf_provider/devops/profiles/test/`, `prod/`, `dev/` - Каждый профиль содержит: `profile.env`, `services_list.txt`, `operation_timeouts.json`, `generated/` **Вопросы к Opus:** - Насколько надёжен конвейер? Что произойдёт если API изменит формат ответа? - Достаточно ли валидации на каждом шаге? Нет ли риска генерации битого кода? - Почему генераторы на Go, а не на Python (учитывая что скрипты на bash)? - Как обрабатываются ошибки API (retry, rate limiting)? См. `service_spec_gen` — есть `ATTEMPTS=3`, `REQUEST_DELAY=0.5` - Комментирование сервисов в `services_list.txt` — это единственный способ исключить сервис? Не приведёт ли к рассинхрону? --- ## 3. Core: UniversalClient и API-взаимодействие ### Файл: `/home/naeel/tf_provider/universal_rebuild/internal/core/client.go` **API Flow V6 (create):** 1. `POST /instances` → получаем instanceUid 2. `POST /instanceOperations` (operation="create") → получаем instanceOperationUid 3. `GET /instanceOperations/{uid}?fields=cfsParams` → получаем параметры с дефолтами 4. `resolveRefSvcParamValues` — разрешение ref-параметров (UUID других сервисов) 5. Для каждого параметра: `POST /instanceOperationCfsParams` 6. Валидация + запуск операции **Методы:** - `CreateGenericInstanceUniversalV6` — полный create flow - `FindInstanceByDisplayName` — поиск по displayName с фильтрацией deleted/дубликатов - `GetInstanceState` / `GetInstanceStateRaw` — чтение состояния - `RunInstanceOperationUniversal` / `RunInstanceOperationUniversalWithDefaults` — modify/suspend/resume/delete - `RunInstanceOperationUniversalByCode` — операции по коду (для action/subresource) ### HTTP-транспорт: `/home/naeel/tf_provider/universal_rebuild/internal/provider/provider.go` - Force HTTP/1.1 (API не поддерживает HTTP/2) - InsecureSkipVerify опционально (для dev-стендов) - Timeout 300s - TLS 1.2 minimum ### Поддержка core: - `/home/naeel/tf_provider/universal_rebuild/internal/core/instance_params.go` — маппинг параметров - `/home/naeel/tf_provider/universal_rebuild/internal/core/instance_outputs.go` — чтение outputs - `/home/naeel/tf_provider/universal_rebuild/internal/core/refsvc_resolve.go` — разрешение ref_svc_id - `/home/naeel/tf_provider/universal_rebuild/internal/core/operation_timeouts.go` — таймауты операций **Вопросы к Opus:** - API Flow V6 — есть ли проблемы с идемпотентностью? Что при обрыве на шаге 4 или 5? - `doRequest` внутри — есть ли retry logic? Как обрабатываются 429/503? - Почему HTTP/1.1 принудительно? Это ограничение API или обход бага? - 300s timeout на всём HTTP-клиенте — не мало ли для длинных операций (создание VM может идти 10+ минут)? --- ## 4. CRUD-логика и Lifecycle ### Файл: `/home/naeel/tf_provider/universal_rebuild/internal/resources_core/crud.go` **CreateResource:** 1. `FindInstanceByDisplayName` — поиск существующего 2. Если найден → `adoptExistingInstanceOnCreate`: - Проверка `operation_in_progress`/`operation_pending` - Если `adopt_existing_on_create=false` → ошибка - Статус `not_created` → ошибка - Статус `running` → валидация ref-параметров → adopt (возврат UUID) - Статус `suspended` → проверка required-params → resume → валидация ref → adopt 3. Если не найден → `CreateGenericInstanceUniversalV6` **DeleteResource:** - `suspend` → вызов suspend - `state_only`/`detach` → только удаление из state **UpdateResource:** - `RunInstanceOperationUniversalWithDefaults("modify")` ### Поддерживающие файлы в `resources_core/` (все в `/home/naeel/tf_provider/universal_rebuild/internal/resources_core/`): - `ref_validation.go` — валидация ref-параметров при adopt - `required_params.go` + `required_params_compare.go` — проверка обязательных параметров - `params_compare.go` — сравнение параметров для detect changes - `params_mapping.go` + `params_ref_mapping.go` — маппинг параметров из/в API - `params_validation_mapping.go` — маппинг для plan validation - `state_refresh.go` — RefreshResourceState (чтение state после apply) - `outputs.go` — FetchInstanceOutputs - `operation_ids.go` — маппинг operation ID → имя - `json_normalize.go` + `json_planmodifier.go` — нормализация JSON-параметров - `uuid_planmodifier.go` — план-модификатор для UUID - `domain_collision.go` — проверка коллизий доменов - `resource_diagnostics.go` + `resource_diagnostics_required.go` — форматирование диагностик - `subresource_guard.go` — защита подресурсов - `crud_test.go` — тесты **Вопросы к Opus:** - `adoptExistingInstanceOnCreate` — не слишком ли сложная логика? 100+ строк, много ветвлений. Есть ли риск не покрытых кейсов? - Что происходит при concurrent apply из двух разных Terraform-окружений? - `state_only` destroy — не остаются ли orphaned ресурсы в облаке? - Как определяется `suspend_on_destroy` по умолчанию? Где логика `hasSuspend → suspendOnDestroyDefault`? --- ## 5. Генерация Go-кода из YAML — КРИТИЧЕСКИ ### Файл: `/home/naeel/tf_provider/universal_rebuild/tools/gen_v2/generate_resources_v2.go` **На входе:** YAML-спек каждого сервиса **На выходе:** 3 типа Go-ресурсов: - **Instance** (kind=instance) — CRUD + lifecycle (suspend/resume) - **Subresource** (kind=subresource) — CRUD для подобъектов (users, databases, topics) - **Action** (kind=action) — одноразовые операции (restart, redeploy, reconcile) **Логика генератора:** 1. Парсит все YAML → `ServiceSpec` (name, service_id, outputs, lifecycle, operations) 2. Для instance: собирает create/modify params → computeCreateOnly → mergeParams → генерирует `.go` 3. Для subresource: группирует по subresource name → create/modify/delete params 4. Для action: каждый action → отдельный ресурс с trigger-полем 5. Генерирует `registry.go` — `AllResources()` со всеми New* функциями ### Пример сгенерированного файла: `/home/naeel/tf_provider/universal_rebuild/internal/resources_gen/90_postgres_resource.go` **Вопросы к Opus:** - Шаблоны генерятся через `text/template` — где сами шаблоны? Они вшиты в `gen_v2` как константы? Насколько они поддерживаемы? - Что произойдёт если в YAML появится новый kind операции, не известный генератору? - `createOnly` параметры — как определяется что параметр immutable? Из API или эвристика? - JSON-параметры (`data_type: json`) — как обрабатываются? Есть `IsJson` + `JsonNormalize` план-модификатор. Это надёжно? - Для subresource — как определяется identity (какие параметры идентифицируют ресурс)? --- ## 6. Известные проблемы (из 23 файлов истории) Архив: `/home/naeel/tf_provider/docs/50_history/` (23 файла, от `00_system_mechanics.md` до `23_vapp_uid_inconsistency_displayname_resolve_bug.md`) ### Ключевые баги (прочитай эти файлы): - **23** — `vapp_uid_inconsistency`: `FindInstanceByDisplayName` возвращает deleted инстанс (нет фильтра isDeleted) - **22** — `adopt_ref_validation`: ref-параметры не валидировались при adopt → ссылки на deleted ресурсы - **21** — `plan_validation_ref_svc_filter`: план показывал deleted/suspended инстансы в ref-списках - **16** — `create_only_params`: create-only параметры не блокировались при modify - **13** — `universal_flow_param_normalization`: нормализация параметров между API и Terraform - **06** — `postgres_update_immutable_params`: immutable параметры при модификации - **05** — `polling_fixes`: проблемы с поллингом длительных операций - **04** — `vm_hang_fix_and_500_error`: 500 ошибка при модификации VM (см. также DEBUG_REPORT_VM_FIX.md) ### Другие важные документы: - `/home/naeel/tf_provider/docs/INSTANCE_STATES.md` — полная матрица состояний инстансов - `/home/naeel/tf_provider/docs/STATE_TRANSITIONS.md` — все переходы состояний (NOT_CREATED, CREATING, RUNNING, SUSPENDED, DELETED, ...) - `/home/naeel/tf_provider/docs/DEBUG_REPORT_VM_FIX.md` — отчёт о попытке исправить 500 при modify VM **Вопросы к Opus:** - Какие баги из истории до сих пор актуальны (не исправлены)? - Есть ли системные проблемы, которые порождают целые классы багов (например, отсутствие фильтрации deleted инстансов)? - Насколько полна матрица состояний? Все ли переходы обрабатываются? - 500 ошибка при modify VM — правильно ли был сделан анализ? Может быть проблема в API, а не в провайдере? --- ## 7. HAR-трассировки — источник правды об API Файлы в `/home/naeel/tf_provider/HAR/`: - `OK.har`, `goodmodify.har`, `baddelete.har` — реальные HTTP-трассировки - `deck.ngcloud.ru.har`, `deck.ngcloud1.ru.har` — полные сессии - `keycloak.nubes.ru.har`, `lucee.har`, `pguser.har` — специфичные сервисы **Вопросы к Opus:** - HAR-файлы — ценный источник для верификации API-контракта. Используются ли они в тестах? - Можно ли автоматизировать проверку что провайдер соответствует реальному API на основе HAR? --- ## 8. Тестирование ### Где тесты: - `/home/naeel/tf_provider/universal_rebuild/internal/resources_core/crud_test.go` - `/home/naeel/tf_provider/universal_rebuild/internal/core/client_test.go` **Вопросы к Opus:** - Достаточно ли тестов? Какие пробелы? - Как тестировать сгенерированные ресурсы без реального API? - Нужны ли integration-тесты против реального API (с мок-сервером или тестовым стендом)? --- ## 9. Безопасность - Токен аутентификации: env `NUBES_API_TOKEN`, файл `~/.nubes_token`, или в HCL (`api_token` — sensitive) - GPG-ключ для подписи провайдера: `/home/naeel/tf_provider/secrets/private_key.asc` - Токены: `/home/naeel/tf_provider/secrets/dev.token`, `prod.token`, `test.token` - InsecureSkipVerify для dev-стендов **Вопросы к Opus:** - Есть ли риск утечки токена через логи/диагностики? - `Sensitive: true` на api_token — достаточно ли этого? - GPG-ключ в репозитории — это нормально? (в `.gitignore` ли он?) --- ## 10. Что нужно оценить Opus (итоговый список) 1. **Архитектура:** два провайдера → стратегия перехода на Universal 2. **Конвейер:** надёжность, валидация, обработка ошибок API 3. **Генератор кода:** поддерживаемость шаблонов, расширяемость 4. **Core/API:** retry logic, таймауты, идемпотентность, HTTP/1.1 vs HTTP/2 5. **Lifecycle:** полнота coverage состояний, краевые кейзы adopt/resume 6. **Баги:** какие системные, какие ещё не исправлены 7. **Тесты:** пробелы в покрытии 8. **Безопасность:** токены, GPG, secrets management 9. **Производительность:** поллинг, параллельные запросы, кэширование 10. **Документация:** насколько генерируемые доки соответствуют реальности ### На что обратить ОСОБОЕ внимание: - `adoptExistingInstanceOnCreate` в `crud.go` — самая сложная функция, много ветвлений - `FindInstanceByDisplayName` — была переписана, но всё ещё есть риск не найти/найти не тот - Генератор `gen_v2` — если сломается, сломается ВЕСЬ провайдер - Immutable параметры — как определяется неизменяемость? Из API или из YAML? - Конкурентный доступ — что если два `terraform apply` одновременно? --- ## Инструкция Opus 1. Начни с чтения `devops/ARCHITECTURE.md` и `docs/CODEBASE_ANALYSIS_AND_ROADMAP.md` 2. Затем прочитай ключевые файлы конвейера: `service_spec_gen/generate_service_spec.go` и `gen_v2/generate_resources_v2.go` 3. Затем core: `client.go` и `crud.go` 4. Затем историю проблем: выборочно 2-3 последних файла из `docs/50_history/` 5. После этого — дай развёрнутый анализ по ВСЕМ 10 пунктам выше 6. В анализе на каждый пункт: текущее состояние → что хорошо → что плохо → конкретные предложения → риски **НЕ читай все 50+ сгенерированных файлов подряд — они генерируются и не содержат уникальной логики.**