diff --git a/DEV_STAND/FPipeGmail/versions.tf b/DEV_STAND/FPipeGmail/versions.tf index eca54b9..f28cb12 100644 --- a/DEV_STAND/FPipeGmail/versions.tf +++ b/DEV_STAND/FPipeGmail/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { nubes = { source = "tf-registry.containerk8s.services.ngcloud.ru/nubes-dev/nubes" - version = "2.0.23" + version = "2.0.1" } } } diff --git a/HISTORY/2026-09-30_dev_release_2_0_1.md b/HISTORY/2026-09-30_dev_release_2_0_1.md index acee516..b77cf8e 100644 --- a/HISTORY/2026-09-30_dev_release_2_0_1.md +++ b/HISTORY/2026-09-30_dev_release_2_0_1.md @@ -35,3 +35,40 @@ GPG → заливка 5 объектов в S3). - `VERSION` в `TOOLS/config/dev/profile.env`: `2.0.0` → `2.0.1`. - `test` и `prod` **не перезаливались** — правки ядра в них не включены (по указанию владельца). - Версия `2.0.0` в реестре осталась от предыдущей заливки (там правок нет). + +--- + +## Инцидент при первой заливке: невалидные имена атрибутов (`s3-inst`, `s3-ref-root`) + +**Симптом.** После первой заливки `2.0.1` провайдер не мог отдать схему: +`Invalid Attribute/Block Name: "s3-inst" at schema path "map_fixed.s3-inst"`, +`"s3-ref-root" at schema path "s3-ref-root"` → падали `terraform plan/apply/validate`. + +**Причина.** В API dev-стенда в тестовом сервисе `1_dummy` появились параметры с кодами +с дефисами (`s3-inst`, `s3-ref-root`). Проверено по бэкапам YAML: в наборах от 09:50, 10:15 и +11:05 (из последнего собрана рабочая `2.0.0`) их **нет**, в наборе от 21:35 — 2 вхождения. +То есть данные изменились на стороне платформы уже после утренней заливки. +`ToSnake` не удалял дефисы → в схему уходило `tfsdk:"s3-inst"`, Terraform отвергает такие имена +(допустимы только `[a-z0-9_]`) и **целиком** не загружает схему провайдера. + +**Фикс.** `TOOLS/resource-generator/internal/helpers/helpers.go`: `ToSnake` завершается +`sanitizeAttrName` — всё вне `[a-z0-9_]` заменяется на `_` (`s3-inst` → `s3_inst`). +Код для API не меняется: `json:"s3-inst"` в генерате сохранён (это значение поля, а не имя +атрибута). Проверено: в сгенерированном коде не осталось ни одного `tfsdk:"…"` с недопустимыми +символами; сборка и `go test ./internal/... -short` — зелёные. + +**Повторная заливка.** `03` прогнан заново (та же версия `2.0.1`), sha256 нового +linux-артефакта: `d25a71a31dbc9ab16e494b3d1f68b38b2214bd530045c5a3003f515bc725e407`. + +**Важно про локальный кэш.** После перезаписи артефакта **под тем же номером** Terraform +продолжает использовать старый файл: `init -upgrade` хеш не пересчитывает (версия и constraint +не изменились). Лечится удалением `.terraform.lock.hcl` + `.terraform` и повторным `init`. +Для внешних потребителей, которые ставят `2.0.1` впервые, проблемы нет — lock получит новый хеш. + +**Верификация.** `DEV_STAND/FPipeGmail`: провайдер `2.0.1` (после сброса lock) → +`terraform validate` — **Success**. + +**Не закрыто (предложение).** В пайплайне нет проверки схемы: `02`/сборка/заливка проходят при +невалидных именах атрибутов, дефект обнаруживается только при обращении Terraform к провайдеру. +Стоит добавить шаг валидации схемы в `03` (или fail-fast в генераторе по `[a-z0-9_]`). + diff --git a/TOOLS/resource-generator/internal/helpers/helpers.go b/TOOLS/resource-generator/internal/helpers/helpers.go index dbe257e..23bb1a3 100644 --- a/TOOLS/resource-generator/internal/helpers/helpers.go +++ b/TOOLS/resource-generator/internal/helpers/helpers.go @@ -43,7 +43,29 @@ func ToSnake(s string) string { } out = append(out, rune(strings.ToLower(string(r))[0])) } - return string(out) + return sanitizeAttrName(string(out)) +} + +// sanitizeAttrName приводит имя атрибута к допустимому в Terraform виду: +// разрешены только [a-z0-9_], всё остальное (в т.ч. '-', '.') заменяется на '_'. +// +// Зачем: API может отдавать коды с дефисами (например `s3-inst`, `s3-ref-root`). +// Terraform отвергает такие имена атрибутов целиком ("Invalid Attribute/Block Name"), +// из-за чего провайдер не может отдать схему и падает любой plan/apply. +func sanitizeAttrName(s string) string { + var b strings.Builder + b.Grow(len(s)) + for _, r := range s { + switch { + case r >= 'a' && r <= 'z', r >= '0' && r <= '9', r == '_': + b.WriteRune(r) + case r >= 'A' && r <= 'Z': + b.WriteRune(r + ('a' - 'A')) + default: + b.WriteRune('_') + } + } + return b.String() } // ParamType возвращает Go-тип для параметра (types.Bool/Int64/String).