From 208d97e2ce7515141837bc5cf5cfb2b10d5e50e2 Mon Sep 17 00:00:00 2001 From: Nail Date: Thu, 24 Sep 2026 20:22:39 +0300 Subject: [PATCH] =?UTF-8?q?docs+release(dev):=202.0.23=20=E2=80=94=20?= =?UTF-8?q?=D0=B0=D1=83=D0=B4=D0=B8=D1=82=20=D1=80=D0=B5=D0=B3=D0=B8=D1=81?= =?UTF-8?q?=D1=82=D1=80=D0=B0=20UUID=20(8=20=D0=BC=D0=B5=D1=81=D1=82),=20?= =?UTF-8?q?=D1=84=D0=B8=D0=BA=D1=81=20=D0=B2=D0=BD=D1=83=D1=82=D1=80=D0=B8?= =?UTF-8?q?=20JSON,=20=D0=B7=D0=B0=D0=BB=D0=B8=D1=82=D0=BE=20=D0=B2=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B5=D1=81=D1=82=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ..._shturval_dev00_adopt_and_freeze_design.md | 11 +++++ ...DEV00_DIAG_AND_FREEZE_DESIGN_2026-09-24.md | 45 +++++++++++++++++++ VERSIONS.md | 2 +- 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/HISTORY/2026-09-24_shturval_dev00_adopt_and_freeze_design.md b/HISTORY/2026-09-24_shturval_dev00_adopt_and_freeze_design.md index 8c4e924..d33cd5e 100644 --- a/HISTORY/2026-09-24_shturval_dev00_adopt_and_freeze_design.md +++ b/HISTORY/2026-09-24_shturval_dev00_adopt_and_freeze_design.md @@ -14,6 +14,17 @@ | Режим «заморозки» в конфиге стенда: `keep_on_destroy=true` (эдж/SNAT/квота IP), adopt для эджа, явный `suspend_on_destroy` у кластера | `DEV_STAND/FullPipe/{edge.tf,modifiers.tf,shturval.tf}` | `40aef87` | | Релиз dev-провайдера `2.0.22` (три платформы + SHA256SUMS/подпись, залито в реестр) | `VERSIONS.md` | `c29df21` | +## Баг после заморозки: регистр UUID внутри JSON (исправлен) + +- Первый `apply` после freeze упал: `required params mismatch … startupConfiguration` — `nsxtUid` в плане + (`2c37fed1-…`, lowercase из пересозданного эджа) против `2C37FED1-…` (UPPERCASE) в живом инстансе. +- Причина: регистр UUID нормализовался в 5 местах (отправка в API, одиночные значения, create-only сравнение, + state), но **внутри JSON** — нет; adopt приостановленного инстанса сравнивает параметр целиком как JSON. +- Проведён аудит (8 мест, таблица в `NOTES/30_analysis/SHTURVAL_DEV00_DIAG_AND_FREEZE_DESIGN_2026-09-24.md` §5.3). +- Фикс: `jsonutil.LowercaseUUIDsInText` + нормализация строк внутри JSON (закрывает adopt-suspended, modifier-compare, + state_refresh, диагностику), UUID-подстроки в `JsonNormalize()`; тесты в `jsonutil` и `resources_core`. +- Открыто: ref-параметр внутри JSON не валидируется при adopt; регистр ключей в `lookupLiveParam`. + ## Проверка цикла на живом стенде - `terraform destroy` (провайдер `2.0.22`): `0 added, 0 changed, 5 destroyed`, ошибок нет. diff --git a/NOTES/30_analysis/SHTURVAL_DEV00_DIAG_AND_FREEZE_DESIGN_2026-09-24.md b/NOTES/30_analysis/SHTURVAL_DEV00_DIAG_AND_FREEZE_DESIGN_2026-09-24.md index ae8d0a9..d63fcdc 100644 --- a/NOTES/30_analysis/SHTURVAL_DEV00_DIAG_AND_FREEZE_DESIGN_2026-09-24.md +++ b/NOTES/30_analysis/SHTURVAL_DEV00_DIAG_AND_FREEZE_DESIGN_2026-09-24.md @@ -242,6 +242,51 @@ SNAT останется включённым (Delete при `keep=true` печа --- +## 5.3. Баг: регистр UUID внутри JSON (первый `apply` после заморозки) + +**Симптом.** `apply` после destroy (провайдер `2.0.22`) упал: +`Error: Ошибка клиента … required params mismatch for resource_name shturval-dev: startupConfiguration +(plan={…"nsxtUid":"2c37fed1-…"}, actual={…"nsxtUid":"2C37FED1-…"})`. +Эдж после пересоздания вернул UUID в lowercase, а в живом инстансе кластера тот же UUID лежит в UPPERCASE. + +**Почему вылезло именно сейчас.** Регистр ранее учли в пяти местах — `core/refsvc.go:20` (lowercase при отправке), +`core/refsvc_resolve.go:28-29`, `resources_core/params_compare.go` (`normalizeCompareValue` — одиночные значения), +шаблон `instance.go:204` (`strings.EqualFold` для create-only), плюс восстановление регистра в state. +Ни одно из них не смотрит **внутрь JSON**, а adopt **приостановленного** инстанса сравнивает параметр целиком как JSON +(`RequiredParamsMismatch` → `paramsEquivalent` → `JSONStringsEquivalent` → `normalizeJSONScalarsToStrings`, +где было `case string: return val`). У Штурвала ref-параметры упакованы в JSON (`startupConfiguration`), +а путь adopt-suspended задействован впервые. + +**Аудит: где ещё может вылезти.** + +| # | Место | Что ломает | +|---|---|---| +| 1 | `resources_core/required_params_compare.go:94` | adopt suspended — hard error (сегодняшний кейс) | +| 2 | `core/modifier_compare.go:47,53` | ложное «не равно» → лишний `modify` при каждом apply (сейчас спит: у `org_ip_allocation` UUID внутри `vip_configure` нет) | +| 3 | `resources_core/state_refresh.go:150` | сохранение планового JSON при эквивалентности → в стейт уедет регистр API | +| 4 | `resources_core/resource_diagnostics_required.go:104` | та же `RequiredParamsMismatch` в create-диагностике | +| 5 | `resources_core/params_compare.go` (`ParamsMatchForResume`) | одиночный UUID ок, JSON — та же дыра (в сгенерированном коде не вызывается) | +| 6 | `resources_core/json_planmodifier.go` (`JsonNormalize`) | только `json.Compact` → для user-facing JSON-атрибутов с UUID риск вечного diff | +| 7 | `resources_core/ref_validation.go` (`ValidateRefParamsOnAdopt`) | ref-параметр, зашитый внутрь JSON, не проверяется вовсе → чужой инстанс не отловится (открыто) | +| 8 | `core/operation_run.go:151`, `operation_run_bycode.go:125` (`lookupLiveParam`) | подстановка live-значений по ключам; при другом регистре ключа молча не сработает (надо проверить, открыто) | + +**Фикс (коммит — см. ниже).** + +- `internal/core/jsonutil/jsonutil.go`: добавлен `LowercaseUUIDsInText` (regex по UUID-подстроке) и строковые значения + внутри JSON теперь нормализуются (`normalizeJSONScalarsToStrings`, `case string`) — закрывает пункты 1–5 сразу. +- `internal/resources_core/json_planmodifier.go`: `JsonNormalize()` после `json.Compact` приводит UUID-подстроки + к lowercase (типы и порядок ключей НЕ меняются) — закрывает пункт 6. +- Тесты: `internal/core/jsonutil/jsonutil_test.go` (UUID внутри вложенного JSON, регистр, разные UUID, числа/bool, + текст без UUID), `internal/resources_core/params_compare_test.go` (`paramsEquivalent` на реальном `startupConfiguration`). + +**Открыто (7–8):** валидация ref-параметров внутри JSON и регистр ключей в `lookupLiveParam` — отдельная задача +(требует решения, что делать при mismatch, и живой проверки). + +**Релиз:** `2.0.23` собран и залит в dev-реестр (`03_build_and_upload_provider.sh`), версия видна в реестре; +`VERSIONS.md` обновлён. После него нужно повторить `apply` на стенде (усыновление + `resume`). + +--- + ## 6. Мои ошибки в этой сессии (обязательно к фиксации) 1. Сказал, что apply «либо даст ошибку, либо создаст дубль кластера» — **неверно**: будет hard error diff --git a/VERSIONS.md b/VERSIONS.md index 6de2480..6a9d6c1 100644 --- a/VERSIONS.md +++ b/VERSIONS.md @@ -5,7 +5,7 @@ | Стенд | Namespace | Версия | Дата заливки | |---|---|---|---| | PROD | `nubes` | `1.0.0` | 2026-09-03 | (новая нумерация) | -| DEV | `nubes-dev` | `2.0.22` | 2026-09-24 | (feat: третий режим destroy `keep_on_destroy` = state_only для всех instance-ресурсов (в т.ч. Эдж, у которого нет suspend) + предупреждения «заморожен/оставлен как есть» в `Delete`; реализовано универсально в генераторе) | +| DEV | `nubes-dev` | `2.0.23` | 2026-09-24 | (fix: UUID внутри JSON нормализуется к lowercase при сравнении (adopt suspended-инстанса падал на регистре `nsxtUid`) + `JsonNormalize` приводит UUID-подстроки; тесты) | | TEST | `nubes-test` | `3.0.0` | 2026-09-03 | (новая нумерация) | ## Как проверить