diff --git a/universal_rebuild/internal/resources_gen/25_vcexternalip_resource.go b/universal_rebuild/internal/resources_gen/25_vcexternalip_resource.go
new file mode 100644
index 0000000..c8beddf
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/25_vcexternalip_resource.go
@@ -0,0 +1,558 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: vcexternalip
+// Service ID: 25
+
+var _ resource.Resource = &VcexternalipResource{}
+var _ resource.ResourceWithModifyPlan = &VcexternalipResource{}
+var _ resource.ResourceWithImportState = &VcexternalipResource{}
+
+type VcexternalipResource struct {
+ client *core.UniversalClient
+}
+
+type VcexternalipModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ DnatCreate types.Bool `tfsdk:"dnat_create"`
+ FromServiceCloudEdgeName types.String `tfsdk:"from_service_cloud_edge_name"`
+ FromServiceCloudEdgeScope types.String `tfsdk:"from_service_cloud_edge_scope"`
+ FromServiceCloudOrgName types.String `tfsdk:"from_service_cloud_org_name"`
+ FromServiceCloudVdcName types.String `tfsdk:"from_service_cloud_vdc_name"`
+ FromServiceCloudVmwareUrl types.String `tfsdk:"from_service_cloud_vmware_url"`
+ FromServiceNamespace types.String `tfsdk:"from_service_namespace"`
+ FromServiceVdcGroupName types.String `tfsdk:"from_service_vdc_group_name"`
+ InternalAddrAccess types.String `tfsdk:"internal_addr_access"`
+ InternalPortAccess types.String `tfsdk:"internal_port_access"`
+ IpSpaceName types.String `tfsdk:"ip_space_name"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+ ServiceUid types.String `tfsdk:"service_uid"`
+ SnatCreate types.Bool `tfsdk:"snat_create"`
+ 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 NewVcexternalipResource() resource.Resource {
+ return &VcexternalipResource{}
+}
+
+func (r *VcexternalipResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_vcexternalip"
+}
+
+func (r *VcexternalipResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "dnat_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true), MarkdownDescription: "Необходимо создать DNAT-правило."},
+ "from_service_cloud_edge_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Edge составной услуги (указывать, если resourceRealm связан с CloudDirector) Не изменяется после создания."},
+ "from_service_cloud_edge_scope": schema.StringAttribute{Optional: true, MarkdownDescription: "Не изменяется после создания."},
+ "from_service_cloud_org_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Org составной услуги (указывать, если resourceRealm связан с CloudDirector) Не изменяется после создания."},
+ "from_service_cloud_vdc_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Vdc составной услуги (указывать, если resourceRealm связан с CloudDirector) Не изменяется после создания."},
+ "from_service_cloud_vmware_url": schema.StringAttribute{Optional: true, MarkdownDescription: "Api-Url составной услуги (указывать, если resourceRealm связан с CloudDirector) Не изменяется после создания."},
+ "from_service_namespace": schema.StringAttribute{Required: true, MarkdownDescription: "Namespace составной услуги (для отображения правил FW) Не изменяется после создания."},
+ "from_service_vdc_group_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Не изменяется после создания."},
+ "internal_addr_access": schema.StringAttribute{Required: true, MarkdownDescription: "Внутренний адрес для связки ната. Требует dnatCreate=true или snatCreate=true"},
+ "internal_port_access": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("5432"), MarkdownDescription: "Порт для связки ната с адресом. Несколько значений можно передавать через пробел. Если передать all, то dnat будет на все порты. Требует dnatCreate=true
"},
+ "ip_space_name": schema.StringAttribute{Required: true, MarkdownDescription: "Тип ip Space (internet-ipv4-v1 / internet-antiddos-v1 / internet-no-antiddos-v1)"},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."},
+ "service_uid": schema.StringAttribute{Required: true},
+ "snat_create": schema.BoolAttribute{Optional: true, MarkdownDescription: "Необходимо создать SNAT-правило.
"},
+ "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)},
+ "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 *VcexternalipResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *VcexternalipModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *VcexternalipModel
+ 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 VcexternalipModel
+ 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.FromServiceCloudEdgeName.IsNull() && !plan.FromServiceCloudEdgeName.IsUnknown() && !state.FromServiceCloudEdgeName.IsNull() && !state.FromServiceCloudEdgeName.IsUnknown() {
+ if plan.FromServiceCloudEdgeName.ValueString() != state.FromServiceCloudEdgeName.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_edge_name", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.FromServiceCloudEdgeScope.IsNull() && !plan.FromServiceCloudEdgeScope.IsUnknown() && !state.FromServiceCloudEdgeScope.IsNull() && !state.FromServiceCloudEdgeScope.IsUnknown() {
+ if plan.FromServiceCloudEdgeScope.ValueString() != state.FromServiceCloudEdgeScope.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_edge_scope", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.FromServiceCloudOrgName.IsNull() && !plan.FromServiceCloudOrgName.IsUnknown() && !state.FromServiceCloudOrgName.IsNull() && !state.FromServiceCloudOrgName.IsUnknown() {
+ if plan.FromServiceCloudOrgName.ValueString() != state.FromServiceCloudOrgName.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_org_name", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.FromServiceCloudVdcName.IsNull() && !plan.FromServiceCloudVdcName.IsUnknown() && !state.FromServiceCloudVdcName.IsNull() && !state.FromServiceCloudVdcName.IsUnknown() {
+ if plan.FromServiceCloudVdcName.ValueString() != state.FromServiceCloudVdcName.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_vdc_name", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.FromServiceCloudVmwareUrl.IsNull() && !plan.FromServiceCloudVmwareUrl.IsUnknown() && !state.FromServiceCloudVmwareUrl.IsNull() && !state.FromServiceCloudVmwareUrl.IsUnknown() {
+ if plan.FromServiceCloudVmwareUrl.ValueString() != state.FromServiceCloudVmwareUrl.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_vmware_url", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.FromServiceNamespace.IsNull() && !plan.FromServiceNamespace.IsUnknown() && !state.FromServiceNamespace.IsNull() && !state.FromServiceNamespace.IsUnknown() {
+ if plan.FromServiceNamespace.ValueString() != state.FromServiceNamespace.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить from_service_namespace", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.FromServiceVdcGroupName.IsNull() && !plan.FromServiceVdcGroupName.IsUnknown() && !state.FromServiceVdcGroupName.IsNull() && !state.FromServiceVdcGroupName.IsUnknown() {
+ if plan.FromServiceVdcGroupName.ValueString() != state.FromServiceVdcGroupName.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить from_service_vdc_group_name", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() {
+ if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.FromServiceNamespace.IsNull() || config.FromServiceNamespace.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "from_service_namespace is required.")
+ return
+ }
+ if config.InternalAddrAccess.IsNull() || config.InternalAddrAccess.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "internal_addr_access is required.")
+ return
+ }
+ if config.IpSpaceName.IsNull() || config.IpSpaceName.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.")
+ return
+ }
+ if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+ if config.ServiceUid.IsNull() || config.ServiceUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "service_uid is required.")
+ 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{
+ 140: resources_core.FormatString(config.ServiceUid),
+ 141: resources_core.FormatBool(config.DnatCreate),
+ 142: resources_core.FormatString(config.InternalPortAccess),
+ 143: resources_core.FormatBool(config.SnatCreate),
+ 144: resources_core.FormatString(config.InternalAddrAccess),
+ 324: resources_core.FormatString(config.FromServiceNamespace),
+ 325: resources_core.FormatString(config.FromServiceCloudEdgeName),
+ 326: resources_core.FormatString(config.FromServiceCloudVdcName),
+ 327: resources_core.FormatString(config.FromServiceCloudOrgName),
+ 328: resources_core.FormatString(config.FromServiceCloudVmwareUrl),
+ 336: resources_core.FormatString(config.IpSpaceName),
+ 488: resources_core.FormatString(config.ResourceRealm),
+ 624: resources_core.FormatString(config.FromServiceCloudEdgeScope),
+ 626: resources_core.FormatString(config.FromServiceVdcGroupName),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 25, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *VcexternalipResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data VcexternalipModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.FromServiceNamespace.IsNull() || data.FromServiceNamespace.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "from_service_namespace is required.")
+ return
+ }
+ if data.InternalAddrAccess.IsNull() || data.InternalAddrAccess.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "internal_addr_access is required.")
+ return
+ }
+ if data.IpSpaceName.IsNull() || data.IpSpaceName.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.")
+ return
+ }
+ if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+ if data.ServiceUid.IsNull() || data.ServiceUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "service_uid is required.")
+ return
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 25, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 140: resources_core.FormatString(data.ServiceUid),
+ 141: resources_core.FormatBool(data.DnatCreate),
+ 142: resources_core.FormatString(data.InternalPortAccess),
+ 143: resources_core.FormatBool(data.SnatCreate),
+ 144: resources_core.FormatString(data.InternalAddrAccess),
+ 324: resources_core.FormatString(data.FromServiceNamespace),
+ 325: resources_core.FormatString(data.FromServiceCloudEdgeName),
+ 326: resources_core.FormatString(data.FromServiceCloudVdcName),
+ 327: resources_core.FormatString(data.FromServiceCloudOrgName),
+ 328: resources_core.FormatString(data.FromServiceCloudVmwareUrl),
+ 336: resources_core.FormatString(data.IpSpaceName),
+ 488: resources_core.FormatString(data.ResourceRealm),
+ 624: resources_core.FormatString(data.FromServiceCloudEdgeScope),
+ 626: resources_core.FormatString(data.FromServiceVdcGroupName),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 25, 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, 25, 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: "dnatCreate", Field: "DnatCreate", Type: "bool"},
+ {Code: "fromServiceCloudEdgeName", Field: "FromServiceCloudEdgeName", Type: "string"},
+ {Code: "fromServiceCloudEdgeScope", Field: "FromServiceCloudEdgeScope", Type: "string"},
+ {Code: "fromServiceCloudOrgName", Field: "FromServiceCloudOrgName", Type: "string"},
+ {Code: "fromServiceCloudVdcName", Field: "FromServiceCloudVdcName", Type: "string"},
+ {Code: "fromServiceCloudVmwareUrl", Field: "FromServiceCloudVmwareUrl", Type: "string"},
+ {Code: "fromServiceNamespace", Field: "FromServiceNamespace", Type: "string"},
+ {Code: "fromServiceVdcGroupName", Field: "FromServiceVdcGroupName", Type: "string"},
+ {Code: "internalAddrAccess", Field: "InternalAddrAccess", Type: "string"},
+ {Code: "internalPortAccess", Field: "InternalPortAccess", Type: "string"},
+ {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ {Code: "serviceUid", Field: "ServiceUid", Type: "string"},
+ {Code: "snatCreate", Field: "SnatCreate", Type: "bool"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *VcexternalipResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state VcexternalipModel
+ 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(), 25, 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: "dnatCreate", Field: "DnatCreate", Type: "bool"},
+ {Code: "fromServiceCloudEdgeName", Field: "FromServiceCloudEdgeName", Type: "string"},
+ {Code: "fromServiceCloudEdgeScope", Field: "FromServiceCloudEdgeScope", Type: "string"},
+ {Code: "fromServiceCloudOrgName", Field: "FromServiceCloudOrgName", Type: "string"},
+ {Code: "fromServiceCloudVdcName", Field: "FromServiceCloudVdcName", Type: "string"},
+ {Code: "fromServiceCloudVmwareUrl", Field: "FromServiceCloudVmwareUrl", Type: "string"},
+ {Code: "fromServiceNamespace", Field: "FromServiceNamespace", Type: "string"},
+ {Code: "fromServiceVdcGroupName", Field: "FromServiceVdcGroupName", Type: "string"},
+ {Code: "internalAddrAccess", Field: "InternalAddrAccess", Type: "string"},
+ {Code: "internalPortAccess", Field: "InternalPortAccess", Type: "string"},
+ {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ {Code: "serviceUid", Field: "ServiceUid", Type: "string"},
+ {Code: "snatCreate", Field: "SnatCreate", Type: "bool"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *VcexternalipResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan VcexternalipModel
+ var state VcexternalipModel
+ 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.ServiceUid.IsNull() != state.ServiceUid.IsNull() || plan.ServiceUid.IsUnknown() != state.ServiceUid.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ServiceUid.IsNull() && !plan.ServiceUid.IsUnknown() && !state.ServiceUid.IsNull() && !state.ServiceUid.IsUnknown() {
+ if plan.ServiceUid.ValueString() != state.ServiceUid.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.IpSpaceName.IsNull() != state.IpSpaceName.IsNull() || plan.IpSpaceName.IsUnknown() != state.IpSpaceName.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.IpSpaceName.IsNull() && !plan.IpSpaceName.IsUnknown() && !state.IpSpaceName.IsNull() && !state.IpSpaceName.IsUnknown() {
+ if plan.IpSpaceName.ValueString() != state.IpSpaceName.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.DnatCreate.IsNull() != state.DnatCreate.IsNull() || plan.DnatCreate.IsUnknown() != state.DnatCreate.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.DnatCreate.IsNull() && !plan.DnatCreate.IsUnknown() && !state.DnatCreate.IsNull() && !state.DnatCreate.IsUnknown() {
+ if plan.DnatCreate.ValueBool() != state.DnatCreate.ValueBool() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.SnatCreate.IsNull() != state.SnatCreate.IsNull() || plan.SnatCreate.IsUnknown() != state.SnatCreate.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.SnatCreate.IsNull() && !plan.SnatCreate.IsUnknown() && !state.SnatCreate.IsNull() && !state.SnatCreate.IsUnknown() {
+ if plan.SnatCreate.ValueBool() != state.SnatCreate.ValueBool() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.InternalPortAccess.IsNull() != state.InternalPortAccess.IsNull() || plan.InternalPortAccess.IsUnknown() != state.InternalPortAccess.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.InternalPortAccess.IsNull() && !plan.InternalPortAccess.IsUnknown() && !state.InternalPortAccess.IsNull() && !state.InternalPortAccess.IsUnknown() {
+ if plan.InternalPortAccess.ValueString() != state.InternalPortAccess.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.InternalAddrAccess.IsNull() != state.InternalAddrAccess.IsNull() || plan.InternalAddrAccess.IsUnknown() != state.InternalAddrAccess.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.InternalAddrAccess.IsNull() && !plan.InternalAddrAccess.IsUnknown() && !state.InternalAddrAccess.IsNull() && !state.InternalAddrAccess.IsUnknown() {
+ if plan.InternalAddrAccess.ValueString() != state.InternalAddrAccess.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+
+ if !hasServiceParamChanges {
+ 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
+ }
+
+ params := map[int]string{
+ 627: resources_core.FormatString(plan.ServiceUid),
+ 628: resources_core.FormatString(plan.IpSpaceName),
+ 629: resources_core.FormatBool(plan.DnatCreate),
+ 630: resources_core.FormatBool(plan.SnatCreate),
+ 631: resources_core.FormatString(plan.InternalPortAccess),
+ 632: resources_core.FormatString(plan.InternalAddrAccess),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 25, 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: "dnatCreate", Field: "DnatCreate", Type: "bool"},
+ {Code: "fromServiceCloudEdgeName", Field: "FromServiceCloudEdgeName", Type: "string"},
+ {Code: "fromServiceCloudEdgeScope", Field: "FromServiceCloudEdgeScope", Type: "string"},
+ {Code: "fromServiceCloudOrgName", Field: "FromServiceCloudOrgName", Type: "string"},
+ {Code: "fromServiceCloudVdcName", Field: "FromServiceCloudVdcName", Type: "string"},
+ {Code: "fromServiceCloudVmwareUrl", Field: "FromServiceCloudVmwareUrl", Type: "string"},
+ {Code: "fromServiceNamespace", Field: "FromServiceNamespace", Type: "string"},
+ {Code: "fromServiceVdcGroupName", Field: "FromServiceVdcGroupName", Type: "string"},
+ {Code: "internalAddrAccess", Field: "InternalAddrAccess", Type: "string"},
+ {Code: "internalPortAccess", Field: "InternalPortAccess", Type: "string"},
+ {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ {Code: "serviceUid", Field: "ServiceUid", Type: "string"},
+ {Code: "snatCreate", Field: "SnatCreate", Type: "bool"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *VcexternalipResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state VcexternalipModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *VcexternalipResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *VcexternalipResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/26_vapp_resource.go b/universal_rebuild/internal/resources_gen/26_vapp_resource.go
new file mode 100644
index 0000000..35e9615
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/26_vapp_resource.go
@@ -0,0 +1,482 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: vapp
+// Service ID: 26
+
+var _ resource.Resource = &VappResource{}
+var _ resource.ResourceWithModifyPlan = &VappResource{}
+var _ resource.ResourceWithImportState = &VappResource{}
+
+type VappResource struct {
+ client *core.UniversalClient
+}
+
+type VappModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ NsxtUid types.String `tfsdk:"nsxt_uid"`
+ VappName types.String `tfsdk:"vapp_name"`
+ VdcUid types.String `tfsdk:"vdc_uid"`
+ 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 NewVappResource() resource.Resource {
+ return &VappResource{}
+}
+
+func (r *VappResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_vapp"
+}
+
+func (r *VappResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "nsxt_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UUID Услуги `Сетевой шлюз периметра (Edge)` Не изменяется после создания."},
+ "vapp_name": schema.StringAttribute{Required: true, MarkdownDescription: "Уникальное в рамках организации Не изменяется после создания."},
+ "vdc_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UUID Услуги `Виртуальный датацентр (vDC)` Не изменяется после создания."},
+ "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 *VappResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *VappModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *VappModel
+ 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 VappModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ planChanged := false
+ if !plan.NsxtUid.IsNull() && !plan.NsxtUid.IsUnknown() {
+ resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, plan.NsxtUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error())
+ } else if resolvedNsxtUid != "" && resolvedNsxtUid != plan.NsxtUid.ValueString() {
+ plan.NsxtUid = types.StringValue(resolvedNsxtUid)
+ planChanged = true
+ }
+ }
+ if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, plan.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error())
+ } else if resolvedVdcUid != "" && resolvedVdcUid != plan.VdcUid.ValueString() {
+ plan.VdcUid = types.StringValue(resolvedVdcUid)
+ planChanged = true
+ }
+ }
+ if planChanged {
+ resp.Diagnostics.Append(resp.Plan.Set(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.NsxtUid.IsNull() && !plan.NsxtUid.IsUnknown() && !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() {
+ if plan.NsxtUid.ValueString() != state.NsxtUid.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить nsxt_uid", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.VappName.IsNull() && !plan.VappName.IsUnknown() && !state.VappName.IsNull() && !state.VappName.IsUnknown() {
+ if plan.VappName.ValueString() != state.VappName.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить vapp_name", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() {
+ if plan.VdcUid.ValueString() != state.VdcUid.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить vdc_uid", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.NsxtUid.IsNull() || config.NsxtUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "nsxt_uid is required.")
+ return
+ }
+ if config.VappName.IsNull() || config.VappName.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "vapp_name is required.")
+ return
+ }
+ if config.VdcUid.IsNull() || config.VdcUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.")
+ return
+ }
+
+ if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() {
+ return
+ }
+ adoptExistingOnCreate := false
+ if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() {
+ adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool()
+ }
+ if !config.NsxtUid.IsNull() && !config.NsxtUid.IsUnknown() {
+ resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, config.NsxtUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error())
+ } else if resolvedNsxtUid != "" && resolvedNsxtUid != config.NsxtUid.ValueString() {
+ config.NsxtUid = types.StringValue(resolvedNsxtUid)
+ }
+ }
+ if !config.VdcUid.IsNull() && !config.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, config.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error())
+ } else if resolvedVdcUid != "" && resolvedVdcUid != config.VdcUid.ValueString() {
+ config.VdcUid = types.StringValue(resolvedVdcUid)
+ }
+ }
+ params := map[int]string{
+ 190: resources_core.FormatString(config.NsxtUid),
+ 191: resources_core.FormatString(config.VappName),
+ 623: resources_core.FormatString(config.VdcUid),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 26, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *VappResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data VappModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.NsxtUid.IsNull() || data.NsxtUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "nsxt_uid is required.")
+ return
+ }
+ if data.VappName.IsNull() || data.VappName.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "vapp_name is required.")
+ return
+ }
+ if data.VdcUid.IsNull() || data.VdcUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.")
+ return
+ }
+ if !data.NsxtUid.IsNull() && !data.NsxtUid.IsUnknown() {
+ resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, data.NsxtUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if resolvedNsxtUid != "" && resolvedNsxtUid != data.NsxtUid.ValueString() {
+ data.NsxtUid = types.StringValue(resolvedNsxtUid)
+ }
+ }
+ if !data.VdcUid.IsNull() && !data.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, data.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if resolvedVdcUid != "" && resolvedVdcUid != data.VdcUid.ValueString() {
+ data.VdcUid = types.StringValue(resolvedVdcUid)
+ }
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 26, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 190: resources_core.FormatString(data.NsxtUid),
+ 191: resources_core.FormatString(data.VappName),
+ 623: resources_core.FormatString(data.VdcUid),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 26, 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, 26, 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: "nsxtUid", Field: "NsxtUid", Type: "string"},
+ {Code: "vappName", Field: "VappName", Type: "string"},
+ {Code: "vdcUid", Field: "VdcUid", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() {
+ resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, state.NsxtUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error())
+ } else if resolvedNsxtUid != "" && resolvedNsxtUid != state.NsxtUid.ValueString() {
+ state.NsxtUid = types.StringValue(resolvedNsxtUid)
+ }
+ }
+ if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error())
+ } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() {
+ state.VdcUid = types.StringValue(resolvedVdcUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *VappResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state VappModel
+ 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(), 26, 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: "nsxtUid", Field: "NsxtUid", Type: "string"},
+ {Code: "vappName", Field: "VappName", Type: "string"},
+ {Code: "vdcUid", Field: "VdcUid", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !newState.NsxtUid.IsNull() && !newState.NsxtUid.IsUnknown() {
+ resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, newState.NsxtUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error())
+ } else if resolvedNsxtUid != "" && resolvedNsxtUid != newState.NsxtUid.ValueString() {
+ newState.NsxtUid = types.StringValue(resolvedNsxtUid)
+ }
+ }
+ if !newState.VdcUid.IsNull() && !newState.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, newState.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error())
+ } else if resolvedVdcUid != "" && resolvedVdcUid != newState.VdcUid.ValueString() {
+ newState.VdcUid = types.StringValue(resolvedVdcUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *VappResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan VappModel
+ var state VappModel
+ 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 {
+ 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
+ }
+
+ params := map[int]string{}
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 26, 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: "nsxtUid", Field: "NsxtUid", Type: "string"},
+ {Code: "vappName", Field: "VappName", Type: "string"},
+ {Code: "vdcUid", Field: "VdcUid", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() {
+ resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, state.NsxtUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error())
+ } else if resolvedNsxtUid != "" && resolvedNsxtUid != state.NsxtUid.ValueString() {
+ state.NsxtUid = types.StringValue(resolvedNsxtUid)
+ }
+ }
+ if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error())
+ } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() {
+ state.VdcUid = types.StringValue(resolvedVdcUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *VappResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state VappModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *VappResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *VappResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/27_vc_vm_v2_resource.go b/universal_rebuild/internal/resources_gen/27_vc_vm_v2_resource.go
new file mode 100644
index 0000000..53b57db
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/27_vc_vm_v2_resource.go
@@ -0,0 +1,329 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: vc_vm_v2
+// Service ID: 27
+
+var _ resource.Resource = &VcVmV2Resource{}
+var _ resource.ResourceWithModifyPlan = &VcVmV2Resource{}
+var _ resource.ResourceWithImportState = &VcVmV2Resource{}
+
+type VcVmV2Resource struct {
+ client *core.UniversalClient
+}
+
+type VcVmV2Model struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ ServerListJson types.String `tfsdk:"server_list_json"`
+ 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 NewVcVmV2Resource() resource.Resource {
+ return &VcVmV2Resource{}
+}
+
+func (r *VcVmV2Resource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_vc_vm_v2"
+}
+
+func (r *VcVmV2Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "server_list_json": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[{}]"), MarkdownDescription: "Необходимо изменить vappUid и ipSpaceName
Пример конфигурации взять по ссылке ниже
Объект серверов вида [{}] (Map(Object))
Более подробнее смотреть в README.md (https://gitea.mgmt.nubes.ru/cloudServices/vcVmV2)"},
+ "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 *VcVmV2Resource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *VcVmV2Model
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *VcVmV2Model
+ 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 VcVmV2Model
+ 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
+ }
+ }
+ 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{
+ 301: resources_core.FormatString(config.ServerListJson),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 27, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *VcVmV2Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data VcVmV2Model
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 27, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 301: resources_core.FormatString(data.ServerListJson),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 27, 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, 27, 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: "serverListJson", Field: "ServerListJson", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *VcVmV2Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state VcVmV2Model
+ 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(), 27, 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: "serverListJson", Field: "ServerListJson", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *VcVmV2Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan VcVmV2Model
+ var state VcVmV2Model
+ 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.ServerListJson.IsNull() != state.ServerListJson.IsNull() || plan.ServerListJson.IsUnknown() != state.ServerListJson.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ServerListJson.IsNull() && !plan.ServerListJson.IsUnknown() && !state.ServerListJson.IsNull() && !state.ServerListJson.IsUnknown() {
+ if plan.ServerListJson.ValueString() != state.ServerListJson.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+
+ if !hasServiceParamChanges {
+ 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
+ }
+
+ params := map[int]string{
+ 302: resources_core.FormatString(plan.ServerListJson),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 27, 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: "serverListJson", Field: "ServerListJson", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *VcVmV2Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state VcVmV2Model
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *VcVmV2Resource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *VcVmV2Resource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/28_vc_vm_v3_redeploy_action.go b/universal_rebuild/internal/resources_gen/28_vc_vm_v3_redeploy_action.go
new file mode 100644
index 0000000..f2212aa
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/28_vc_vm_v3_redeploy_action.go
@@ -0,0 +1,198 @@
+package resources_gen
+
+import (
+ "context"
+ "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"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: vc_vm_v3
+// Action: redeploy
+
+var _ resource.Resource = &VcVmV3RedeployResource{}
+
+// VcVmV3RedeployResource triggers a one-time action.
+type VcVmV3RedeployResource struct {
+ client *core.UniversalClient
+}
+
+type VcVmV3RedeployModel struct {
+ ID types.String `tfsdk:"id"`
+ VcVmV3ID types.String `tfsdk:"vc_vm_v3_id"`
+ RunID types.String `tfsdk:"run_id"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ VmName types.String `tfsdk:"vm_name"`
+ VmCpu types.Int64 `tfsdk:"vm_cpu"`
+ VmRam types.Int64 `tfsdk:"vm_ram"`
+ VmDisk types.Int64 `tfsdk:"vm_disk"`
+ IpSpaceName types.String `tfsdk:"ip_space_name"`
+ AccessIpList types.String `tfsdk:"access_ip_list"`
+ ImageVm types.String `tfsdk:"image_vm"`
+ UserLogin types.String `tfsdk:"user_login"`
+ UserPublicKey types.String `tfsdk:"user_public_key"`
+ CloudInit types.String `tfsdk:"cloud_init"`
+ AccessPortList types.String `tfsdk:"access_port_list"`
+}
+
+func NewVcVmV3RedeployResource() resource.Resource {
+ return &VcVmV3RedeployResource{}
+}
+
+func (r *VcVmV3RedeployResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_vc_vm_v3_redeploy"
+}
+
+func (r *VcVmV3RedeployResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "vc_vm_v3_id": schema.StringAttribute{Required: true},
+ "run_id": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "vm_name": schema.StringAttribute{Required: true},
+ "vm_cpu": schema.Int64Attribute{Required: true, MarkdownDescription: "шт"},
+ "vm_ram": schema.Int64Attribute{Required: true, MarkdownDescription: "Gb"},
+ "vm_disk": schema.Int64Attribute{Optional: true, MarkdownDescription: "Основной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму"},
+ "ip_space_name": schema.StringAttribute{Optional: true, MarkdownDescription: "no-needed, без внешнего ip
internet-antiddos-v1, с функцией защиты от ddos атак
internet-no-antiddos-v1, с функцией защиты от ddos атак
internet-ipv4-v1 тестовое простанство dev"},
+ "access_ip_list": schema.StringAttribute{Optional: true, MarkdownDescription: "Формат массива
Каким адресам будет предоставлен доступ до вм
Требует выделенного внешнего IP
Если ничего не передано, то выставлено ["0.0.0.0/0"]"},
+ "image_vm": schema.StringAttribute{Required: true},
+ "user_login": schema.StringAttribute{Required: true, MarkdownDescription: "Учётка SSH"},
+ "user_public_key": schema.StringAttribute{Required: true, MarkdownDescription: "Публичная часть SSH-Ключа для пользователя"},
+ "cloud_init": schema.StringAttribute{Optional: true, MarkdownDescription: "Можно передать создание дополнительных пользователей.
На текущий момент не реализовано выполнения в cloud-init, установки пакетов, выполнения команд и записи файлов."},
+ "access_port_list": schema.StringAttribute{Optional: true, MarkdownDescription: "По каким портам открыть доступ к ВМ.
Порты 22, 10050 проставляются автоматически
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX"},
+ }
+ resp.Schema = schema.Schema{Attributes: attrs}
+}
+
+func (r *VcVmV3RedeployResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan VcVmV3RedeployModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if plan.VmName.IsNull() || plan.VmName.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "vm_name is required.")
+ return
+ }
+ if plan.VmCpu.IsNull() || plan.VmCpu.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "vm_cpu is required.")
+ return
+ }
+ if plan.VmRam.IsNull() || plan.VmRam.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "vm_ram is required.")
+ return
+ }
+ if plan.ImageVm.IsNull() || plan.ImageVm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "image_vm is required.")
+ return
+ }
+ if plan.UserLogin.IsNull() || plan.UserLogin.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "user_login is required.")
+ return
+ }
+ if plan.UserPublicKey.IsNull() || plan.UserPublicKey.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "user_public_key is required.")
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.VcVmV3ID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{
+ "vmName": resources_core.FormatString(plan.VmName),
+ "vmCpu": resources_core.FormatInt64(plan.VmCpu),
+ "vmRam": resources_core.FormatInt64(plan.VmRam),
+ "vmDisk": resources_core.FormatInt64(plan.VmDisk),
+ "ipSpaceName": resources_core.FormatString(plan.IpSpaceName),
+ "accessIpList": resources_core.FormatString(plan.AccessIpList),
+ "imageVm": resources_core.FormatString(plan.ImageVm),
+ "userLogin": resources_core.FormatString(plan.UserLogin),
+ "userPublicKey": resources_core.FormatString(plan.UserPublicKey),
+ "cloudInit": resources_core.FormatString(plan.CloudInit),
+ "accessPortList": resources_core.FormatString(plan.AccessPortList),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "redeploy", params, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *VcVmV3RedeployResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state VcVmV3RedeployModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *VcVmV3RedeployResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan VcVmV3RedeployModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.VcVmV3ID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{
+ "vmName": resources_core.FormatString(plan.VmName),
+ "vmCpu": resources_core.FormatInt64(plan.VmCpu),
+ "vmRam": resources_core.FormatInt64(plan.VmRam),
+ "vmDisk": resources_core.FormatInt64(plan.VmDisk),
+ "ipSpaceName": resources_core.FormatString(plan.IpSpaceName),
+ "accessIpList": resources_core.FormatString(plan.AccessIpList),
+ "imageVm": resources_core.FormatString(plan.ImageVm),
+ "userLogin": resources_core.FormatString(plan.UserLogin),
+ "userPublicKey": resources_core.FormatString(plan.UserPublicKey),
+ "cloudInit": resources_core.FormatString(plan.CloudInit),
+ "accessPortList": resources_core.FormatString(plan.AccessPortList),
+ }
+
+ if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "redeploy", params); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *VcVmV3RedeployResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ // No-op: removing the resource does not trigger a remote action.
+}
+
+func (r *VcVmV3RedeployResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/28_vc_vm_v3_resource.go b/universal_rebuild/internal/resources_gen/28_vc_vm_v3_resource.go
new file mode 100644
index 0000000..fdfdd1e
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/28_vc_vm_v3_resource.go
@@ -0,0 +1,583 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: vc_vm_v3
+// Service ID: 28
+
+var _ resource.Resource = &VcVmV3Resource{}
+var _ resource.ResourceWithModifyPlan = &VcVmV3Resource{}
+var _ resource.ResourceWithImportState = &VcVmV3Resource{}
+
+type VcVmV3Resource struct {
+ client *core.UniversalClient
+}
+
+type VcVmV3Model struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ AccessIpList types.String `tfsdk:"access_ip_list"`
+ AccessPortList types.String `tfsdk:"access_port_list"`
+ CloudInit types.String `tfsdk:"cloud_init"`
+ ImageVm types.String `tfsdk:"image_vm"`
+ IpSpaceName types.String `tfsdk:"ip_space_name"`
+ UserLogin types.String `tfsdk:"user_login"`
+ UserPublicKey types.String `tfsdk:"user_public_key"`
+ VappUid types.String `tfsdk:"vapp_uid"`
+ VmCpu types.Int64 `tfsdk:"vm_cpu"`
+ VmDisk types.Int64 `tfsdk:"vm_disk"`
+ VmName types.String `tfsdk:"vm_name"`
+ VmRam types.Int64 `tfsdk:"vm_ram"`
+ 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 NewVcVmV3Resource() resource.Resource {
+ return &VcVmV3Resource{}
+}
+
+func (r *VcVmV3Resource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_vc_vm_v3"
+}
+
+func (r *VcVmV3Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "access_ip_list": schema.StringAttribute{Optional: true, MarkdownDescription: "Формат массива
Каким адресам будет предоставлен доступ до вм
Требует выделенного внешнего IP
Если ничего не передано, то выставлено ["0.0.0.0/0"]"},
+ "access_port_list": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[\"22\"]"), MarkdownDescription: "По каким портам открыть доступ к ВМ.
Порты 22, 10050 проставляются автоматически
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX"},
+ "cloud_init": schema.StringAttribute{Optional: true, MarkdownDescription: "Можно передать создание дополнительных пользователей.
На текущий момент не реализовано выполнения в cloud-init, установки пакетов, выполнения команд и записи файлов. Не изменяется после создания."},
+ "image_vm": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."},
+ "ip_space_name": schema.StringAttribute{Required: true},
+ "user_login": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("myuser"), MarkdownDescription: "Учётка SSH Не изменяется после создания."},
+ "user_public_key": schema.StringAttribute{Required: true, MarkdownDescription: "Публичная часть SSH-Ключа для пользователя Не изменяется после создания."},
+ "vapp_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UI display_name for service_id=26 (mapped to UUID in core) Не изменяется после создания."},
+ "vm_cpu": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "шт"},
+ "vm_disk": schema.Int64Attribute{Optional: true, MarkdownDescription: "Основной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму"},
+ "vm_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Не изменяется после создания."},
+ "vm_ram": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Gb"},
+ "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 *VcVmV3Resource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *VcVmV3Model
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *VcVmV3Model
+ 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 VcVmV3Model
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ planChanged := false
+ if !plan.VappUid.IsNull() && !plan.VappUid.IsUnknown() {
+ resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, plan.VappUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error())
+ } else if resolvedVappUid != "" && resolvedVappUid != plan.VappUid.ValueString() {
+ plan.VappUid = types.StringValue(resolvedVappUid)
+ planChanged = true
+ }
+ }
+ if planChanged {
+ resp.Diagnostics.Append(resp.Plan.Set(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.CloudInit.IsNull() && !plan.CloudInit.IsUnknown() && !state.CloudInit.IsNull() && !state.CloudInit.IsUnknown() {
+ if plan.CloudInit.ValueString() != state.CloudInit.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить cloud_init", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ImageVm.IsNull() && !plan.ImageVm.IsUnknown() && !state.ImageVm.IsNull() && !state.ImageVm.IsUnknown() {
+ if plan.ImageVm.ValueString() != state.ImageVm.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить image_vm", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.UserLogin.IsNull() && !plan.UserLogin.IsUnknown() && !state.UserLogin.IsNull() && !state.UserLogin.IsUnknown() {
+ if plan.UserLogin.ValueString() != state.UserLogin.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить user_login", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.UserPublicKey.IsNull() && !plan.UserPublicKey.IsUnknown() && !state.UserPublicKey.IsNull() && !state.UserPublicKey.IsUnknown() {
+ if plan.UserPublicKey.ValueString() != state.UserPublicKey.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить user_public_key", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.VappUid.IsNull() && !plan.VappUid.IsUnknown() && !state.VappUid.IsNull() && !state.VappUid.IsUnknown() {
+ if plan.VappUid.ValueString() != state.VappUid.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить vapp_uid", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.VmName.IsNull() && !plan.VmName.IsUnknown() && !state.VmName.IsNull() && !state.VmName.IsUnknown() {
+ if plan.VmName.ValueString() != state.VmName.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить vm_name", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.ImageVm.IsNull() || config.ImageVm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "image_vm is required.")
+ return
+ }
+ if config.IpSpaceName.IsNull() || config.IpSpaceName.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.")
+ return
+ }
+ if config.UserPublicKey.IsNull() || config.UserPublicKey.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "user_public_key is required.")
+ return
+ }
+ if config.VappUid.IsNull() || config.VappUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "vapp_uid is required.")
+ return
+ }
+
+ if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() {
+ return
+ }
+ adoptExistingOnCreate := false
+ if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() {
+ adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool()
+ }
+ if !config.VappUid.IsNull() && !config.VappUid.IsUnknown() {
+ resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, config.VappUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error())
+ } else if resolvedVappUid != "" && resolvedVappUid != config.VappUid.ValueString() {
+ config.VappUid = types.StringValue(resolvedVappUid)
+ }
+ }
+ params := map[int]string{
+ 407: resources_core.FormatString(config.VappUid),
+ 408: resources_core.FormatString(config.VmName),
+ 409: resources_core.FormatInt64(config.VmCpu),
+ 410: resources_core.FormatInt64(config.VmRam),
+ 411: resources_core.FormatInt64(config.VmDisk),
+ 412: resources_core.FormatString(config.IpSpaceName),
+ 413: resources_core.FormatString(config.AccessIpList),
+ 414: resources_core.FormatString(config.ImageVm),
+ 415: resources_core.FormatString(config.CloudInit),
+ 416: resources_core.FormatString(config.UserLogin),
+ 417: resources_core.FormatString(config.UserPublicKey),
+ 448: resources_core.FormatString(config.AccessPortList),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 28, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *VcVmV3Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data VcVmV3Model
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.ImageVm.IsNull() || data.ImageVm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "image_vm is required.")
+ return
+ }
+ if data.IpSpaceName.IsNull() || data.IpSpaceName.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.")
+ return
+ }
+ if data.UserPublicKey.IsNull() || data.UserPublicKey.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "user_public_key is required.")
+ return
+ }
+ if data.VappUid.IsNull() || data.VappUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "vapp_uid is required.")
+ return
+ }
+ if !data.VappUid.IsNull() && !data.VappUid.IsUnknown() {
+ resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, data.VappUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if resolvedVappUid != "" && resolvedVappUid != data.VappUid.ValueString() {
+ data.VappUid = types.StringValue(resolvedVappUid)
+ }
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 28, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 407: resources_core.FormatString(data.VappUid),
+ 408: resources_core.FormatString(data.VmName),
+ 409: resources_core.FormatInt64(data.VmCpu),
+ 410: resources_core.FormatInt64(data.VmRam),
+ 411: resources_core.FormatInt64(data.VmDisk),
+ 412: resources_core.FormatString(data.IpSpaceName),
+ 413: resources_core.FormatString(data.AccessIpList),
+ 414: resources_core.FormatString(data.ImageVm),
+ 415: resources_core.FormatString(data.CloudInit),
+ 416: resources_core.FormatString(data.UserLogin),
+ 417: resources_core.FormatString(data.UserPublicKey),
+ 448: resources_core.FormatString(data.AccessPortList),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 28, 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, 28, 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: "accessIpList", Field: "AccessIpList", Type: "string"},
+ {Code: "accessPortList", Field: "AccessPortList", Type: "string"},
+ {Code: "cloudInit", Field: "CloudInit", Type: "string"},
+ {Code: "imageVm", Field: "ImageVm", Type: "string"},
+ {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"},
+ {Code: "userLogin", Field: "UserLogin", Type: "string"},
+ {Code: "userPublicKey", Field: "UserPublicKey", Type: "string"},
+ {Code: "vappUid", Field: "VappUid", Type: "string"},
+ {Code: "vmCpu", Field: "VmCpu", Type: "int64"},
+ {Code: "vmDisk", Field: "VmDisk", Type: "int64"},
+ {Code: "vmName", Field: "VmName", Type: "string"},
+ {Code: "vmRam", Field: "VmRam", Type: "int64"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !state.VappUid.IsNull() && !state.VappUid.IsUnknown() {
+ resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, state.VappUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error())
+ } else if resolvedVappUid != "" && resolvedVappUid != state.VappUid.ValueString() {
+ state.VappUid = types.StringValue(resolvedVappUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *VcVmV3Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state VcVmV3Model
+ 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(), 28, 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: "accessIpList", Field: "AccessIpList", Type: "string"},
+ {Code: "accessPortList", Field: "AccessPortList", Type: "string"},
+ {Code: "cloudInit", Field: "CloudInit", Type: "string"},
+ {Code: "imageVm", Field: "ImageVm", Type: "string"},
+ {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"},
+ {Code: "userLogin", Field: "UserLogin", Type: "string"},
+ {Code: "userPublicKey", Field: "UserPublicKey", Type: "string"},
+ {Code: "vappUid", Field: "VappUid", Type: "string"},
+ {Code: "vmCpu", Field: "VmCpu", Type: "int64"},
+ {Code: "vmDisk", Field: "VmDisk", Type: "int64"},
+ {Code: "vmName", Field: "VmName", Type: "string"},
+ {Code: "vmRam", Field: "VmRam", Type: "int64"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !newState.VappUid.IsNull() && !newState.VappUid.IsUnknown() {
+ resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, newState.VappUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error())
+ } else if resolvedVappUid != "" && resolvedVappUid != newState.VappUid.ValueString() {
+ newState.VappUid = types.StringValue(resolvedVappUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *VcVmV3Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan VcVmV3Model
+ var state VcVmV3Model
+ 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.VmCpu.IsNull() != state.VmCpu.IsNull() || plan.VmCpu.IsUnknown() != state.VmCpu.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.VmCpu.IsNull() && !plan.VmCpu.IsUnknown() && !state.VmCpu.IsNull() && !state.VmCpu.IsUnknown() {
+ if plan.VmCpu.ValueInt64() != state.VmCpu.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.VmRam.IsNull() != state.VmRam.IsNull() || plan.VmRam.IsUnknown() != state.VmRam.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.VmRam.IsNull() && !plan.VmRam.IsUnknown() && !state.VmRam.IsNull() && !state.VmRam.IsUnknown() {
+ if plan.VmRam.ValueInt64() != state.VmRam.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.VmDisk.IsNull() != state.VmDisk.IsNull() || plan.VmDisk.IsUnknown() != state.VmDisk.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.VmDisk.IsNull() && !plan.VmDisk.IsUnknown() && !state.VmDisk.IsNull() && !state.VmDisk.IsUnknown() {
+ if plan.VmDisk.ValueInt64() != state.VmDisk.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.IpSpaceName.IsNull() != state.IpSpaceName.IsNull() || plan.IpSpaceName.IsUnknown() != state.IpSpaceName.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.IpSpaceName.IsNull() && !plan.IpSpaceName.IsUnknown() && !state.IpSpaceName.IsNull() && !state.IpSpaceName.IsUnknown() {
+ if plan.IpSpaceName.ValueString() != state.IpSpaceName.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.AccessIpList.IsNull() != state.AccessIpList.IsNull() || plan.AccessIpList.IsUnknown() != state.AccessIpList.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.AccessIpList.IsNull() && !plan.AccessIpList.IsUnknown() && !state.AccessIpList.IsNull() && !state.AccessIpList.IsUnknown() {
+ if plan.AccessIpList.ValueString() != state.AccessIpList.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.AccessPortList.IsNull() != state.AccessPortList.IsNull() || plan.AccessPortList.IsUnknown() != state.AccessPortList.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.AccessPortList.IsNull() && !plan.AccessPortList.IsUnknown() && !state.AccessPortList.IsNull() && !state.AccessPortList.IsUnknown() {
+ if plan.AccessPortList.ValueString() != state.AccessPortList.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+
+ if !hasServiceParamChanges {
+ 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
+ }
+
+ params := map[int]string{
+ 493: resources_core.FormatInt64(plan.VmCpu),
+ 494: resources_core.FormatInt64(plan.VmRam),
+ 495: resources_core.FormatInt64(plan.VmDisk),
+ 496: resources_core.FormatString(plan.IpSpaceName),
+ 497: resources_core.FormatString(plan.AccessIpList),
+ 498: resources_core.FormatString(plan.AccessPortList),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 28, 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: "accessIpList", Field: "AccessIpList", Type: "string"},
+ {Code: "accessPortList", Field: "AccessPortList", Type: "string"},
+ {Code: "cloudInit", Field: "CloudInit", Type: "string"},
+ {Code: "imageVm", Field: "ImageVm", Type: "string"},
+ {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"},
+ {Code: "userLogin", Field: "UserLogin", Type: "string"},
+ {Code: "userPublicKey", Field: "UserPublicKey", Type: "string"},
+ {Code: "vappUid", Field: "VappUid", Type: "string"},
+ {Code: "vmCpu", Field: "VmCpu", Type: "int64"},
+ {Code: "vmDisk", Field: "VmDisk", Type: "int64"},
+ {Code: "vmName", Field: "VmName", Type: "string"},
+ {Code: "vmRam", Field: "VmRam", Type: "int64"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !state.VappUid.IsNull() && !state.VappUid.IsUnknown() {
+ resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, state.VappUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error())
+ } else if resolvedVappUid != "" && resolvedVappUid != state.VappUid.ValueString() {
+ state.VappUid = types.StringValue(resolvedVappUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *VcVmV3Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state VcVmV3Model
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *VcVmV3Resource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *VcVmV3Resource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/29_vc_vdc_group_add_vdc_action.go b/universal_rebuild/internal/resources_gen/29_vc_vdc_group_add_vdc_action.go
new file mode 100644
index 0000000..0ae19b7
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/29_vc_vdc_group_add_vdc_action.go
@@ -0,0 +1,138 @@
+package resources_gen
+
+import (
+ "context"
+ "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"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: vc_vdc_group
+// Action: add_vdc
+
+var _ resource.Resource = &VcVdcGroupAddVdcResource{}
+
+// VcVdcGroupAddVdcResource triggers a one-time action.
+type VcVdcGroupAddVdcResource struct {
+ client *core.UniversalClient
+}
+
+type VcVdcGroupAddVdcModel struct {
+ ID types.String `tfsdk:"id"`
+ VcVdcGroupID types.String `tfsdk:"vc_vdc_group_id"`
+ RunID types.String `tfsdk:"run_id"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ VdcUid types.String `tfsdk:"vdc_uid"`
+}
+
+func NewVcVdcGroupAddVdcResource() resource.Resource {
+ return &VcVdcGroupAddVdcResource{}
+}
+
+func (r *VcVdcGroupAddVdcResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_vc_vdc_group_add_vdc"
+}
+
+func (r *VcVdcGroupAddVdcResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "vc_vdc_group_id": schema.StringAttribute{Required: true},
+ "run_id": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "vdc_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UI display_name for service_id=21 (mapped to UUID in core)"},
+ }
+ resp.Schema = schema.Schema{Attributes: attrs}
+}
+
+func (r *VcVdcGroupAddVdcResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan VcVdcGroupAddVdcModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if plan.VdcUid.IsNull() || plan.VdcUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.")
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{
+ "vdcUid": resources_core.FormatString(plan.VdcUid),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "add_vdc", params, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "add_vdc", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *VcVdcGroupAddVdcResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state VcVdcGroupAddVdcModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *VcVdcGroupAddVdcResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan VcVdcGroupAddVdcModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{
+ "vdcUid": resources_core.FormatString(plan.VdcUid),
+ }
+
+ if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "add_vdc", params); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "add_vdc", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *VcVdcGroupAddVdcResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ // No-op: removing the resource does not trigger a remote action.
+}
+
+func (r *VcVdcGroupAddVdcResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/29_vc_vdc_group_reconcile_action.go b/universal_rebuild/internal/resources_gen/29_vc_vdc_group_reconcile_action.go
new file mode 100644
index 0000000..0676cc7
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/29_vc_vdc_group_reconcile_action.go
@@ -0,0 +1,128 @@
+package resources_gen
+
+import (
+ "context"
+ "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"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: vc_vdc_group
+// Action: reconcile
+
+var _ resource.Resource = &VcVdcGroupReconcileResource{}
+
+// VcVdcGroupReconcileResource triggers a one-time action.
+type VcVdcGroupReconcileResource struct {
+ client *core.UniversalClient
+}
+
+type VcVdcGroupReconcileModel struct {
+ ID types.String `tfsdk:"id"`
+ VcVdcGroupID types.String `tfsdk:"vc_vdc_group_id"`
+ RunID types.String `tfsdk:"run_id"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+}
+
+func NewVcVdcGroupReconcileResource() resource.Resource {
+ return &VcVdcGroupReconcileResource{}
+}
+
+func (r *VcVdcGroupReconcileResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_vc_vdc_group_reconcile"
+}
+
+func (r *VcVdcGroupReconcileResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "vc_vdc_group_id": schema.StringAttribute{Required: true},
+ "run_id": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ }
+ resp.Schema = schema.Schema{Attributes: attrs}
+}
+
+func (r *VcVdcGroupReconcileResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan VcVdcGroupReconcileModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{}
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "reconcile", params, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *VcVdcGroupReconcileResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state VcVdcGroupReconcileModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *VcVdcGroupReconcileResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan VcVdcGroupReconcileModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{}
+
+ if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "reconcile", params); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *VcVdcGroupReconcileResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ // No-op: removing the resource does not trigger a remote action.
+}
+
+func (r *VcVdcGroupReconcileResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/29_vc_vdc_group_remove_vdc_action.go b/universal_rebuild/internal/resources_gen/29_vc_vdc_group_remove_vdc_action.go
new file mode 100644
index 0000000..381161d
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/29_vc_vdc_group_remove_vdc_action.go
@@ -0,0 +1,138 @@
+package resources_gen
+
+import (
+ "context"
+ "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"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: vc_vdc_group
+// Action: remove_vdc
+
+var _ resource.Resource = &VcVdcGroupRemoveVdcResource{}
+
+// VcVdcGroupRemoveVdcResource triggers a one-time action.
+type VcVdcGroupRemoveVdcResource struct {
+ client *core.UniversalClient
+}
+
+type VcVdcGroupRemoveVdcModel struct {
+ ID types.String `tfsdk:"id"`
+ VcVdcGroupID types.String `tfsdk:"vc_vdc_group_id"`
+ RunID types.String `tfsdk:"run_id"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ VdcName types.String `tfsdk:"vdc_name"`
+}
+
+func NewVcVdcGroupRemoveVdcResource() resource.Resource {
+ return &VcVdcGroupRemoveVdcResource{}
+}
+
+func (r *VcVdcGroupRemoveVdcResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_vc_vdc_group_remove_vdc"
+}
+
+func (r *VcVdcGroupRemoveVdcResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "vc_vdc_group_id": schema.StringAttribute{Required: true},
+ "run_id": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "vdc_name": schema.StringAttribute{Required: true},
+ }
+ resp.Schema = schema.Schema{Attributes: attrs}
+}
+
+func (r *VcVdcGroupRemoveVdcResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan VcVdcGroupRemoveVdcModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if plan.VdcName.IsNull() || plan.VdcName.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "vdc_name is required.")
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{
+ "vdcName": resources_core.FormatString(plan.VdcName),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "remove_vdc", params, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "remove_vdc", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *VcVdcGroupRemoveVdcResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state VcVdcGroupRemoveVdcModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *VcVdcGroupRemoveVdcResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan VcVdcGroupRemoveVdcModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{
+ "vdcName": resources_core.FormatString(plan.VdcName),
+ }
+
+ if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "remove_vdc", params); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "remove_vdc", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *VcVdcGroupRemoveVdcResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ // No-op: removing the resource does not trigger a remote action.
+}
+
+func (r *VcVdcGroupRemoveVdcResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/29_vc_vdc_group_resource.go b/universal_rebuild/internal/resources_gen/29_vc_vdc_group_resource.go
new file mode 100644
index 0000000..f8f43fa
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/29_vc_vdc_group_resource.go
@@ -0,0 +1,389 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: vc_vdc_group
+// Service ID: 29
+
+var _ resource.Resource = &VcVdcGroupResource{}
+var _ resource.ResourceWithModifyPlan = &VcVdcGroupResource{}
+var _ resource.ResourceWithImportState = &VcVdcGroupResource{}
+
+type VcVdcGroupResource struct {
+ client *core.UniversalClient
+}
+
+type VcVdcGroupModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ VdcUid types.String `tfsdk:"vdc_uid"`
+ 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 NewVcVdcGroupResource() resource.Resource {
+ return &VcVdcGroupResource{}
+}
+
+func (r *VcVdcGroupResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_vc_vdc_group"
+}
+
+func (r *VcVdcGroupResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "vdc_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UI display_name for service_id=21 (mapped to UUID in core) Не изменяется после создания."},
+ "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)},
+ "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 *VcVdcGroupResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *VcVdcGroupModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *VcVdcGroupModel
+ 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 VcVdcGroupModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ planChanged := false
+ if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, plan.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error())
+ } else if resolvedVdcUid != "" && resolvedVdcUid != plan.VdcUid.ValueString() {
+ plan.VdcUid = types.StringValue(resolvedVdcUid)
+ planChanged = true
+ }
+ }
+ if planChanged {
+ resp.Diagnostics.Append(resp.Plan.Set(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.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() {
+ if plan.VdcUid.ValueString() != state.VdcUid.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить vdc_uid", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.VdcUid.IsNull() || config.VdcUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.")
+ return
+ }
+
+ if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() {
+ return
+ }
+ adoptExistingOnCreate := false
+ if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() {
+ adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool()
+ }
+ if !config.VdcUid.IsNull() && !config.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, config.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error())
+ } else if resolvedVdcUid != "" && resolvedVdcUid != config.VdcUid.ValueString() {
+ config.VdcUid = types.StringValue(resolvedVdcUid)
+ }
+ }
+ params := map[int]string{
+ 618: resources_core.FormatString(config.VdcUid),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 29, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *VcVdcGroupResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data VcVdcGroupModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.VdcUid.IsNull() || data.VdcUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.")
+ return
+ }
+ if !data.VdcUid.IsNull() && !data.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, data.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if resolvedVdcUid != "" && resolvedVdcUid != data.VdcUid.ValueString() {
+ data.VdcUid = types.StringValue(resolvedVdcUid)
+ }
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 29, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 618: resources_core.FormatString(data.VdcUid),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 29, 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, 29, 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: "vdcUid", Field: "VdcUid", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error())
+ } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() {
+ state.VdcUid = types.StringValue(resolvedVdcUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *VcVdcGroupResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state VcVdcGroupModel
+ 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(), 29, 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: "vdcUid", Field: "VdcUid", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !newState.VdcUid.IsNull() && !newState.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, newState.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error())
+ } else if resolvedVdcUid != "" && resolvedVdcUid != newState.VdcUid.ValueString() {
+ newState.VdcUid = types.StringValue(resolvedVdcUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *VcVdcGroupResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan VcVdcGroupModel
+ var state VcVdcGroupModel
+ 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 {
+ 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
+ }
+
+ params := map[int]string{}
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 29, 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: "vdcUid", Field: "VdcUid", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error())
+ } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() {
+ state.VdcUid = types.StringValue(resolvedVdcUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *VcVdcGroupResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state VcVdcGroupModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *VcVdcGroupResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *VcVdcGroupResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/32_vmpostgre_resource.go b/universal_rebuild/internal/resources_gen/32_vmpostgre_resource.go
new file mode 100644
index 0000000..11236dc
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/32_vmpostgre_resource.go
@@ -0,0 +1,594 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: vmpostgre
+// Service ID: 32
+
+var _ resource.Resource = &VmpostgreResource{}
+var _ resource.ResourceWithModifyPlan = &VmpostgreResource{}
+var _ resource.ResourceWithImportState = &VmpostgreResource{}
+
+type VmpostgreResource struct {
+ client *core.UniversalClient
+}
+
+type VmpostgreModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ NsxtUid types.String `tfsdk:"nsxt_uid"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+ UserDb types.String `tfsdk:"user_db"`
+ UserLogin types.String `tfsdk:"user_login"`
+ UserPassword types.String `tfsdk:"user_password"`
+ VdcUid types.String `tfsdk:"vdc_uid"`
+ VmUid types.String `tfsdk:"vm_uid"`
+ 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 NewVmpostgreResource() resource.Resource {
+ return &VmpostgreResource{}
+}
+
+func (r *VmpostgreResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_vmpostgre"
+}
+
+func (r *VmpostgreResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "nsxt_uid": schema.StringAttribute{Required: true, MarkdownDescription: "InstanceUid nsxt. Nsxt должен быть создан
Не изменяется после создания."},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Ресурсная платформа Не изменяется после создания."},
+ "user_db": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("servicedb"), MarkdownDescription: "Наименование Базы данных
Не изменяется после создания."},
+ "user_login": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("serviceuser"), MarkdownDescription: "Пользователь базы данных
Не изменяется после создания."},
+ "user_password": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("fj29gm48fm!d374mc9"), MarkdownDescription: "Пароль от доступа к Базе данных
Не изменяется после создания."},
+ "vdc_uid": schema.StringAttribute{Required: true, MarkdownDescription: "InstanceUid vdc. Vdc должен быть создан
Не изменяется после создания."},
+ "vm_uid": schema.StringAttribute{Required: true, MarkdownDescription: "InstanceUid ВМ. ВМ должна быть создана
Не изменяется после создания."},
+ "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)},
+ "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 *VmpostgreResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *VmpostgreModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *VmpostgreModel
+ 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 VmpostgreModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ planChanged := false
+ if !plan.NsxtUid.IsNull() && !plan.NsxtUid.IsUnknown() {
+ resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, plan.NsxtUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error())
+ } else if resolvedNsxtUid != "" && resolvedNsxtUid != plan.NsxtUid.ValueString() {
+ plan.NsxtUid = types.StringValue(resolvedNsxtUid)
+ planChanged = true
+ }
+ }
+ if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, plan.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error())
+ } else if resolvedVdcUid != "" && resolvedVdcUid != plan.VdcUid.ValueString() {
+ plan.VdcUid = types.StringValue(resolvedVdcUid)
+ planChanged = true
+ }
+ }
+ if !plan.VmUid.IsNull() && !plan.VmUid.IsUnknown() {
+ resolvedVmUid, err := r.client.ResolveRefSvcParamValue(ctx, 23, plan.VmUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vm_uid", err.Error())
+ } else if resolvedVmUid != "" && resolvedVmUid != plan.VmUid.ValueString() {
+ plan.VmUid = types.StringValue(resolvedVmUid)
+ planChanged = true
+ }
+ }
+ if planChanged {
+ resp.Diagnostics.Append(resp.Plan.Set(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.NsxtUid.IsNull() && !plan.NsxtUid.IsUnknown() && !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() {
+ if plan.NsxtUid.ValueString() != state.NsxtUid.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить nsxt_uid", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() {
+ if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.UserDb.IsNull() && !plan.UserDb.IsUnknown() && !state.UserDb.IsNull() && !state.UserDb.IsUnknown() {
+ if plan.UserDb.ValueString() != state.UserDb.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить user_db", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.UserLogin.IsNull() && !plan.UserLogin.IsUnknown() && !state.UserLogin.IsNull() && !state.UserLogin.IsUnknown() {
+ if plan.UserLogin.ValueString() != state.UserLogin.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить user_login", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.UserPassword.IsNull() && !plan.UserPassword.IsUnknown() && !state.UserPassword.IsNull() && !state.UserPassword.IsUnknown() {
+ if plan.UserPassword.ValueString() != state.UserPassword.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить user_password", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() {
+ if plan.VdcUid.ValueString() != state.VdcUid.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить vdc_uid", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.VmUid.IsNull() && !plan.VmUid.IsUnknown() && !state.VmUid.IsNull() && !state.VmUid.IsUnknown() {
+ if plan.VmUid.ValueString() != state.VmUid.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить vm_uid", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.NsxtUid.IsNull() || config.NsxtUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "nsxt_uid is required.")
+ return
+ }
+ if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+ if config.VdcUid.IsNull() || config.VdcUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.")
+ return
+ }
+ if config.VmUid.IsNull() || config.VmUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "vm_uid is required.")
+ return
+ }
+
+ if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() {
+ return
+ }
+ adoptExistingOnCreate := false
+ if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() {
+ adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool()
+ }
+ if !config.NsxtUid.IsNull() && !config.NsxtUid.IsUnknown() {
+ resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, config.NsxtUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error())
+ } else if resolvedNsxtUid != "" && resolvedNsxtUid != config.NsxtUid.ValueString() {
+ config.NsxtUid = types.StringValue(resolvedNsxtUid)
+ }
+ }
+ if !config.VdcUid.IsNull() && !config.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, config.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error())
+ } else if resolvedVdcUid != "" && resolvedVdcUid != config.VdcUid.ValueString() {
+ config.VdcUid = types.StringValue(resolvedVdcUid)
+ }
+ }
+ if !config.VmUid.IsNull() && !config.VmUid.IsUnknown() {
+ resolvedVmUid, err := r.client.ResolveRefSvcParamValue(ctx, 23, config.VmUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vm_uid", err.Error())
+ } else if resolvedVmUid != "" && resolvedVmUid != config.VmUid.ValueString() {
+ config.VmUid = types.StringValue(resolvedVmUid)
+ }
+ }
+ params := map[int]string{
+ 43: resources_core.FormatString(config.VdcUid),
+ 44: resources_core.FormatString(config.NsxtUid),
+ 45: resources_core.FormatString(config.VmUid),
+ 46: resources_core.FormatString(config.UserDb),
+ 47: resources_core.FormatString(config.UserLogin),
+ 48: resources_core.FormatString(config.UserPassword),
+ 859: resources_core.FormatString(config.ResourceRealm),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 32, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *VmpostgreResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data VmpostgreModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.NsxtUid.IsNull() || data.NsxtUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "nsxt_uid is required.")
+ return
+ }
+ if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+ if data.VdcUid.IsNull() || data.VdcUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.")
+ return
+ }
+ if data.VmUid.IsNull() || data.VmUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "vm_uid is required.")
+ return
+ }
+ if !data.NsxtUid.IsNull() && !data.NsxtUid.IsUnknown() {
+ resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, data.NsxtUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if resolvedNsxtUid != "" && resolvedNsxtUid != data.NsxtUid.ValueString() {
+ data.NsxtUid = types.StringValue(resolvedNsxtUid)
+ }
+ }
+ if !data.VdcUid.IsNull() && !data.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, data.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if resolvedVdcUid != "" && resolvedVdcUid != data.VdcUid.ValueString() {
+ data.VdcUid = types.StringValue(resolvedVdcUid)
+ }
+ }
+ if !data.VmUid.IsNull() && !data.VmUid.IsUnknown() {
+ resolvedVmUid, err := r.client.ResolveRefSvcParamValue(ctx, 23, data.VmUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if resolvedVmUid != "" && resolvedVmUid != data.VmUid.ValueString() {
+ data.VmUid = types.StringValue(resolvedVmUid)
+ }
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 32, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 43: resources_core.FormatString(data.VdcUid),
+ 44: resources_core.FormatString(data.NsxtUid),
+ 45: resources_core.FormatString(data.VmUid),
+ 46: resources_core.FormatString(data.UserDb),
+ 47: resources_core.FormatString(data.UserLogin),
+ 48: resources_core.FormatString(data.UserPassword),
+ 859: resources_core.FormatString(data.ResourceRealm),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 32, 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, 32, 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: "nsxtUid", Field: "NsxtUid", Type: "string"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ {Code: "userDb", Field: "UserDb", Type: "string"},
+ {Code: "userLogin", Field: "UserLogin", Type: "string"},
+ {Code: "userPassword", Field: "UserPassword", Type: "string"},
+ {Code: "vdcUid", Field: "VdcUid", Type: "string"},
+ {Code: "vmUid", Field: "VmUid", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() {
+ resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, state.NsxtUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error())
+ } else if resolvedNsxtUid != "" && resolvedNsxtUid != state.NsxtUid.ValueString() {
+ state.NsxtUid = types.StringValue(resolvedNsxtUid)
+ }
+ }
+ if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error())
+ } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() {
+ state.VdcUid = types.StringValue(resolvedVdcUid)
+ }
+ }
+ if !state.VmUid.IsNull() && !state.VmUid.IsUnknown() {
+ resolvedVmUid, err := r.client.ResolveRefSvcParamValue(ctx, 23, state.VmUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vm_uid", err.Error())
+ } else if resolvedVmUid != "" && resolvedVmUid != state.VmUid.ValueString() {
+ state.VmUid = types.StringValue(resolvedVmUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *VmpostgreResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state VmpostgreModel
+ 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(), 32, 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: "nsxtUid", Field: "NsxtUid", Type: "string"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ {Code: "userDb", Field: "UserDb", Type: "string"},
+ {Code: "userLogin", Field: "UserLogin", Type: "string"},
+ {Code: "userPassword", Field: "UserPassword", Type: "string"},
+ {Code: "vdcUid", Field: "VdcUid", Type: "string"},
+ {Code: "vmUid", Field: "VmUid", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !newState.NsxtUid.IsNull() && !newState.NsxtUid.IsUnknown() {
+ resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, newState.NsxtUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error())
+ } else if resolvedNsxtUid != "" && resolvedNsxtUid != newState.NsxtUid.ValueString() {
+ newState.NsxtUid = types.StringValue(resolvedNsxtUid)
+ }
+ }
+ if !newState.VdcUid.IsNull() && !newState.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, newState.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error())
+ } else if resolvedVdcUid != "" && resolvedVdcUid != newState.VdcUid.ValueString() {
+ newState.VdcUid = types.StringValue(resolvedVdcUid)
+ }
+ }
+ if !newState.VmUid.IsNull() && !newState.VmUid.IsUnknown() {
+ resolvedVmUid, err := r.client.ResolveRefSvcParamValue(ctx, 23, newState.VmUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vm_uid", err.Error())
+ } else if resolvedVmUid != "" && resolvedVmUid != newState.VmUid.ValueString() {
+ newState.VmUid = types.StringValue(resolvedVmUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *VmpostgreResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan VmpostgreModel
+ var state VmpostgreModel
+ 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 {
+ 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
+ }
+
+ params := map[int]string{}
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 32, 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: "nsxtUid", Field: "NsxtUid", Type: "string"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ {Code: "userDb", Field: "UserDb", Type: "string"},
+ {Code: "userLogin", Field: "UserLogin", Type: "string"},
+ {Code: "userPassword", Field: "UserPassword", Type: "string"},
+ {Code: "vdcUid", Field: "VdcUid", Type: "string"},
+ {Code: "vmUid", Field: "VmUid", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() {
+ resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, state.NsxtUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error())
+ } else if resolvedNsxtUid != "" && resolvedNsxtUid != state.NsxtUid.ValueString() {
+ state.NsxtUid = types.StringValue(resolvedNsxtUid)
+ }
+ }
+ if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() {
+ resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error())
+ } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() {
+ state.VdcUid = types.StringValue(resolvedVdcUid)
+ }
+ }
+ if !state.VmUid.IsNull() && !state.VmUid.IsUnknown() {
+ resolvedVmUid, err := r.client.ResolveRefSvcParamValue(ctx, 23, state.VmUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve vm_uid", err.Error())
+ } else if resolvedVmUid != "" && resolvedVmUid != state.VmUid.ValueString() {
+ state.VmUid = types.StringValue(resolvedVmUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *VmpostgreResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state VmpostgreModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *VmpostgreResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *VmpostgreResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/50_nextcloud_resource.go b/universal_rebuild/internal/resources_gen/50_nextcloud_resource.go
new file mode 100644
index 0000000..5509d65
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/50_nextcloud_resource.go
@@ -0,0 +1,575 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: nextcloud
+// Service ID: 50
+
+var _ resource.Resource = &NextcloudResource{}
+var _ resource.ResourceWithModifyPlan = &NextcloudResource{}
+var _ resource.ResourceWithImportState = &NextcloudResource{}
+
+type NextcloudResource struct {
+ client *core.UniversalClient
+}
+
+type NextcloudModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ AppVersion types.String `tfsdk:"app_version"`
+ DocumentServer types.String `tfsdk:"document_server"`
+ Domain types.String `tfsdk:"domain"`
+ PsqlUid types.String `tfsdk:"psql_uid"`
+ RedisUid types.String `tfsdk:"redis_uid"`
+ ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"`
+ ResourceDisk types.Int64 `tfsdk:"resource_disk"`
+ ResourceInstances types.Int64 `tfsdk:"resource_instances"`
+ ResourceMemory types.Int64 `tfsdk:"resource_memory"`
+ 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 NewNextcloudResource() resource.Resource {
+ return &NextcloudResource{}
+}
+
+func (r *NextcloudResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_nextcloud"
+}
+
+func (r *NextcloudResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("32.0.1")},
+ "document_server": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("collabora"), MarkdownDescription: "Выбор сервера документов (onlyoffice)/(collabora). onlyoffice пока не доступен
Размер пода collabora:
1.8 ядра. 2Gi ОЗУ Не изменяется после создания."},
+ "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."},
+ "psql_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UI display_name for service_id=90 (mapped to UUID in core) Не изменяется после создания."},
+ "redis_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UI display_name for service_id=91 (mapped to UUID in core) Не изменяется после создания."},
+ "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1000), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1 ядро = 1000 Mili"},
+ "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(2), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)
Диск не может быть меньше 2G (!)"},
+ "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов
Не может пока быть больше одного, так как нужны SC под RWMany"},
+ "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1024), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes)"},
+ "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 *NextcloudResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *NextcloudModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *NextcloudModel
+ 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 NextcloudModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ planChanged := false
+ if !plan.PsqlUid.IsNull() && !plan.PsqlUid.IsUnknown() {
+ resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, plan.PsqlUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error())
+ } else if resolvedPsqlUid != "" && resolvedPsqlUid != plan.PsqlUid.ValueString() {
+ plan.PsqlUid = types.StringValue(resolvedPsqlUid)
+ planChanged = true
+ }
+ }
+ if !plan.RedisUid.IsNull() && !plan.RedisUid.IsUnknown() {
+ resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, plan.RedisUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve redis_uid", err.Error())
+ } else if resolvedRedisUid != "" && resolvedRedisUid != plan.RedisUid.ValueString() {
+ plan.RedisUid = types.StringValue(resolvedRedisUid)
+ planChanged = true
+ }
+ }
+ if planChanged {
+ resp.Diagnostics.Append(resp.Plan.Set(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.DocumentServer.IsNull() && !plan.DocumentServer.IsUnknown() && !state.DocumentServer.IsNull() && !state.DocumentServer.IsUnknown() {
+ if plan.DocumentServer.ValueString() != state.DocumentServer.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить document_server", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() {
+ if plan.Domain.ValueString() != state.Domain.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.PsqlUid.IsNull() && !plan.PsqlUid.IsUnknown() && !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() {
+ if plan.PsqlUid.ValueString() != state.PsqlUid.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить psql_uid", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.RedisUid.IsNull() && !plan.RedisUid.IsUnknown() && !state.RedisUid.IsNull() && !state.RedisUid.IsUnknown() {
+ if plan.RedisUid.ValueString() != state.RedisUid.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить redis_uid", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.PsqlUid.IsNull() || config.PsqlUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "psql_uid is required.")
+ return
+ }
+ if config.RedisUid.IsNull() || config.RedisUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "redis_uid is required.")
+ return
+ }
+
+ if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() {
+ return
+ }
+ adoptExistingOnCreate := false
+ if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() {
+ adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool()
+ }
+ if !config.PsqlUid.IsNull() && !config.PsqlUid.IsUnknown() {
+ resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, config.PsqlUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error())
+ } else if resolvedPsqlUid != "" && resolvedPsqlUid != config.PsqlUid.ValueString() {
+ config.PsqlUid = types.StringValue(resolvedPsqlUid)
+ }
+ }
+ if !config.RedisUid.IsNull() && !config.RedisUid.IsUnknown() {
+ resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, config.RedisUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve redis_uid", err.Error())
+ } else if resolvedRedisUid != "" && resolvedRedisUid != config.RedisUid.ValueString() {
+ config.RedisUid = types.StringValue(resolvedRedisUid)
+ }
+ }
+ params := map[int]string{
+ 21: resources_core.FormatString(config.Domain),
+ 99: resources_core.FormatInt64(config.ResourceCPU),
+ 100: resources_core.FormatInt64(config.ResourceMemory),
+ 101: resources_core.FormatInt64(config.ResourceDisk),
+ 192: resources_core.FormatString(config.DocumentServer),
+ 470: resources_core.FormatInt64(config.ResourceInstances),
+ 564: resources_core.FormatString(config.PsqlUid),
+ 569: resources_core.FormatString(config.AppVersion),
+ 570: resources_core.FormatString(config.RedisUid),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 50, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *NextcloudResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data NextcloudModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.PsqlUid.IsNull() || data.PsqlUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "psql_uid is required.")
+ return
+ }
+ if data.RedisUid.IsNull() || data.RedisUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "redis_uid is required.")
+ return
+ }
+ if !data.PsqlUid.IsNull() && !data.PsqlUid.IsUnknown() {
+ resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, data.PsqlUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if resolvedPsqlUid != "" && resolvedPsqlUid != data.PsqlUid.ValueString() {
+ data.PsqlUid = types.StringValue(resolvedPsqlUid)
+ }
+ }
+ if !data.RedisUid.IsNull() && !data.RedisUid.IsUnknown() {
+ resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, data.RedisUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if resolvedRedisUid != "" && resolvedRedisUid != data.RedisUid.ValueString() {
+ data.RedisUid = types.StringValue(resolvedRedisUid)
+ }
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 50, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 21: resources_core.FormatString(data.Domain),
+ 99: resources_core.FormatInt64(data.ResourceCPU),
+ 100: resources_core.FormatInt64(data.ResourceMemory),
+ 101: resources_core.FormatInt64(data.ResourceDisk),
+ 192: resources_core.FormatString(data.DocumentServer),
+ 470: resources_core.FormatInt64(data.ResourceInstances),
+ 564: resources_core.FormatString(data.PsqlUid),
+ 569: resources_core.FormatString(data.AppVersion),
+ 570: resources_core.FormatString(data.RedisUid),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 50, 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, 50, 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: "appVersion", Field: "AppVersion", Type: "string"},
+ {Code: "documentServer", Field: "DocumentServer", Type: "string"},
+ {Code: "domain", Field: "Domain", Type: "string"},
+ {Code: "psqlUid", Field: "PsqlUid", Type: "string"},
+ {Code: "redisUid", Field: "RedisUid", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() {
+ resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, state.PsqlUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error())
+ } else if resolvedPsqlUid != "" && resolvedPsqlUid != state.PsqlUid.ValueString() {
+ state.PsqlUid = types.StringValue(resolvedPsqlUid)
+ }
+ }
+ if !state.RedisUid.IsNull() && !state.RedisUid.IsUnknown() {
+ resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, state.RedisUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve redis_uid", err.Error())
+ } else if resolvedRedisUid != "" && resolvedRedisUid != state.RedisUid.ValueString() {
+ state.RedisUid = types.StringValue(resolvedRedisUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *NextcloudResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state NextcloudModel
+ 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(), 50, 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: "appVersion", Field: "AppVersion", Type: "string"},
+ {Code: "documentServer", Field: "DocumentServer", Type: "string"},
+ {Code: "domain", Field: "Domain", Type: "string"},
+ {Code: "psqlUid", Field: "PsqlUid", Type: "string"},
+ {Code: "redisUid", Field: "RedisUid", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !newState.PsqlUid.IsNull() && !newState.PsqlUid.IsUnknown() {
+ resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, newState.PsqlUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error())
+ } else if resolvedPsqlUid != "" && resolvedPsqlUid != newState.PsqlUid.ValueString() {
+ newState.PsqlUid = types.StringValue(resolvedPsqlUid)
+ }
+ }
+ if !newState.RedisUid.IsNull() && !newState.RedisUid.IsUnknown() {
+ resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, newState.RedisUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve redis_uid", err.Error())
+ } else if resolvedRedisUid != "" && resolvedRedisUid != newState.RedisUid.ValueString() {
+ newState.RedisUid = types.StringValue(resolvedRedisUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *NextcloudResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan NextcloudModel
+ var state NextcloudModel
+ 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.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() {
+ if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() {
+ if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() {
+ if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() {
+ if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.AppVersion.IsNull() != state.AppVersion.IsNull() || plan.AppVersion.IsUnknown() != state.AppVersion.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() {
+ if plan.AppVersion.ValueString() != state.AppVersion.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+
+ if !hasServiceParamChanges {
+ 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
+ }
+
+ params := map[int]string{
+ 178: resources_core.FormatInt64(plan.ResourceCPU),
+ 179: resources_core.FormatInt64(plan.ResourceMemory),
+ 180: resources_core.FormatInt64(plan.ResourceDisk),
+ 547: resources_core.FormatInt64(plan.ResourceInstances),
+ 571: resources_core.FormatString(plan.AppVersion),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 50, 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: "appVersion", Field: "AppVersion", Type: "string"},
+ {Code: "documentServer", Field: "DocumentServer", Type: "string"},
+ {Code: "domain", Field: "Domain", Type: "string"},
+ {Code: "psqlUid", Field: "PsqlUid", Type: "string"},
+ {Code: "redisUid", Field: "RedisUid", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() {
+ resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, state.PsqlUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error())
+ } else if resolvedPsqlUid != "" && resolvedPsqlUid != state.PsqlUid.ValueString() {
+ state.PsqlUid = types.StringValue(resolvedPsqlUid)
+ }
+ }
+ if !state.RedisUid.IsNull() && !state.RedisUid.IsUnknown() {
+ resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, state.RedisUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve redis_uid", err.Error())
+ } else if resolvedRedisUid != "" && resolvedRedisUid != state.RedisUid.ValueString() {
+ state.RedisUid = types.StringValue(resolvedRedisUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *NextcloudResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state NextcloudModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *NextcloudResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *NextcloudResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/50_nextcloud_restart_action.go b/universal_rebuild/internal/resources_gen/50_nextcloud_restart_action.go
new file mode 100644
index 0000000..7568ac5
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/50_nextcloud_restart_action.go
@@ -0,0 +1,128 @@
+package resources_gen
+
+import (
+ "context"
+ "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"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: nextcloud
+// Action: restart
+
+var _ resource.Resource = &NextcloudRestartResource{}
+
+// NextcloudRestartResource triggers a one-time action.
+type NextcloudRestartResource struct {
+ client *core.UniversalClient
+}
+
+type NextcloudRestartModel struct {
+ ID types.String `tfsdk:"id"`
+ NextcloudID types.String `tfsdk:"nextcloud_id"`
+ RunID types.String `tfsdk:"run_id"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+}
+
+func NewNextcloudRestartResource() resource.Resource {
+ return &NextcloudRestartResource{}
+}
+
+func (r *NextcloudRestartResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_nextcloud_restart"
+}
+
+func (r *NextcloudRestartResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "nextcloud_id": schema.StringAttribute{Required: true},
+ "run_id": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ }
+ resp.Schema = schema.Schema{Attributes: attrs}
+}
+
+func (r *NextcloudRestartResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan NextcloudRestartModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.NextcloudID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{}
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "restart", params, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *NextcloudRestartResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state NextcloudRestartModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *NextcloudRestartResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan NextcloudRestartModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.NextcloudID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{}
+
+ if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "restart", params); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *NextcloudRestartResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ // No-op: removing the resource does not trigger a remote action.
+}
+
+func (r *NextcloudRestartResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/81_superset_resource.go b/universal_rebuild/internal/resources_gen/81_superset_resource.go
new file mode 100644
index 0000000..ab9d101
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/81_superset_resource.go
@@ -0,0 +1,411 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: superset
+// Service ID: 81
+
+var _ resource.Resource = &SupersetResource{}
+var _ resource.ResourceWithModifyPlan = &SupersetResource{}
+var _ resource.ResourceWithImportState = &SupersetResource{}
+
+type SupersetResource struct {
+ client *core.UniversalClient
+}
+
+type SupersetModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ Domain types.String `tfsdk:"domain"`
+ Emails types.String `tfsdk:"emails"`
+ ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"`
+ ResourceDisk types.Int64 `tfsdk:"resource_disk"`
+ ResourceInstances types.Int64 `tfsdk:"resource_instances"`
+ ResourceMemory types.Int64 `tfsdk:"resource_memory"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+ 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 NewSupersetResource() resource.Resource {
+ return &SupersetResource{}
+}
+
+func (r *SupersetResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_superset"
+}
+
+func (r *SupersetResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."},
+ "emails": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("testuser1"), MarkdownDescription: "Учётная запись, которой будут выданы админские права. В формате email [ну не совсем. Для доменных учетных записей - без доменного суффикса]. Обязана находиться в Keycloak. Можно передавать несколько через пробел Не изменяется после создания."},
+ "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1000 Mili = 1 ядро Не изменяется после создания."},
+ "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes) Не изменяется после создания."},
+ "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."},
+ "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes) Не изменяется после создания."},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."},
+ "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)},
+ "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 *SupersetResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *SupersetModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *SupersetModel
+ 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 SupersetModel
+ 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.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() {
+ if plan.Domain.ValueString() != state.Domain.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.Emails.IsNull() && !plan.Emails.IsUnknown() && !state.Emails.IsNull() && !state.Emails.IsUnknown() {
+ if plan.Emails.ValueString() != state.Emails.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить emails", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() {
+ if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() {
+ if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() {
+ if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() {
+ if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() {
+ if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ 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{
+ 14: resources_core.FormatString(config.Domain),
+ 20: resources_core.FormatString(config.Emails),
+ 96: resources_core.FormatInt64(config.ResourceCPU),
+ 97: resources_core.FormatInt64(config.ResourceMemory),
+ 98: resources_core.FormatInt64(config.ResourceDisk),
+ 109: resources_core.FormatString(config.ResourceRealm),
+ 227: resources_core.FormatInt64(config.ResourceInstances),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 81, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *SupersetResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data SupersetModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 81, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 14: resources_core.FormatString(data.Domain),
+ 20: resources_core.FormatString(data.Emails),
+ 96: resources_core.FormatInt64(data.ResourceCPU),
+ 97: resources_core.FormatInt64(data.ResourceMemory),
+ 98: resources_core.FormatInt64(data.ResourceDisk),
+ 109: resources_core.FormatString(data.ResourceRealm),
+ 227: resources_core.FormatInt64(data.ResourceInstances),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 81, 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, 81, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "emails", Field: "Emails", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *SupersetResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state SupersetModel
+ 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(), 81, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "emails", Field: "Emails", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *SupersetResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan SupersetModel
+ var state SupersetModel
+ 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 {
+ 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
+ }
+
+ params := map[int]string{}
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 81, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "emails", Field: "Emails", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *SupersetResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state SupersetModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *SupersetResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *SupersetResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/82_harbor_resource.go b/universal_rebuild/internal/resources_gen/82_harbor_resource.go
new file mode 100644
index 0000000..4e1e3e3
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/82_harbor_resource.go
@@ -0,0 +1,440 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: harbor
+// Service ID: 82
+
+var _ resource.Resource = &HarborResource{}
+var _ resource.ResourceWithModifyPlan = &HarborResource{}
+var _ resource.ResourceWithImportState = &HarborResource{}
+
+type HarborResource struct {
+ client *core.UniversalClient
+}
+
+type HarborModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ Domain types.String `tfsdk:"domain"`
+ Emails types.String `tfsdk:"emails"`
+ ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"`
+ ResourceInstances types.Int64 `tfsdk:"resource_instances"`
+ ResourceMemory types.Int64 `tfsdk:"resource_memory"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+ S3Uid types.String `tfsdk:"s3_uid"`
+ 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 NewHarborResource() resource.Resource {
+ return &HarborResource{}
+}
+
+func (r *HarborResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_harbor"
+}
+
+func (r *HarborResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."},
+ "emails": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("testuser1"), MarkdownDescription: "Учётная запись, которой будут выданы админские права. Обязана находиться в Keycloak. Можно передавать несколько через пробел Не изменяется после создания."},
+ "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(100), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро Не изменяется после создания."},
+ "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."},
+ "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(200), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes) Не изменяется после создания."},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."},
+ "s3_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UUID экземпляра услуги S3 Не изменяется после создания."},
+ "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)},
+ "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 *HarborResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *HarborModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *HarborModel
+ 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 HarborModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ planChanged := false
+ if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() {
+ resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, plan.S3Uid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error())
+ } else if resolvedS3Uid != "" && resolvedS3Uid != plan.S3Uid.ValueString() {
+ plan.S3Uid = types.StringValue(resolvedS3Uid)
+ planChanged = true
+ }
+ }
+ if planChanged {
+ resp.Diagnostics.Append(resp.Plan.Set(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.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() {
+ if plan.Domain.ValueString() != state.Domain.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.Emails.IsNull() && !plan.Emails.IsUnknown() && !state.Emails.IsNull() && !state.Emails.IsUnknown() {
+ if plan.Emails.ValueString() != state.Emails.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить emails", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() {
+ if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() {
+ if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() {
+ if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() {
+ if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() && !state.S3Uid.IsNull() && !state.S3Uid.IsUnknown() {
+ if plan.S3Uid.ValueString() != state.S3Uid.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить s3_uid", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+ if config.S3Uid.IsNull() || config.S3Uid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.")
+ return
+ }
+
+ if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() {
+ return
+ }
+ adoptExistingOnCreate := false
+ if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() {
+ adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool()
+ }
+ if !config.S3Uid.IsNull() && !config.S3Uid.IsUnknown() {
+ resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, config.S3Uid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error())
+ } else if resolvedS3Uid != "" && resolvedS3Uid != config.S3Uid.ValueString() {
+ config.S3Uid = types.StringValue(resolvedS3Uid)
+ }
+ }
+ params := map[int]string{
+ 16: resources_core.FormatString(config.Domain),
+ 17: resources_core.FormatString(config.Emails),
+ 110: resources_core.FormatString(config.ResourceRealm),
+ 228: resources_core.FormatInt64(config.ResourceCPU),
+ 229: resources_core.FormatInt64(config.ResourceMemory),
+ 230: resources_core.FormatInt64(config.ResourceInstances),
+ 231: resources_core.FormatString(config.S3Uid),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 82, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *HarborResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data HarborModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+ if data.S3Uid.IsNull() || data.S3Uid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.")
+ return
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 82, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 16: resources_core.FormatString(data.Domain),
+ 17: resources_core.FormatString(data.Emails),
+ 110: resources_core.FormatString(data.ResourceRealm),
+ 228: resources_core.FormatInt64(data.ResourceCPU),
+ 229: resources_core.FormatInt64(data.ResourceMemory),
+ 230: resources_core.FormatInt64(data.ResourceInstances),
+ 231: resources_core.FormatString(data.S3Uid),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 82, 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, 82, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "emails", Field: "Emails", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *HarborResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state HarborModel
+ 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(), 82, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "emails", Field: "Emails", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *HarborResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan HarborModel
+ var state HarborModel
+ 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 {
+ 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
+ }
+
+ params := map[int]string{}
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 82, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "emails", Field: "Emails", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *HarborResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state HarborModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *HarborResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *HarborResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/88_k8s_ziti_controller_resource.go b/universal_rebuild/internal/resources_gen/88_k8s_ziti_controller_resource.go
new file mode 100644
index 0000000..4ff2545
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/88_k8s_ziti_controller_resource.go
@@ -0,0 +1,398 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: k8s_ziti_controller
+// Service ID: 88
+
+var _ resource.Resource = &K8sZitiControllerResource{}
+var _ resource.ResourceWithModifyPlan = &K8sZitiControllerResource{}
+var _ resource.ResourceWithImportState = &K8sZitiControllerResource{}
+
+type K8sZitiControllerResource struct {
+ client *core.UniversalClient
+}
+
+type K8sZitiControllerModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ Domain types.String `tfsdk:"domain"`
+ ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"`
+ ResourceDisk types.Int64 `tfsdk:"resource_disk"`
+ ResourceInstances types.Int64 `tfsdk:"resource_instances"`
+ ResourceMemory types.Int64 `tfsdk:"resource_memory"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+ 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 NewK8sZitiControllerResource() resource.Resource {
+ return &K8sZitiControllerResource{}
+}
+
+func (r *K8sZitiControllerResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_k8s_ziti_controller"
+}
+
+func (r *K8sZitiControllerResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."},
+ "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(300), MarkdownDescription: "Квота ядра пода (milicores) Не изменяется после создания."},
+ "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes) Не изменяется после создания."},
+ "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."},
+ "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (MBytes) Не изменяется после создания."},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."},
+ "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)},
+ "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 *K8sZitiControllerResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *K8sZitiControllerModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *K8sZitiControllerModel
+ 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 K8sZitiControllerModel
+ 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.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() {
+ if plan.Domain.ValueString() != state.Domain.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() {
+ if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() {
+ if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() {
+ if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() {
+ if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() {
+ if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ 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{
+ 294: resources_core.FormatInt64(config.ResourceCPU),
+ 295: resources_core.FormatInt64(config.ResourceMemory),
+ 296: resources_core.FormatInt64(config.ResourceDisk),
+ 297: resources_core.FormatInt64(config.ResourceInstances),
+ 298: resources_core.FormatString(config.ResourceRealm),
+ 299: resources_core.FormatString(config.Domain),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 88, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *K8sZitiControllerResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data K8sZitiControllerModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 88, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 294: resources_core.FormatInt64(data.ResourceCPU),
+ 295: resources_core.FormatInt64(data.ResourceMemory),
+ 296: resources_core.FormatInt64(data.ResourceDisk),
+ 297: resources_core.FormatInt64(data.ResourceInstances),
+ 298: resources_core.FormatString(data.ResourceRealm),
+ 299: resources_core.FormatString(data.Domain),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 88, 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, 88, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *K8sZitiControllerResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state K8sZitiControllerModel
+ 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(), 88, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *K8sZitiControllerResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan K8sZitiControllerModel
+ var state K8sZitiControllerModel
+ 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 {
+ 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
+ }
+
+ params := map[int]string{}
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 88, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *K8sZitiControllerResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state K8sZitiControllerModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *K8sZitiControllerResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *K8sZitiControllerResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/89_flask_resource.go b/universal_rebuild/internal/resources_gen/89_flask_resource.go
new file mode 100644
index 0000000..10cf82a
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/89_flask_resource.go
@@ -0,0 +1,445 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: flask
+// Service ID: 89
+
+var _ resource.Resource = &FlaskResource{}
+var _ resource.ResourceWithModifyPlan = &FlaskResource{}
+var _ resource.ResourceWithImportState = &FlaskResource{}
+
+type FlaskResource struct {
+ client *core.UniversalClient
+}
+
+type FlaskModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ Domain types.String `tfsdk:"domain"`
+ GitPath types.String `tfsdk:"git_path"`
+ HealthPath types.String `tfsdk:"health_path"`
+ JsonEnv types.String `tfsdk:"json_env"`
+ ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"`
+ ResourceInstances types.Int64 `tfsdk:"resource_instances"`
+ ResourceMemory types.Int64 `tfsdk:"resource_memory"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+ 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 NewFlaskResource() resource.Resource {
+ return &FlaskResource{}
+}
+
+func (r *FlaskResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_flask"
+}
+
+func (r *FlaskResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."},
+ "git_path": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("https://github.com/Foxyhhd/Baldurs-Gate-test.git"), MarkdownDescription: "Путь до Git, который будет webroot для сайта"},
+ "health_path": schema.StringAttribute{Optional: true, MarkdownDescription: "Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код Не изменяется после создания."},
+ "json_env": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{ "param": "value" }"), MarkdownDescription: "Массив переменных, будут переданы в env приложения"},
+ "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(300), MarkdownDescription: "Квота ядра пода (milicores)"},
+ "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"},
+ "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(256), MarkdownDescription: "Квота памяти пода (MBytes)"},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."},
+ "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 *FlaskResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *FlaskModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *FlaskModel
+ 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 FlaskModel
+ 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.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() {
+ if plan.Domain.ValueString() != state.Domain.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.HealthPath.IsNull() && !plan.HealthPath.IsUnknown() && !state.HealthPath.IsNull() && !state.HealthPath.IsUnknown() {
+ if plan.HealthPath.ValueString() != state.HealthPath.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить health_path", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() {
+ if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ 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{
+ 248: resources_core.FormatString(config.Domain),
+ 249: resources_core.FormatString(config.ResourceRealm),
+ 250: resources_core.FormatInt64(config.ResourceCPU),
+ 251: resources_core.FormatInt64(config.ResourceMemory),
+ 252: resources_core.FormatInt64(config.ResourceInstances),
+ 253: resources_core.FormatString(config.GitPath),
+ 254: resources_core.FormatString(config.JsonEnv),
+ 255: resources_core.FormatString(config.HealthPath),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 89, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *FlaskResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data FlaskModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 89, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 248: resources_core.FormatString(data.Domain),
+ 249: resources_core.FormatString(data.ResourceRealm),
+ 250: resources_core.FormatInt64(data.ResourceCPU),
+ 251: resources_core.FormatInt64(data.ResourceMemory),
+ 252: resources_core.FormatInt64(data.ResourceInstances),
+ 253: resources_core.FormatString(data.GitPath),
+ 254: resources_core.FormatString(data.JsonEnv),
+ 255: resources_core.FormatString(data.HealthPath),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 89, 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, 89, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "gitPath", Field: "GitPath", Type: "string"},
+ {Code: "healthPath", Field: "HealthPath", Type: "string"},
+ {Code: "jsonEnv", Field: "JsonEnv", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *FlaskResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state FlaskModel
+ 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(), 89, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "gitPath", Field: "GitPath", Type: "string"},
+ {Code: "healthPath", Field: "HealthPath", Type: "string"},
+ {Code: "jsonEnv", Field: "JsonEnv", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *FlaskResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan FlaskModel
+ var state FlaskModel
+ 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.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() {
+ if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() {
+ if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() {
+ if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.GitPath.IsNull() != state.GitPath.IsNull() || plan.GitPath.IsUnknown() != state.GitPath.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.GitPath.IsNull() && !plan.GitPath.IsUnknown() && !state.GitPath.IsNull() && !state.GitPath.IsUnknown() {
+ if plan.GitPath.ValueString() != state.GitPath.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.JsonEnv.IsNull() != state.JsonEnv.IsNull() || plan.JsonEnv.IsUnknown() != state.JsonEnv.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.JsonEnv.IsNull() && !plan.JsonEnv.IsUnknown() && !state.JsonEnv.IsNull() && !state.JsonEnv.IsUnknown() {
+ if plan.JsonEnv.ValueString() != state.JsonEnv.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+
+ if !hasServiceParamChanges {
+ 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
+ }
+
+ params := map[int]string{
+ 451: resources_core.FormatInt64(plan.ResourceCPU),
+ 452: resources_core.FormatInt64(plan.ResourceMemory),
+ 453: resources_core.FormatInt64(plan.ResourceInstances),
+ 454: resources_core.FormatString(plan.GitPath),
+ 455: resources_core.FormatString(plan.JsonEnv),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 89, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "gitPath", Field: "GitPath", Type: "string"},
+ {Code: "healthPath", Field: "HealthPath", Type: "string"},
+ {Code: "jsonEnv", Field: "JsonEnv", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *FlaskResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state FlaskModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *FlaskResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *FlaskResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/90_postgres_database_resource.go b/universal_rebuild/internal/resources_gen/90_postgres_database_resource.go
new file mode 100644
index 0000000..79ea316
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/90_postgres_database_resource.go
@@ -0,0 +1,334 @@
+package resources_gen
+
+import (
+ "context"
+ "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"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+ "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: postgres
+// Subresource: database
+
+var _ resource.Resource = &PostgresDatabaseResource{}
+
+// PostgresDatabaseResource manages a subresource via operations.
+type PostgresDatabaseResource struct {
+ client *core.UniversalClient
+}
+
+type PostgresDatabaseModel struct {
+ ID types.String `tfsdk:"id"`
+ PostgresID types.String `tfsdk:"postgres_id"`
+ AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"`
+ SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ DbName types.String `tfsdk:"db_name"`
+ DbOwner types.String `tfsdk:"db_owner"`
+}
+
+func NewPostgresDatabaseResource() resource.Resource {
+ return &PostgresDatabaseResource{}
+}
+
+func (r *PostgresDatabaseResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_postgres_database"
+}
+
+func (r *PostgresDatabaseResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "postgres_id": schema.StringAttribute{
+ Required: true,
+ PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
+ },
+ "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(false)},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "db_name": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}},
+ "db_owner": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}},
+ }
+ resp.Schema = schema.Schema{Attributes: attrs}
+}
+
+func (r *PostgresDatabaseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan PostgresDatabaseModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if plan.DbName.IsNull() || plan.DbName.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "db_name is required.")
+ return
+ }
+ if plan.DbOwner.IsNull() || plan.DbOwner.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "db_owner is required.")
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.PostgresID.ValueString())
+ if instanceUID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра")
+ return
+ }
+ adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool()
+
+ idParams := map[string]string{
+ "dbName": resources_core.FormatString(plan.DbName),
+ "dbOwner": resources_core.FormatString(plan.DbOwner),
+ }
+ identityCodes := []string{
+ "dbName",
+ "dbOwner",
+ }
+ listKey, idKey := resources_core.ResolveSubresourceStateKeys("database", identityCodes)
+ targetValue := strings.TrimSpace(idParams[idKey])
+ if targetValue == "" {
+ for _, code := range identityCodes {
+ candidate := strings.TrimSpace(idParams[code])
+ if candidate == "" {
+ continue
+ }
+ targetValue = candidate
+ idKey = code
+ break
+ }
+ }
+
+ if targetValue != "" {
+ found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if known && found {
+ if adoptExistingOnCreate {
+ plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams))
+ resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue)
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+ return
+ }
+ resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue)
+ return
+ }
+ }
+
+ params := resources_core.CompactParams(map[string]string{
+ "dbName": resources_core.FormatString(plan.DbName),
+ "dbOwner": resources_core.FormatString(plan.DbOwner),
+ })
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_database", params, operationTimeout); err != nil {
+ if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(err) {
+ if targetValue != "" {
+ found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if checkErr != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error())
+ return
+ }
+ if known && found {
+ plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams))
+ resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление")
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+ return
+ }
+ }
+ resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out")
+ return
+ }
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if targetValue != "" {
+ found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if known && !found {
+ resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue)
+ return
+ }
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *PostgresDatabaseResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state PostgresDatabaseModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *PostgresDatabaseResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan PostgresDatabaseModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ if "" == "" {
+ var state PostgresDatabaseModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if plan.ID.IsNull() || plan.ID.IsUnknown() {
+ plan.ID = state.ID
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.PostgresID.ValueString())
+ if instanceUID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра")
+ return
+ }
+
+ params := resources_core.CompactParams(map[string]string{})
+
+ idParams := map[string]string{
+ "dbName": resources_core.FormatString(plan.DbName),
+ "dbOwner": resources_core.FormatString(plan.DbOwner),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *PostgresDatabaseResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state PostgresDatabaseModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ if "delete_database" == "" {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(state.PostgresID.ValueString())
+ if instanceUID == "" {
+ return
+ }
+ skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool()
+
+ idParams := map[string]string{
+ "dbName": resources_core.FormatString(state.DbName),
+ "dbOwner": resources_core.FormatString(state.DbOwner),
+ }
+ identityCodes := []string{
+ "dbName",
+ "dbOwner",
+ }
+ listKey, idKey := resources_core.ResolveSubresourceStateKeys("database", identityCodes)
+ targetValue := strings.TrimSpace(idParams[idKey])
+ if targetValue == "" {
+ for _, code := range identityCodes {
+ candidate := strings.TrimSpace(idParams[code])
+ if candidate == "" {
+ continue
+ }
+ targetValue = candidate
+ idKey = code
+ break
+ }
+ }
+
+ if targetValue != "" {
+ found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if known && !found {
+ if skipMissingOnDelete {
+ resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue)
+ return
+ }
+ resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue)
+ return
+ }
+ }
+
+ params := resources_core.CompactParams(map[string]string{
+ "dbName": resources_core.FormatString(state.DbName),
+ })
+
+ operationTimeout := ""
+ if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() {
+ operationTimeout = state.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_database", params, operationTimeout); err != nil {
+ if resources_core.IsSubresourceMissingError(err) {
+ if targetValue != "" {
+ found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if checkErr != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error())
+ return
+ }
+ if known && found {
+ resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue)
+ return
+ }
+ }
+ if skipMissingOnDelete {
+ resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено")
+ return
+ }
+ }
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ if targetValue != "" {
+ found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if known && found {
+ resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue)
+ return
+ }
+ }
+}
+
+func (r *PostgresDatabaseResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/90_postgres_recovery_action.go b/universal_rebuild/internal/resources_gen/90_postgres_recovery_action.go
new file mode 100644
index 0000000..51004dc
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/90_postgres_recovery_action.go
@@ -0,0 +1,155 @@
+package resources_gen
+
+import (
+ "context"
+ "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"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: postgres
+// Action: recovery
+
+var _ resource.Resource = &PostgresRecoveryResource{}
+
+// PostgresRecoveryResource triggers a one-time action.
+type PostgresRecoveryResource struct {
+ client *core.UniversalClient
+}
+
+type PostgresRecoveryModel struct {
+ ID types.String `tfsdk:"id"`
+ PostgresID types.String `tfsdk:"postgres_id"`
+ RunID types.String `tfsdk:"run_id"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ ResourceInstances types.Int64 `tfsdk:"resource_instances"`
+ ResourceMemory types.Int64 `tfsdk:"resource_memory"`
+ ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"`
+ ResourceDisk types.Int64 `tfsdk:"resource_disk"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+}
+
+func NewPostgresRecoveryResource() resource.Resource {
+ return &PostgresRecoveryResource{}
+}
+
+func (r *PostgresRecoveryResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_postgres_recovery"
+}
+
+func (r *PostgresRecoveryResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "postgres_id": schema.StringAttribute{Required: true},
+ "run_id": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"},
+ "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes)
"},
+ "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (Указывается в mili)
"},
+ "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания"},
+ }
+ resp.Schema = schema.Schema{Attributes: attrs}
+}
+
+func (r *PostgresRecoveryResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan PostgresRecoveryModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if plan.ResourceRealm.IsNull() || plan.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.PostgresID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{
+ "resourceInstances": resources_core.FormatInt64(plan.ResourceInstances),
+ "resourceMemory": resources_core.FormatInt64(plan.ResourceMemory),
+ "resourceCPU": resources_core.FormatInt64(plan.ResourceCPU),
+ "resourceDisk": resources_core.FormatInt64(plan.ResourceDisk),
+ "resourceRealm": resources_core.FormatString(plan.ResourceRealm),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "recovery", params, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "recovery", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *PostgresRecoveryResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state PostgresRecoveryModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *PostgresRecoveryResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan PostgresRecoveryModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.PostgresID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{
+ "resourceInstances": resources_core.FormatInt64(plan.ResourceInstances),
+ "resourceMemory": resources_core.FormatInt64(plan.ResourceMemory),
+ "resourceCPU": resources_core.FormatInt64(plan.ResourceCPU),
+ "resourceDisk": resources_core.FormatInt64(plan.ResourceDisk),
+ "resourceRealm": resources_core.FormatString(plan.ResourceRealm),
+ }
+
+ if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "recovery", params); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "recovery", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *PostgresRecoveryResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ // No-op: removing the resource does not trigger a remote action.
+}
+
+func (r *PostgresRecoveryResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/90_postgres_resource.go b/universal_rebuild/internal/resources_gen/90_postgres_resource.go
new file mode 100644
index 0000000..bf9c85b
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/90_postgres_resource.go
@@ -0,0 +1,683 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: postgres
+// Service ID: 90
+
+var _ resource.Resource = &PostgresResource{}
+var _ resource.ResourceWithModifyPlan = &PostgresResource{}
+var _ resource.ResourceWithImportState = &PostgresResource{}
+
+type PostgresResource struct {
+ client *core.UniversalClient
+}
+
+type PostgresModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ AllowNoSSL types.Bool `tfsdk:"allow_no_s_s_l"`
+ AppVersion types.String `tfsdk:"app_version"`
+ AutoScale types.Bool `tfsdk:"auto_scale"`
+ AutoScalePercentage types.Int64 `tfsdk:"auto_scale_percentage"`
+ AutoScaleQuotaGb types.String `tfsdk:"auto_scale_quota_gb"`
+ AutoScaleTechWindow types.Int64 `tfsdk:"auto_scale_tech_window"`
+ EnablePgPoolerMaster types.Bool `tfsdk:"enable_pg_pooler_master"`
+ EnablePgPoolerSlave types.Bool `tfsdk:"enable_pg_pooler_slave"`
+ ExtBACKUPNUMTORETAIN types.Int64 `tfsdk:"ext__b_a_c_k_u_p__n_u_m__t_o__r_e_t_a_i_n"`
+ ExtBACKUPSCHEDULE types.String `tfsdk:"ext__b_a_c_k_u_p__s_c_h_e_d_u_l_e"`
+ IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"`
+ IpSpaceNameSlave types.String `tfsdk:"ip_space_name_slave"`
+ JsonParameters types.String `tfsdk:"json_parameters"`
+ NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"`
+ NeedExternalAddressSlave types.Bool `tfsdk:"need_external_address_slave"`
+ ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"`
+ ResourceDisk types.String `tfsdk:"resource_disk"`
+ ResourceInstances types.Int64 `tfsdk:"resource_instances"`
+ ResourceMemory types.Int64 `tfsdk:"resource_memory"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+ S3Uid types.String `tfsdk:"s3_uid"`
+ 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 NewPostgresResource() resource.Resource {
+ return &PostgresResource{}
+}
+
+func (r *PostgresResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_postgres"
+}
+
+func (r *PostgresResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "allow_no_s_s_l": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "По умолчанию подключение обязательное (sslmode=require). Выставление в true отключит этот параметр"},
+ "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("17"), MarkdownDescription: "Версия PostgreSQL"},
+ "auto_scale": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Включает автоскейлинг PV. При включении параметра необходимо настроить autoScalePercentage и autoScaleTechWindow. Алерт при срабатывании вызывает modify у текущей услуги Не изменяется после создания."},
+ "auto_scale_percentage": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "Требует включения autoScale. Позволяет указать в процентах расширение от текущего макс объема Не изменяется после создания."},
+ "auto_scale_quota_gb": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("1"), MarkdownDescription: "Квота для autoScale Не изменяется после создания."},
+ "auto_scale_tech_window": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(0), MarkdownDescription: "Требует включения autoScale. Окно обновления (пока не реализовано). Указывается час в виде Integer (0 / 5 / 12 / 23) Не изменяется после создания."},
+ "enable_pg_pooler_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Включает pgPooler (на запись). Будет создан новый под"},
+ "enable_pg_pooler_slave": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Включает pgPooler (на чтение). Будет создан новый под"},
+ "ext__b_a_c_k_u_p__n_u_m__t_o__r_e_t_a_i_n": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(7), MarkdownDescription: "Не обязательный. Количество сохраняемых бекапов"},
+ "ext__b_a_c_k_u_p__s_c_h_e_d_u_l_e": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("0 0 * * *"), MarkdownDescription: "Не обязательный. Время запуска бекапа"},
+ "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Имя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster. Пример: `internet-no-antiddos-v1`"},
+ "ip_space_name_slave": schema.StringAttribute{Optional: true, MarkdownDescription: "Имя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave"},
+ "json_parameters": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{ \"log_connections\": \"off\", \"log_disconnections\": \"off\" }"), MarkdownDescription: "Массив переменных, более подробнее про настройку можно посмотреть https://www.postgresql.org/docs/current/runtime-config.html"},
+ "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Выделяет внешний (белый) IP для доступа к master"},
+ "need_external_address_slave": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Выделяет внешний (белый) IP для доступа к slave. Будет работать, если slave в принципе есть"},
+ "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (milicores)"},
+ "resource_disk": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("10"), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"},
+ "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"},
+ "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (MBytes)"},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."},
+ "s3_uid": schema.StringAttribute{Required: true, MarkdownDescription: "Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно Не изменяется после создания."},
+ "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 *PostgresResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *PostgresModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *PostgresModel
+ 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 PostgresModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ planChanged := false
+ if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() {
+ resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, plan.S3Uid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error())
+ } else if resolvedS3Uid != "" && resolvedS3Uid != plan.S3Uid.ValueString() {
+ plan.S3Uid = types.StringValue(resolvedS3Uid)
+ planChanged = true
+ }
+ }
+ if planChanged {
+ resp.Diagnostics.Append(resp.Plan.Set(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.AutoScale.IsNull() && !plan.AutoScale.IsUnknown() && !state.AutoScale.IsNull() && !state.AutoScale.IsUnknown() {
+ if plan.AutoScale.ValueBool() != state.AutoScale.ValueBool() {
+ resp.Diagnostics.AddError("Нельзя изменить auto_scale", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.AutoScalePercentage.IsNull() && !plan.AutoScalePercentage.IsUnknown() && !state.AutoScalePercentage.IsNull() && !state.AutoScalePercentage.IsUnknown() {
+ if plan.AutoScalePercentage.ValueInt64() != state.AutoScalePercentage.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить auto_scale_percentage", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.AutoScaleQuotaGb.IsNull() && !plan.AutoScaleQuotaGb.IsUnknown() && !state.AutoScaleQuotaGb.IsNull() && !state.AutoScaleQuotaGb.IsUnknown() {
+ if plan.AutoScaleQuotaGb.ValueString() != state.AutoScaleQuotaGb.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить auto_scale_quota_gb", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.AutoScaleTechWindow.IsNull() && !plan.AutoScaleTechWindow.IsUnknown() && !state.AutoScaleTechWindow.IsNull() && !state.AutoScaleTechWindow.IsUnknown() {
+ if plan.AutoScaleTechWindow.ValueInt64() != state.AutoScaleTechWindow.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить auto_scale_tech_window", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() {
+ if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() && !state.S3Uid.IsNull() && !state.S3Uid.IsUnknown() {
+ if plan.S3Uid.ValueString() != state.S3Uid.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить s3_uid", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+ if config.S3Uid.IsNull() || config.S3Uid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.")
+ return
+ }
+
+ if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() {
+ return
+ }
+ adoptExistingOnCreate := false
+ if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() {
+ adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool()
+ }
+ if !config.S3Uid.IsNull() && !config.S3Uid.IsUnknown() {
+ resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, config.S3Uid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error())
+ } else if resolvedS3Uid != "" && resolvedS3Uid != config.S3Uid.ValueString() {
+ config.S3Uid = types.StringValue(resolvedS3Uid)
+ }
+ }
+ params := map[int]string{
+ 23: resources_core.FormatString(config.S3Uid),
+ 80: resources_core.FormatInt64(config.ResourceInstances),
+ 81: resources_core.FormatInt64(config.ResourceMemory),
+ 82: resources_core.FormatInt64(config.ResourceCPU),
+ 83: resources_core.FormatString(config.ResourceDisk),
+ 102: resources_core.FormatString(config.ResourceRealm),
+ 145: resources_core.FormatBool(config.NeedExternalAddressMaster),
+ 146: resources_core.FormatBool(config.NeedExternalAddressSlave),
+ 265: resources_core.FormatString(config.ExtBACKUPSCHEDULE),
+ 266: resources_core.FormatInt64(config.ExtBACKUPNUMTORETAIN),
+ 310: resources_core.FormatString(config.AppVersion),
+ 311: resources_core.FormatString(config.JsonParameters),
+ 312: resources_core.FormatBool(config.EnablePgPoolerMaster),
+ 313: resources_core.FormatBool(config.EnablePgPoolerSlave),
+ 314: resources_core.FormatBool(config.AllowNoSSL),
+ 329: resources_core.FormatBool(config.AutoScale),
+ 330: resources_core.FormatInt64(config.AutoScalePercentage),
+ 331: resources_core.FormatInt64(config.AutoScaleTechWindow),
+ 337: resources_core.FormatString(config.IpSpaceNameMaster),
+ 338: resources_core.FormatString(config.IpSpaceNameSlave),
+ 339: resources_core.FormatString(config.AutoScaleQuotaGb),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 90, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *PostgresResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data PostgresModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+ if data.S3Uid.IsNull() || data.S3Uid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.")
+ return
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 90, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 23: resources_core.FormatString(data.S3Uid),
+ 80: resources_core.FormatInt64(data.ResourceInstances),
+ 81: resources_core.FormatInt64(data.ResourceMemory),
+ 82: resources_core.FormatInt64(data.ResourceCPU),
+ 83: resources_core.FormatString(data.ResourceDisk),
+ 102: resources_core.FormatString(data.ResourceRealm),
+ 145: resources_core.FormatBool(data.NeedExternalAddressMaster),
+ 146: resources_core.FormatBool(data.NeedExternalAddressSlave),
+ 265: resources_core.FormatString(data.ExtBACKUPSCHEDULE),
+ 266: resources_core.FormatInt64(data.ExtBACKUPNUMTORETAIN),
+ 310: resources_core.FormatString(data.AppVersion),
+ 311: resources_core.FormatString(data.JsonParameters),
+ 312: resources_core.FormatBool(data.EnablePgPoolerMaster),
+ 313: resources_core.FormatBool(data.EnablePgPoolerSlave),
+ 314: resources_core.FormatBool(data.AllowNoSSL),
+ 329: resources_core.FormatBool(data.AutoScale),
+ 330: resources_core.FormatInt64(data.AutoScalePercentage),
+ 331: resources_core.FormatInt64(data.AutoScaleTechWindow),
+ 337: resources_core.FormatString(data.IpSpaceNameMaster),
+ 338: resources_core.FormatString(data.IpSpaceNameSlave),
+ 339: resources_core.FormatString(data.AutoScaleQuotaGb),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 90, 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, 90, 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: "allowNoSSL", Field: "AllowNoSSL", Type: "bool"},
+ {Code: "appVersion", Field: "AppVersion", Type: "string"},
+ {Code: "autoScale", Field: "AutoScale", Type: "bool"},
+ {Code: "autoScalePercentage", Field: "AutoScalePercentage", Type: "int64"},
+ {Code: "autoScaleQuotaGb", Field: "AutoScaleQuotaGb", Type: "string"},
+ {Code: "autoScaleTechWindow", Field: "AutoScaleTechWindow", Type: "int64"},
+ {Code: "enablePgPoolerMaster", Field: "EnablePgPoolerMaster", Type: "bool"},
+ {Code: "enablePgPoolerSlave", Field: "EnablePgPoolerSlave", Type: "bool"},
+ {Code: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"},
+ {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"},
+ {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"},
+ {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"},
+ {Code: "jsonParameters", Field: "JsonParameters", Type: "string"},
+ {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"},
+ {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "string"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *PostgresResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state PostgresModel
+ 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(), 90, 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: "allowNoSSL", Field: "AllowNoSSL", Type: "bool"},
+ {Code: "appVersion", Field: "AppVersion", Type: "string"},
+ {Code: "autoScale", Field: "AutoScale", Type: "bool"},
+ {Code: "autoScalePercentage", Field: "AutoScalePercentage", Type: "int64"},
+ {Code: "autoScaleQuotaGb", Field: "AutoScaleQuotaGb", Type: "string"},
+ {Code: "autoScaleTechWindow", Field: "AutoScaleTechWindow", Type: "int64"},
+ {Code: "enablePgPoolerMaster", Field: "EnablePgPoolerMaster", Type: "bool"},
+ {Code: "enablePgPoolerSlave", Field: "EnablePgPoolerSlave", Type: "bool"},
+ {Code: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"},
+ {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"},
+ {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"},
+ {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"},
+ {Code: "jsonParameters", Field: "JsonParameters", Type: "string"},
+ {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"},
+ {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "string"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *PostgresResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan PostgresModel
+ var state PostgresModel
+ 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.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() {
+ if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() {
+ if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() {
+ if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() {
+ if plan.ResourceDisk.ValueString() != state.ResourceDisk.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.NeedExternalAddressMaster.IsNull() != state.NeedExternalAddressMaster.IsNull() || plan.NeedExternalAddressMaster.IsUnknown() != state.NeedExternalAddressMaster.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() {
+ if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.NeedExternalAddressSlave.IsNull() != state.NeedExternalAddressSlave.IsNull() || plan.NeedExternalAddressSlave.IsUnknown() != state.NeedExternalAddressSlave.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.NeedExternalAddressSlave.IsNull() && !plan.NeedExternalAddressSlave.IsUnknown() && !state.NeedExternalAddressSlave.IsNull() && !state.NeedExternalAddressSlave.IsUnknown() {
+ if plan.NeedExternalAddressSlave.ValueBool() != state.NeedExternalAddressSlave.ValueBool() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ExtBACKUPSCHEDULE.IsNull() != state.ExtBACKUPSCHEDULE.IsNull() || plan.ExtBACKUPSCHEDULE.IsUnknown() != state.ExtBACKUPSCHEDULE.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ExtBACKUPSCHEDULE.IsNull() && !plan.ExtBACKUPSCHEDULE.IsUnknown() && !state.ExtBACKUPSCHEDULE.IsNull() && !state.ExtBACKUPSCHEDULE.IsUnknown() {
+ if plan.ExtBACKUPSCHEDULE.ValueString() != state.ExtBACKUPSCHEDULE.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ExtBACKUPNUMTORETAIN.IsNull() != state.ExtBACKUPNUMTORETAIN.IsNull() || plan.ExtBACKUPNUMTORETAIN.IsUnknown() != state.ExtBACKUPNUMTORETAIN.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ExtBACKUPNUMTORETAIN.IsNull() && !plan.ExtBACKUPNUMTORETAIN.IsUnknown() && !state.ExtBACKUPNUMTORETAIN.IsNull() && !state.ExtBACKUPNUMTORETAIN.IsUnknown() {
+ if plan.ExtBACKUPNUMTORETAIN.ValueInt64() != state.ExtBACKUPNUMTORETAIN.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.AppVersion.IsNull() != state.AppVersion.IsNull() || plan.AppVersion.IsUnknown() != state.AppVersion.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() {
+ if plan.AppVersion.ValueString() != state.AppVersion.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.JsonParameters.IsNull() != state.JsonParameters.IsNull() || plan.JsonParameters.IsUnknown() != state.JsonParameters.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.JsonParameters.IsNull() && !plan.JsonParameters.IsUnknown() && !state.JsonParameters.IsNull() && !state.JsonParameters.IsUnknown() {
+ if plan.JsonParameters.ValueString() != state.JsonParameters.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.EnablePgPoolerMaster.IsNull() != state.EnablePgPoolerMaster.IsNull() || plan.EnablePgPoolerMaster.IsUnknown() != state.EnablePgPoolerMaster.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.EnablePgPoolerMaster.IsNull() && !plan.EnablePgPoolerMaster.IsUnknown() && !state.EnablePgPoolerMaster.IsNull() && !state.EnablePgPoolerMaster.IsUnknown() {
+ if plan.EnablePgPoolerMaster.ValueBool() != state.EnablePgPoolerMaster.ValueBool() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.EnablePgPoolerSlave.IsNull() != state.EnablePgPoolerSlave.IsNull() || plan.EnablePgPoolerSlave.IsUnknown() != state.EnablePgPoolerSlave.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.EnablePgPoolerSlave.IsNull() && !plan.EnablePgPoolerSlave.IsUnknown() && !state.EnablePgPoolerSlave.IsNull() && !state.EnablePgPoolerSlave.IsUnknown() {
+ if plan.EnablePgPoolerSlave.ValueBool() != state.EnablePgPoolerSlave.ValueBool() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.AllowNoSSL.IsNull() != state.AllowNoSSL.IsNull() || plan.AllowNoSSL.IsUnknown() != state.AllowNoSSL.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.AllowNoSSL.IsNull() && !plan.AllowNoSSL.IsUnknown() && !state.AllowNoSSL.IsNull() && !state.AllowNoSSL.IsUnknown() {
+ if plan.AllowNoSSL.ValueBool() != state.AllowNoSSL.ValueBool() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.IpSpaceNameMaster.IsNull() != state.IpSpaceNameMaster.IsNull() || plan.IpSpaceNameMaster.IsUnknown() != state.IpSpaceNameMaster.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() {
+ if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.IpSpaceNameSlave.IsNull() != state.IpSpaceNameSlave.IsNull() || plan.IpSpaceNameSlave.IsUnknown() != state.IpSpaceNameSlave.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.IpSpaceNameSlave.IsNull() && !plan.IpSpaceNameSlave.IsUnknown() && !state.IpSpaceNameSlave.IsNull() && !state.IpSpaceNameSlave.IsUnknown() {
+ if plan.IpSpaceNameSlave.ValueString() != state.IpSpaceNameSlave.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+
+ if !hasServiceParamChanges {
+ 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
+ }
+
+ params := map[int]string{
+ 91: resources_core.FormatInt64(plan.ResourceInstances),
+ 92: resources_core.FormatInt64(plan.ResourceMemory),
+ 93: resources_core.FormatInt64(plan.ResourceCPU),
+ 94: resources_core.FormatString(plan.ResourceDisk),
+ 147: resources_core.FormatBool(plan.NeedExternalAddressMaster),
+ 148: resources_core.FormatBool(plan.NeedExternalAddressSlave),
+ 267: resources_core.FormatString(plan.ExtBACKUPSCHEDULE),
+ 268: resources_core.FormatInt64(plan.ExtBACKUPNUMTORETAIN),
+ 315: resources_core.FormatString(plan.AppVersion),
+ 316: resources_core.FormatString(plan.JsonParameters),
+ 317: resources_core.FormatBool(plan.EnablePgPoolerMaster),
+ 318: resources_core.FormatBool(plan.EnablePgPoolerSlave),
+ 319: resources_core.FormatBool(plan.AllowNoSSL),
+ 541: resources_core.FormatString(plan.IpSpaceNameMaster),
+ 542: resources_core.FormatString(plan.IpSpaceNameSlave),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 90, 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: "allowNoSSL", Field: "AllowNoSSL", Type: "bool"},
+ {Code: "appVersion", Field: "AppVersion", Type: "string"},
+ {Code: "autoScale", Field: "AutoScale", Type: "bool"},
+ {Code: "autoScalePercentage", Field: "AutoScalePercentage", Type: "int64"},
+ {Code: "autoScaleQuotaGb", Field: "AutoScaleQuotaGb", Type: "string"},
+ {Code: "autoScaleTechWindow", Field: "AutoScaleTechWindow", Type: "int64"},
+ {Code: "enablePgPoolerMaster", Field: "EnablePgPoolerMaster", Type: "bool"},
+ {Code: "enablePgPoolerSlave", Field: "EnablePgPoolerSlave", Type: "bool"},
+ {Code: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"},
+ {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"},
+ {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"},
+ {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"},
+ {Code: "jsonParameters", Field: "JsonParameters", Type: "string"},
+ {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"},
+ {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "string"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *PostgresResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state PostgresModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *PostgresResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *PostgresResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/90_postgres_restart_action.go b/universal_rebuild/internal/resources_gen/90_postgres_restart_action.go
new file mode 100644
index 0000000..1f6824c
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/90_postgres_restart_action.go
@@ -0,0 +1,128 @@
+package resources_gen
+
+import (
+ "context"
+ "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"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: postgres
+// Action: restart
+
+var _ resource.Resource = &PostgresRestartResource{}
+
+// PostgresRestartResource triggers a one-time action.
+type PostgresRestartResource struct {
+ client *core.UniversalClient
+}
+
+type PostgresRestartModel struct {
+ ID types.String `tfsdk:"id"`
+ PostgresID types.String `tfsdk:"postgres_id"`
+ RunID types.String `tfsdk:"run_id"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+}
+
+func NewPostgresRestartResource() resource.Resource {
+ return &PostgresRestartResource{}
+}
+
+func (r *PostgresRestartResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_postgres_restart"
+}
+
+func (r *PostgresRestartResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "postgres_id": schema.StringAttribute{Required: true},
+ "run_id": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ }
+ resp.Schema = schema.Schema{Attributes: attrs}
+}
+
+func (r *PostgresRestartResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan PostgresRestartModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.PostgresID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{}
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "restart", params, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *PostgresRestartResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state PostgresRestartModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *PostgresRestartResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan PostgresRestartModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.PostgresID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{}
+
+ if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "restart", params); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *PostgresRestartResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ // No-op: removing the resource does not trigger a remote action.
+}
+
+func (r *PostgresRestartResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/90_postgres_user_resource.go b/universal_rebuild/internal/resources_gen/90_postgres_user_resource.go
new file mode 100644
index 0000000..e307576
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/90_postgres_user_resource.go
@@ -0,0 +1,334 @@
+package resources_gen
+
+import (
+ "context"
+ "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"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+ "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: postgres
+// Subresource: user
+
+var _ resource.Resource = &PostgresUserResource{}
+
+// PostgresUserResource manages a subresource via operations.
+type PostgresUserResource struct {
+ client *core.UniversalClient
+}
+
+type PostgresUserModel struct {
+ ID types.String `tfsdk:"id"`
+ PostgresID types.String `tfsdk:"postgres_id"`
+ AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"`
+ SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ Role types.String `tfsdk:"role"`
+ Username types.String `tfsdk:"username"`
+}
+
+func NewPostgresUserResource() resource.Resource {
+ return &PostgresUserResource{}
+}
+
+func (r *PostgresUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_postgres_user"
+}
+
+func (r *PostgresUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "postgres_id": schema.StringAttribute{
+ Required: true,
+ PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
+ },
+ "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(false)},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "role": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать роль из списка Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}},
+ "username": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}},
+ }
+ resp.Schema = schema.Schema{Attributes: attrs}
+}
+
+func (r *PostgresUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan PostgresUserModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if plan.Role.IsNull() || plan.Role.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "role is required.")
+ return
+ }
+ if plan.Username.IsNull() || plan.Username.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "username is required.")
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.PostgresID.ValueString())
+ if instanceUID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра")
+ return
+ }
+ adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool()
+
+ idParams := map[string]string{
+ "role": resources_core.FormatString(plan.Role),
+ "username": resources_core.FormatString(plan.Username),
+ }
+ identityCodes := []string{
+ "role",
+ "username",
+ }
+ listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes)
+ targetValue := strings.TrimSpace(idParams[idKey])
+ if targetValue == "" {
+ for _, code := range identityCodes {
+ candidate := strings.TrimSpace(idParams[code])
+ if candidate == "" {
+ continue
+ }
+ targetValue = candidate
+ idKey = code
+ break
+ }
+ }
+
+ if targetValue != "" {
+ found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if known && found {
+ if adoptExistingOnCreate {
+ plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams))
+ resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue)
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+ return
+ }
+ resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue)
+ return
+ }
+ }
+
+ params := resources_core.CompactParams(map[string]string{
+ "username": resources_core.FormatString(plan.Username),
+ "role": resources_core.FormatString(plan.Role),
+ })
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout); err != nil {
+ if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(err) {
+ if targetValue != "" {
+ found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if checkErr != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error())
+ return
+ }
+ if known && found {
+ plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams))
+ resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление")
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+ return
+ }
+ }
+ resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out")
+ return
+ }
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if targetValue != "" {
+ found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if known && !found {
+ resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue)
+ return
+ }
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *PostgresUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state PostgresUserModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *PostgresUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan PostgresUserModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ if "" == "" {
+ var state PostgresUserModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if plan.ID.IsNull() || plan.ID.IsUnknown() {
+ plan.ID = state.ID
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.PostgresID.ValueString())
+ if instanceUID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра")
+ return
+ }
+
+ params := resources_core.CompactParams(map[string]string{})
+
+ idParams := map[string]string{
+ "role": resources_core.FormatString(plan.Role),
+ "username": resources_core.FormatString(plan.Username),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *PostgresUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state PostgresUserModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ if "delete_user" == "" {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(state.PostgresID.ValueString())
+ if instanceUID == "" {
+ return
+ }
+ skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool()
+
+ idParams := map[string]string{
+ "role": resources_core.FormatString(state.Role),
+ "username": resources_core.FormatString(state.Username),
+ }
+ identityCodes := []string{
+ "role",
+ "username",
+ }
+ listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes)
+ targetValue := strings.TrimSpace(idParams[idKey])
+ if targetValue == "" {
+ for _, code := range identityCodes {
+ candidate := strings.TrimSpace(idParams[code])
+ if candidate == "" {
+ continue
+ }
+ targetValue = candidate
+ idKey = code
+ break
+ }
+ }
+
+ if targetValue != "" {
+ found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if known && !found {
+ if skipMissingOnDelete {
+ resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue)
+ return
+ }
+ resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue)
+ return
+ }
+ }
+
+ params := resources_core.CompactParams(map[string]string{
+ "username": resources_core.FormatString(state.Username),
+ })
+
+ operationTimeout := ""
+ if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() {
+ operationTimeout = state.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_user", params, operationTimeout); err != nil {
+ if resources_core.IsSubresourceMissingError(err) {
+ if targetValue != "" {
+ found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if checkErr != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error())
+ return
+ }
+ if known && found {
+ resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue)
+ return
+ }
+ }
+ if skipMissingOnDelete {
+ resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено")
+ return
+ }
+ }
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ if targetValue != "" {
+ found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if known && found {
+ resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue)
+ return
+ }
+ }
+}
+
+func (r *PostgresUserResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/91_redis_resource.go b/universal_rebuild/internal/resources_gen/91_redis_resource.go
new file mode 100644
index 0000000..b52f62e
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/91_redis_resource.go
@@ -0,0 +1,436 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: redis
+// Service ID: 91
+
+var _ resource.Resource = &RedisResource{}
+var _ resource.ResourceWithModifyPlan = &RedisResource{}
+var _ resource.ResourceWithImportState = &RedisResource{}
+
+type RedisResource struct {
+ client *core.UniversalClient
+}
+
+type RedisModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"`
+ IpSpaceNameSlave types.String `tfsdk:"ip_space_name_slave"`
+ NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"`
+ NeedExternalAddressSlave types.Bool `tfsdk:"need_external_address_slave"`
+ ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"`
+ ResourceDisk types.Int64 `tfsdk:"resource_disk"`
+ ResourceInstances types.Int64 `tfsdk:"resource_instances"`
+ ResourceMemory types.Int64 `tfsdk:"resource_memory"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+ 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 NewRedisResource() resource.Resource {
+ return &RedisResource{}
+}
+
+func (r *RedisResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_redis"
+}
+
+func (r *RedisResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Имя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster Не изменяется после создания."},
+ "ip_space_name_slave": schema.StringAttribute{Optional: true, MarkdownDescription: "Имя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave Не изменяется после создания."},
+ "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Выделяет внешний IP для доступа к master Не изменяется после создания."},
+ "need_external_address_slave": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Выделяет внешний IP для доступа к slave. Будет работать если slave в целом есть Не изменяется после создания."},
+ "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1000), MarkdownDescription: "Квота ядра пода (Указывается в mili) Не изменяется после создания."},
+ "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(30), MarkdownDescription: "Квота диска (Указывается в GIGAbytes) Не изменяется после создания."},
+ "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."},
+ "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1024), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes) Не изменяется после создания."},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."},
+ "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)},
+ "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 *RedisResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *RedisModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *RedisModel
+ 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 RedisModel
+ 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.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() {
+ if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить ip_space_name_master", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.IpSpaceNameSlave.IsNull() && !plan.IpSpaceNameSlave.IsUnknown() && !state.IpSpaceNameSlave.IsNull() && !state.IpSpaceNameSlave.IsUnknown() {
+ if plan.IpSpaceNameSlave.ValueString() != state.IpSpaceNameSlave.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить ip_space_name_slave", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() {
+ if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() {
+ resp.Diagnostics.AddError("Нельзя изменить need_external_address_master", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.NeedExternalAddressSlave.IsNull() && !plan.NeedExternalAddressSlave.IsUnknown() && !state.NeedExternalAddressSlave.IsNull() && !state.NeedExternalAddressSlave.IsUnknown() {
+ if plan.NeedExternalAddressSlave.ValueBool() != state.NeedExternalAddressSlave.ValueBool() {
+ resp.Diagnostics.AddError("Нельзя изменить need_external_address_slave", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() {
+ if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() {
+ if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() {
+ if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() {
+ if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() {
+ if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ 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{
+ 112: resources_core.FormatInt64(config.ResourceCPU),
+ 113: resources_core.FormatInt64(config.ResourceMemory),
+ 114: resources_core.FormatInt64(config.ResourceDisk),
+ 181: resources_core.FormatInt64(config.ResourceInstances),
+ 182: resources_core.FormatString(config.ResourceRealm),
+ 183: resources_core.FormatBool(config.NeedExternalAddressMaster),
+ 184: resources_core.FormatBool(config.NeedExternalAddressSlave),
+ 548: resources_core.FormatString(config.IpSpaceNameMaster),
+ 549: resources_core.FormatString(config.IpSpaceNameSlave),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 91, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *RedisResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data RedisModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 91, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 112: resources_core.FormatInt64(data.ResourceCPU),
+ 113: resources_core.FormatInt64(data.ResourceMemory),
+ 114: resources_core.FormatInt64(data.ResourceDisk),
+ 181: resources_core.FormatInt64(data.ResourceInstances),
+ 182: resources_core.FormatString(data.ResourceRealm),
+ 183: resources_core.FormatBool(data.NeedExternalAddressMaster),
+ 184: resources_core.FormatBool(data.NeedExternalAddressSlave),
+ 548: resources_core.FormatString(data.IpSpaceNameMaster),
+ 549: resources_core.FormatString(data.IpSpaceNameSlave),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 91, 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, 91, 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: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"},
+ {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"},
+ {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"},
+ {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *RedisResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state RedisModel
+ 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(), 91, 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: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"},
+ {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"},
+ {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"},
+ {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *RedisResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan RedisModel
+ var state RedisModel
+ 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 {
+ 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
+ }
+
+ params := map[int]string{}
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 91, 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: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"},
+ {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"},
+ {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"},
+ {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *RedisResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state RedisModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *RedisResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *RedisResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/92_mongodb_resource.go b/universal_rebuild/internal/resources_gen/92_mongodb_resource.go
new file mode 100644
index 0000000..4b7b992
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/92_mongodb_resource.go
@@ -0,0 +1,442 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: mongodb
+// Service ID: 92
+
+var _ resource.Resource = &MongodbResource{}
+var _ resource.ResourceWithModifyPlan = &MongodbResource{}
+var _ resource.ResourceWithImportState = &MongodbResource{}
+
+type MongodbResource struct {
+ client *core.UniversalClient
+}
+
+type MongodbModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"`
+ NeedExternalAddressMaster types.String `tfsdk:"need_external_address_master"`
+ ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"`
+ ResourceDisk types.Int64 `tfsdk:"resource_disk"`
+ ResourceInstances types.Int64 `tfsdk:"resource_instances"`
+ ResourceMemory types.Int64 `tfsdk:"resource_memory"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+ 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 NewMongodbResource() resource.Resource {
+ return &MongodbResource{}
+}
+
+func (r *MongodbResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_mongodb"
+}
+
+func (r *MongodbResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1` Не изменяется после создания."},
+ "need_external_address_master": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("false"), MarkdownDescription: "Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false` Не изменяется после создания."},
+ "resource_c_p_u": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `1000` Не изменяется после создания."},
+ "resource_disk": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `20` Не изменяется после создания."},
+ "resource_instances": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `2` Не изменяется после создания."},
+ "resource_memory": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `2048` Не изменяется после создания."},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать платформу из списка Не изменяется после создания."},
+ "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 *MongodbResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *MongodbModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *MongodbModel
+ 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 MongodbModel
+ 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.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() {
+ if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить ip_space_name_master", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() {
+ if plan.NeedExternalAddressMaster.ValueString() != state.NeedExternalAddressMaster.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить need_external_address_master", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() {
+ if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() {
+ if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() {
+ if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() {
+ if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() {
+ if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.ResourceCPU.IsNull() || config.ResourceCPU.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_c_p_u is required.")
+ return
+ }
+ if config.ResourceDisk.IsNull() || config.ResourceDisk.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_disk is required.")
+ return
+ }
+ if config.ResourceInstances.IsNull() || config.ResourceInstances.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_instances is required.")
+ return
+ }
+ if config.ResourceMemory.IsNull() || config.ResourceMemory.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_memory is required.")
+ return
+ }
+ if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ 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{
+ 487: resources_core.FormatInt64(config.ResourceInstances),
+ 588: resources_core.FormatInt64(config.ResourceMemory),
+ 589: resources_core.FormatInt64(config.ResourceCPU),
+ 590: resources_core.FormatInt64(config.ResourceDisk),
+ 595: resources_core.FormatString(config.ResourceRealm),
+ 645: resources_core.FormatString(config.NeedExternalAddressMaster),
+ 646: resources_core.FormatString(config.IpSpaceNameMaster),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 92, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *MongodbResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data MongodbModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.ResourceCPU.IsNull() || data.ResourceCPU.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_c_p_u is required.")
+ return
+ }
+ if data.ResourceDisk.IsNull() || data.ResourceDisk.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_disk is required.")
+ return
+ }
+ if data.ResourceInstances.IsNull() || data.ResourceInstances.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_instances is required.")
+ return
+ }
+ if data.ResourceMemory.IsNull() || data.ResourceMemory.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_memory is required.")
+ return
+ }
+ if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 92, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 487: resources_core.FormatInt64(data.ResourceInstances),
+ 588: resources_core.FormatInt64(data.ResourceMemory),
+ 589: resources_core.FormatInt64(data.ResourceCPU),
+ 590: resources_core.FormatInt64(data.ResourceDisk),
+ 595: resources_core.FormatString(data.ResourceRealm),
+ 645: resources_core.FormatString(data.NeedExternalAddressMaster),
+ 646: resources_core.FormatString(data.IpSpaceNameMaster),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 92, 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, 92, 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: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"},
+ {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *MongodbResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state MongodbModel
+ 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(), 92, 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: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"},
+ {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *MongodbResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan MongodbModel
+ var state MongodbModel
+ 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 {
+ 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
+ }
+
+ params := map[int]string{}
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 92, 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: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"},
+ {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *MongodbResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state MongodbModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *MongodbResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *MongodbResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/92_mongodb_user_resource.go b/universal_rebuild/internal/resources_gen/92_mongodb_user_resource.go
new file mode 100644
index 0000000..67a7b2c
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/92_mongodb_user_resource.go
@@ -0,0 +1,340 @@
+package resources_gen
+
+import (
+ "context"
+ "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"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+ "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: mongodb
+// Subresource: user
+
+var _ resource.Resource = &MongodbUserResource{}
+
+// MongodbUserResource manages a subresource via operations.
+type MongodbUserResource struct {
+ client *core.UniversalClient
+}
+
+type MongodbUserModel struct {
+ ID types.String `tfsdk:"id"`
+ MongodbID types.String `tfsdk:"mongodb_id"`
+ AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"`
+ SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ DbName types.String `tfsdk:"db_name"`
+ Role types.String `tfsdk:"role"`
+ Username types.String `tfsdk:"username"`
+}
+
+func NewMongodbUserResource() resource.Resource {
+ return &MongodbUserResource{}
+}
+
+func (r *MongodbUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_mongodb_user"
+}
+
+func (r *MongodbUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "mongodb_id": schema.StringAttribute{
+ Required: true,
+ PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
+ },
+ "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(false)},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "db_name": schema.StringAttribute{Required: true},
+ "role": schema.StringAttribute{Required: true},
+ "username": schema.StringAttribute{Required: true, MarkdownDescription: "Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}},
+ }
+ resp.Schema = schema.Schema{Attributes: attrs}
+}
+
+func (r *MongodbUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan MongodbUserModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if plan.DbName.IsNull() || plan.DbName.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "db_name is required.")
+ return
+ }
+ if plan.Role.IsNull() || plan.Role.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "role is required.")
+ return
+ }
+ if plan.Username.IsNull() || plan.Username.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "username is required.")
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.MongodbID.ValueString())
+ if instanceUID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра")
+ return
+ }
+ adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool()
+
+ idParams := map[string]string{
+ "username": resources_core.FormatString(plan.Username),
+ }
+ identityCodes := []string{
+ "username",
+ }
+ listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes)
+ targetValue := strings.TrimSpace(idParams[idKey])
+ if targetValue == "" {
+ for _, code := range identityCodes {
+ candidate := strings.TrimSpace(idParams[code])
+ if candidate == "" {
+ continue
+ }
+ targetValue = candidate
+ idKey = code
+ break
+ }
+ }
+
+ if targetValue != "" {
+ found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if known && found {
+ if adoptExistingOnCreate {
+ plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams))
+ resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue)
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+ return
+ }
+ resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue)
+ return
+ }
+ }
+
+ params := resources_core.CompactParams(map[string]string{
+ "username": resources_core.FormatString(plan.Username),
+ "dbName": resources_core.FormatString(plan.DbName),
+ "role": resources_core.FormatString(plan.Role),
+ })
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout); err != nil {
+ if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(err) {
+ if targetValue != "" {
+ found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if checkErr != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error())
+ return
+ }
+ if known && found {
+ plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams))
+ resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление")
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+ return
+ }
+ }
+ resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out")
+ return
+ }
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if targetValue != "" {
+ found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if known && !found {
+ resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue)
+ return
+ }
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *MongodbUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state MongodbUserModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *MongodbUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan MongodbUserModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ if "modify_user" == "" {
+ var state MongodbUserModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if plan.ID.IsNull() || plan.ID.IsUnknown() {
+ plan.ID = state.ID
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.MongodbID.ValueString())
+ if instanceUID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра")
+ return
+ }
+
+ params := resources_core.CompactParams(map[string]string{
+ "username": resources_core.FormatString(plan.Username),
+ "dbName": resources_core.FormatString(plan.DbName),
+ "role": resources_core.FormatString(plan.Role),
+ })
+
+ idParams := map[string]string{
+ "username": resources_core.FormatString(plan.Username),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "modify_user", params, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *MongodbUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state MongodbUserModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ if "delete_user" == "" {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(state.MongodbID.ValueString())
+ if instanceUID == "" {
+ return
+ }
+ skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool()
+
+ idParams := map[string]string{
+ "username": resources_core.FormatString(state.Username),
+ }
+ identityCodes := []string{
+ "username",
+ }
+ listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes)
+ targetValue := strings.TrimSpace(idParams[idKey])
+ if targetValue == "" {
+ for _, code := range identityCodes {
+ candidate := strings.TrimSpace(idParams[code])
+ if candidate == "" {
+ continue
+ }
+ targetValue = candidate
+ idKey = code
+ break
+ }
+ }
+
+ if targetValue != "" {
+ found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if known && !found {
+ if skipMissingOnDelete {
+ resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue)
+ return
+ }
+ resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue)
+ return
+ }
+ }
+
+ params := resources_core.CompactParams(map[string]string{
+ "username": resources_core.FormatString(state.Username),
+ })
+
+ operationTimeout := ""
+ if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() {
+ operationTimeout = state.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_user", params, operationTimeout); err != nil {
+ if resources_core.IsSubresourceMissingError(err) {
+ if targetValue != "" {
+ found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if checkErr != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error())
+ return
+ }
+ if known && found {
+ resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue)
+ return
+ }
+ }
+ if skipMissingOnDelete {
+ resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено")
+ return
+ }
+ }
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ if targetValue != "" {
+ found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue)
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if known && found {
+ resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue)
+ return
+ }
+ }
+}
+
+func (r *MongodbUserResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/93_rabbitmq_resource.go b/universal_rebuild/internal/resources_gen/93_rabbitmq_resource.go
new file mode 100644
index 0000000..0e99b59
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/93_rabbitmq_resource.go
@@ -0,0 +1,465 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: rabbitmq
+// Service ID: 93
+
+var _ resource.Resource = &RabbitmqResource{}
+var _ resource.ResourceWithModifyPlan = &RabbitmqResource{}
+var _ resource.ResourceWithImportState = &RabbitmqResource{}
+
+type RabbitmqResource struct {
+ client *core.UniversalClient
+}
+
+type RabbitmqModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"`
+ IpSpaceNameSlave types.String `tfsdk:"ip_space_name_slave"`
+ NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"`
+ NeedExternalAddressSlave types.Bool `tfsdk:"need_external_address_slave"`
+ ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"`
+ ResourceDisk types.Int64 `tfsdk:"resource_disk"`
+ ResourceInstances types.Int64 `tfsdk:"resource_instances"`
+ ResourceMemory types.Int64 `tfsdk:"resource_memory"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+ 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 NewRabbitmqResource() resource.Resource {
+ return &RabbitmqResource{}
+}
+
+func (r *RabbitmqResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_rabbitmq"
+}
+
+func (r *RabbitmqResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Пример: `internet-no-antiddos-v1`"},
+ "ip_space_name_slave": schema.StringAttribute{Optional: true, MarkdownDescription: "Пример: `internet-no-antiddos-v1`"},
+ "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Флаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`"},
+ "need_external_address_slave": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Выделяет внешний (белый) IP для доступа к slave"},
+ "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1000), MarkdownDescription: "Пример: `2000`"},
+ "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(30), MarkdownDescription: "Пример: `20`"},
+ "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Пример: `1`"},
+ "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1124), MarkdownDescription: "Пример: `2048`"},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать платформу из списка Не изменяется после создания."},
+ "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 *RabbitmqResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *RabbitmqModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *RabbitmqModel
+ 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 RabbitmqModel
+ 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.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() {
+ if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ 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{
+ 116: resources_core.FormatInt64(config.ResourceCPU),
+ 117: resources_core.FormatInt64(config.ResourceMemory),
+ 118: resources_core.FormatInt64(config.ResourceDisk),
+ 119: resources_core.FormatString(config.ResourceRealm),
+ 224: resources_core.FormatInt64(config.ResourceInstances),
+ 225: resources_core.FormatBool(config.NeedExternalAddressMaster),
+ 543: resources_core.FormatString(config.IpSpaceNameMaster),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 93, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *RabbitmqResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data RabbitmqModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 93, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 116: resources_core.FormatInt64(data.ResourceCPU),
+ 117: resources_core.FormatInt64(data.ResourceMemory),
+ 118: resources_core.FormatInt64(data.ResourceDisk),
+ 119: resources_core.FormatString(data.ResourceRealm),
+ 224: resources_core.FormatInt64(data.ResourceInstances),
+ 225: resources_core.FormatBool(data.NeedExternalAddressMaster),
+ 543: resources_core.FormatString(data.IpSpaceNameMaster),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 93, 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, 93, 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: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"},
+ {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"},
+ {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"},
+ {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *RabbitmqResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state RabbitmqModel
+ 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(), 93, 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: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"},
+ {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"},
+ {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"},
+ {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *RabbitmqResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan RabbitmqModel
+ var state RabbitmqModel
+ 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.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() {
+ if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() {
+ if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() {
+ if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() {
+ if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.NeedExternalAddressMaster.IsNull() != state.NeedExternalAddressMaster.IsNull() || plan.NeedExternalAddressMaster.IsUnknown() != state.NeedExternalAddressMaster.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() {
+ if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.NeedExternalAddressSlave.IsNull() != state.NeedExternalAddressSlave.IsNull() || plan.NeedExternalAddressSlave.IsUnknown() != state.NeedExternalAddressSlave.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.NeedExternalAddressSlave.IsNull() && !plan.NeedExternalAddressSlave.IsUnknown() && !state.NeedExternalAddressSlave.IsNull() && !state.NeedExternalAddressSlave.IsUnknown() {
+ if plan.NeedExternalAddressSlave.ValueBool() != state.NeedExternalAddressSlave.ValueBool() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.IpSpaceNameMaster.IsNull() != state.IpSpaceNameMaster.IsNull() || plan.IpSpaceNameMaster.IsUnknown() != state.IpSpaceNameMaster.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() {
+ if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.IpSpaceNameSlave.IsNull() != state.IpSpaceNameSlave.IsNull() || plan.IpSpaceNameSlave.IsUnknown() != state.IpSpaceNameSlave.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.IpSpaceNameSlave.IsNull() && !plan.IpSpaceNameSlave.IsUnknown() && !state.IpSpaceNameSlave.IsNull() && !state.IpSpaceNameSlave.IsUnknown() {
+ if plan.IpSpaceNameSlave.ValueString() != state.IpSpaceNameSlave.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+
+ if !hasServiceParamChanges {
+ 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
+ }
+
+ params := map[int]string{
+ 304: resources_core.FormatInt64(plan.ResourceCPU),
+ 305: resources_core.FormatInt64(plan.ResourceMemory),
+ 306: resources_core.FormatInt64(plan.ResourceDisk),
+ 307: resources_core.FormatInt64(plan.ResourceInstances),
+ 308: resources_core.FormatBool(plan.NeedExternalAddressMaster),
+ 309: resources_core.FormatBool(plan.NeedExternalAddressSlave),
+ 545: resources_core.FormatString(plan.IpSpaceNameMaster),
+ 546: resources_core.FormatString(plan.IpSpaceNameSlave),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 93, 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: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"},
+ {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"},
+ {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"},
+ {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *RabbitmqResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state RabbitmqModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *RabbitmqResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *RabbitmqResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/94_lucee_redeploy_action.go b/universal_rebuild/internal/resources_gen/94_lucee_redeploy_action.go
new file mode 100644
index 0000000..635a4da
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/94_lucee_redeploy_action.go
@@ -0,0 +1,138 @@
+package resources_gen
+
+import (
+ "context"
+ "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"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: lucee
+// Action: redeploy
+
+var _ resource.Resource = &LuceeRedeployResource{}
+
+// LuceeRedeployResource triggers a one-time action.
+type LuceeRedeployResource struct {
+ client *core.UniversalClient
+}
+
+type LuceeRedeployModel struct {
+ ID types.String `tfsdk:"id"`
+ LuceeID types.String `tfsdk:"lucee_id"`
+ RunID types.String `tfsdk:"run_id"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+}
+
+func NewLuceeRedeployResource() resource.Resource {
+ return &LuceeRedeployResource{}
+}
+
+func (r *LuceeRedeployResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_lucee_redeploy"
+}
+
+func (r *LuceeRedeployResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "lucee_id": schema.StringAttribute{Required: true},
+ "run_id": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания"},
+ }
+ resp.Schema = schema.Schema{Attributes: attrs}
+}
+
+func (r *LuceeRedeployResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan LuceeRedeployModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if plan.ResourceRealm.IsNull() || plan.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.LuceeID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{
+ "resourceRealm": resources_core.FormatString(plan.ResourceRealm),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "redeploy", params, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *LuceeRedeployResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state LuceeRedeployModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *LuceeRedeployResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan LuceeRedeployModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.LuceeID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{
+ "resourceRealm": resources_core.FormatString(plan.ResourceRealm),
+ }
+
+ if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "redeploy", params); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *LuceeRedeployResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ // No-op: removing the resource does not trigger a remote action.
+}
+
+func (r *LuceeRedeployResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/94_lucee_resource.go b/universal_rebuild/internal/resources_gen/94_lucee_resource.go
new file mode 100644
index 0000000..09ccecc
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/94_lucee_resource.go
@@ -0,0 +1,466 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: lucee
+// Service ID: 94
+
+var _ resource.Resource = &LuceeResource{}
+var _ resource.ResourceWithModifyPlan = &LuceeResource{}
+var _ resource.ResourceWithImportState = &LuceeResource{}
+
+type LuceeResource struct {
+ client *core.UniversalClient
+}
+
+type LuceeModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ AppVersion types.String `tfsdk:"app_version"`
+ Domain types.String `tfsdk:"domain"`
+ GitPath types.String `tfsdk:"git_path"`
+ HealthPath types.String `tfsdk:"health_path"`
+ JsonEnv types.String `tfsdk:"json_env"`
+ ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"`
+ ResourceInstances types.Int64 `tfsdk:"resource_instances"`
+ ResourceMemory types.Int64 `tfsdk:"resource_memory"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+ 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 NewLuceeResource() resource.Resource {
+ return &LuceeResource{}
+}
+
+func (r *LuceeResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_lucee"
+}
+
+func (r *LuceeResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("5.4"), MarkdownDescription: "Версия Lucee"},
+ "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."},
+ "git_path": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("https://github.com/xahys/testlucee"), MarkdownDescription: "Путь до Git, который будет webroot для сайта"},
+ "health_path": schema.StringAttribute{Optional: true, MarkdownDescription: "Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код"},
+ "json_env": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{ \"param\": \"value\" }"), MarkdownDescription: "Здесь вы можете задать переменные среды в формате KEY=VALUE. Они будут доступны внутри вашего приложения."},
+ "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(300), MarkdownDescription: "Квота ядра пода (milicores)"},
+ "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"},
+ "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (MBytes)"},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."},
+ "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 *LuceeResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *LuceeModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *LuceeModel
+ 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 LuceeModel
+ 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.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() {
+ if plan.Domain.ValueString() != state.Domain.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() {
+ if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ 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{
+ 103: resources_core.FormatString(config.Domain),
+ 104: resources_core.FormatString(config.GitPath),
+ 105: resources_core.FormatString(config.JsonEnv),
+ 106: resources_core.FormatInt64(config.ResourceCPU),
+ 107: resources_core.FormatInt64(config.ResourceMemory),
+ 108: resources_core.FormatString(config.ResourceRealm),
+ 132: resources_core.FormatString(config.HealthPath),
+ 139: resources_core.FormatInt64(config.ResourceInstances),
+ 263: resources_core.FormatString(config.AppVersion),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 94, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *LuceeResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data LuceeModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 94, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 103: resources_core.FormatString(data.Domain),
+ 104: resources_core.FormatString(data.GitPath),
+ 105: resources_core.FormatString(data.JsonEnv),
+ 106: resources_core.FormatInt64(data.ResourceCPU),
+ 107: resources_core.FormatInt64(data.ResourceMemory),
+ 108: resources_core.FormatString(data.ResourceRealm),
+ 132: resources_core.FormatString(data.HealthPath),
+ 139: resources_core.FormatInt64(data.ResourceInstances),
+ 263: resources_core.FormatString(data.AppVersion),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 94, 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, 94, 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: "appVersion", Field: "AppVersion", Type: "string"},
+ {Code: "domain", Field: "Domain", Type: "string"},
+ {Code: "gitPath", Field: "GitPath", Type: "string"},
+ {Code: "healthPath", Field: "HealthPath", Type: "string"},
+ {Code: "jsonEnv", Field: "JsonEnv", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *LuceeResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state LuceeModel
+ 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(), 94, 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: "appVersion", Field: "AppVersion", Type: "string"},
+ {Code: "domain", Field: "Domain", Type: "string"},
+ {Code: "gitPath", Field: "GitPath", Type: "string"},
+ {Code: "healthPath", Field: "HealthPath", Type: "string"},
+ {Code: "jsonEnv", Field: "JsonEnv", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *LuceeResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan LuceeModel
+ var state LuceeModel
+ 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.GitPath.IsNull() != state.GitPath.IsNull() || plan.GitPath.IsUnknown() != state.GitPath.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.GitPath.IsNull() && !plan.GitPath.IsUnknown() && !state.GitPath.IsNull() && !state.GitPath.IsUnknown() {
+ if plan.GitPath.ValueString() != state.GitPath.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.HealthPath.IsNull() != state.HealthPath.IsNull() || plan.HealthPath.IsUnknown() != state.HealthPath.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.HealthPath.IsNull() && !plan.HealthPath.IsUnknown() && !state.HealthPath.IsNull() && !state.HealthPath.IsUnknown() {
+ if plan.HealthPath.ValueString() != state.HealthPath.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.JsonEnv.IsNull() != state.JsonEnv.IsNull() || plan.JsonEnv.IsUnknown() != state.JsonEnv.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.JsonEnv.IsNull() && !plan.JsonEnv.IsUnknown() && !state.JsonEnv.IsNull() && !state.JsonEnv.IsUnknown() {
+ if plan.JsonEnv.ValueString() != state.JsonEnv.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() {
+ if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() {
+ if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() {
+ if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.AppVersion.IsNull() != state.AppVersion.IsNull() || plan.AppVersion.IsUnknown() != state.AppVersion.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() {
+ if plan.AppVersion.ValueString() != state.AppVersion.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+
+ if !hasServiceParamChanges {
+ 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
+ }
+
+ params := map[int]string{
+ 133: resources_core.FormatString(plan.GitPath),
+ 134: resources_core.FormatString(plan.HealthPath),
+ 135: resources_core.FormatString(plan.JsonEnv),
+ 136: resources_core.FormatInt64(plan.ResourceCPU),
+ 137: resources_core.FormatInt64(plan.ResourceMemory),
+ 138: resources_core.FormatInt64(plan.ResourceInstances),
+ 264: resources_core.FormatString(plan.AppVersion),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 94, 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: "appVersion", Field: "AppVersion", Type: "string"},
+ {Code: "domain", Field: "Domain", Type: "string"},
+ {Code: "gitPath", Field: "GitPath", Type: "string"},
+ {Code: "healthPath", Field: "HealthPath", Type: "string"},
+ {Code: "jsonEnv", Field: "JsonEnv", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *LuceeResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state LuceeModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *LuceeResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *LuceeResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/94_lucee_restart_action.go b/universal_rebuild/internal/resources_gen/94_lucee_restart_action.go
new file mode 100644
index 0000000..4432ff7
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/94_lucee_restart_action.go
@@ -0,0 +1,128 @@
+package resources_gen
+
+import (
+ "context"
+ "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"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: lucee
+// Action: restart
+
+var _ resource.Resource = &LuceeRestartResource{}
+
+// LuceeRestartResource triggers a one-time action.
+type LuceeRestartResource struct {
+ client *core.UniversalClient
+}
+
+type LuceeRestartModel struct {
+ ID types.String `tfsdk:"id"`
+ LuceeID types.String `tfsdk:"lucee_id"`
+ RunID types.String `tfsdk:"run_id"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+}
+
+func NewLuceeRestartResource() resource.Resource {
+ return &LuceeRestartResource{}
+}
+
+func (r *LuceeRestartResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_lucee_restart"
+}
+
+func (r *LuceeRestartResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "lucee_id": schema.StringAttribute{Required: true},
+ "run_id": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ }
+ resp.Schema = schema.Schema{Attributes: attrs}
+}
+
+func (r *LuceeRestartResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan LuceeRestartModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.LuceeID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{}
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "restart", params, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *LuceeRestartResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state LuceeRestartModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *LuceeRestartResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan LuceeRestartModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.LuceeID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{}
+
+ if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "restart", params); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *LuceeRestartResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ // No-op: removing the resource does not trigger a remote action.
+}
+
+func (r *LuceeRestartResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/95_nodejs_redeploy_action.go b/universal_rebuild/internal/resources_gen/95_nodejs_redeploy_action.go
new file mode 100644
index 0000000..11804bc
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/95_nodejs_redeploy_action.go
@@ -0,0 +1,138 @@
+package resources_gen
+
+import (
+ "context"
+ "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"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: nodejs
+// Action: redeploy
+
+var _ resource.Resource = &NodejsRedeployResource{}
+
+// NodejsRedeployResource triggers a one-time action.
+type NodejsRedeployResource struct {
+ client *core.UniversalClient
+}
+
+type NodejsRedeployModel struct {
+ ID types.String `tfsdk:"id"`
+ NodejsID types.String `tfsdk:"nodejs_id"`
+ RunID types.String `tfsdk:"run_id"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+}
+
+func NewNodejsRedeployResource() resource.Resource {
+ return &NodejsRedeployResource{}
+}
+
+func (r *NodejsRedeployResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_nodejs_redeploy"
+}
+
+func (r *NodejsRedeployResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "nodejs_id": schema.StringAttribute{Required: true},
+ "run_id": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания"},
+ }
+ resp.Schema = schema.Schema{Attributes: attrs}
+}
+
+func (r *NodejsRedeployResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan NodejsRedeployModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if plan.ResourceRealm.IsNull() || plan.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.NodejsID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{
+ "resourceRealm": resources_core.FormatString(plan.ResourceRealm),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "redeploy", params, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *NodejsRedeployResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state NodejsRedeployModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *NodejsRedeployResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan NodejsRedeployModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.NodejsID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{
+ "resourceRealm": resources_core.FormatString(plan.ResourceRealm),
+ }
+
+ if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "redeploy", params); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *NodejsRedeployResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ // No-op: removing the resource does not trigger a remote action.
+}
+
+func (r *NodejsRedeployResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/95_nodejs_resource.go b/universal_rebuild/internal/resources_gen/95_nodejs_resource.go
new file mode 100644
index 0000000..a6be789
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/95_nodejs_resource.go
@@ -0,0 +1,466 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: nodejs
+// Service ID: 95
+
+var _ resource.Resource = &NodejsResource{}
+var _ resource.ResourceWithModifyPlan = &NodejsResource{}
+var _ resource.ResourceWithImportState = &NodejsResource{}
+
+type NodejsResource struct {
+ client *core.UniversalClient
+}
+
+type NodejsModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ AppVersion types.String `tfsdk:"app_version"`
+ Domain types.String `tfsdk:"domain"`
+ GitPath types.String `tfsdk:"git_path"`
+ HealthPath types.String `tfsdk:"health_path"`
+ JsonEnv types.String `tfsdk:"json_env"`
+ ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"`
+ ResourceInstances types.Int64 `tfsdk:"resource_instances"`
+ ResourceMemory types.Int64 `tfsdk:"resource_memory"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+ 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 NewNodejsResource() resource.Resource {
+ return &NodejsResource{}
+}
+
+func (r *NodejsResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_nodejs"
+}
+
+func (r *NodejsResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("23"), MarkdownDescription: "Версия приложения"},
+ "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."},
+ "git_path": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("https://github.com/xahys/testnode.git"), MarkdownDescription: "Путь до Git, который будет webroot для сайта"},
+ "health_path": schema.StringAttribute{Optional: true, MarkdownDescription: "Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код. Если оставить пустым, healtcheck'а не будет"},
+ "json_env": schema.StringAttribute{Optional: true, MarkdownDescription: "Массив переменных, будут переданы в env приложения"},
+ "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (milicores). 1000Mili = 1 Ядро"},
+ "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"},
+ "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1024), MarkdownDescription: "Квота памяти пода (MBytes)"},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."},
+ "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 *NodejsResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *NodejsModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *NodejsModel
+ 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 NodejsModel
+ 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.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() {
+ if plan.Domain.ValueString() != state.Domain.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() {
+ if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ 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{
+ 149: resources_core.FormatString(config.Domain),
+ 150: resources_core.FormatString(config.GitPath),
+ 151: resources_core.FormatString(config.HealthPath),
+ 152: resources_core.FormatString(config.JsonEnv),
+ 153: resources_core.FormatInt64(config.ResourceCPU),
+ 154: resources_core.FormatInt64(config.ResourceMemory),
+ 155: resources_core.FormatInt64(config.ResourceInstances),
+ 156: resources_core.FormatString(config.ResourceRealm),
+ 270: resources_core.FormatString(config.AppVersion),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 95, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *NodejsResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data NodejsModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 95, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 149: resources_core.FormatString(data.Domain),
+ 150: resources_core.FormatString(data.GitPath),
+ 151: resources_core.FormatString(data.HealthPath),
+ 152: resources_core.FormatString(data.JsonEnv),
+ 153: resources_core.FormatInt64(data.ResourceCPU),
+ 154: resources_core.FormatInt64(data.ResourceMemory),
+ 155: resources_core.FormatInt64(data.ResourceInstances),
+ 156: resources_core.FormatString(data.ResourceRealm),
+ 270: resources_core.FormatString(data.AppVersion),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 95, 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, 95, 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: "appVersion", Field: "AppVersion", Type: "string"},
+ {Code: "domain", Field: "Domain", Type: "string"},
+ {Code: "gitPath", Field: "GitPath", Type: "string"},
+ {Code: "healthPath", Field: "HealthPath", Type: "string"},
+ {Code: "jsonEnv", Field: "JsonEnv", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *NodejsResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state NodejsModel
+ 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(), 95, 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: "appVersion", Field: "AppVersion", Type: "string"},
+ {Code: "domain", Field: "Domain", Type: "string"},
+ {Code: "gitPath", Field: "GitPath", Type: "string"},
+ {Code: "healthPath", Field: "HealthPath", Type: "string"},
+ {Code: "jsonEnv", Field: "JsonEnv", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *NodejsResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan NodejsModel
+ var state NodejsModel
+ 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.GitPath.IsNull() != state.GitPath.IsNull() || plan.GitPath.IsUnknown() != state.GitPath.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.GitPath.IsNull() && !plan.GitPath.IsUnknown() && !state.GitPath.IsNull() && !state.GitPath.IsUnknown() {
+ if plan.GitPath.ValueString() != state.GitPath.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.HealthPath.IsNull() != state.HealthPath.IsNull() || plan.HealthPath.IsUnknown() != state.HealthPath.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.HealthPath.IsNull() && !plan.HealthPath.IsUnknown() && !state.HealthPath.IsNull() && !state.HealthPath.IsUnknown() {
+ if plan.HealthPath.ValueString() != state.HealthPath.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.JsonEnv.IsNull() != state.JsonEnv.IsNull() || plan.JsonEnv.IsUnknown() != state.JsonEnv.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.JsonEnv.IsNull() && !plan.JsonEnv.IsUnknown() && !state.JsonEnv.IsNull() && !state.JsonEnv.IsUnknown() {
+ if plan.JsonEnv.ValueString() != state.JsonEnv.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() {
+ if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() {
+ if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() {
+ if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.AppVersion.IsNull() != state.AppVersion.IsNull() || plan.AppVersion.IsUnknown() != state.AppVersion.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() {
+ if plan.AppVersion.ValueString() != state.AppVersion.ValueString() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+
+ if !hasServiceParamChanges {
+ 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
+ }
+
+ params := map[int]string{
+ 157: resources_core.FormatString(plan.GitPath),
+ 158: resources_core.FormatString(plan.HealthPath),
+ 159: resources_core.FormatString(plan.JsonEnv),
+ 160: resources_core.FormatInt64(plan.ResourceCPU),
+ 161: resources_core.FormatInt64(plan.ResourceMemory),
+ 162: resources_core.FormatInt64(plan.ResourceInstances),
+ 271: resources_core.FormatString(plan.AppVersion),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 95, 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: "appVersion", Field: "AppVersion", Type: "string"},
+ {Code: "domain", Field: "Domain", Type: "string"},
+ {Code: "gitPath", Field: "GitPath", Type: "string"},
+ {Code: "healthPath", Field: "HealthPath", Type: "string"},
+ {Code: "jsonEnv", Field: "JsonEnv", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *NodejsResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state NodejsModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *NodejsResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *NodejsResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/96_pgadmin_redeploy_action.go b/universal_rebuild/internal/resources_gen/96_pgadmin_redeploy_action.go
new file mode 100644
index 0000000..2ad2820
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/96_pgadmin_redeploy_action.go
@@ -0,0 +1,138 @@
+package resources_gen
+
+import (
+ "context"
+ "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"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: pgadmin
+// Action: redeploy
+
+var _ resource.Resource = &PgadminRedeployResource{}
+
+// PgadminRedeployResource triggers a one-time action.
+type PgadminRedeployResource struct {
+ client *core.UniversalClient
+}
+
+type PgadminRedeployModel struct {
+ ID types.String `tfsdk:"id"`
+ PgadminID types.String `tfsdk:"pgadmin_id"`
+ RunID types.String `tfsdk:"run_id"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+}
+
+func NewPgadminRedeployResource() resource.Resource {
+ return &PgadminRedeployResource{}
+}
+
+func (r *PgadminRedeployResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_pgadmin_redeploy"
+}
+
+func (r *PgadminRedeployResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "pgadmin_id": schema.StringAttribute{Required: true},
+ "run_id": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания"},
+ }
+ resp.Schema = schema.Schema{Attributes: attrs}
+}
+
+func (r *PgadminRedeployResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan PgadminRedeployModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if plan.ResourceRealm.IsNull() || plan.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.PgadminID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{
+ "resourceRealm": resources_core.FormatString(plan.ResourceRealm),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "redeploy", params, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *PgadminRedeployResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state PgadminRedeployModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *PgadminRedeployResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan PgadminRedeployModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.PgadminID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{
+ "resourceRealm": resources_core.FormatString(plan.ResourceRealm),
+ }
+
+ if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "redeploy", params); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *PgadminRedeployResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ // No-op: removing the resource does not trigger a remote action.
+}
+
+func (r *PgadminRedeployResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/96_pgadmin_resource.go b/universal_rebuild/internal/resources_gen/96_pgadmin_resource.go
new file mode 100644
index 0000000..f94e314
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/96_pgadmin_resource.go
@@ -0,0 +1,440 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: pgadmin
+// Service ID: 96
+
+var _ resource.Resource = &PgadminResource{}
+var _ resource.ResourceWithModifyPlan = &PgadminResource{}
+var _ resource.ResourceWithImportState = &PgadminResource{}
+
+type PgadminResource struct {
+ client *core.UniversalClient
+}
+
+type PgadminModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ Domain types.String `tfsdk:"domain"`
+ Login types.String `tfsdk:"login"`
+ Password types.String `tfsdk:"password"`
+ ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"`
+ ResourceDisk types.Int64 `tfsdk:"resource_disk"`
+ ResourceMemory types.Int64 `tfsdk:"resource_memory"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+ 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 NewPgadminResource() resource.Resource {
+ return &PgadminResource{}
+}
+
+func (r *PgadminResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_pgadmin"
+}
+
+func (r *PgadminResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."},
+ "login": schema.StringAttribute{Required: true, MarkdownDescription: "Логин для подключения к pgAdmin, в формате email (login@email.net) Не изменяется после создания."},
+ "password": schema.StringAttribute{Required: true, MarkdownDescription: "Пароль для подключения к pgAdmin Не изменяется после создания.", Sensitive: true},
+ "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(200), MarkdownDescription: "Квота ядра пода (milicores). 1000Mili = 1 Ядро"},
+ "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"},
+ "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(256), MarkdownDescription: "Квота памяти пода (MBytes)"},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."},
+ "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 *PgadminResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *PgadminModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *PgadminModel
+ 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 PgadminModel
+ 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.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() {
+ if plan.Domain.ValueString() != state.Domain.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.Login.IsNull() && !plan.Login.IsUnknown() && !state.Login.IsNull() && !state.Login.IsUnknown() {
+ if plan.Login.ValueString() != state.Login.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить login", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.Password.IsNull() && !plan.Password.IsUnknown() && !state.Password.IsNull() && !state.Password.IsUnknown() {
+ if plan.Password.ValueString() != state.Password.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить password", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() {
+ if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.Login.IsNull() || config.Login.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "login is required.")
+ return
+ }
+ if config.Password.IsNull() || config.Password.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "password is required.")
+ return
+ }
+ if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ 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{
+ 164: resources_core.FormatString(config.Domain),
+ 165: resources_core.FormatInt64(config.ResourceCPU),
+ 166: resources_core.FormatInt64(config.ResourceMemory),
+ 167: resources_core.FormatInt64(config.ResourceDisk),
+ 169: resources_core.FormatString(config.ResourceRealm),
+ 170: resources_core.FormatString(config.Login),
+ 171: resources_core.FormatString(config.Password),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 96, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *PgadminResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data PgadminModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.Login.IsNull() || data.Login.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "login is required.")
+ return
+ }
+ if data.Password.IsNull() || data.Password.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "password is required.")
+ return
+ }
+ if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 96, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 164: resources_core.FormatString(data.Domain),
+ 165: resources_core.FormatInt64(data.ResourceCPU),
+ 166: resources_core.FormatInt64(data.ResourceMemory),
+ 167: resources_core.FormatInt64(data.ResourceDisk),
+ 169: resources_core.FormatString(data.ResourceRealm),
+ 170: resources_core.FormatString(data.Login),
+ 171: resources_core.FormatString(data.Password),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 96, 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, 96, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "login", Field: "Login", Type: "string"},
+ {Code: "password", Field: "Password", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *PgadminResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state PgadminModel
+ 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(), 96, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "login", Field: "Login", Type: "string"},
+ {Code: "password", Field: "Password", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *PgadminResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan PgadminModel
+ var state PgadminModel
+ 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.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() {
+ if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() {
+ if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() {
+ if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+
+ if !hasServiceParamChanges {
+ 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
+ }
+
+ params := map[int]string{
+ 172: resources_core.FormatInt64(plan.ResourceCPU),
+ 173: resources_core.FormatInt64(plan.ResourceMemory),
+ 174: resources_core.FormatInt64(plan.ResourceDisk),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 96, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "login", Field: "Login", Type: "string"},
+ {Code: "password", Field: "Password", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *PgadminResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state PgadminModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *PgadminResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *PgadminResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/97_nodered_resource.go b/universal_rebuild/internal/resources_gen/97_nodered_resource.go
new file mode 100644
index 0000000..6ce2414
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/97_nodered_resource.go
@@ -0,0 +1,405 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: nodered
+// Service ID: 97
+
+var _ resource.Resource = &NoderedResource{}
+var _ resource.ResourceWithModifyPlan = &NoderedResource{}
+var _ resource.ResourceWithImportState = &NoderedResource{}
+
+type NoderedResource struct {
+ client *core.UniversalClient
+}
+
+type NoderedModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ Domain types.String `tfsdk:"domain"`
+ ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"`
+ ResourceDisk types.Int64 `tfsdk:"resource_disk"`
+ ResourceInstances types.Int64 `tfsdk:"resource_instances"`
+ ResourceMemory types.Int64 `tfsdk:"resource_memory"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+ 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 NewNoderedResource() resource.Resource {
+ return &NoderedResource{}
+}
+
+func (r *NoderedResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_nodered"
+}
+
+func (r *NoderedResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "domain": schema.StringAttribute{Required: true, MarkdownDescription: "Наименование поддомена, будет добавлено в k8stemplate.dev.nubes.ru Не изменяется после создания."},
+ "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро Не изменяется после создания."},
+ "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes) Не изменяется после создания."},
+ "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."},
+ "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes) Не изменяется после создания."},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."},
+ "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)},
+ "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 *NoderedResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *NoderedModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *NoderedModel
+ 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 NoderedModel
+ 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.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() {
+ if plan.Domain.ValueString() != state.Domain.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() {
+ if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() {
+ if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() {
+ if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() {
+ if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() {
+ if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.Domain.IsNull() || config.Domain.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "domain is required.")
+ return
+ }
+ if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ 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{
+ 193: resources_core.FormatInt64(config.ResourceCPU),
+ 194: resources_core.FormatInt64(config.ResourceMemory),
+ 195: resources_core.FormatInt64(config.ResourceDisk),
+ 196: resources_core.FormatString(config.ResourceRealm),
+ 197: resources_core.FormatString(config.Domain),
+ 323: resources_core.FormatInt64(config.ResourceInstances),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 97, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *NoderedResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data NoderedModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.Domain.IsNull() || data.Domain.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "domain is required.")
+ return
+ }
+ if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 97, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 193: resources_core.FormatInt64(data.ResourceCPU),
+ 194: resources_core.FormatInt64(data.ResourceMemory),
+ 195: resources_core.FormatInt64(data.ResourceDisk),
+ 196: resources_core.FormatString(data.ResourceRealm),
+ 197: resources_core.FormatString(data.Domain),
+ 323: resources_core.FormatInt64(data.ResourceInstances),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 97, 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, 97, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *NoderedResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state NoderedModel
+ 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(), 97, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *NoderedResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan NoderedModel
+ var state NoderedModel
+ 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 {
+ 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
+ }
+
+ params := map[int]string{}
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 97, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *NoderedResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state NoderedModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *NoderedResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *NoderedResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/98_http_redeploy_action.go b/universal_rebuild/internal/resources_gen/98_http_redeploy_action.go
new file mode 100644
index 0000000..a3f4ea0
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/98_http_redeploy_action.go
@@ -0,0 +1,138 @@
+package resources_gen
+
+import (
+ "context"
+ "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"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: http
+// Action: redeploy
+
+var _ resource.Resource = &HttpRedeployResource{}
+
+// HttpRedeployResource triggers a one-time action.
+type HttpRedeployResource struct {
+ client *core.UniversalClient
+}
+
+type HttpRedeployModel struct {
+ ID types.String `tfsdk:"id"`
+ HttpID types.String `tfsdk:"http_id"`
+ RunID types.String `tfsdk:"run_id"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+}
+
+func NewHttpRedeployResource() resource.Resource {
+ return &HttpRedeployResource{}
+}
+
+func (r *HttpRedeployResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_http_redeploy"
+}
+
+func (r *HttpRedeployResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "http_id": schema.StringAttribute{Required: true},
+ "run_id": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания"},
+ }
+ resp.Schema = schema.Schema{Attributes: attrs}
+}
+
+func (r *HttpRedeployResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan HttpRedeployModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if plan.ResourceRealm.IsNull() || plan.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.HttpID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{
+ "resourceRealm": resources_core.FormatString(plan.ResourceRealm),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "redeploy", params, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *HttpRedeployResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state HttpRedeployModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *HttpRedeployResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan HttpRedeployModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ instanceUID := strings.TrimSpace(plan.HttpID.ValueString())
+ runID := strings.TrimSpace(plan.RunID.ValueString())
+ if instanceUID == "" || runID == "" {
+ resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id")
+ return
+ }
+
+ params := map[string]string{
+ "resourceRealm": resources_core.FormatString(plan.ResourceRealm),
+ }
+
+ if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "redeploy", params); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+
+ plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID))
+ resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
+}
+
+func (r *HttpRedeployResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ // No-op: removing the resource does not trigger a remote action.
+}
+
+func (r *HttpRedeployResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/98_http_resource.go b/universal_rebuild/internal/resources_gen/98_http_resource.go
new file mode 100644
index 0000000..63dbf17
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/98_http_resource.go
@@ -0,0 +1,424 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: http
+// Service ID: 98
+
+var _ resource.Resource = &HttpResource{}
+var _ resource.ResourceWithModifyPlan = &HttpResource{}
+var _ resource.ResourceWithImportState = &HttpResource{}
+
+type HttpResource struct {
+ client *core.UniversalClient
+}
+
+type HttpModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ Domain types.String `tfsdk:"domain"`
+ JsonEnv types.String `tfsdk:"json_env"`
+ RegistryPath types.String `tfsdk:"registry_path"`
+ ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"`
+ ResourceInstances types.Int64 `tfsdk:"resource_instances"`
+ ResourceMemory types.Int64 `tfsdk:"resource_memory"`
+ ResourceRealm types.String `tfsdk:"resource_realm"`
+ 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 NewHttpResource() resource.Resource {
+ return &HttpResource{}
+}
+
+func (r *HttpResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_http"
+}
+
+func (r *HttpResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."},
+ "json_env": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{"param": "value"}"), MarkdownDescription: "Массив переменных, будут переданы в env приложения Не изменяется после создания."},
+ "registry_path": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("nexus-sa.tst.nubes.ru/docker-nubes/jolt"), MarkdownDescription: "Путь до image, который будет установлен как deployment Не изменяется после создания."},
+ "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(100), MarkdownDescription: "Квота ядра пода (Указывается в mili)"},
+ "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"},
+ "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(200), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes)"},
+ "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."},
+ "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 *HttpResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *HttpModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *HttpModel
+ 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 HttpModel
+ 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.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() {
+ if plan.Domain.ValueString() != state.Domain.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.JsonEnv.IsNull() && !plan.JsonEnv.IsUnknown() && !state.JsonEnv.IsNull() && !state.JsonEnv.IsUnknown() {
+ if plan.JsonEnv.ValueString() != state.JsonEnv.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить json_env", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.RegistryPath.IsNull() && !plan.RegistryPath.IsUnknown() && !state.RegistryPath.IsNull() && !state.RegistryPath.IsUnknown() {
+ if plan.RegistryPath.ValueString() != state.RegistryPath.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить registry_path", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() {
+ if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ 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{
+ 212: resources_core.FormatString(config.Domain),
+ 213: resources_core.FormatInt64(config.ResourceCPU),
+ 214: resources_core.FormatInt64(config.ResourceMemory),
+ 215: resources_core.FormatInt64(config.ResourceInstances),
+ 216: resources_core.FormatString(config.ResourceRealm),
+ 217: resources_core.FormatString(config.RegistryPath),
+ 241: resources_core.FormatString(config.JsonEnv),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 98, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *HttpResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data HttpModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
+ return
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 98, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 212: resources_core.FormatString(data.Domain),
+ 213: resources_core.FormatInt64(data.ResourceCPU),
+ 214: resources_core.FormatInt64(data.ResourceMemory),
+ 215: resources_core.FormatInt64(data.ResourceInstances),
+ 216: resources_core.FormatString(data.ResourceRealm),
+ 217: resources_core.FormatString(data.RegistryPath),
+ 241: resources_core.FormatString(data.JsonEnv),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 98, 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, 98, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "jsonEnv", Field: "JsonEnv", Type: "string"},
+ {Code: "registryPath", Field: "RegistryPath", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *HttpResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state HttpModel
+ 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(), 98, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "jsonEnv", Field: "JsonEnv", Type: "string"},
+ {Code: "registryPath", Field: "RegistryPath", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *HttpResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan HttpModel
+ var state HttpModel
+ 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.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() {
+ if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() {
+ if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() {
+ if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+
+ if !hasServiceParamChanges {
+ 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
+ }
+
+ params := map[int]string{
+ 218: resources_core.FormatInt64(plan.ResourceCPU),
+ 219: resources_core.FormatInt64(plan.ResourceMemory),
+ 220: resources_core.FormatInt64(plan.ResourceInstances),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 98, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "jsonEnv", Field: "JsonEnv", Type: "string"},
+ {Code: "registryPath", Field: "RegistryPath", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *HttpResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state HttpModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *HttpResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *HttpResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/99_gitea_resource.go b/universal_rebuild/internal/resources_gen/99_gitea_resource.go
new file mode 100644
index 0000000..b2a90ac
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/99_gitea_resource.go
@@ -0,0 +1,473 @@
+package resources_gen
+
+import (
+ "context"
+
+ "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/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+// Service: gitea
+// Service ID: 99
+
+var _ resource.Resource = &GiteaResource{}
+var _ resource.ResourceWithModifyPlan = &GiteaResource{}
+var _ resource.ResourceWithImportState = &GiteaResource{}
+
+type GiteaResource struct {
+ client *core.UniversalClient
+}
+
+type GiteaModel struct {
+ ID types.String `tfsdk:"id"`
+ ResourceName types.String `tfsdk:"resource_name"`
+ OperationTimeout types.String `tfsdk:"operation_timeout"`
+ Domain types.String `tfsdk:"domain"`
+ PsqlUid types.String `tfsdk:"psql_uid"`
+ ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"`
+ ResourceDisk types.Int64 `tfsdk:"resource_disk"`
+ ResourceInstances types.Int64 `tfsdk:"resource_instances"`
+ ResourceMemory types.Int64 `tfsdk:"resource_memory"`
+ 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 NewGiteaResource() resource.Resource {
+ return &GiteaResource{}
+}
+
+func (r *GiteaResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_gitea"
+}
+
+func (r *GiteaResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ attrs := map[string]schema.Attribute{
+ "id": schema.StringAttribute{Computed: true},
+ "resource_name": schema.StringAttribute{Required: true},
+ "operation_timeout": schema.StringAttribute{Optional: true},
+ "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."},
+ "psql_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UUID Услуги k8sPgsql. Пользователя techGitea, базу данных gitea создаёт автоматически Не изменяется после создания."},
+ "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро"},
+ "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"},
+ "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"},
+ "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes)"},
+ "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 *GiteaResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ if r.client == nil {
+ return
+ }
+
+ var config *GiteaModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if config == nil {
+ return
+ }
+
+ var state *GiteaModel
+ 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 GiteaModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ planChanged := false
+ if !plan.PsqlUid.IsNull() && !plan.PsqlUid.IsUnknown() {
+ resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, plan.PsqlUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error())
+ } else if resolvedPsqlUid != "" && resolvedPsqlUid != plan.PsqlUid.ValueString() {
+ plan.PsqlUid = types.StringValue(resolvedPsqlUid)
+ planChanged = true
+ }
+ }
+ if planChanged {
+ resp.Diagnostics.Append(resp.Plan.Set(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.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() {
+ if plan.Domain.ValueString() != state.Domain.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ if !plan.PsqlUid.IsNull() && !plan.PsqlUid.IsUnknown() && !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() {
+ if plan.PsqlUid.ValueString() != state.PsqlUid.ValueString() {
+ resp.Diagnostics.AddError("Нельзя изменить psql_uid", "Параметр задается при создании и не может быть изменен.")
+ return
+ }
+ }
+ return
+ }
+ if config.PsqlUid.IsNull() || config.PsqlUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "psql_uid is required.")
+ return
+ }
+
+ if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() {
+ return
+ }
+ adoptExistingOnCreate := false
+ if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() {
+ adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool()
+ }
+ if !config.PsqlUid.IsNull() && !config.PsqlUid.IsUnknown() {
+ resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, config.PsqlUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error())
+ } else if resolvedPsqlUid != "" && resolvedPsqlUid != config.PsqlUid.ValueString() {
+ config.PsqlUid = types.StringValue(resolvedPsqlUid)
+ }
+ }
+ params := map[int]string{
+ 232: resources_core.FormatInt64(config.ResourceCPU),
+ 233: resources_core.FormatInt64(config.ResourceMemory),
+ 234: resources_core.FormatInt64(config.ResourceDisk),
+ 235: resources_core.FormatInt64(config.ResourceInstances),
+ 237: resources_core.FormatString(config.Domain),
+ 238: resources_core.FormatString(config.PsqlUid),
+ }
+
+ resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 99, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
+}
+
+func (r *GiteaResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data GiteaModel
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if data.PsqlUid.IsNull() || data.PsqlUid.IsUnknown() {
+ resp.Diagnostics.AddError("Missing required attribute", "psql_uid is required.")
+ return
+ }
+ if !data.PsqlUid.IsNull() && !data.PsqlUid.IsUnknown() {
+ resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, data.PsqlUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+ if resolvedPsqlUid != "" && resolvedPsqlUid != data.PsqlUid.ValueString() {
+ data.PsqlUid = types.StringValue(resolvedPsqlUid)
+ }
+ }
+
+ resourceName := data.ResourceName.ValueString()
+ resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 99, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
+
+ params := map[int]string{
+ 232: resources_core.FormatInt64(data.ResourceCPU),
+ 233: resources_core.FormatInt64(data.ResourceMemory),
+ 234: resources_core.FormatInt64(data.ResourceDisk),
+ 235: resources_core.FormatInt64(data.ResourceInstances),
+ 237: resources_core.FormatString(data.Domain),
+ 238: resources_core.FormatString(data.PsqlUid),
+ }
+
+ operationTimeout := ""
+ if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
+ operationTimeout = data.OperationTimeout.ValueString()
+ }
+ id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 99, 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, 99, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "psqlUid", Field: "PsqlUid", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() {
+ resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, state.PsqlUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error())
+ } else if resolvedPsqlUid != "" && resolvedPsqlUid != state.PsqlUid.ValueString() {
+ state.PsqlUid = types.StringValue(resolvedPsqlUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *GiteaResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state GiteaModel
+ 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(), 99, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "psqlUid", Field: "PsqlUid", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !newState.PsqlUid.IsNull() && !newState.PsqlUid.IsUnknown() {
+ resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, newState.PsqlUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error())
+ } else if resolvedPsqlUid != "" && resolvedPsqlUid != newState.PsqlUid.ValueString() {
+ newState.PsqlUid = types.StringValue(resolvedPsqlUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
+}
+
+func (r *GiteaResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan GiteaModel
+ var state GiteaModel
+ 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.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() {
+ if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() {
+ if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() {
+ if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+ if !hasServiceParamChanges {
+ if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() {
+ hasServiceParamChanges = true
+ } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() {
+ if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() {
+ hasServiceParamChanges = true
+ }
+ }
+ }
+
+ if !hasServiceParamChanges {
+ 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
+ }
+
+ params := map[int]string{
+ 259: resources_core.FormatInt64(plan.ResourceCPU),
+ 260: resources_core.FormatInt64(plan.ResourceMemory),
+ 261: resources_core.FormatInt64(plan.ResourceDisk),
+ 262: resources_core.FormatInt64(plan.ResourceInstances),
+ }
+
+ operationTimeout := ""
+ if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
+ operationTimeout = plan.OperationTimeout.ValueString()
+ }
+ 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(), 99, 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: "domain", Field: "Domain", Type: "string"},
+ {Code: "psqlUid", Field: "PsqlUid", Type: "string"},
+ {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
+ {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
+ {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
+ {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
+ })
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ if !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() {
+ resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, state.PsqlUid.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error())
+ } else if resolvedPsqlUid != "" && resolvedPsqlUid != state.PsqlUid.ValueString() {
+ state.PsqlUid = types.StringValue(resolvedPsqlUid)
+ }
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *GiteaResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state GiteaModel
+ 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 err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil {
+ resp.Diagnostics.AddError("Ошибка клиента", err.Error())
+ return
+ }
+}
+
+func (r *GiteaResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
+
+func (r *GiteaResource) 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
+}
diff --git a/universal_rebuild/internal/resources_gen/registry.go b/universal_rebuild/internal/resources_gen/registry.go
new file mode 100644
index 0000000..183b8c8
--- /dev/null
+++ b/universal_rebuild/internal/resources_gen/registry.go
@@ -0,0 +1,76 @@
+package resources_gen
+
+import "github.com/hashicorp/terraform-plugin-framework/resource"
+
+// Code generated by tools/gen_v2. DO NOT EDIT.
+func AllResources() []func() resource.Resource {
+ return []func() resource.Resource{
+ NewAkhqResource,
+ NewClickhouseResource,
+ NewDnsrecordResource,
+ NewDnszoneResource,
+ NewDummyResource,
+ NewFlaskResource,
+ NewGiteaResource,
+ NewGiteaComplexResource,
+ NewHarborResource,
+ NewHttpResource,
+ NewK8sSthutrvalClusterResource,
+ NewK8sZitiControllerResource,
+ NewKafkaResource,
+ NewLuceeResource,
+ NewMariadbResource,
+ NewMongodbResource,
+ NewNextcloudResource,
+ NewNifiResource,
+ NewNodejsResource,
+ NewNoderedResource,
+ NewOpenwhiskResource,
+ NewPgadminResource,
+ NewPostgresResource,
+ NewRabbitmqResource,
+ NewRedisResource,
+ NewS3Resource,
+ NewS3bucketResource,
+ NewSupersetResource,
+ NewTemplateResource,
+ NewTenantResource,
+ NewValoTenantResource,
+ NewVappResource,
+ NewVcComplexResource,
+ NewVcNsxtResource,
+ NewVcOrgResource,
+ NewVcOrgSaasResource,
+ NewVcVdcResource,
+ NewVcVdcGroupResource,
+ NewVcVmResource,
+ NewVcVmV2Resource,
+ NewVcVmV3Resource,
+ NewVcexternalipResource,
+ NewVmpostgreResource,
+ NewClickhouseDatabaseResource,
+ NewClickhouseUserResource,
+ NewKafkaTopicResource,
+ NewKafkaUserResource,
+ NewMongodbUserResource,
+ NewS3SubUserResource,
+ NewDummyRedeployResource,
+ NewHttpRedeployResource,
+ NewK8sSthutrvalClusterReconcileResource,
+ NewK8sSthutrvalClusterUpdateSecretsResource,
+ NewLuceeRedeployResource,
+ NewLuceeRestartResource,
+ NewNextcloudRestartResource,
+ NewNodejsRedeployResource,
+ NewPgadminRedeployResource,
+ NewPostgresRecoveryResource,
+ NewPostgresRestartResource,
+ NewVcNsxtReconcileResource,
+ NewVcOrgReconcileResource,
+ NewVcVdcReconcileResource,
+ NewVcVdcGroupAddVdcResource,
+ NewVcVdcGroupReconcileResource,
+ NewVcVdcGroupRemoveVdcResource,
+ NewVcVmV3RedeployResource,
+ }
+}