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