Files
tf_provider/TOOLS/resource-generator/internal/templates/modifier.go
T

181 lines
8.8 KiB
Go

package templates
const Modifier = `package resources_gen
import (
"context"
"fmt"
"strings"
"terraform-provider-nubes/internal/core"
"terraform-provider-nubes/internal/resources_core"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
{{- if .NeedsBoolDefault }}
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
{{- end }}
{{- if .NeedsInt64Default }}
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default"
{{- end }}
{{- if .NeedsStringDefault }}
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
{{- end }}
{{- if .NeedsJsonPlanMod }}
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
{{- end }}
"github.com/hashicorp/terraform-plugin-framework/types"
)
// Code generated by TOOLS/resource-generator. DO NOT EDIT.
// Modifier: {{.ServiceName}}.{{.ModifierName}}
var _ resource.Resource = &{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource{}
type {{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource struct {
client *core.UniversalClient
}
type {{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Model struct {
ID types.String {{bt}}tfsdk:"id"{{bt}}
{{ToCamel .ServiceName}}ID types.String {{bt}}tfsdk:"{{ToSnake .ServiceName}}_id"{{bt}}
OperationTimeout types.String {{bt}}tfsdk:"operation_timeout"{{bt}}
LogLevel types.String {{bt}}tfsdk:"log_level"{{bt}}
{{- range .SchemaParams }}
{{ToCamel .Code}} {{ParamType .}} {{bt}}tfsdk:"{{ToSnake .Code}}"{{bt}}
{{- end }}
}
func New{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource() resource.Resource {
return &{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource{}
}
func (r *{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_{{.ServiceName}}_{{.ModifierName}}"
}
func (r *{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
attrs := map[string]schema.Attribute{
"id": schema.StringAttribute{Computed: true},
"{{ToSnake .ServiceName}}_id": schema.StringAttribute{Required: true},
"operation_timeout": schema.StringAttribute{Optional: true},
"log_level": schema.StringAttribute{Optional: true},
{{- range .SchemaParams }}
"{{ToSnake .Code}}": schema.{{if eq (ParamType .) "types.Bool"}}Bool{{else if eq (ParamType .) "types.Int64"}}Int64{{else}}String{{end}}Attribute{
{{- if and .Required (eq (ParamDefaultExpr .) "") }}Required: true,{{else}}Optional: true,{{end}}
{{- if ne (ParamDefaultExpr .) "" }}Computed: true, Default: {{ParamDefaultExpr .}},{{- end }}
{{- if ne (ParamDescription .) "" }}MarkdownDescription: {{ParamDescription .}},{{end}}
{{- if .Sensitive }}Sensitive: true,{{end}}
{{- if .IsJson }}PlanModifiers: []planmodifier.String{resources_core.JsonNormalize()},{{end}}
},
{{- end }}
}
resp.Schema = schema.Schema{Attributes: attrs}
}
func (r *{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
var plan {{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Model
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() { return }
if err := r.reconcile(ctx, &plan, nil); err != nil {
resp.Diagnostics.AddError("Ошибка клиента", err.Error()); return
}
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
}
func (r *{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
var state {{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Model
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.{{ToCamel .ServiceName}}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.{{ToCamel .ServiceName}}ID.ValueString(), {{.ServiceID}}, state, nil, []resources_core.InputField{
{{- range .SchemaParams }}
{Code: "{{.Code}}", Field: "{{ToCamel .Code}}", Type: "{{.Type}}"},
{{- end }}
})
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() { return }
resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
}
func (r *{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var plan {{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Model
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() { return }
if err := r.reconcile(ctx, &plan, nil); err != nil {
resp.Diagnostics.AddError("Ошибка клиента", err.Error()); return
}
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
}
// reconcile — единый путь apply для модификатора (полный payload, досылка в core).
// override — обратные значения (wire-строки), используются только Delete=inverse.
func (r *{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource) reconcile(ctx context.Context, model *{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Model, override map[string]string) error {
instanceUID := strings.TrimSpace(model.{{ToCamel .ServiceName}}ID.ValueString())
if instanceUID == "" { return fmt.Errorf("отсутствует идентификатор экземпляра") }
params := map[string]string{}
{{- range .SchemaParams }}
{{- if .Required }}
if model.{{ToCamel .Code}}.IsNull() || model.{{ToCamel .Code}}.IsUnknown() {
return fmt.Errorf("{{ToSnake .Code}} is required")
}
params["{{.Code}}"] = {{ParamFormat . (printf "model.%s" (ToCamel .Code))}}
{{- else }}
if !model.{{ToCamel .Code}}.IsNull() && !model.{{ToCamel .Code}}.IsUnknown() {
params["{{.Code}}"] = {{ParamFormat . (printf "model.%s" (ToCamel .Code))}}
}
{{- end }}
{{- end }}
for k, v := range override {
params[k] = v
}
operationTimeout := ""
if !model.OperationTimeout.IsNull() && !model.OperationTimeout.IsUnknown() { operationTimeout = model.OperationTimeout.ValueString() }
if !model.LogLevel.IsNull() && !model.LogLevel.IsUnknown() { ctx = core.CtxWithLogLevel(ctx, model.LogLevel.ValueString()) }
{{- if eq .Idempotency "check_before_run" }}
if err := resources_core.RunOperationByCodeIdempotent(ctx, r.client, instanceUID, "{{.OperationName}}", params, operationTimeout); err != nil {
return err
}
{{- else }}
if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "{{.OperationName}}", params, operationTimeout); err != nil {
return err
}
{{- end }}
model.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "{{.OperationName}}", "{{.ModifierName}}"))
return nil
}
func (r *{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
var state {{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Model
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() { return }
{{- if eq .DeleteStrategy "error" }}
resp.Diagnostics.AddError("Запрещено удалять", "Модификатор {{.ServiceName}}.{{.ModifierName}} нельзя удалять: эффект необратим. Обратитесь в техническую поддержку.")
return
{{- else if eq .DeleteStrategy "inverse" }}
override := map[string]string{
{{- range .DeleteParams }}
"{{.Code}}": {{printf "%q" .Value}},
{{- end }}
}
if err := r.reconcile(ctx, &state, override); err != nil {
resp.Diagnostics.AddError("Ошибка клиента", err.Error()); return
}
{{- else }}
resp.Diagnostics.AddWarning("Эффект остаётся на платформе", "Удаление модификатора {{.ServiceName}}.{{.ModifierName}} снимает его из state, но его эффект на платформе остаётся. Откатите вручную при необходимости.")
{{- end }}
}
func (r *{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource) 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
}
`