Files
tf_provider/HISTORY/OPUS/2026-09-22_modifier_null_reset_bug.md
T

4.0 KiB
Raw Blame History

Opus-разбор: modify-модификатор сбрасывает create-поля в дефолт — 2026-09-22

Источник: ответ Opus на prompt_for_opus_modifier_null_bug.md.

Симптом

nubes_vc_nsxt_network (modifier vc_nsxt.network, modify 111) после create Edge с needEnableAVI=true, virtualServicesCount=3 сбрасывал needEnableAVI на платформе обратно в false.

Корень бага (подтверждено cfsParams операций)

Два пути отправки modify ведут себя по-разному:

  • Generic modify (UpdateResource → RunInstanceOperationUniversalWithDefaults, client.go:493) — в цикле дозаполнения шлёт все незаданные cfsParams их текущим ParamValue (или DefaultValue) — безусловно.
  • Модификатор (RunOperationByCodeWithTimeout → RunInstanceOperationUniversalByCode, client.go:1518) — в аналогичном цикле стоял guard if !param.IsRequired { continue }, который пропускал опциональные параметры.

needEnableAVI — опциональный параметр modify 111 и не входит в SchemaParams модификатора vc_nsxt.network (там только SNAT/routedNetConfiguration). Итог:

  1. модификатор его не шлёт (не его поле);
  2. back-fill его пропускает (IsRequired == false);
  3. бэкенд видит отсутствующий параметр → трактует как reset-to-default → false.

CompactParams тут ни при чём для needEnableAVI — параметр вообще не был в payload модификатора.

Ответы Opus

  1. Полный или частичный payload? Канон — полный: все параметры операции, незаданные дозаполняются текущим live-значением (ParamValue). Бэкенд для modify трактует пропущенный/null как reset-to-default, поэтому частичный payload обязан затирать create-поля.
  2. Где чинить? В RunInstanceOperationUniversalByCode — убрать IsRequired-guard в цикле дозаполнения (стало: слать ВСЕ незаданные params их live-значением, как в WithDefaults).
    • НЕ в CompactParams (он не видит полный набор cfsParams, только поля модификатора).
    • НЕ в шаблоне генератора (шаблон тоже не знает полного набора).
  3. Риск для vc_org.ip_space: основной live-путь безопасен (досылка идёт текущим значением, не хардкод-дефолтом). На fallback-пути /instanceOperations/default/{opId} ParamValue пуст — есть только DefaultValue; но тот же риск уже несёт WithDefaults, новой регрессии нет.

Внесённый фикс

provider/internal/core/client.go — RunInstanceOperationUniversalByCode, цикл дозаполнения: убраны if !param.IsRequired { continue } и if !param.IsRequired && val == "" { continue }. Теперь все незаданные параметры modify досылаются их live-значением (или default).

Коммит: c420ea0.

Примечание

Костыль в DEV_STAND/FullPipe/edge_network.tf (явная передача ALB/VS/qos в модификаторе) после фикса ядра становится избыточным, но не вреден. После пересборки провайдера можно убрать эти три поля из edge_network.tf — досылка теперь происходит автоматически.