fix(generator): нормализация имён атрибутов (fail-safe для кодов с дефисами)

Инцидент: в 1_dummy (API dev) появились коды s3-inst / s3-ref-root. ToSnake не убирал
дефисы -> в схему уходило tfsdk:"s3-inst" -> Terraform отвергает такие имена и НЕ
загружает схему провайдера целиком (plan/apply падали).

- helpers.go: ToSnake завершается sanitizeAttrName ([a-z0-9_] допустимы, остальное -> _).
  Код для API не меняется: json:"s3-inst" в генерате сохранён.
- Проверено: в generated/dev/go нет tfsdk-имён с недопустимыми символами;
  go build OK; go test ./internal/... -short PASS.
- DEV_STAND/FPipeGmail: провайдер 2.0.23 -> 2.0.1; после сброса lock/кэша
  terraform validate -> Success.
- HISTORY: описан инцидент, причина (данные API изменились после утра), фикс и
  особенность: перезапись артефакта под тем же номером требует сброса lock
  (init -upgrade хеш не пересчитывает).

dev 2.0.1 перезалит (sha256 linux d25a71a31dbc9ab16e494b3d1f68b38b2214bd530045c5a3003f515bc725e407).
This commit is contained in:
Repinoid
2026-09-30 21:42:37 +03:00
parent daece181d7
commit fbc20eea61
3 changed files with 61 additions and 2 deletions
+1 -1
View File
@@ -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"
}
}
}
+37
View File
@@ -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_]`).
@@ -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).