Files
tf_provider/provider/internal/resources_gen/1_dummy_resource.go
T

583 lines
30 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package resources_gen
import (
"context"
"fmt"
"strings"
"terraform-provider-nubes/internal/core"
"terraform-provider-nubes/internal/resources_core"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/types"
)
// Code generated by tools/gen_v2. DO NOT EDIT.
// Service: dummy
// Service ID: 1
var _ resource.Resource = &DummyResource{}
var _ resource.ResourceWithModifyPlan = &DummyResource{}
var _ resource.ResourceWithImportState = &DummyResource{}
type DummyResource struct {
client *core.UniversalClient
}
// DummyMapExampleModel — вложенная модель для map-fixed параметра mapExample.
type DummyMapExampleModel struct {
Subparam1 types.String `tfsdk:"subparam1" json:"subparam1"`
Secret types.String `tfsdk:"secret" json:"secret"`
Subparam2 types.String `tfsdk:"subparam2" json:"subparam2"`
}
// DummyMapFixedModel — вложенная модель для map-fixed параметра mapFixed.
type DummyMapFixedModel struct {
Bol1 types.Bool `tfsdk:"bol1" json:"bol1"`
MinStr1 types.String `tfsdk:"min_str1" json:"minStr1"`
Param1 types.Int64 `tfsdk:"param1" json:"param1"`
Param2 types.String `tfsdk:"param2" json:"param2"`
Param3 types.Int64 `tfsdk:"param3" json:"param3"`
}
type DummyModel struct {
ID types.String `tfsdk:"id"`
ResourceName types.String `tfsdk:"resource_name"`
OperationTimeout types.String `tfsdk:"operation_timeout"`
LogLevel types.String `tfsdk:"log_level"`
// --- Redeploy support (ARCHITECTURE.md) ---
// git_revision: при изменении вызывает redeploy вместо modify.
// Опциональное поле — если не задано, modify работает как обычно.
GitRevision types.String `tfsdk:"git_revision"`
Arr types.String `tfsdk:"arr"`
ArrayMapFixedExample types.String `tfsdk:"array_map_fixed_example"`
Bodymessage types.String `tfsdk:"bodymessage"`
DurationMs types.Int64 `tfsdk:"duration_ms"`
FailAtStart types.Bool `tfsdk:"fail_at_start"`
FailInProgress types.Bool `tfsdk:"fail_in_progress"`
JsonExample types.String `tfsdk:"json_example"`
MapExample *DummyMapExampleModel `tfsdk:"map_example"`
MapFixed *DummyMapFixedModel `tfsdk:"map_fixed"`
NestedRefExample types.String `tfsdk:"nested_ref_example"`
ResourceRealm types.String `tfsdk:"resource_realm"`
WhereFail types.Int64 `tfsdk:"where_fail"`
SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"`
AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"`
StateParams types.Map `tfsdk:"state_params"`
StateOut types.Map `tfsdk:"state_out"`
StateParamsFlat types.Map `tfsdk:"state_params_flat"`
StateOutFlat types.Map `tfsdk:"state_out_flat"`
VaultSecrets types.Map `tfsdk:"vault_secrets"`
VaultUrl types.String `tfsdk:"vault_url"`
VaultUserPath types.String `tfsdk:"vault_user_path"`
VaultFields types.List `tfsdk:"vault_fields"`
}
func NewDummyResource() resource.Resource {
return &DummyResource{}
}
func (r *DummyResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_dummy"
}
func (r *DummyResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
attrs := map[string]schema.Attribute{
"id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
"resource_name": schema.StringAttribute{Required: 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."},
"arr": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."},
"array_map_fixed_example": schema.StringAttribute{Optional: true, MarkdownDescription: "Array of map-fixed Не изменяется после создания."},
"bodymessage": schema.StringAttribute{Optional: true, MarkdownDescription: "Дата, уходящая в Vault"},
"duration_ms": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(0), MarkdownDescription: "перед завершением подождать (sleep) столько миллисекунд"},
"fail_at_start": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "если true, завершить джоб, ничего не записывая в cmdb"},
"fail_in_progress": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "если true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdb"},
"json_example": schema.StringAttribute{Optional: true, Computed: true, MarkdownDescription: "Для тестирования интерфейса", PlanModifiers: []planmodifier.String{resources_core.JsonNormalize()}},
"map_example": schema.SingleNestedAttribute{Required: true,
Attributes: map[string]schema.Attribute{
"subparam1": schema.StringAttribute{Optional: true, MarkdownDescription: "это для администратора"},
"secret": schema.StringAttribute{Optional: true, MarkdownDescription: "это секрет"},
"subparam2": schema.StringAttribute{Optional: true},
}},
"map_fixed": schema.SingleNestedAttribute{Required: true,
Attributes: map[string]schema.Attribute{
"bol1": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Булевский, обязательный"},
"min_str1": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("abracadabra"), MarkdownDescription: "не меньше 10 символов"},
"param1": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Integer, secret"},
"param2": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("1"), MarkdownDescription: "Дескрипшен"},
"param3": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "целое положительное"},
}},
"nested_ref_example": schema.StringAttribute{Optional: true, MarkdownDescription: "Не изменяется после создания."},
"resource_realm": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("dummy"), MarkdownDescription: "Платформа для развертывания Не изменяется после создания."},
"where_fail": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write"},
// --- Redeploy support (ARCHITECTURE.md) ---
// При изменении git_revision вызывается redeploy вместо modify.
// Если не задано — modify работает без изменений.
"git_revision": schema.StringAttribute{Optional: true, MarkdownDescription: "Git revision (commit hash/tag). Changing this triggers redeploy instead of modify."},
"suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)},
"adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)},
"state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType},
"state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType},
"state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType},
"state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType},
"vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true},
"vault_url": schema.StringAttribute{Computed: true},
"vault_user_path": schema.StringAttribute{Computed: true},
"vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType},
}
resp.Schema = schema.Schema{Attributes: attrs}
}
func (r *DummyResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
if r.client == nil {
return
}
var config *DummyModel
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
if resp.Diagnostics.HasError() {
return
}
if config == nil {
return
}
var state *DummyModel
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}
if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() {
return
}
if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() {
var plan DummyModel
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
return
}
if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() {
if plan.ResourceName.ValueString() != state.ResourceName.ValueString() {
resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.")
return
}
}
if !plan.Arr.IsNull() && !plan.Arr.IsUnknown() && !state.Arr.IsNull() && !state.Arr.IsUnknown() {
// FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID
// в lowercase, пользователь мог написать upper/mixed. Это одно и то же
// значение, менять его нельзя только если оно реально другое.
if !strings.EqualFold(plan.Arr.ValueString(), state.Arr.ValueString()) {
resp.Diagnostics.AddError("Нельзя изменить arr", "Параметр задается при создании и не может быть изменен.")
return
}
}
if !plan.ArrayMapFixedExample.IsNull() && !plan.ArrayMapFixedExample.IsUnknown() && !state.ArrayMapFixedExample.IsNull() && !state.ArrayMapFixedExample.IsUnknown() {
// FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID
// в lowercase, пользователь мог написать upper/mixed. Это одно и то же
// значение, менять его нельзя только если оно реально другое.
if !strings.EqualFold(plan.ArrayMapFixedExample.ValueString(), state.ArrayMapFixedExample.ValueString()) {
resp.Diagnostics.AddError("Нельзя изменить array_map_fixed_example", "Параметр задается при создании и не может быть изменен.")
return
}
}
if !plan.NestedRefExample.IsNull() && !plan.NestedRefExample.IsUnknown() && !state.NestedRefExample.IsNull() && !state.NestedRefExample.IsUnknown() {
// FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID
// в lowercase, пользователь мог написать upper/mixed. Это одно и то же
// значение, менять его нельзя только если оно реально другое.
if !strings.EqualFold(plan.NestedRefExample.ValueString(), state.NestedRefExample.ValueString()) {
resp.Diagnostics.AddError("Нельзя изменить nested_ref_example", "Параметр задается при создании и не может быть изменен.")
return
}
}
if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() {
// FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID
// в lowercase, пользователь мог написать upper/mixed. Это одно и то же
// значение, менять его нельзя только если оно реально другое.
if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) {
resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.")
return
}
}
return
}
if config.Arr.IsNull() {
resp.Diagnostics.AddError("Missing required attribute", "arr is required.")
return
}
if config.Arr.IsUnknown() {
return
}
if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() {
return
}
adoptExistingOnCreate := false
if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() {
adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool()
}
params := map[int]string{
198: resources_core.FormatInt64(config.DurationMs),
199: resources_core.FormatBool(config.FailAtStart),
200: resources_core.FormatBool(config.FailInProgress),
201: resources_core.FormatInt64(config.WhereFail),
242: resources_core.FormatString(config.ResourceRealm),
286: resources_core.FormatString(config.Bodymessage),
321: resources_core.BuildJSON(map[string]string{"subparam1": fmt.Sprintf("\"%s\"", config.MapExample.Subparam1.ValueString()), "secret": fmt.Sprintf("\"%s\"", config.MapExample.Secret.ValueString()), "subparam2": fmt.Sprintf("\"%s\"", config.MapExample.Subparam2.ValueString())}),
322: resources_core.FormatString(config.JsonExample),
396: resources_core.FormatString(config.NestedRefExample),
647: resources_core.BuildJSON(map[string]string{"bol1": fmt.Sprintf("%v", config.MapFixed.Bol1.ValueBool()), "minStr1": fmt.Sprintf("\"%s\"", config.MapFixed.MinStr1.ValueString()), "param1": fmt.Sprintf("%d", config.MapFixed.Param1.ValueInt64()), "param2": fmt.Sprintf("\"%s\"", config.MapFixed.Param2.ValueString()), "param3": fmt.Sprintf("%d", config.MapFixed.Param3.ValueInt64())}),
654: resources_core.FormatString(config.ArrayMapFixedExample),
863: resources_core.FormatString(config.Arr),
}
desiredDomain := ""
domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149, 151, 153}
resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 1, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...)
}
func (r *DummyResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
var data DummyModel
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
if data.Arr.IsNull() || data.Arr.IsUnknown() {
resp.Diagnostics.AddError("Missing required attribute", "arr is required.")
return
}
resourceName := data.ResourceName.ValueString()
desiredDomain := ""
domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149, 151, 153}
resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 1, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...)
// ⛔ Проверяем HasError ДО create — при hard-error (running без adopt, suspend без adopt,
// not created, конфликт) сайд-эффект create не должен выполняться.
if resp.Diagnostics.HasError() {
return
}
params := map[int]string{
198: resources_core.FormatInt64(data.DurationMs),
199: resources_core.FormatBool(data.FailAtStart),
200: resources_core.FormatBool(data.FailInProgress),
201: resources_core.FormatInt64(data.WhereFail),
242: resources_core.FormatString(data.ResourceRealm),
286: resources_core.FormatString(data.Bodymessage),
321: resources_core.BuildJSON(map[string]string{"subparam1": fmt.Sprintf("\"%s\"", data.MapExample.Subparam1.ValueString()), "secret": fmt.Sprintf("\"%s\"", data.MapExample.Secret.ValueString()), "subparam2": fmt.Sprintf("\"%s\"", data.MapExample.Subparam2.ValueString())}),
322: resources_core.FormatString(data.JsonExample),
396: resources_core.FormatString(data.NestedRefExample),
647: resources_core.BuildJSON(map[string]string{"bol1": fmt.Sprintf("%v", data.MapFixed.Bol1.ValueBool()), "minStr1": fmt.Sprintf("\"%s\"", data.MapFixed.MinStr1.ValueString()), "param1": fmt.Sprintf("%d", data.MapFixed.Param1.ValueInt64()), "param2": fmt.Sprintf("\"%s\"", data.MapFixed.Param2.ValueString()), "param3": fmt.Sprintf("%d", data.MapFixed.Param3.ValueInt64())}),
654: resources_core.FormatString(data.ArrayMapFixedExample),
863: resources_core.FormatString(data.Arr),
}
operationTimeout := ""
if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
operationTimeout = data.OperationTimeout.ValueString()
}
if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() {
ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString())
}
id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 1, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout)
if err != nil {
resp.Diagnostics.AddError("Ошибка клиента", err.Error())
return
}
data.ID = types.StringValue(id)
state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 1, data, []resources_core.StateField{
{Code: "state_params"},
{Code: "state_out"},
{Code: "state_params_flat"},
{Code: "state_out_flat"},
{Code: "vault_secrets"},
{Code: "vault_url"},
{Code: "vault_user_path"},
{Code: "vault_fields"},
}, []resources_core.InputField{
{Code: "arr", Field: "Arr", Type: "string"},
{Code: "arrayMapFixedExample", Field: "ArrayMapFixedExample", Type: "array-map-fixed"},
{Code: "bodymessage", Field: "Bodymessage", Type: "string"},
{Code: "durationMs", Field: "DurationMs", Type: "int64"},
{Code: "failAtStart", Field: "FailAtStart", Type: "bool"},
{Code: "failInProgress", Field: "FailInProgress", Type: "bool"},
{Code: "jsonExample", Field: "JsonExample", Type: "string"},
{Code: "mapExample", Field: "MapExample", Type: "string"},
{Code: "mapFixed", Field: "MapFixed", Type: "map-fixed"},
{Code: "nestedRefExample", Field: "NestedRefExample", Type: "string"},
{Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
{Code: "whereFail", Field: "WhereFail", Type: "int64"},
})
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}
func (r *DummyResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
var state DummyModel
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}
if state.ID.IsNull() || state.ID.IsUnknown() {
return
}
if r.client != nil {
remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString())
if err != nil {
resp.Diagnostics.AddError("Ошибка клиента", err.Error())
return
}
if remove {
resp.State.RemoveResource(ctx)
return
}
}
newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 1, state, []resources_core.StateField{
{Code: "state_params"},
{Code: "state_out"},
{Code: "state_params_flat"},
{Code: "state_out_flat"},
{Code: "vault_secrets"},
{Code: "vault_url"},
{Code: "vault_user_path"},
{Code: "vault_fields"},
}, []resources_core.InputField{
{Code: "arr", Field: "Arr", Type: "string"},
{Code: "arrayMapFixedExample", Field: "ArrayMapFixedExample", Type: "array-map-fixed"},
{Code: "bodymessage", Field: "Bodymessage", Type: "string"},
{Code: "durationMs", Field: "DurationMs", Type: "int64"},
{Code: "failAtStart", Field: "FailAtStart", Type: "bool"},
{Code: "failInProgress", Field: "FailInProgress", Type: "bool"},
{Code: "jsonExample", Field: "JsonExample", Type: "string"},
{Code: "mapExample", Field: "MapExample", Type: "string"},
{Code: "mapFixed", Field: "MapFixed", Type: "map-fixed"},
{Code: "nestedRefExample", Field: "NestedRefExample", Type: "string"},
{Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
{Code: "whereFail", Field: "WhereFail", Type: "int64"},
})
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
}
func (r *DummyResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var plan DummyModel
var state DummyModel
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}
instanceID := state.ID
if instanceID.IsNull() || instanceID.IsUnknown() {
instanceID = plan.ID
}
if instanceID.IsNull() || instanceID.IsUnknown() {
resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify")
return
}
hasServiceParamChanges := false
if !hasServiceParamChanges {
if plan.DurationMs.IsNull() != state.DurationMs.IsNull() || plan.DurationMs.IsUnknown() != state.DurationMs.IsUnknown() {
hasServiceParamChanges = true
} else if !plan.DurationMs.IsNull() && !plan.DurationMs.IsUnknown() && !state.DurationMs.IsNull() && !state.DurationMs.IsUnknown() {
if plan.DurationMs.ValueInt64() != state.DurationMs.ValueInt64() {
hasServiceParamChanges = true
}
}
}
if !hasServiceParamChanges {
if plan.FailAtStart.IsNull() != state.FailAtStart.IsNull() || plan.FailAtStart.IsUnknown() != state.FailAtStart.IsUnknown() {
hasServiceParamChanges = true
} else if !plan.FailAtStart.IsNull() && !plan.FailAtStart.IsUnknown() && !state.FailAtStart.IsNull() && !state.FailAtStart.IsUnknown() {
if plan.FailAtStart.ValueBool() != state.FailAtStart.ValueBool() {
hasServiceParamChanges = true
}
}
}
if !hasServiceParamChanges {
if plan.FailInProgress.IsNull() != state.FailInProgress.IsNull() || plan.FailInProgress.IsUnknown() != state.FailInProgress.IsUnknown() {
hasServiceParamChanges = true
} else if !plan.FailInProgress.IsNull() && !plan.FailInProgress.IsUnknown() && !state.FailInProgress.IsNull() && !state.FailInProgress.IsUnknown() {
if plan.FailInProgress.ValueBool() != state.FailInProgress.ValueBool() {
hasServiceParamChanges = true
}
}
}
if !hasServiceParamChanges {
if plan.WhereFail.IsNull() != state.WhereFail.IsNull() || plan.WhereFail.IsUnknown() != state.WhereFail.IsUnknown() {
hasServiceParamChanges = true
} else if !plan.WhereFail.IsNull() && !plan.WhereFail.IsUnknown() && !state.WhereFail.IsNull() && !state.WhereFail.IsUnknown() {
if plan.WhereFail.ValueInt64() != state.WhereFail.ValueInt64() {
hasServiceParamChanges = true
}
}
}
if !hasServiceParamChanges {
if plan.Bodymessage.IsNull() != state.Bodymessage.IsNull() || plan.Bodymessage.IsUnknown() != state.Bodymessage.IsUnknown() {
hasServiceParamChanges = true
} else if !plan.Bodymessage.IsNull() && !plan.Bodymessage.IsUnknown() && !state.Bodymessage.IsNull() && !state.Bodymessage.IsUnknown() {
if !strings.EqualFold(plan.Bodymessage.ValueString(), state.Bodymessage.ValueString()) {
hasServiceParamChanges = true
}
}
}
if !hasServiceParamChanges {
if plan.JsonExample.IsNull() != state.JsonExample.IsNull() || plan.JsonExample.IsUnknown() != state.JsonExample.IsUnknown() {
hasServiceParamChanges = true
} else if !plan.JsonExample.IsNull() && !plan.JsonExample.IsUnknown() && !state.JsonExample.IsNull() && !state.JsonExample.IsUnknown() {
if !strings.EqualFold(plan.JsonExample.ValueString(), state.JsonExample.ValueString()) {
hasServiceParamChanges = true
}
}
}
// --- Redeploy support (ARCHITECTURE.md) ---
// Проверяем изменился ли git_revision.
// Если да — вызываем redeploy вместо modify.
// git_revision = "" (не задано) → обычный modify.
redeployRequested := false
if !plan.GitRevision.IsNull() && !plan.GitRevision.IsUnknown() {
if state.GitRevision.IsNull() || state.GitRevision.IsUnknown() || plan.GitRevision.ValueString() != state.GitRevision.ValueString() {
redeployRequested = true
}
}
if !hasServiceParamChanges && !redeployRequested {
plan.ID = instanceID
plan.StateParams = state.StateParams
plan.StateOut = state.StateOut
plan.StateParamsFlat = state.StateParamsFlat
plan.StateOutFlat = state.StateOutFlat
plan.VaultSecrets = state.VaultSecrets
plan.VaultUrl = state.VaultUrl
plan.VaultUserPath = state.VaultUserPath
plan.VaultFields = state.VaultFields
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
return
}
operationTimeout := ""
if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
operationTimeout = plan.OperationTimeout.ValueString()
}
if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() {
ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString())
}
// --- Redeploy support (ARCHITECTURE.md) ---
if redeployRequested {
// Вызываем redeploy — пустой params (операция не требует CFS-параметров)
if err := r.client.RunRedeployOperation(ctx, instanceID.ValueString(), operationTimeout); err != nil {
resp.Diagnostics.AddError("Ошибка клиента", err.Error())
return
}
} else {
params := map[int]string{
287: resources_core.FormatInt64(plan.DurationMs),
288: resources_core.FormatBool(plan.FailAtStart),
289: resources_core.FormatBool(plan.FailInProgress),
290: resources_core.FormatInt64(plan.WhereFail),
291: resources_core.FormatString(plan.Bodymessage),
373: resources_core.BuildJSON(map[string]string{"secret": fmt.Sprintf("\"%s\"", plan.MapExample.Secret.ValueString())}),
374: resources_core.FormatString(plan.JsonExample),
}
if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil {
resp.Diagnostics.AddError("Ошибка клиента", err.Error())
return
}
}
plan.ID = instanceID
state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 1, plan, []resources_core.StateField{
{Code: "state_params"},
{Code: "state_out"},
{Code: "state_params_flat"},
{Code: "state_out_flat"},
{Code: "vault_secrets"},
{Code: "vault_url"},
{Code: "vault_user_path"},
{Code: "vault_fields"},
}, []resources_core.InputField{
{Code: "arr", Field: "Arr", Type: "string"},
{Code: "arrayMapFixedExample", Field: "ArrayMapFixedExample", Type: "array-map-fixed"},
{Code: "bodymessage", Field: "Bodymessage", Type: "string"},
{Code: "durationMs", Field: "DurationMs", Type: "int64"},
{Code: "failAtStart", Field: "FailAtStart", Type: "bool"},
{Code: "failInProgress", Field: "FailInProgress", Type: "bool"},
{Code: "jsonExample", Field: "JsonExample", Type: "string"},
{Code: "mapExample", Field: "MapExample", Type: "string"},
{Code: "mapFixed", Field: "MapFixed", Type: "map-fixed"},
{Code: "nestedRefExample", Field: "NestedRefExample", Type: "string"},
{Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
{Code: "whereFail", Field: "WhereFail", Type: "int64"},
})
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}
func (r *DummyResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
var state DummyModel
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}
if state.ID.IsNull() || state.ID.IsUnknown() {
return
}
deleteMode := "state_only"
if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() {
deleteMode = "suspend"
}
operationTimeout := ""
if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() {
operationTimeout = state.OperationTimeout.ValueString()
}
if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() {
ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString())
}
if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
resp.Diagnostics.AddError("Ошибка клиента", err.Error())
return
}
}
func (r *DummyResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
}
func (r *DummyResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
if req.ProviderData == nil {
return
}
client, ok := req.ProviderData.(*core.UniversalClient)
if !ok {
resp.Diagnostics.AddError("Error", "Invalid client type")
return
}
r.client = client
}