20 KiB
Промпт для 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/vsuniversal_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):
POST /instances→ получаем instanceUidPOST /instanceOperations(operation="create") → получаем instanceOperationUidGET /instanceOperations/{uid}?fields=cfsParams→ получаем параметры с дефолтамиresolveRefSvcParamValues— разрешение ref-параметров (UUID других сервисов)- Для каждого параметра:
POST /instanceOperationCfsParams - Валидация + запуск операции
Методы:
CreateGenericInstanceUniversalV6— полный create flowFindInstanceByDisplayName— поиск по displayName с фильтрацией deleted/дубликатовGetInstanceState/GetInstanceStateRaw— чтение состоянияRunInstanceOperationUniversal/RunInstanceOperationUniversalWithDefaults— modify/suspend/resume/deleteRunInstanceOperationUniversalByCode— операции по коду (для 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:
FindInstanceByDisplayName— поиск существующего- Если найден →
adoptExistingInstanceOnCreate:- Проверка
operation_in_progress/operation_pending - Если
adopt_existing_on_create=false→ ошибка - Статус
not_created→ ошибка - Статус
running→ валидация ref-параметров → adopt (возврат UUID) - Статус
suspended→ проверка required-params → resume → валидация ref → adopt
- Проверка
- Если не найден →
CreateGenericInstanceUniversalV6
DeleteResource:
suspend→ вызов suspendstate_only/detach→ только удаление из state
UpdateResource:
RunInstanceOperationUniversalWithDefaults("modify")
Поддерживающие файлы в resources_core/ (все в /home/naeel/tf_provider/universal_rebuild/internal/resources_core/):
ref_validation.go— валидация ref-параметров при adoptrequired_params.go+required_params_compare.go— проверка обязательных параметровparams_compare.go— сравнение параметров для detect changesparams_mapping.go+params_ref_mapping.go— маппинг параметров из/в APIparams_validation_mapping.go— маппинг для plan validationstate_refresh.go— RefreshResourceState (чтение state после apply)outputs.go— FetchInstanceOutputsoperation_ids.go— маппинг operation ID → имяjson_normalize.go+json_planmodifier.go— нормализация JSON-параметровuuid_planmodifier.go— план-модификатор для UUIDdomain_collision.go— проверка коллизий доменовresource_diagnostics.go+resource_diagnostics_required.go— форматирование диагностикsubresource_guard.go— защита подресурсовcrud_test.go— тесты
Вопросы к Opus:
adoptExistingInstanceOnCreate— не слишком ли сложная логика? 100+ строк, много ветвлений. Есть ли риск не покрытых кейсов?- Что происходит при concurrent apply из двух разных Terraform-окружений?
state_onlydestroy — не остаются ли 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)
Логика генератора:
- Парсит все YAML →
ServiceSpec(name, service_id, outputs, lifecycle, operations) - Для instance: собирает create/modify params → computeCreateOnly → mergeParams → генерирует
.go - Для subresource: группирует по subresource name → create/modify/delete params
- Для action: каждый action → отдельный ресурс с trigger-полем
- Генерирует
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 (итоговый список)
- Архитектура: два провайдера → стратегия перехода на Universal
- Конвейер: надёжность, валидация, обработка ошибок API
- Генератор кода: поддерживаемость шаблонов, расширяемость
- Core/API: retry logic, таймауты, идемпотентность, HTTP/1.1 vs HTTP/2
- Lifecycle: полнота coverage состояний, краевые кейзы adopt/resume
- Баги: какие системные, какие ещё не исправлены
- Тесты: пробелы в покрытии
- Безопасность: токены, GPG, secrets management
- Производительность: поллинг, параллельные запросы, кэширование
- Документация: насколько генерируемые доки соответствуют реальности
На что обратить ОСОБОЕ внимание:
adoptExistingInstanceOnCreateвcrud.go— самая сложная функция, много ветвленийFindInstanceByDisplayName— была переписана, но всё ещё есть риск не найти/найти не тот- Генератор
gen_v2— если сломается, сломается ВЕСЬ провайдер - Immutable параметры — как определяется неизменяемость? Из API или из YAML?
- Конкурентный доступ — что если два
terraform applyодновременно?
Инструкция Opus
- Начни с чтения
devops/ARCHITECTURE.mdиdocs/CODEBASE_ANALYSIS_AND_ROADMAP.md - Затем прочитай ключевые файлы конвейера:
service_spec_gen/generate_service_spec.goиgen_v2/generate_resources_v2.go - Затем core:
client.goиcrud.go - Затем историю проблем: выборочно 2-3 последних файла из
docs/50_history/ - После этого — дай развёрнутый анализ по ВСЕМ 10 пунктам выше
- В анализе на каждый пункт: текущее состояние → что хорошо → что плохо → конкретные предложения → риски
НЕ читай все 50+ сгенерированных файлов подряд — они генерируются и не содержат уникальной логики.