generator: третий режим destroy keep_on_destroy (state_only) для всех instance-ресурсов + предупреждения «заморожен/оставлен как есть»
This commit is contained in:
@@ -116,6 +116,11 @@ func LoadSpecs(dir string) ([]types.GenResource, []types.GenSubresource, []types
|
||||
suspendOnDestroy = *spec.Lifecycle.SuspendOnDestroyDefault
|
||||
}
|
||||
|
||||
keepOnDestroy := false
|
||||
if spec.Lifecycle.KeepOnDestroyDefault != nil {
|
||||
keepOnDestroy = *spec.Lifecycle.KeepOnDestroyDefault
|
||||
}
|
||||
|
||||
gr := types.GenResource{
|
||||
Name: spec.Name,
|
||||
ServiceID: spec.ServiceID,
|
||||
@@ -128,6 +133,7 @@ func LoadSpecs(dir string) ([]types.GenResource, []types.GenSubresource, []types
|
||||
HasRefSvcParams: HasRefSvcParams(schemaParams),
|
||||
SupportsSuspendDestroy: supportsSuspendDestroy,
|
||||
SuspendOnDestroy: suspendOnDestroy,
|
||||
KeepOnDestroy: keepOnDestroy,
|
||||
AdoptExistingOnCreate: adoptExistingOnCreate,
|
||||
HasDomainParam: hasDomainParam,
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@ type {{ToCamel .Name}}Model struct {
|
||||
{{- if .SupportsSuspendDestroy }}
|
||||
SuspendOnDestroy types.Bool ` + "`" + `tfsdk:"suspend_on_destroy"` + "`" + `
|
||||
{{- end }}
|
||||
KeepOnDestroy types.Bool ` + "`" + `tfsdk:"keep_on_destroy"` + "`" + `
|
||||
AdoptExistingOnCreate types.Bool ` + "`" + `tfsdk:"adopt_existing_on_create"` + "`" + `
|
||||
{{- range .OutputParams }}
|
||||
{{ToCamel .Code}} {{OutputType .}} ` + "`" + `tfsdk:"{{ToSnake .Code}}"` + "`" + `
|
||||
@@ -128,6 +129,7 @@ func (r *{{ToCamel .Name}}Resource) Schema(ctx context.Context, req resource.Sch
|
||||
{{- if .SupportsSuspendDestroy }}
|
||||
"suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool({{.SuspendOnDestroy}})},
|
||||
{{- end }}
|
||||
"keep_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool({{.KeepOnDestroy}}), MarkdownDescription: "Режим state_only при destroy: ресурс не удаляется и не меняется в облаке, только убирается из состояния. Имеет приоритет над suspend_on_destroy. false = обычное удаление."},
|
||||
"adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool({{.AdoptExistingOnCreate}})},
|
||||
{{- range .OutputParams }}
|
||||
{{- if or (OutputIsMap .) (OutputIsList .) }}
|
||||
@@ -543,14 +545,15 @@ func (r *{{ToCamel .Name}}Resource) Delete(ctx context.Context, req resource.Del
|
||||
return
|
||||
}
|
||||
|
||||
deleteMode := "delete"
|
||||
{{- if .SupportsSuspendDestroy }}
|
||||
deleteMode := "state_only"
|
||||
if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() {
|
||||
deleteMode = "suspend"
|
||||
}
|
||||
{{- else }}
|
||||
deleteMode := "delete"
|
||||
{{- end }}
|
||||
if !state.KeepOnDestroy.IsNull() && !state.KeepOnDestroy.IsUnknown() && state.KeepOnDestroy.ValueBool() {
|
||||
deleteMode = "state_only"
|
||||
}
|
||||
|
||||
operationTimeout := ""
|
||||
if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() {
|
||||
@@ -563,6 +566,19 @@ func (r *{{ToCamel .Name}}Resource) Delete(ctx context.Context, req resource.Del
|
||||
resp.Diagnostics.AddError("Ошибка клиента", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
switch deleteMode {
|
||||
case "suspend":
|
||||
resp.Diagnostics.AddWarning(
|
||||
"Ресурс заморожен, а не удалён",
|
||||
"destroy: {{.Name}} (service_id={{.ServiceID}}) переведён в suspend, удаление не выполнялось. Для полного удаления выставьте suspend_on_destroy = false.",
|
||||
)
|
||||
case "state_only":
|
||||
resp.Diagnostics.AddWarning(
|
||||
"Ресурс оставлен как есть, а не удалён",
|
||||
"destroy: {{.Name}} (service_id={{.ServiceID}}) не изменялся в облаке и только убран из состояния (keep_on_destroy = true). Для полного удаления выставьте keep_on_destroy = false.",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *{{ToCamel .Name}}Resource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
|
||||
|
||||
@@ -32,6 +32,9 @@ type ServiceSpec struct {
|
||||
Lifecycle struct {
|
||||
SuspendOnDestroyDefault *bool `yaml:"suspend_on_destroy_default"`
|
||||
AdoptExistingOnCreateDefault *bool `yaml:"adopt_existing_on_create_default"`
|
||||
// KeepOnDestroyDefault: дефолт ресурса для режима state_only (ничего не менять в облаке).
|
||||
// Нужен там, где сервис не умеет suspend (например, Эдж) — иначе destroy удаляет объект.
|
||||
KeepOnDestroyDefault *bool `yaml:"keep_on_destroy_default"`
|
||||
} `yaml:"lifecycle"`
|
||||
Operations []OperationSpec `yaml:"operations"`
|
||||
}
|
||||
@@ -75,18 +78,21 @@ type GenResource struct {
|
||||
HasRefSvcParams bool
|
||||
SupportsSuspendDestroy bool
|
||||
SuspendOnDestroy bool
|
||||
AdoptExistingOnCreate bool
|
||||
UsesBool bool
|
||||
UsesInt64 bool
|
||||
UsesString bool
|
||||
HasDefaults bool
|
||||
NeedsBoolDefault bool
|
||||
NeedsInt64Default bool
|
||||
NeedsStringDefault bool
|
||||
NeedsBoolUseStateForUnknown bool
|
||||
NeedsInt64UseStateForUnknown bool
|
||||
HasDomainParam bool
|
||||
DomainServiceIDs []int
|
||||
// KeepOnDestroy: destroy только убирает ресурс из состояния (state_only),
|
||||
// ничего не меняя в облаке. Приоритетнее suspend_on_destroy.
|
||||
KeepOnDestroy bool
|
||||
AdoptExistingOnCreate bool
|
||||
UsesBool bool
|
||||
UsesInt64 bool
|
||||
UsesString bool
|
||||
HasDefaults bool
|
||||
NeedsBoolDefault bool
|
||||
NeedsInt64Default bool
|
||||
NeedsStringDefault bool
|
||||
NeedsBoolUseStateForUnknown bool
|
||||
NeedsInt64UseStateForUnknown bool
|
||||
HasDomainParam bool
|
||||
DomainServiceIDs []int
|
||||
// HasRedeploy: сервис поддерживает redeploy (пересборка из git).
|
||||
// Если true — в основной ресурс добавляется поле git_revision.
|
||||
// При изменении git_revision вызывается redeploy вместо modify.
|
||||
@@ -154,12 +160,12 @@ type GenAction struct {
|
||||
// GenModifier — отдельный ресурс для отложенной parent-level modify операции.
|
||||
// Delete намеренно не содержит rollback: API-контракт обратного payload не подтверждён.
|
||||
type GenModifier struct {
|
||||
ServiceName string
|
||||
ServiceID int
|
||||
ModifierName string
|
||||
OperationName string
|
||||
Params []Param
|
||||
SchemaParams []Param
|
||||
ServiceName string
|
||||
ServiceID int
|
||||
ModifierName string
|
||||
OperationName string
|
||||
Params []Param
|
||||
SchemaParams []Param
|
||||
// DeleteStrategy — noop_warn | inverse | error (нормализовано из YAML, пусто → noop_warn).
|
||||
DeleteStrategy string
|
||||
// Idempotency — none | check_before_run (нормализовано из YAML, пусто → none).
|
||||
|
||||
Reference in New Issue
Block a user