fix(provider): нормализация регистра UUID при отправке map-fixed JSON в API
- resources_core.BuildJSON оборачивает результат в jsonutil.LowercaseUUIDsInText: платформа сравнивает регистр UUID при create, а ресурсы отдают id в UPPERCASE (nsxtUid/vdcUid) -> без нормализации create Штурвала падал 'Edge не развёрнут в указанном vDC' (обнаружено на провайдере 2.0.23 из-под Windows). - Одна точка покрывает все map-fixed-параметры (create/modify/redeploy), регенерация не требуется. - Документация: HISTORY/2026-09-30, docs/60_strategy/terraform_case_sensitivity_fix.md §11, NOTES/30_analysis/ARCHITECTURE_NEW.md §6.5, docs/help/architecture-and-methods.md §7. Не выпущено: версия не поднималась, релиз/регенерация не выполнялись.
This commit is contained in:
@@ -280,6 +280,8 @@ Error: required params mismatch for resource_name shturval-dev: startupConfigura
|
||||
| 7 | `resources_core/ref_validation.go` (`ValidateRefParamsOnAdopt`) | ref-параметр, зашитый внутрь JSON, **не проверяется вообще** (открыто) |
|
||||
| 8 | `core/operation_run*.go` (`lookupLiveParam`) | подстановка live-значений по ключам: при другом регистре ключа может молча не сработать (открыто, требует живой проверки) |
|
||||
|
||||
> **Дополнение 2026-09-30**: пункты 9–10 (регистр UUID на **отправке** в API) — см. §11.
|
||||
|
||||
**Фикс (провайдер `2.0.23`, dev).**
|
||||
|
||||
- `internal/core/jsonutil/jsonutil.go`: добавлен `LowercaseUUIDsInText` (UUID-подстрока → lowercase), и строковые
|
||||
@@ -295,3 +297,57 @@ Error: required params mismatch for resource_name shturval-dev: startupConfigura
|
||||
значения); смотрите `jsonutil.LowercaseUUIDsInText`.
|
||||
8. Не «лечите» это нормализацией плана целиком (скаляры → строки, сортировка ключей): для атрибутов из config
|
||||
допустимо менять только регистр UUID-подстрок, иначе Terraform ругнётся на несоответствие плана конфигу.
|
||||
9. Разделяйте **сравнение** и **отправку**: фиксы §10 закрывали только сравнение (план/state/adopt). Если ресурс
|
||||
падает на create без видимых расхождений плана — смотрите путь отправки, §11.
|
||||
|
||||
---
|
||||
|
||||
## 11. Обновление 2026-09-30: UUID внутри JSON на ОТПРАВКЕ в API (create/modify/redeploy)
|
||||
|
||||
**Что уточнилось.** Все фиксы §10 закрывали **сравнение** (план vs state, adopt-suspended,
|
||||
modifier-compare, диагностика) и **не** трогали то, что реально уходит в API при создании.
|
||||
На провайдере `2.0.23` (то есть уже после §10) `create` кластера Штурвала **без** `lower(...)`
|
||||
в HCL падал с «Edge не развёрнут в указанном vDC». Обнаружено при запуске Terraform
|
||||
**из-под Windows**.
|
||||
|
||||
**Где именно.**
|
||||
|
||||
- Все map-fixed JSON-параметры (`startupConfiguration`, `clusterConfiguration`, …) собираются
|
||||
одной функцией `resources_core.BuildJSON` (`provider/internal/resources_core/helpers.go`) —
|
||||
она берёт значения подполей (`ValueString()`) **как есть**.
|
||||
- Вызывает её сгенерированный код через `NestedJSONExpr` (`TOOLS/resource-generator/internal/templates/instance.go`,
|
||||
ветки **Create** ~строка 302, **Modify** ~488, **Redeploy** ~505).
|
||||
- `nubes_vc_nsxt` отдаёт `id` в UPPERCASE (`2C37FED1-…`), платформа хранит UUID в lowercase
|
||||
и **сравнивает регистр при create** → UPPERCASE `nsxtUid`/`vdcUid` внутри JSON отвергается.
|
||||
- `resolveRefSvcParamValues` (`core/refsvc.go`, `core/refsvc_resolve.go`) тут не спасает: он
|
||||
нормализует только **top-level** refSvc-параметры и `s3.*uid` **внутри** map-fixed;
|
||||
`vdcUid`/`nsxtUid` — обычные строковые подполя JSON, refSvcId у них нет.
|
||||
|
||||
**Аудит (продолжение таблицы §10, проверено 30.09).**
|
||||
|
||||
| # | Место | Что ломает |
|
||||
|---|---|---|
|
||||
| 9 | `resources_core/helpers.go` (`BuildJSON`) — **отправка** map-fixed JSON в API (create/modify/redeploy) | create падает: «Edge не развёрнут в указанном vDC» — регистр `vdcUid`/`nsxtUid` внутри JSON |
|
||||
| 10 | `core/params.go` (`normalizeUniversalValueV6`) — дефолты create (`instance_create.go`) и досылка modify (`operation_run.go`) | скалярный UUID к lowercase не приводится (открыто, вторично) |
|
||||
|
||||
**Фикс (не выпущен, только код).**
|
||||
|
||||
- `provider/internal/resources_core/helpers.go`: `BuildJSON` оборачивает результат в
|
||||
`jsonutil.LowercaseUUIDsInText(...)` (+ импорт `core/jsonutil`). Одна точка → покрыты **все**
|
||||
map-fixed-параметры всех ресурсов на create / modify / redeploy. Регенерация не нужна.
|
||||
|
||||
**Почему это безопасно.**
|
||||
|
||||
- `BuildJSON` используется **только для отправки**, не для построения state (проверено: вызовы
|
||||
только в `resources_gen/*.go`).
|
||||
- Regex `uuidAnywhereRegex` (`[0-9a-f]{8}-xxxx-xxxx-xxxx-xxxxxxxxxxxx`) совпадает только с UUID;
|
||||
пароли/имена/иные строки не задевает. Внутри map-fixed строковых секретных полей
|
||||
(password/secret/token) в спеках нет — только `*Uid`-ссылки на ресурсы.
|
||||
- Это **выравнивание** с правилом «регистр UUID незначим» (то же приведение уже делается на
|
||||
сравнении), а не новое поведение.
|
||||
|
||||
**Костыль в HCL.** `tf_examples/fullpipe_chain/shturval.tf:139-140`
|
||||
(`vdc_uid = lower(...)`, `nsxt_uid = lower(...)`) после релиза этого фикса станет не нужен.
|
||||
В локальных стендах `lower()` не используется: `DEV_STAND/FPipeGmail/shturval.tf:125-126` и
|
||||
`DEV_STAND/FullPipe/shturval.tf1:123` передают `nubes_vc_vdc.vdc.id` / `nubes_vc_nsxt.edge.id`
|
||||
напрямую → на create у них тот же риск.
|
||||
|
||||
@@ -48,6 +48,11 @@
|
||||
- map/json → "{}"
|
||||
- list/array → "[]"
|
||||
- Пустые строки в JSON-параметрах запрещены (валидаторы на plan).
|
||||
- UUID-подстроки в JSON (map-fixed) приводятся к lowercase **и при сравнении, и при отправке**
|
||||
в API (`resources_core.BuildJSON` → `jsonutil.LowercaseUUIDsInText`). Платформа сравнивает
|
||||
регистр UUID при create, а ресурсы могут отдавать `id` в UPPERCASE (например `nsxtUid`).
|
||||
Поэтому `lower(...)` в конфигах стендов не нужен — см.
|
||||
`docs/60_strategy/terraform_case_sensitivity_fix.md` §10–§11.
|
||||
|
||||
## 8. Soft Delete и карантин
|
||||
- Для тяжёлых ресурсов delete часто заменён на suspend с периодом удержания.
|
||||
|
||||
Reference in New Issue
Block a user