fix(provider): nsxt_snat — не писать null в Required-атрибут, ошибки API в Delete → error, валидация пустого ip_space_name

This commit is contained in:
Repinoid
2026-09-24 10:52:36 +03:00
parent ba6c4f5122
commit 4b497e61db
@@ -146,11 +146,10 @@ func (r *NsxtSnatResource) Read(ctx context.Context, req resource.ReadRequest, r
return
}
// Ключа ipSpaceName нет, пока SNAT ни разу не включали (HAR fresh-create),
// поэтому отсутствие ключа = null. Значение "no-needed" (SNAT выключен) — реальное.
if raw, ok := live["ipSpaceName"]; !ok || strings.TrimSpace(raw) == "" {
state.IpSpaceName = types.StringNull()
} else {
// ВАЖНО: в Required-атрибут нельзя писать null — после apply state обязан совпасть с планом,
// иначе Terraform вернёт "Provider produced inconsistent result after apply". Если ключа ещё нет
// (SNAT ни разу не включали, HAR fresh-create) — оставляем текущее значение state.
if raw, ok := live["ipSpaceName"]; ok && strings.TrimSpace(raw) != "" {
state.IpSpaceName = types.StringValue(strings.TrimSpace(raw))
}
@@ -180,10 +179,9 @@ func (r *NsxtSnatResource) Delete(ctx context.Context, req resource.DeleteReques
remove, err := ShouldRemoveFromState(ctx, r.client, nsxtUID)
if err != nil {
resp.Diagnostics.AddWarning(
"SNAT не выключался",
fmt.Sprintf("не удалось проверить существование шлюза %s: %s", nsxtUID, err),
)
// Реальная ошибка API (не «шлюза нет») — нельзя молча терять SNAT: ресурс уйдёт из state,
// а SNAT останется включённым.
resp.Diagnostics.AddError("Ошибка клиента", err.Error())
return
}
if remove {
@@ -242,9 +240,11 @@ func (r *NsxtSnatResource) setSnat(ctx context.Context, nsxtUID types.String, ip
return fmt.Errorf("клиент не инициализирован")
}
// Пустую строку молча подменять нельзя (скрытое поведение + риск вечного diff).
// Выключение SNAT — явное каноническое значение "no-needed".
value := strings.TrimSpace(ipSpaceName.ValueString())
if value == "" {
value = noNeededIpSpace
return fmt.Errorf("ip_space_name не может быть пустым: укажите имя ipSpace или %q для выключения SNAT", noNeededIpSpace)
}
unlock := r.client.LockInstance(uid)