Files
tf_provider/prompt_for_opus48.md
T
2026-06-30 15:46:41 +04:00

290 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Промпт для 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+ сгенерированных файлов подряд — они генерируются и не содержат уникальной логики.**