gen(subresource): keep_on_destroy — подресурс при destroy остаётся в облаке

Подресурсы (nubes_postgres_user/database и остальные 20) удалялись всегда, даже когда
родительский инстанс при destroy только приостанавливается. Из-за этого пользователь БД
удалялся, а следующий apply создавал его заново с НОВЫМ паролем.

Добавлен атрибут keep_on_destroy (как у инстансовых ресурсов, Default=false):
- поле KeepOnDestroy в модели;
- атрибут схемы (Optional+Computed, Default=false);
- ранний выход в Delete с предупреждением (режим state_only).

Проверено: 22 подресурса получили атрибут; сборка провайдера с перегенерённым кодом — BUILD_OK.
Дефолт false → поведение существующих конфигураций не меняется.
This commit is contained in:
Repinoid
2026-10-01 15:44:14 +03:00
parent 00bfe7a3ad
commit fefc2006b1
@@ -45,6 +45,7 @@ type {{ToCamel (printf "%s_%s" .ServiceName .SubName)}}Model struct {
{{ToCamel .ServiceName}}ID types.String ` + "`" + `tfsdk:"{{ToSnake .ServiceName}}_id"` + "`" + ` {{ToCamel .ServiceName}}ID types.String ` + "`" + `tfsdk:"{{ToSnake .ServiceName}}_id"` + "`" + `
AdoptExistingOnCreate types.Bool ` + "`" + `tfsdk:"adopt_existing_on_create"` + "`" + ` AdoptExistingOnCreate types.Bool ` + "`" + `tfsdk:"adopt_existing_on_create"` + "`" + `
SkipMissingOnDelete types.Bool ` + "`" + `tfsdk:"skip_missing_on_delete"` + "`" + ` SkipMissingOnDelete types.Bool ` + "`" + `tfsdk:"skip_missing_on_delete"` + "`" + `
KeepOnDestroy types.Bool ` + "`" + `tfsdk:"keep_on_destroy"` + "`" + `
OperationTimeout types.String ` + "`" + `tfsdk:"operation_timeout"` + "`" + ` OperationTimeout types.String ` + "`" + `tfsdk:"operation_timeout"` + "`" + `
LogLevel types.String ` + "`" + `tfsdk:"log_level"` + "`" + ` LogLevel types.String ` + "`" + `tfsdk:"log_level"` + "`" + `
{{- range .SchemaParams }} {{- range .SchemaParams }}
@@ -69,6 +70,7 @@ func (r *{{ToCamel (printf "%s_%s" .ServiceName .SubName)}}Resource) Schema(ctx
}, },
"adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)},
"skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)},
"keep_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Режим state_only при destroy: подресурс не удаляется и не меняется в облаке, только убирается из состояния. Нужен там, где родительский инстанс при destroy не удаляется (например suspend_on_destroy = true) и объект должен остаться внутри него. false = обычное удаление."},
"operation_timeout": schema.StringAttribute{Optional: true}, "operation_timeout": schema.StringAttribute{Optional: true},
"log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."},
{{- range .SchemaParams }} {{- range .SchemaParams }}
@@ -327,6 +329,13 @@ func (r *{{ToCamel (printf "%s_%s" .ServiceName .SubName)}}Resource) Delete(ctx
if resp.Diagnostics.HasError() { if resp.Diagnostics.HasError() {
return return
} }
if !state.KeepOnDestroy.IsNull() && !state.KeepOnDestroy.IsUnknown() && state.KeepOnDestroy.ValueBool() {
resp.Diagnostics.AddWarning(
"Подресурс оставлен как есть, а не удалён",
"destroy: {{.ServiceName}}_{{.SubName}} (service_id={{.ServiceID}}) не изменялся в облаке и только убран из состояния (keep_on_destroy = true). Для полного удаления выставьте keep_on_destroy = false.",
)
return
}
{{- if .HasRefSvcParams }} {{- if .HasRefSvcParams }}
{{- range .SchemaParams }} {{- range .SchemaParams }}
{{- if and (gt .RefSvcId 0) (eq (ParamType .) "types.String") }} {{- if and (gt .RefSvcId 0) (eq (ParamType .) "types.String") }}