# Передача контекста: Terraform-провайдер Nubes Дата: 2026-09-22 | Версия DEV: 2.0.8 | HEAD: 13beb9c (`release(dev): 2.0.8`) Документ для старта новой сессии. Прочитать целиком перед любыми действиями. --- ## 1. Правила работы (соблюдать строго) - **Никаких действий без прямого разрешения.** Правки, сборки, заливки, коммиты, запуск terraform, запросы в API — только по явной команде оператора. - **Вопрос в любой форме = только ответ.** Не выполнять действий, не предлагать «а ещё могу». - **Коммитить после каждой правки**, разбивая по смыслу. Не копить в рабочем дереве. - **Не расширять область работ.** Формулировка «сделай актуальным везде» не даёт права на дополнительные шаги. - **Не догадываться.** Не уверен — сказать прямо и спросить. Причину бага доказывать фактами (логи, трассировки, содержимое файлов), а не гипотезами. - Язык ответов — русский. --- ## 2. Проект - Репозиторий: `/home/naeel/TF/tf_provider` - Провайдер: `terraform-provider-nubes`, Go, `terraform-plugin-framework v1.8.0` - **Go-модуль провайдера лежит в `provider/`** (не в корне). `go build ./...` из корня падает с «directory prefix . does not contain main module». - Генераторы в `TOOLS/`: - `yaml-generator` — из API в YAML-спеки; - `resource-generator` — из YAML в Go (шаблоны `text/template` в `TOOLS/resource-generator/internal/templates/`); - `docs-generator` — из YAML в Markdown. - Пайплайн: `TOOLS/scripts/01_generate_yamls.sh` → `02_generate_resources_and_docs_v2.sh` → `03_build_and_upload_provider.sh` (скрипт `03` сам прогоняет `01` и `02`). --- ## 3. Состояние на 2026-09-21 (конец сессии) - Ветка `master`, **рабочее дерево чистое**, HEAD = `13beb9c` (`release(dev): 2.0.8`). - Локальные коммиты **в origin не пушились**. - **DEV-версия: 2.0.8**, залита в `tf-registry.containerk8s.services.ngcloud.ru/nubes-dev/nubes`, подпись GPG `CB3A0DF161ECC416` (`tazet@narod.ru`, ключ `secrets/private_key.asc`). - S3: `prod-s3/nubes-terraform-registry/...`, endpoint `https://s3.msk-1.ngcloud.ru`. - Namespace: `nubes-dev`, провайдер `nubes`. - Terraform v1.9.5 локально. --- ## 4. Что починено в этой сессии | Коммит | Что | |---|---| | `7ecd2aa` | детерминированная пересборка генераторов (удалён устаревший бинарь) | | `2286d34` | destroy-guard в `ModifyPlan` + универсальный refSvc (имя или UUID) | | `1401003` | release 2.0.4 | | `d608fba` | FullPipe: `edge.tf`, `storage_config` fast→SATA | | `92e04da` | TODO-документ по багу docs-generator | | `bffe3d9` | refSvc-поля без `Computed` (unset = null, а не unknown) | | `61c7e20` | HISTORY сессии | | `54b0baa` | release 2.0.5 | | `af2e10b` | docs-generator: `map-fixed` → `= { ... }` (аргумент, не блок) | | `7c2cc67` | docs-generator: `array-map-fixed` → `jsonencode([...])` | | `3ca0752` | docs-generator: строковые дефолты в кавычках | | `8d405ba` | core: lifecycle-aware подсказки + `supportsSuspend` в сигнатурах | | `c6715e8` | генератор: `supportsSuspend` в diagnostics; нет `suspend_on_destroy` без suspend | | `69808bd` | release 2.0.6 | | `67c4d2f` | `TOOLS/scripts/validate_docs_examples.sh` | | `14ada09` | ТЗ для Flash по tainted-replace | | `724f5f7` | **убрана create-time проверка существования из `ModifyPlan`** (ломал tainted-replace и `destroy`) | | `25080b7` | release 2.0.7 | | `3c0157a` | **`ShouldBeOptionalComputed`**: read-back параметры без Default → `Optional+Computed` | | `4b34cc7` | **core: гарантия known** — `unknown → null` для read-back полей | | `13beb9c` | release 2.0.8 | --- ## 5. Ключевые архитектурные факты (не переоткрывать заново) 1. **Две копии сгенерированного кода.** - `provider/internal/resources_gen/` — в `.gitignore`, локальный артефакт; - `generated/dev/go/` — актуальный вывод генератора; именно его компилирует релиз (скрипт `03` копирует его в temp-копию `provider`). Проверять надо **`generated/dev/go`**, не `resources_gen`. Проверка не той копии уже приводила к ложным выводам. 2. **Рецепт проверки сборки без релиза:** ```bash TMP=$(mktemp -d) && cp -R provider "$TMP/provider" && \ find "$TMP/provider/internal/resources_gen" -maxdepth 1 -type f -name '*.go' -delete && \ cp generated/dev/go/*.go "$TMP/provider/internal/resources_gen/" && \ (cd "$TMP/provider" && go build ./...) && echo BUILD_OK && rm -rf "$TMP" ``` 3. **Версия правится в 3 файлах:** `TOOLS/config/dev/profile.env` (`VERSION`), `DEV_STAND/FullPipe/versions.tf`, `VERSIONS.md`. Затем коммит `release(dev): X.Y.Z` и `./TOOLS/scripts/03_build_and_upload_provider.sh --profile TOOLS/config/dev X.Y.Z`. 4. **Перезаливка той же версии бесполезна** — Terraform не перекачает провайдер. Всегда бампать версию. 5. `*.tfvars` в `.gitignore` (реальный токен в `terraform.tfvars` безопасен от коммита). 6. **Read-back инвариант.** Провайдер читает параметр обратно из `state_params` инстанса (`RefreshResourceState` + `InputField`). Такой параметр обязан быть `Optional+Computed`, если он не `Required` и без `Default` — правило `helpers.ShouldBeOptionalComputed`. Иначе `plan=null` vs `state=значение` → «Provider produced inconsistent result after apply». 7. `RefreshResourceState` при отсутствии кода в `state_params` схлопывает `unknown → null` (иначе «Provider produced invalid result object after apply: ... was unknown»). 8. **`terraform destroy` при tainted-ресурсе** выполняет внутренний обычный plan, который планирует замену (destroy+create); create-узел замены приходит в `ModifyPlan` с prior state = null — отличить замену от создания невозможно. Поэтому create-time проверка существования из `ModifyPlan` убрана (коммит `724f5f7`), проверка осталась в `Create`. 9. У сервиса без операции `suspend` в YAML: `SupportsSuspendDestroy=false` → `deleteMode := "delete"`, атрибут `suspend_on_destroy` не генерируется, а подсказки в diagnostics не предлагают adopt (он невозможен). 10. Вложенные параметры (`map-fixed`) — `schema.SingleNestedAttribute`; в HCL это **аргумент** `= { ... }`, не блок. `array-map-fixed` — `schema.StringAttribute` (JSON-строка). 11. Логи и артефакты отладки: `/tmp/nubes_find_debug.log` (пишет только Plan-диагностика), `/tmp/plan_trace.txt`, `/tmp/plan_destroy.txt`, `/tmp/plan_norefresh.txt`. 12. Секреты: `secrets/private_key.asc`, `secrets/public_key.asc`, `secrets/dev.token`. Не выводить содержимое в чат. --- ## 6. Файлы, которые нужно прочесть **Обязательно:** 1. `.github/copilot-instructions.md` — жёсткие правила оператора. 2. `VERSIONS.md` — что и когда залито. 3. `HISTORY/2026-09-21_fullpipe_vdc_nsxt_and_refsvc_fixes.md` — журнал предыдущей сессии. 4. `TOOLS/resource-generator/internal/templates/instance.go` — главный шаблон ресурса инстанса (ModifyPlan / Create / Read / Update / Delete / Schema). 5. `TOOLS/resource-generator/internal/helpers/helpers.go` — `ShouldBeOptionalComputed`, `ParamDefaultExpr`, `IsNested`, nested-хелперы. 6. `provider/internal/resources_core/state_refresh.go` — read-back и инвариант known. 7. `provider/internal/resources_core/resource_diagnostics_required.go` — create-time проверки существования/усыновления, `runningConflictHint` / `suspendConflictHint`. 8. `TOOLS/scripts/03_build_and_upload_provider.sh` и `TOOLS/scripts/build-provider.sh` — релизный пайплайн. 9. `DEV_STAND/FullPipe/` — `versions.tf`, `vdc.tf`, `edge.tf`, `variables.tf`, `outputs.tf`. 10. `docs/TODO/docs_generator_nested_attr_syntax.md` — описание бага docs-generator (уже исправлен, см. раздел 8). **По необходимости:** - `TOOLS/resource-generator/internal/templates/{subresource,modifier,action}.go` - `TOOLS/docs-generator/internal/writers/writers.go` — `formatParamOrBlock`, `sampleValue`, `isNestedListParam` - `provider/internal/resources_core/crud.go` — adopt / suspend / delete - `docs/prompt_for_flash_fix_tainted_replace.md` — разбор tainted-replace (реализован в `724f5f7`) - `TOOLS/scripts/validate_docs_examples.sh` — прогон `terraform validate` по примерам из доков - Память репозитория: `/memories/repo/registry-versions.md` --- ## 7. Стенд FullPipe (Organization → vDC → Edge) - Каталог `DEV_STAND/FullPipe`, провайдер берётся из `versions.tf` (сейчас 2.0.8). - `nubes_vc_vdc.vdc` — `suspend_on_destroy = true`, `adopt_existing_on_create = true`. - `nubes_vc_nsxt.edge` — `routed_net_configuration` задаётся **через `=`** (объект), не блоком. - Подхватить новую версию: `terraform init -upgrade`. - На 2026-09-21 `nubes_vc_nsxt.edge` был **tainted** в state (последствие прошлых неудачных apply). Убирается `terraform untaint nubes_vc_nsxt.edge`. --- ## 8. Открытые вопросы 1. **`docs/TODO/docs_generator_nested_attr_syntax.md` устарел** — баг исправлен (`af2e10b`, `7c2cc67`, `3ca0752`), но в файле статус «не исправлено». 2. **Стенд FullPipe не проверен end-to-end на 2.0.8** — нет подтверждённого успешного `apply` (Organization → vDC → Edge) и `destroy` после фиксов. 3. Полный прогон `terraform validate` по всем примерам из доков (63 сервиса) не делался — проверен только `vc_nsxt`. Скрипт для прогона готов: `TOOLS/scripts/validate_docs_examples.sh`. 4. `TOOLS/resource-generator/internal/templates/modifier.go:65` — та же схема `Computed` без ветки read-back. Для бага «inconsistent result after apply» не критично (Create/Update модификаторов не читают обратно в state), но при работе с `kind: modifier` держать в голове. 5. Пуш локальных коммитов в `origin/master` не делался.