fix(generator): read-back параметры без Default -> Optional+Computed (универсальное правило ShouldBeOptionalComputed)

This commit is contained in:
Repinoid
2026-09-21 21:48:54 +03:00
parent 25080b7379
commit 3c0157a1af
3 changed files with 65 additions and 30 deletions
@@ -74,6 +74,37 @@ func ParamDefaultExpr(p types.Param) string {
}
}
// ShouldBeOptionalComputed — обязан ли параметр быть объявлен в схеме как
// `Optional: true, Computed: true` (при отсутствии явного Default).
//
// ОБЩИЙ ИНВАРИАНТ ПРОВАЙДЕРА (не привязан к конкретному сервису или параметру):
// каждый скалярный параметр, который провайдер читает ОБРАТНО из state_params
// инстанса и записывает в state (см. RefreshResourceState + InputField в шаблоне
// instance.go), обязан быть Optional+Computed, если он не Required и без Default.
//
// ПОЧЕМУ ИНАЧЕ ЛОМАЕТСЯ:
// - Пользователь не задал опциональный параметр → в плане он = null.
// - Платформа подставляет своё значение (например дефолтный QoS-профиль
// "QoS-100Mbit" для vc_nsxt) → провайдер кладёт его в state при apply.
// - Terraform видит расхождение plan(null) ≠ state(значение) и падает:
// "Provider produced inconsistent result after apply: .qos_profile:
// was null, but now cty.StringVal("QoS-100Mbit")".
//
// ПОЧЕМУ Computed ЭТО ЧИНИТ:
// - С `Computed: true` незаданный параметр в плане = unknown (не null),
// и провайдер имеет право заполнить его значением из API — это штатная
// семантика Optional+Computed, а не обходной путь.
//
// УСЛОВИЯ, ПРИ КОТОРЫХ Computed НЕ НУЖЕН:
// - Required: значение всегда задано пользователем → план уже известен;
// - RefSvcId != 0: refSvc-параметры НЕ читаются обратно в модель — они
// резолвятся только для API-вызова, а в state остаётся ровно то, что
// написал пользователь (иначе получим plan(display name) ≠ state(UUID));
// - Default != "": атрибут уже объявлен Computed+Default, значение известно.
func ShouldBeOptionalComputed(p types.Param) bool {
return !p.Required && p.RefSvcId == 0 && p.Default == ""
}
// ParamFormat возвращает вызов Format* для форматирования значения параметра.
func ParamFormat(p types.Param, varName string) string {
switch strings.ToLower(p.Type) {