add: generated resources batch 2/4
This commit is contained in:
@@ -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: kafka
|
||||
// Subresource: topic
|
||||
|
||||
var _ resource.Resource = &KafkaTopicResource{}
|
||||
|
||||
// KafkaTopicResource manages a subresource via operations.
|
||||
type KafkaTopicResource struct {
|
||||
client *core.UniversalClient
|
||||
}
|
||||
|
||||
type KafkaTopicModel struct {
|
||||
ID types.String `tfsdk:"id"`
|
||||
KafkaID types.String `tfsdk:"kafka_id"`
|
||||
AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"`
|
||||
SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"`
|
||||
OperationTimeout types.String `tfsdk:"operation_timeout"`
|
||||
NameTopic types.String `tfsdk:"name_topic"`
|
||||
Partitions types.Int64 `tfsdk:"partitions"`
|
||||
Replicas types.Int64 `tfsdk:"replicas"`
|
||||
}
|
||||
|
||||
func NewKafkaTopicResource() resource.Resource {
|
||||
return &KafkaTopicResource{}
|
||||
}
|
||||
|
||||
func (r *KafkaTopicResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_kafka_topic"
|
||||
}
|
||||
|
||||
func (r *KafkaTopicResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||
attrs := map[string]schema.Attribute{
|
||||
"id": schema.StringAttribute{Computed: true},
|
||||
"kafka_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},
|
||||
"name_topic": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `orders-events` Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}},
|
||||
"partitions": schema.Int64Attribute{Required: true, MarkdownDescription: "Число партиций можно увеличить, но уменьшить их нельзя."},
|
||||
"replicas": schema.Int64Attribute{Required: true, MarkdownDescription: "Количество реплик не может привышать количество реплик брокера"},
|
||||
}
|
||||
resp.Schema = schema.Schema{Attributes: attrs}
|
||||
}
|
||||
|
||||
func (r *KafkaTopicResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
var plan KafkaTopicModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if plan.NameTopic.IsNull() || plan.NameTopic.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "name_topic is required.")
|
||||
return
|
||||
}
|
||||
if plan.Partitions.IsNull() || plan.Partitions.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "partitions is required.")
|
||||
return
|
||||
}
|
||||
if plan.Replicas.IsNull() || plan.Replicas.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "replicas is required.")
|
||||
return
|
||||
}
|
||||
|
||||
instanceUID := strings.TrimSpace(plan.KafkaID.ValueString())
|
||||
if instanceUID == "" {
|
||||
resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра")
|
||||
return
|
||||
}
|
||||
adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool()
|
||||
|
||||
idParams := map[string]string{
|
||||
"nameTopic": resources_core.FormatString(plan.NameTopic),
|
||||
}
|
||||
identityCodes := []string{
|
||||
"nameTopic",
|
||||
}
|
||||
listKey, idKey := resources_core.ResolveSubresourceStateKeys("topic", 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, "topic", 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{
|
||||
"nameTopic": resources_core.FormatString(plan.NameTopic),
|
||||
"partitions": resources_core.FormatInt64(plan.Partitions),
|
||||
"replicas": resources_core.FormatInt64(plan.Replicas),
|
||||
})
|
||||
|
||||
operationTimeout := ""
|
||||
if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
|
||||
operationTimeout = plan.OperationTimeout.ValueString()
|
||||
}
|
||||
if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_topic", 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, "topic", 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, "topic", idParams))
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
|
||||
}
|
||||
|
||||
func (r *KafkaTopicResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
var state KafkaTopicModel
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
|
||||
func (r *KafkaTopicResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
var plan KafkaTopicModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if "modify_topic" == "" {
|
||||
var state KafkaTopicModel
|
||||
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.KafkaID.ValueString())
|
||||
if instanceUID == "" {
|
||||
resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра")
|
||||
return
|
||||
}
|
||||
|
||||
params := resources_core.CompactParams(map[string]string{
|
||||
"nameTopic": resources_core.FormatString(plan.NameTopic),
|
||||
"partitions": resources_core.FormatInt64(plan.Partitions),
|
||||
"replicas": resources_core.FormatInt64(plan.Replicas),
|
||||
})
|
||||
|
||||
idParams := map[string]string{
|
||||
"nameTopic": resources_core.FormatString(plan.NameTopic),
|
||||
}
|
||||
|
||||
operationTimeout := ""
|
||||
if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
|
||||
operationTimeout = plan.OperationTimeout.ValueString()
|
||||
}
|
||||
if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "modify_topic", params, operationTimeout); err != nil {
|
||||
resp.Diagnostics.AddError("Ошибка клиента", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "topic", idParams))
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
|
||||
}
|
||||
|
||||
func (r *KafkaTopicResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
var state KafkaTopicModel
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if "delete_topic" == "" {
|
||||
return
|
||||
}
|
||||
|
||||
instanceUID := strings.TrimSpace(state.KafkaID.ValueString())
|
||||
if instanceUID == "" {
|
||||
return
|
||||
}
|
||||
skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool()
|
||||
|
||||
idParams := map[string]string{
|
||||
"nameTopic": resources_core.FormatString(state.NameTopic),
|
||||
}
|
||||
identityCodes := []string{
|
||||
"nameTopic",
|
||||
}
|
||||
listKey, idKey := resources_core.ResolveSubresourceStateKeys("topic", 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{
|
||||
"nameTopic": resources_core.FormatString(state.NameTopic),
|
||||
})
|
||||
|
||||
operationTimeout := ""
|
||||
if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() {
|
||||
operationTimeout = state.OperationTimeout.ValueString()
|
||||
}
|
||||
if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_topic", 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 *KafkaTopicResource) 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
|
||||
}
|
||||
@@ -0,0 +1,356 @@
|
||||
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: kafka
|
||||
// Subresource: user
|
||||
|
||||
var _ resource.Resource = &KafkaUserResource{}
|
||||
|
||||
// KafkaUserResource manages a subresource via operations.
|
||||
type KafkaUserResource struct {
|
||||
client *core.UniversalClient
|
||||
}
|
||||
|
||||
type KafkaUserModel struct {
|
||||
ID types.String `tfsdk:"id"`
|
||||
KafkaID types.String `tfsdk:"kafka_id"`
|
||||
AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"`
|
||||
SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"`
|
||||
OperationTimeout types.String `tfsdk:"operation_timeout"`
|
||||
AccessHosts types.String `tfsdk:"access_hosts"`
|
||||
Group types.String `tfsdk:"group"`
|
||||
NameTopic types.String `tfsdk:"name_topic"`
|
||||
Operations types.String `tfsdk:"operations"`
|
||||
Username types.String `tfsdk:"username"`
|
||||
}
|
||||
|
||||
func NewKafkaUserResource() resource.Resource {
|
||||
return &KafkaUserResource{}
|
||||
}
|
||||
|
||||
func (r *KafkaUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_kafka_user"
|
||||
}
|
||||
|
||||
func (r *KafkaUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||
attrs := map[string]schema.Attribute{
|
||||
"id": schema.StringAttribute{Computed: true},
|
||||
"kafka_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},
|
||||
"access_hosts": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `192.168.1.0/24` или `*`"},
|
||||
"group": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `order-consumers` или `*`"},
|
||||
"name_topic": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `orders-events`. Использовать маску нельзя(`orders*`), только полное название или `*`"},
|
||||
"operations": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `Create, Describe, Read, Write`"},
|
||||
"username": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `username-admin` Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}},
|
||||
}
|
||||
resp.Schema = schema.Schema{Attributes: attrs}
|
||||
}
|
||||
|
||||
func (r *KafkaUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
var plan KafkaUserModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if plan.AccessHosts.IsNull() || plan.AccessHosts.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "access_hosts is required.")
|
||||
return
|
||||
}
|
||||
if plan.Group.IsNull() || plan.Group.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "group is required.")
|
||||
return
|
||||
}
|
||||
if plan.NameTopic.IsNull() || plan.NameTopic.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "name_topic is required.")
|
||||
return
|
||||
}
|
||||
if plan.Operations.IsNull() || plan.Operations.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "operations is required.")
|
||||
return
|
||||
}
|
||||
if plan.Username.IsNull() || plan.Username.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "username is required.")
|
||||
return
|
||||
}
|
||||
|
||||
instanceUID := strings.TrimSpace(plan.KafkaID.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),
|
||||
"nameTopic": resources_core.FormatString(plan.NameTopic),
|
||||
"operations": resources_core.FormatString(plan.Operations),
|
||||
"group": resources_core.FormatString(plan.Group),
|
||||
"accessHosts": resources_core.FormatString(plan.AccessHosts),
|
||||
})
|
||||
|
||||
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 *KafkaUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
var state KafkaUserModel
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
|
||||
func (r *KafkaUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
var plan KafkaUserModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if "modify_user" == "" {
|
||||
var state KafkaUserModel
|
||||
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.KafkaID.ValueString())
|
||||
if instanceUID == "" {
|
||||
resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра")
|
||||
return
|
||||
}
|
||||
|
||||
params := resources_core.CompactParams(map[string]string{
|
||||
"nameTopic": resources_core.FormatString(plan.NameTopic),
|
||||
"operations": resources_core.FormatString(plan.Operations),
|
||||
"group": resources_core.FormatString(plan.Group),
|
||||
"accessHosts": resources_core.FormatString(plan.AccessHosts),
|
||||
"username": resources_core.FormatString(plan.Username),
|
||||
})
|
||||
|
||||
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 *KafkaUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
var state KafkaUserModel
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if "delete_user" == "" {
|
||||
return
|
||||
}
|
||||
|
||||
instanceUID := strings.TrimSpace(state.KafkaID.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 *KafkaUserResource) 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
|
||||
}
|
||||
@@ -0,0 +1,461 @@
|
||||
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: nifi
|
||||
// Service ID: 117
|
||||
|
||||
var _ resource.Resource = &NifiResource{}
|
||||
var _ resource.ResourceWithModifyPlan = &NifiResource{}
|
||||
var _ resource.ResourceWithImportState = &NifiResource{}
|
||||
|
||||
type NifiResource struct {
|
||||
client *core.UniversalClient
|
||||
}
|
||||
|
||||
type NifiModel struct {
|
||||
ID types.String `tfsdk:"id"`
|
||||
ResourceName types.String `tfsdk:"resource_name"`
|
||||
OperationTimeout types.String `tfsdk:"operation_timeout"`
|
||||
KafkaUid types.String `tfsdk:"kafka_uid"`
|
||||
NameTopic types.String `tfsdk:"name_topic"`
|
||||
Partitions types.Int64 `tfsdk:"partitions"`
|
||||
Replicas types.Int64 `tfsdk:"replicas"`
|
||||
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 NewNifiResource() resource.Resource {
|
||||
return &NifiResource{}
|
||||
}
|
||||
|
||||
func (r *NifiResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_nifi"
|
||||
}
|
||||
|
||||
func (r *NifiResource) 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},
|
||||
"kafka_uid": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать кластер из списка Не изменяется после создания."},
|
||||
"name_topic": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `orders-events` Не изменяется после создания."},
|
||||
"partitions": schema.Int64Attribute{Required: true, MarkdownDescription: "Число партиций на кластер ≤ 100 × (число брокеров) × (фактор репликации). Пример `50`"},
|
||||
"replicas": schema.Int64Attribute{Required: true, MarkdownDescription: "Количество партиций ≤ (число брокеров). Пример `2`"},
|
||||
"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 *NifiResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
|
||||
if r.client == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var config *NifiModel
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if config == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var state *NifiModel
|
||||
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 NifiModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
planChanged := false
|
||||
if !plan.KafkaUid.IsNull() && !plan.KafkaUid.IsUnknown() {
|
||||
resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, plan.KafkaUid.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error())
|
||||
} else if resolvedKafkaUid != "" && resolvedKafkaUid != plan.KafkaUid.ValueString() {
|
||||
plan.KafkaUid = types.StringValue(resolvedKafkaUid)
|
||||
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.KafkaUid.IsNull() && !plan.KafkaUid.IsUnknown() && !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() {
|
||||
if plan.KafkaUid.ValueString() != state.KafkaUid.ValueString() {
|
||||
resp.Diagnostics.AddError("Нельзя изменить kafka_uid", "Параметр задается при создании и не может быть изменен.")
|
||||
return
|
||||
}
|
||||
}
|
||||
if !plan.NameTopic.IsNull() && !plan.NameTopic.IsUnknown() && !state.NameTopic.IsNull() && !state.NameTopic.IsUnknown() {
|
||||
if plan.NameTopic.ValueString() != state.NameTopic.ValueString() {
|
||||
resp.Diagnostics.AddError("Нельзя изменить name_topic", "Параметр задается при создании и не может быть изменен.")
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if config.KafkaUid.IsNull() || config.KafkaUid.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "kafka_uid is required.")
|
||||
return
|
||||
}
|
||||
if config.NameTopic.IsNull() || config.NameTopic.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "name_topic is required.")
|
||||
return
|
||||
}
|
||||
if config.Partitions.IsNull() || config.Partitions.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "partitions is required.")
|
||||
return
|
||||
}
|
||||
if config.Replicas.IsNull() || config.Replicas.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "replicas 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.KafkaUid.IsNull() && !config.KafkaUid.IsUnknown() {
|
||||
resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, config.KafkaUid.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error())
|
||||
} else if resolvedKafkaUid != "" && resolvedKafkaUid != config.KafkaUid.ValueString() {
|
||||
config.KafkaUid = types.StringValue(resolvedKafkaUid)
|
||||
}
|
||||
}
|
||||
params := map[int]string{
|
||||
471: resources_core.FormatString(config.KafkaUid),
|
||||
472: resources_core.FormatInt64(config.Partitions),
|
||||
473: resources_core.FormatInt64(config.Replicas),
|
||||
474: resources_core.FormatString(config.NameTopic),
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 117, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
|
||||
}
|
||||
|
||||
func (r *NifiResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
var data NifiModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if data.KafkaUid.IsNull() || data.KafkaUid.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "kafka_uid is required.")
|
||||
return
|
||||
}
|
||||
if data.NameTopic.IsNull() || data.NameTopic.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "name_topic is required.")
|
||||
return
|
||||
}
|
||||
if data.Partitions.IsNull() || data.Partitions.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "partitions is required.")
|
||||
return
|
||||
}
|
||||
if data.Replicas.IsNull() || data.Replicas.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "replicas is required.")
|
||||
return
|
||||
}
|
||||
if !data.KafkaUid.IsNull() && !data.KafkaUid.IsUnknown() {
|
||||
resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, data.KafkaUid.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Ошибка клиента", err.Error())
|
||||
return
|
||||
}
|
||||
if resolvedKafkaUid != "" && resolvedKafkaUid != data.KafkaUid.ValueString() {
|
||||
data.KafkaUid = types.StringValue(resolvedKafkaUid)
|
||||
}
|
||||
}
|
||||
|
||||
resourceName := data.ResourceName.ValueString()
|
||||
resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 117, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
|
||||
|
||||
params := map[int]string{
|
||||
471: resources_core.FormatString(data.KafkaUid),
|
||||
472: resources_core.FormatInt64(data.Partitions),
|
||||
473: resources_core.FormatInt64(data.Replicas),
|
||||
474: resources_core.FormatString(data.NameTopic),
|
||||
}
|
||||
|
||||
operationTimeout := ""
|
||||
if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
|
||||
operationTimeout = data.OperationTimeout.ValueString()
|
||||
}
|
||||
id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 117, 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, 117, 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: "kafkaUid", Field: "KafkaUid", Type: "string"},
|
||||
{Code: "nameTopic", Field: "NameTopic", Type: "string"},
|
||||
{Code: "partitions", Field: "Partitions", Type: "int64"},
|
||||
{Code: "replicas", Field: "Replicas", Type: "int64"},
|
||||
})
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() {
|
||||
resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, state.KafkaUid.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error())
|
||||
} else if resolvedKafkaUid != "" && resolvedKafkaUid != state.KafkaUid.ValueString() {
|
||||
state.KafkaUid = types.StringValue(resolvedKafkaUid)
|
||||
}
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
|
||||
func (r *NifiResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
var state NifiModel
|
||||
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(), 117, 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: "kafkaUid", Field: "KafkaUid", Type: "string"},
|
||||
{Code: "nameTopic", Field: "NameTopic", Type: "string"},
|
||||
{Code: "partitions", Field: "Partitions", Type: "int64"},
|
||||
{Code: "replicas", Field: "Replicas", Type: "int64"},
|
||||
})
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if !newState.KafkaUid.IsNull() && !newState.KafkaUid.IsUnknown() {
|
||||
resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, newState.KafkaUid.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error())
|
||||
} else if resolvedKafkaUid != "" && resolvedKafkaUid != newState.KafkaUid.ValueString() {
|
||||
newState.KafkaUid = types.StringValue(resolvedKafkaUid)
|
||||
}
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
|
||||
}
|
||||
|
||||
func (r *NifiResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
var plan NifiModel
|
||||
var state NifiModel
|
||||
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.Partitions.IsNull() != state.Partitions.IsNull() || plan.Partitions.IsUnknown() != state.Partitions.IsUnknown() {
|
||||
hasServiceParamChanges = true
|
||||
} else if !plan.Partitions.IsNull() && !plan.Partitions.IsUnknown() && !state.Partitions.IsNull() && !state.Partitions.IsUnknown() {
|
||||
if plan.Partitions.ValueInt64() != state.Partitions.ValueInt64() {
|
||||
hasServiceParamChanges = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if !hasServiceParamChanges {
|
||||
if plan.Replicas.IsNull() != state.Replicas.IsNull() || plan.Replicas.IsUnknown() != state.Replicas.IsUnknown() {
|
||||
hasServiceParamChanges = true
|
||||
} else if !plan.Replicas.IsNull() && !plan.Replicas.IsUnknown() && !state.Replicas.IsNull() && !state.Replicas.IsUnknown() {
|
||||
if plan.Replicas.ValueInt64() != state.Replicas.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{
|
||||
477: resources_core.FormatInt64(plan.Partitions),
|
||||
478: resources_core.FormatInt64(plan.Replicas),
|
||||
}
|
||||
|
||||
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(), 117, 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: "kafkaUid", Field: "KafkaUid", Type: "string"},
|
||||
{Code: "nameTopic", Field: "NameTopic", Type: "string"},
|
||||
{Code: "partitions", Field: "Partitions", Type: "int64"},
|
||||
{Code: "replicas", Field: "Replicas", Type: "int64"},
|
||||
})
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() {
|
||||
resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, state.KafkaUid.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error())
|
||||
} else if resolvedKafkaUid != "" && resolvedKafkaUid != state.KafkaUid.ValueString() {
|
||||
state.KafkaUid = types.StringValue(resolvedKafkaUid)
|
||||
}
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
|
||||
func (r *NifiResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
var state NifiModel
|
||||
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 *NifiResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
|
||||
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
|
||||
}
|
||||
|
||||
func (r *NifiResource) 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
|
||||
}
|
||||
@@ -0,0 +1,476 @@
|
||||
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: akhq
|
||||
// Service ID: 119
|
||||
|
||||
var _ resource.Resource = &AkhqResource{}
|
||||
var _ resource.ResourceWithModifyPlan = &AkhqResource{}
|
||||
var _ resource.ResourceWithImportState = &AkhqResource{}
|
||||
|
||||
type AkhqResource struct {
|
||||
client *core.UniversalClient
|
||||
}
|
||||
|
||||
type AkhqModel struct {
|
||||
ID types.String `tfsdk:"id"`
|
||||
ResourceName types.String `tfsdk:"resource_name"`
|
||||
OperationTimeout types.String `tfsdk:"operation_timeout"`
|
||||
Domain types.String `tfsdk:"domain"`
|
||||
KafkaUid types.String `tfsdk:"kafka_uid"`
|
||||
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 NewAkhqResource() resource.Resource {
|
||||
return &AkhqResource{}
|
||||
}
|
||||
|
||||
func (r *AkhqResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_akhq"
|
||||
}
|
||||
|
||||
func (r *AkhqResource) 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: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."},
|
||||
"kafka_uid": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать кластер из списка"},
|
||||
"resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Пример: `1000` Не изменяется после создания."},
|
||||
"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: "Пример: `1024` Не изменяется после создания."},
|
||||
"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 *AkhqResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
|
||||
if r.client == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var config *AkhqModel
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if config == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var state *AkhqModel
|
||||
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 AkhqModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
planChanged := false
|
||||
if !plan.KafkaUid.IsNull() && !plan.KafkaUid.IsUnknown() {
|
||||
resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, plan.KafkaUid.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error())
|
||||
} else if resolvedKafkaUid != "" && resolvedKafkaUid != plan.KafkaUid.ValueString() {
|
||||
plan.KafkaUid = types.StringValue(resolvedKafkaUid)
|
||||
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.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
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if config.Domain.IsNull() || config.Domain.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "domain is required.")
|
||||
return
|
||||
}
|
||||
if config.KafkaUid.IsNull() || config.KafkaUid.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "kafka_uid 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()
|
||||
}
|
||||
if !config.KafkaUid.IsNull() && !config.KafkaUid.IsUnknown() {
|
||||
resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, config.KafkaUid.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error())
|
||||
} else if resolvedKafkaUid != "" && resolvedKafkaUid != config.KafkaUid.ValueString() {
|
||||
config.KafkaUid = types.StringValue(resolvedKafkaUid)
|
||||
}
|
||||
}
|
||||
params := map[int]string{
|
||||
550: resources_core.FormatString(config.ResourceRealm),
|
||||
551: resources_core.FormatInt64(config.ResourceMemory),
|
||||
552: resources_core.FormatInt64(config.ResourceCPU),
|
||||
553: resources_core.FormatString(config.Domain),
|
||||
554: resources_core.FormatInt64(config.ResourceInstances),
|
||||
555: resources_core.FormatString(config.KafkaUid),
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 119, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
|
||||
}
|
||||
|
||||
func (r *AkhqResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
var data AkhqModel
|
||||
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.KafkaUid.IsNull() || data.KafkaUid.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "kafka_uid is required.")
|
||||
return
|
||||
}
|
||||
if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.")
|
||||
return
|
||||
}
|
||||
if !data.KafkaUid.IsNull() && !data.KafkaUid.IsUnknown() {
|
||||
resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, data.KafkaUid.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Ошибка клиента", err.Error())
|
||||
return
|
||||
}
|
||||
if resolvedKafkaUid != "" && resolvedKafkaUid != data.KafkaUid.ValueString() {
|
||||
data.KafkaUid = types.StringValue(resolvedKafkaUid)
|
||||
}
|
||||
}
|
||||
|
||||
resourceName := data.ResourceName.ValueString()
|
||||
resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 119, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
|
||||
|
||||
params := map[int]string{
|
||||
550: resources_core.FormatString(data.ResourceRealm),
|
||||
551: resources_core.FormatInt64(data.ResourceMemory),
|
||||
552: resources_core.FormatInt64(data.ResourceCPU),
|
||||
553: resources_core.FormatString(data.Domain),
|
||||
554: resources_core.FormatInt64(data.ResourceInstances),
|
||||
555: resources_core.FormatString(data.KafkaUid),
|
||||
}
|
||||
|
||||
operationTimeout := ""
|
||||
if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
|
||||
operationTimeout = data.OperationTimeout.ValueString()
|
||||
}
|
||||
id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 119, 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, 119, 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: "kafkaUid", Field: "KafkaUid", 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
|
||||
}
|
||||
if !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() {
|
||||
resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, state.KafkaUid.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error())
|
||||
} else if resolvedKafkaUid != "" && resolvedKafkaUid != state.KafkaUid.ValueString() {
|
||||
state.KafkaUid = types.StringValue(resolvedKafkaUid)
|
||||
}
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
|
||||
func (r *AkhqResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
var state AkhqModel
|
||||
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(), 119, 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: "kafkaUid", Field: "KafkaUid", 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
|
||||
}
|
||||
if !newState.KafkaUid.IsNull() && !newState.KafkaUid.IsUnknown() {
|
||||
resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, newState.KafkaUid.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error())
|
||||
} else if resolvedKafkaUid != "" && resolvedKafkaUid != newState.KafkaUid.ValueString() {
|
||||
newState.KafkaUid = types.StringValue(resolvedKafkaUid)
|
||||
}
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
|
||||
}
|
||||
|
||||
func (r *AkhqResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
var plan AkhqModel
|
||||
var state AkhqModel
|
||||
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.KafkaUid.IsNull() != state.KafkaUid.IsNull() || plan.KafkaUid.IsUnknown() != state.KafkaUid.IsUnknown() {
|
||||
hasServiceParamChanges = true
|
||||
} else if !plan.KafkaUid.IsNull() && !plan.KafkaUid.IsUnknown() && !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() {
|
||||
if plan.KafkaUid.ValueString() != state.KafkaUid.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{
|
||||
565: resources_core.FormatString(plan.KafkaUid),
|
||||
}
|
||||
|
||||
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(), 119, 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: "kafkaUid", Field: "KafkaUid", 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
|
||||
}
|
||||
if !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() {
|
||||
resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, state.KafkaUid.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error())
|
||||
} else if resolvedKafkaUid != "" && resolvedKafkaUid != state.KafkaUid.ValueString() {
|
||||
state.KafkaUid = types.StringValue(resolvedKafkaUid)
|
||||
}
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
|
||||
func (r *AkhqResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
var state AkhqModel
|
||||
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 *AkhqResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
|
||||
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
|
||||
}
|
||||
|
||||
func (r *AkhqResource) 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
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
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: clickhouse
|
||||
// Subresource: database
|
||||
|
||||
var _ resource.Resource = &ClickhouseDatabaseResource{}
|
||||
|
||||
// ClickhouseDatabaseResource manages a subresource via operations.
|
||||
type ClickhouseDatabaseResource struct {
|
||||
client *core.UniversalClient
|
||||
}
|
||||
|
||||
type ClickhouseDatabaseModel struct {
|
||||
ID types.String `tfsdk:"id"`
|
||||
ClickhouseID types.String `tfsdk:"clickhouse_id"`
|
||||
AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"`
|
||||
SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"`
|
||||
OperationTimeout types.String `tfsdk:"operation_timeout"`
|
||||
DatabaseName types.String `tfsdk:"database_name"`
|
||||
}
|
||||
|
||||
func NewClickhouseDatabaseResource() resource.Resource {
|
||||
return &ClickhouseDatabaseResource{}
|
||||
}
|
||||
|
||||
func (r *ClickhouseDatabaseResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_clickhouse_database"
|
||||
}
|
||||
|
||||
func (r *ClickhouseDatabaseResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||
attrs := map[string]schema.Attribute{
|
||||
"id": schema.StringAttribute{Computed: true},
|
||||
"clickhouse_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},
|
||||
"database_name": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `db01` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}},
|
||||
}
|
||||
resp.Schema = schema.Schema{Attributes: attrs}
|
||||
}
|
||||
|
||||
func (r *ClickhouseDatabaseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
var plan ClickhouseDatabaseModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if plan.DatabaseName.IsNull() || plan.DatabaseName.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "database_name is required.")
|
||||
return
|
||||
}
|
||||
|
||||
instanceUID := strings.TrimSpace(plan.ClickhouseID.ValueString())
|
||||
if instanceUID == "" {
|
||||
resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра")
|
||||
return
|
||||
}
|
||||
adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool()
|
||||
|
||||
idParams := map[string]string{
|
||||
"databaseName": resources_core.FormatString(plan.DatabaseName),
|
||||
}
|
||||
identityCodes := []string{
|
||||
"databaseName",
|
||||
}
|
||||
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{
|
||||
"databaseName": resources_core.FormatString(plan.DatabaseName),
|
||||
})
|
||||
|
||||
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 *ClickhouseDatabaseResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
var state ClickhouseDatabaseModel
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
|
||||
func (r *ClickhouseDatabaseResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
var plan ClickhouseDatabaseModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if "" == "" {
|
||||
var state ClickhouseDatabaseModel
|
||||
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.ClickhouseID.ValueString())
|
||||
if instanceUID == "" {
|
||||
resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра")
|
||||
return
|
||||
}
|
||||
|
||||
params := resources_core.CompactParams(map[string]string{})
|
||||
|
||||
idParams := map[string]string{
|
||||
"databaseName": resources_core.FormatString(plan.DatabaseName),
|
||||
}
|
||||
|
||||
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 *ClickhouseDatabaseResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
var state ClickhouseDatabaseModel
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if "delete_database" == "" {
|
||||
return
|
||||
}
|
||||
|
||||
instanceUID := strings.TrimSpace(state.ClickhouseID.ValueString())
|
||||
if instanceUID == "" {
|
||||
return
|
||||
}
|
||||
skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool()
|
||||
|
||||
idParams := map[string]string{
|
||||
"databaseName": resources_core.FormatString(state.DatabaseName),
|
||||
}
|
||||
identityCodes := []string{
|
||||
"databaseName",
|
||||
}
|
||||
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{
|
||||
"databaseName": resources_core.FormatString(state.DatabaseName),
|
||||
})
|
||||
|
||||
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 *ClickhouseDatabaseResource) 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
|
||||
}
|
||||
@@ -0,0 +1,614 @@
|
||||
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: clickhouse
|
||||
// Service ID: 120
|
||||
|
||||
var _ resource.Resource = &ClickhouseResource{}
|
||||
var _ resource.ResourceWithModifyPlan = &ClickhouseResource{}
|
||||
var _ resource.ResourceWithImportState = &ClickhouseResource{}
|
||||
|
||||
type ClickhouseResource struct {
|
||||
client *core.UniversalClient
|
||||
}
|
||||
|
||||
type ClickhouseModel struct {
|
||||
ID types.String `tfsdk:"id"`
|
||||
ResourceName types.String `tfsdk:"resource_name"`
|
||||
OperationTimeout types.String `tfsdk:"operation_timeout"`
|
||||
AppVersion types.String `tfsdk:"app_version"`
|
||||
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"`
|
||||
NeedCreateKeeper types.Bool `tfsdk:"need_create_keeper"`
|
||||
NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"`
|
||||
ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"`
|
||||
ResourceCPUKeeper types.Int64 `tfsdk:"resource_c_p_u_keeper"`
|
||||
ResourceDisk types.Int64 `tfsdk:"resource_disk"`
|
||||
ResourceInstances types.Int64 `tfsdk:"resource_instances"`
|
||||
ResourceInstancesKeeper types.Int64 `tfsdk:"resource_instances_keeper"`
|
||||
ResourceInstancesShards types.Int64 `tfsdk:"resource_instances_shards"`
|
||||
ResourceMemory types.Int64 `tfsdk:"resource_memory"`
|
||||
ResourceMemoryKeeper types.Int64 `tfsdk:"resource_memory_keeper"`
|
||||
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 NewClickhouseResource() resource.Resource {
|
||||
return &ClickhouseResource{}
|
||||
}
|
||||
|
||||
func (r *ClickhouseResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_clickhouse"
|
||||
}
|
||||
|
||||
func (r *ClickhouseResource) 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("25.10"), MarkdownDescription: "Версия `clickhouse-server`"},
|
||||
"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: "Пример: `7`"},
|
||||
"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: "Принимает формат `CRON`"},
|
||||
"ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Пример: `internet-no-antiddos-v1`"},
|
||||
"need_create_keeper": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true), MarkdownDescription: "Необходим для кластеризации ClickHouse"},
|
||||
"need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Позволяет подключиться извне к ClickHouse"},
|
||||
"resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1000), MarkdownDescription: "Пример: `1000`"},
|
||||
"resource_c_p_u_keeper": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(50), MarkdownDescription: "Пример: `100`"},
|
||||
"resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "Пример: `100`"},
|
||||
"resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Пример: `3`"},
|
||||
"resource_instances_keeper": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Пример: `1`"},
|
||||
"resource_instances_shards": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Пример: `1`"},
|
||||
"resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1536), MarkdownDescription: "Пример: `2048`"},
|
||||
"resource_memory_keeper": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(152), MarkdownDescription: "Пример: `256`"},
|
||||
"resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Кластер Kubernetes в котором будет развёрнуто приложение Не изменяется после создания."},
|
||||
"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 *ClickhouseResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
|
||||
if r.client == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var config *ClickhouseModel
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if config == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var state *ClickhouseModel
|
||||
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 ClickhouseModel
|
||||
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.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{
|
||||
572: resources_core.FormatString(config.ResourceRealm),
|
||||
573: resources_core.FormatString(config.S3Uid),
|
||||
574: resources_core.FormatInt64(config.ResourceInstances),
|
||||
575: resources_core.FormatInt64(config.ResourceInstancesShards),
|
||||
576: resources_core.FormatInt64(config.ResourceCPU),
|
||||
577: resources_core.FormatInt64(config.ResourceMemory),
|
||||
578: resources_core.FormatString(config.AppVersion),
|
||||
579: resources_core.FormatInt64(config.ResourceDisk),
|
||||
580: resources_core.FormatBool(config.NeedExternalAddressMaster),
|
||||
581: resources_core.FormatString(config.IpSpaceNameMaster),
|
||||
582: resources_core.FormatBool(config.NeedCreateKeeper),
|
||||
583: resources_core.FormatInt64(config.ResourceCPUKeeper),
|
||||
584: resources_core.FormatInt64(config.ResourceMemoryKeeper),
|
||||
585: resources_core.FormatInt64(config.ResourceInstancesKeeper),
|
||||
586: resources_core.FormatString(config.ExtBACKUPSCHEDULE),
|
||||
587: resources_core.FormatInt64(config.ExtBACKUPNUMTORETAIN),
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 120, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
|
||||
}
|
||||
|
||||
func (r *ClickhouseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
var data ClickhouseModel
|
||||
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, 120, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
|
||||
|
||||
params := map[int]string{
|
||||
572: resources_core.FormatString(data.ResourceRealm),
|
||||
573: resources_core.FormatString(data.S3Uid),
|
||||
574: resources_core.FormatInt64(data.ResourceInstances),
|
||||
575: resources_core.FormatInt64(data.ResourceInstancesShards),
|
||||
576: resources_core.FormatInt64(data.ResourceCPU),
|
||||
577: resources_core.FormatInt64(data.ResourceMemory),
|
||||
578: resources_core.FormatString(data.AppVersion),
|
||||
579: resources_core.FormatInt64(data.ResourceDisk),
|
||||
580: resources_core.FormatBool(data.NeedExternalAddressMaster),
|
||||
581: resources_core.FormatString(data.IpSpaceNameMaster),
|
||||
582: resources_core.FormatBool(data.NeedCreateKeeper),
|
||||
583: resources_core.FormatInt64(data.ResourceCPUKeeper),
|
||||
584: resources_core.FormatInt64(data.ResourceMemoryKeeper),
|
||||
585: resources_core.FormatInt64(data.ResourceInstancesKeeper),
|
||||
586: resources_core.FormatString(data.ExtBACKUPSCHEDULE),
|
||||
587: resources_core.FormatInt64(data.ExtBACKUPNUMTORETAIN),
|
||||
}
|
||||
|
||||
operationTimeout := ""
|
||||
if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
|
||||
operationTimeout = data.OperationTimeout.ValueString()
|
||||
}
|
||||
id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 120, 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, 120, 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: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"},
|
||||
{Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"},
|
||||
{Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"},
|
||||
{Code: "needCreateKeeper", Field: "NeedCreateKeeper", Type: "bool"},
|
||||
{Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"},
|
||||
{Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
|
||||
{Code: "resourceCPUKeeper", Field: "ResourceCPUKeeper", Type: "int64"},
|
||||
{Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
|
||||
{Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
|
||||
{Code: "resourceInstancesKeeper", Field: "ResourceInstancesKeeper", Type: "int64"},
|
||||
{Code: "resourceInstancesShards", Field: "ResourceInstancesShards", Type: "int64"},
|
||||
{Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
|
||||
{Code: "resourceMemoryKeeper", Field: "ResourceMemoryKeeper", 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 *ClickhouseResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
var state ClickhouseModel
|
||||
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(), 120, 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: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"},
|
||||
{Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"},
|
||||
{Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"},
|
||||
{Code: "needCreateKeeper", Field: "NeedCreateKeeper", Type: "bool"},
|
||||
{Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"},
|
||||
{Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
|
||||
{Code: "resourceCPUKeeper", Field: "ResourceCPUKeeper", Type: "int64"},
|
||||
{Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
|
||||
{Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
|
||||
{Code: "resourceInstancesKeeper", Field: "ResourceInstancesKeeper", Type: "int64"},
|
||||
{Code: "resourceInstancesShards", Field: "ResourceInstancesShards", Type: "int64"},
|
||||
{Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
|
||||
{Code: "resourceMemoryKeeper", Field: "ResourceMemoryKeeper", 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 *ClickhouseResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
var plan ClickhouseModel
|
||||
var state ClickhouseModel
|
||||
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.ResourceInstancesShards.IsNull() != state.ResourceInstancesShards.IsNull() || plan.ResourceInstancesShards.IsUnknown() != state.ResourceInstancesShards.IsUnknown() {
|
||||
hasServiceParamChanges = true
|
||||
} else if !plan.ResourceInstancesShards.IsNull() && !plan.ResourceInstancesShards.IsUnknown() && !state.ResourceInstancesShards.IsNull() && !state.ResourceInstancesShards.IsUnknown() {
|
||||
if plan.ResourceInstancesShards.ValueInt64() != state.ResourceInstancesShards.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.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.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.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.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.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.NeedCreateKeeper.IsNull() != state.NeedCreateKeeper.IsNull() || plan.NeedCreateKeeper.IsUnknown() != state.NeedCreateKeeper.IsUnknown() {
|
||||
hasServiceParamChanges = true
|
||||
} else if !plan.NeedCreateKeeper.IsNull() && !plan.NeedCreateKeeper.IsUnknown() && !state.NeedCreateKeeper.IsNull() && !state.NeedCreateKeeper.IsUnknown() {
|
||||
if plan.NeedCreateKeeper.ValueBool() != state.NeedCreateKeeper.ValueBool() {
|
||||
hasServiceParamChanges = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if !hasServiceParamChanges {
|
||||
if plan.ResourceCPUKeeper.IsNull() != state.ResourceCPUKeeper.IsNull() || plan.ResourceCPUKeeper.IsUnknown() != state.ResourceCPUKeeper.IsUnknown() {
|
||||
hasServiceParamChanges = true
|
||||
} else if !plan.ResourceCPUKeeper.IsNull() && !plan.ResourceCPUKeeper.IsUnknown() && !state.ResourceCPUKeeper.IsNull() && !state.ResourceCPUKeeper.IsUnknown() {
|
||||
if plan.ResourceCPUKeeper.ValueInt64() != state.ResourceCPUKeeper.ValueInt64() {
|
||||
hasServiceParamChanges = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if !hasServiceParamChanges {
|
||||
if plan.ResourceMemoryKeeper.IsNull() != state.ResourceMemoryKeeper.IsNull() || plan.ResourceMemoryKeeper.IsUnknown() != state.ResourceMemoryKeeper.IsUnknown() {
|
||||
hasServiceParamChanges = true
|
||||
} else if !plan.ResourceMemoryKeeper.IsNull() && !plan.ResourceMemoryKeeper.IsUnknown() && !state.ResourceMemoryKeeper.IsNull() && !state.ResourceMemoryKeeper.IsUnknown() {
|
||||
if plan.ResourceMemoryKeeper.ValueInt64() != state.ResourceMemoryKeeper.ValueInt64() {
|
||||
hasServiceParamChanges = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if !hasServiceParamChanges {
|
||||
if plan.ResourceInstancesKeeper.IsNull() != state.ResourceInstancesKeeper.IsNull() || plan.ResourceInstancesKeeper.IsUnknown() != state.ResourceInstancesKeeper.IsUnknown() {
|
||||
hasServiceParamChanges = true
|
||||
} else if !plan.ResourceInstancesKeeper.IsNull() && !plan.ResourceInstancesKeeper.IsUnknown() && !state.ResourceInstancesKeeper.IsNull() && !state.ResourceInstancesKeeper.IsUnknown() {
|
||||
if plan.ResourceInstancesKeeper.ValueInt64() != state.ResourceInstancesKeeper.ValueInt64() {
|
||||
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 {
|
||||
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{
|
||||
603: resources_core.FormatInt64(plan.ResourceInstances),
|
||||
604: resources_core.FormatInt64(plan.ResourceInstancesShards),
|
||||
605: resources_core.FormatInt64(plan.ResourceCPU),
|
||||
606: resources_core.FormatInt64(plan.ResourceMemory),
|
||||
607: resources_core.FormatString(plan.AppVersion),
|
||||
608: resources_core.FormatInt64(plan.ResourceDisk),
|
||||
609: resources_core.FormatBool(plan.NeedExternalAddressMaster),
|
||||
610: resources_core.FormatString(plan.IpSpaceNameMaster),
|
||||
611: resources_core.FormatBool(plan.NeedCreateKeeper),
|
||||
612: resources_core.FormatInt64(plan.ResourceCPUKeeper),
|
||||
613: resources_core.FormatInt64(plan.ResourceMemoryKeeper),
|
||||
614: resources_core.FormatInt64(plan.ResourceInstancesKeeper),
|
||||
615: resources_core.FormatString(plan.ExtBACKUPSCHEDULE),
|
||||
616: resources_core.FormatInt64(plan.ExtBACKUPNUMTORETAIN),
|
||||
}
|
||||
|
||||
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(), 120, 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: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"},
|
||||
{Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"},
|
||||
{Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"},
|
||||
{Code: "needCreateKeeper", Field: "NeedCreateKeeper", Type: "bool"},
|
||||
{Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"},
|
||||
{Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"},
|
||||
{Code: "resourceCPUKeeper", Field: "ResourceCPUKeeper", Type: "int64"},
|
||||
{Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"},
|
||||
{Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"},
|
||||
{Code: "resourceInstancesKeeper", Field: "ResourceInstancesKeeper", Type: "int64"},
|
||||
{Code: "resourceInstancesShards", Field: "ResourceInstancesShards", Type: "int64"},
|
||||
{Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"},
|
||||
{Code: "resourceMemoryKeeper", Field: "ResourceMemoryKeeper", 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 *ClickhouseResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
var state ClickhouseModel
|
||||
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 *ClickhouseResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
|
||||
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
|
||||
}
|
||||
|
||||
func (r *ClickhouseResource) 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
|
||||
}
|
||||
@@ -0,0 +1,339 @@
|
||||
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/stringdefault"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
)
|
||||
|
||||
// Code generated by tools/gen_v2. DO NOT EDIT.
|
||||
// Service: clickhouse
|
||||
// Subresource: user
|
||||
|
||||
var _ resource.Resource = &ClickhouseUserResource{}
|
||||
|
||||
// ClickhouseUserResource manages a subresource via operations.
|
||||
type ClickhouseUserResource struct {
|
||||
client *core.UniversalClient
|
||||
}
|
||||
|
||||
type ClickhouseUserModel struct {
|
||||
ID types.String `tfsdk:"id"`
|
||||
ClickhouseID types.String `tfsdk:"clickhouse_id"`
|
||||
AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"`
|
||||
SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"`
|
||||
OperationTimeout types.String `tfsdk:"operation_timeout"`
|
||||
AccessHosts types.String `tfsdk:"access_hosts"`
|
||||
DatabaseName types.String `tfsdk:"database_name"`
|
||||
Username types.String `tfsdk:"username"`
|
||||
}
|
||||
|
||||
func NewClickhouseUserResource() resource.Resource {
|
||||
return &ClickhouseUserResource{}
|
||||
}
|
||||
|
||||
func (r *ClickhouseUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_clickhouse_user"
|
||||
}
|
||||
|
||||
func (r *ClickhouseUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||
attrs := map[string]schema.Attribute{
|
||||
"id": schema.StringAttribute{Computed: true},
|
||||
"clickhouse_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},
|
||||
"access_hosts": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("::/0"), MarkdownDescription: "Пример: `::/0` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}},
|
||||
"database_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[\"database\"]"), MarkdownDescription: "Необходимо указать массив существующих баз Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}},
|
||||
"username": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `myusername` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}},
|
||||
}
|
||||
resp.Schema = schema.Schema{Attributes: attrs}
|
||||
}
|
||||
|
||||
func (r *ClickhouseUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
var plan ClickhouseUserModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if plan.Username.IsNull() || plan.Username.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "username is required.")
|
||||
return
|
||||
}
|
||||
|
||||
instanceUID := strings.TrimSpace(plan.ClickhouseID.ValueString())
|
||||
if instanceUID == "" {
|
||||
resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра")
|
||||
return
|
||||
}
|
||||
adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool()
|
||||
|
||||
idParams := map[string]string{
|
||||
"accessHosts": resources_core.FormatString(plan.AccessHosts),
|
||||
"databaseName": resources_core.FormatString(plan.DatabaseName),
|
||||
"username": resources_core.FormatString(plan.Username),
|
||||
}
|
||||
identityCodes := []string{
|
||||
"accessHosts",
|
||||
"databaseName",
|
||||
"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),
|
||||
"databaseName": resources_core.FormatString(plan.DatabaseName),
|
||||
"accessHosts": resources_core.FormatString(plan.AccessHosts),
|
||||
})
|
||||
|
||||
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 *ClickhouseUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
var state ClickhouseUserModel
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
|
||||
func (r *ClickhouseUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
var plan ClickhouseUserModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if "" == "" {
|
||||
var state ClickhouseUserModel
|
||||
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.ClickhouseID.ValueString())
|
||||
if instanceUID == "" {
|
||||
resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра")
|
||||
return
|
||||
}
|
||||
|
||||
params := resources_core.CompactParams(map[string]string{})
|
||||
|
||||
idParams := map[string]string{
|
||||
"accessHosts": resources_core.FormatString(plan.AccessHosts),
|
||||
"databaseName": resources_core.FormatString(plan.DatabaseName),
|
||||
"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 *ClickhouseUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
var state ClickhouseUserModel
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if "delete_user" == "" {
|
||||
return
|
||||
}
|
||||
|
||||
instanceUID := strings.TrimSpace(state.ClickhouseID.ValueString())
|
||||
if instanceUID == "" {
|
||||
return
|
||||
}
|
||||
skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool()
|
||||
|
||||
idParams := map[string]string{
|
||||
"accessHosts": resources_core.FormatString(state.AccessHosts),
|
||||
"databaseName": resources_core.FormatString(state.DatabaseName),
|
||||
"username": resources_core.FormatString(state.Username),
|
||||
}
|
||||
identityCodes := []string{
|
||||
"accessHosts",
|
||||
"databaseName",
|
||||
"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 *ClickhouseUserResource) 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
|
||||
}
|
||||
@@ -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/types"
|
||||
)
|
||||
|
||||
// Code generated by tools/gen_v2. DO NOT EDIT.
|
||||
// Service: s3
|
||||
// Service ID: 12
|
||||
|
||||
var _ resource.Resource = &S3Resource{}
|
||||
var _ resource.ResourceWithModifyPlan = &S3Resource{}
|
||||
var _ resource.ResourceWithImportState = &S3Resource{}
|
||||
|
||||
type S3Resource struct {
|
||||
client *core.UniversalClient
|
||||
}
|
||||
|
||||
type S3Model struct {
|
||||
ID types.String `tfsdk:"id"`
|
||||
ResourceName types.String `tfsdk:"resource_name"`
|
||||
OperationTimeout types.String `tfsdk:"operation_timeout"`
|
||||
DisplayName types.String `tfsdk:"display_name"`
|
||||
MaxBucketsPerUser types.Int64 `tfsdk:"max_buckets_per_user"`
|
||||
MaxObjectsPerBucket types.Int64 `tfsdk:"max_objects_per_bucket"`
|
||||
MaxSizeGbPerUser types.Int64 `tfsdk:"max_size_gb_per_user"`
|
||||
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 NewS3Resource() resource.Resource {
|
||||
return &S3Resource{}
|
||||
}
|
||||
|
||||
func (r *S3Resource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_s3"
|
||||
}
|
||||
|
||||
func (r *S3Resource) 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},
|
||||
"display_name": schema.StringAttribute{Required: true, MarkdownDescription: "Человеко-читаемое имя (транслит из Elma) - передаётся имя клиента Не изменяется после создания."},
|
||||
"max_buckets_per_user": schema.Int64Attribute{Optional: true, MarkdownDescription: "Квота на пользователя. Количество бакетов пользователя. Передаём руками"},
|
||||
"max_objects_per_bucket": schema.Int64Attribute{Optional: true, MarkdownDescription: "Квота на бакет. Кол-во объектов. Передаём руками"},
|
||||
"max_size_gb_per_user": schema.Int64Attribute{Optional: true, MarkdownDescription: "maxSizeGb. Передаём руками"},
|
||||
"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 *S3Resource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
|
||||
if r.client == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var config *S3Model
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if config == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var state *S3Model
|
||||
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 S3Model
|
||||
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.DisplayName.IsNull() && !plan.DisplayName.IsUnknown() && !state.DisplayName.IsNull() && !state.DisplayName.IsUnknown() {
|
||||
if plan.DisplayName.ValueString() != state.DisplayName.ValueString() {
|
||||
resp.Diagnostics.AddError("Нельзя изменить display_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.DisplayName.IsNull() || config.DisplayName.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "display_name 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{
|
||||
163: resources_core.FormatString(config.ResourceRealm),
|
||||
320: resources_core.FormatString(config.DisplayName),
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 12, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
|
||||
}
|
||||
|
||||
func (r *S3Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
var data S3Model
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if data.DisplayName.IsNull() || data.DisplayName.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "display_name 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, 12, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
|
||||
|
||||
params := map[int]string{
|
||||
163: resources_core.FormatString(data.ResourceRealm),
|
||||
320: resources_core.FormatString(data.DisplayName),
|
||||
}
|
||||
|
||||
operationTimeout := ""
|
||||
if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
|
||||
operationTimeout = data.OperationTimeout.ValueString()
|
||||
}
|
||||
id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 12, 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, 12, 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: "displayName", Field: "DisplayName", Type: "string"},
|
||||
{Code: "maxBucketsPerUser", Field: "MaxBucketsPerUser", Type: "int64"},
|
||||
{Code: "maxObjectsPerBucket", Field: "MaxObjectsPerBucket", Type: "int64"},
|
||||
{Code: "maxSizeGbPerUser", Field: "MaxSizeGbPerUser", 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 *S3Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
var state S3Model
|
||||
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(), 12, 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: "displayName", Field: "DisplayName", Type: "string"},
|
||||
{Code: "maxBucketsPerUser", Field: "MaxBucketsPerUser", Type: "int64"},
|
||||
{Code: "maxObjectsPerBucket", Field: "MaxObjectsPerBucket", Type: "int64"},
|
||||
{Code: "maxSizeGbPerUser", Field: "MaxSizeGbPerUser", 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 *S3Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
var plan S3Model
|
||||
var state S3Model
|
||||
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.MaxSizeGbPerUser.IsNull() != state.MaxSizeGbPerUser.IsNull() || plan.MaxSizeGbPerUser.IsUnknown() != state.MaxSizeGbPerUser.IsUnknown() {
|
||||
hasServiceParamChanges = true
|
||||
} else if !plan.MaxSizeGbPerUser.IsNull() && !plan.MaxSizeGbPerUser.IsUnknown() && !state.MaxSizeGbPerUser.IsNull() && !state.MaxSizeGbPerUser.IsUnknown() {
|
||||
if plan.MaxSizeGbPerUser.ValueInt64() != state.MaxSizeGbPerUser.ValueInt64() {
|
||||
hasServiceParamChanges = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if !hasServiceParamChanges {
|
||||
if plan.MaxObjectsPerBucket.IsNull() != state.MaxObjectsPerBucket.IsNull() || plan.MaxObjectsPerBucket.IsUnknown() != state.MaxObjectsPerBucket.IsUnknown() {
|
||||
hasServiceParamChanges = true
|
||||
} else if !plan.MaxObjectsPerBucket.IsNull() && !plan.MaxObjectsPerBucket.IsUnknown() && !state.MaxObjectsPerBucket.IsNull() && !state.MaxObjectsPerBucket.IsUnknown() {
|
||||
if plan.MaxObjectsPerBucket.ValueInt64() != state.MaxObjectsPerBucket.ValueInt64() {
|
||||
hasServiceParamChanges = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if !hasServiceParamChanges {
|
||||
if plan.MaxBucketsPerUser.IsNull() != state.MaxBucketsPerUser.IsNull() || plan.MaxBucketsPerUser.IsUnknown() != state.MaxBucketsPerUser.IsUnknown() {
|
||||
hasServiceParamChanges = true
|
||||
} else if !plan.MaxBucketsPerUser.IsNull() && !plan.MaxBucketsPerUser.IsUnknown() && !state.MaxBucketsPerUser.IsNull() && !state.MaxBucketsPerUser.IsUnknown() {
|
||||
if plan.MaxBucketsPerUser.ValueInt64() != state.MaxBucketsPerUser.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{
|
||||
50: resources_core.FormatInt64(plan.MaxSizeGbPerUser),
|
||||
51: resources_core.FormatInt64(plan.MaxObjectsPerBucket),
|
||||
52: resources_core.FormatInt64(plan.MaxBucketsPerUser),
|
||||
}
|
||||
|
||||
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(), 12, 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: "displayName", Field: "DisplayName", Type: "string"},
|
||||
{Code: "maxBucketsPerUser", Field: "MaxBucketsPerUser", Type: "int64"},
|
||||
{Code: "maxObjectsPerBucket", Field: "MaxObjectsPerBucket", Type: "int64"},
|
||||
{Code: "maxSizeGbPerUser", Field: "MaxSizeGbPerUser", 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 *S3Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
var state S3Model
|
||||
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 *S3Resource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
|
||||
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
|
||||
}
|
||||
|
||||
func (r *S3Resource) 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
|
||||
}
|
||||
@@ -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: s3
|
||||
// Subresource: sub_user
|
||||
|
||||
var _ resource.Resource = &S3SubUserResource{}
|
||||
|
||||
// S3SubUserResource manages a subresource via operations.
|
||||
type S3SubUserResource struct {
|
||||
client *core.UniversalClient
|
||||
}
|
||||
|
||||
type S3SubUserModel struct {
|
||||
ID types.String `tfsdk:"id"`
|
||||
S3ID types.String `tfsdk:"s3_id"`
|
||||
AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"`
|
||||
SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"`
|
||||
OperationTimeout types.String `tfsdk:"operation_timeout"`
|
||||
SubUserAccess types.String `tfsdk:"sub_user_access"`
|
||||
SubUserName types.String `tfsdk:"sub_user_name"`
|
||||
}
|
||||
|
||||
func NewS3SubUserResource() resource.Resource {
|
||||
return &S3SubUserResource{}
|
||||
}
|
||||
|
||||
func (r *S3SubUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_s3_sub_user"
|
||||
}
|
||||
|
||||
func (r *S3SubUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||
attrs := map[string]schema.Attribute{
|
||||
"id": schema.StringAttribute{Computed: true},
|
||||
"s3_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},
|
||||
"sub_user_access": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}},
|
||||
"sub_user_name": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}},
|
||||
}
|
||||
resp.Schema = schema.Schema{Attributes: attrs}
|
||||
}
|
||||
|
||||
func (r *S3SubUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
var plan S3SubUserModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if plan.SubUserAccess.IsNull() || plan.SubUserAccess.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "sub_user_access is required.")
|
||||
return
|
||||
}
|
||||
if plan.SubUserName.IsNull() || plan.SubUserName.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "sub_user_name is required.")
|
||||
return
|
||||
}
|
||||
|
||||
instanceUID := strings.TrimSpace(plan.S3ID.ValueString())
|
||||
if instanceUID == "" {
|
||||
resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра")
|
||||
return
|
||||
}
|
||||
adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool()
|
||||
|
||||
idParams := map[string]string{
|
||||
"subUserAccess": resources_core.FormatString(plan.SubUserAccess),
|
||||
"subUserName": resources_core.FormatString(plan.SubUserName),
|
||||
}
|
||||
identityCodes := []string{
|
||||
"subUserAccess",
|
||||
"subUserName",
|
||||
}
|
||||
listKey, idKey := resources_core.ResolveSubresourceStateKeys("sub_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, "sub_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{
|
||||
"subUserName": resources_core.FormatString(plan.SubUserName),
|
||||
"subUserAccess": resources_core.FormatString(plan.SubUserAccess),
|
||||
})
|
||||
|
||||
operationTimeout := ""
|
||||
if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() {
|
||||
operationTimeout = plan.OperationTimeout.ValueString()
|
||||
}
|
||||
if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_sub_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, "sub_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, "sub_user", idParams))
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
|
||||
}
|
||||
|
||||
func (r *S3SubUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
var state S3SubUserModel
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
|
||||
func (r *S3SubUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
var plan S3SubUserModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if "" == "" {
|
||||
var state S3SubUserModel
|
||||
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.S3ID.ValueString())
|
||||
if instanceUID == "" {
|
||||
resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра")
|
||||
return
|
||||
}
|
||||
|
||||
params := resources_core.CompactParams(map[string]string{})
|
||||
|
||||
idParams := map[string]string{
|
||||
"subUserAccess": resources_core.FormatString(plan.SubUserAccess),
|
||||
"subUserName": resources_core.FormatString(plan.SubUserName),
|
||||
}
|
||||
|
||||
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, "sub_user", idParams))
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
|
||||
}
|
||||
|
||||
func (r *S3SubUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
var state S3SubUserModel
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if "delete_sub_user" == "" {
|
||||
return
|
||||
}
|
||||
|
||||
instanceUID := strings.TrimSpace(state.S3ID.ValueString())
|
||||
if instanceUID == "" {
|
||||
return
|
||||
}
|
||||
skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool()
|
||||
|
||||
idParams := map[string]string{
|
||||
"subUserAccess": resources_core.FormatString(state.SubUserAccess),
|
||||
"subUserName": resources_core.FormatString(state.SubUserName),
|
||||
}
|
||||
identityCodes := []string{
|
||||
"subUserAccess",
|
||||
"subUserName",
|
||||
}
|
||||
listKey, idKey := resources_core.ResolveSubresourceStateKeys("sub_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{
|
||||
"subUserName": resources_core.FormatString(state.SubUserName),
|
||||
})
|
||||
|
||||
operationTimeout := ""
|
||||
if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() {
|
||||
operationTimeout = state.OperationTimeout.ValueString()
|
||||
}
|
||||
if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_sub_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 *S3SubUserResource) 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
|
||||
}
|
||||
@@ -0,0 +1,439 @@
|
||||
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: s3bucket
|
||||
// Service ID: 13
|
||||
|
||||
var _ resource.Resource = &S3bucketResource{}
|
||||
var _ resource.ResourceWithModifyPlan = &S3bucketResource{}
|
||||
var _ resource.ResourceWithImportState = &S3bucketResource{}
|
||||
|
||||
type S3bucketResource struct {
|
||||
client *core.UniversalClient
|
||||
}
|
||||
|
||||
type S3bucketModel struct {
|
||||
ID types.String `tfsdk:"id"`
|
||||
ResourceName types.String `tfsdk:"resource_name"`
|
||||
OperationTimeout types.String `tfsdk:"operation_timeout"`
|
||||
BucketName types.String `tfsdk:"bucket_name"`
|
||||
CorsAll types.Bool `tfsdk:"cors_all"`
|
||||
ListAll types.Bool `tfsdk:"list_all"`
|
||||
MaxSize types.String `tfsdk:"max_size"`
|
||||
Placement types.String `tfsdk:"placement"`
|
||||
ReadAll types.Bool `tfsdk:"read_all"`
|
||||
S3UserUid types.String `tfsdk:"s3_user_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 NewS3bucketResource() resource.Resource {
|
||||
return &S3bucketResource{}
|
||||
}
|
||||
|
||||
func (r *S3bucketResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_s3bucket"
|
||||
}
|
||||
|
||||
func (r *S3bucketResource) 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},
|
||||
"bucket_name": schema.StringAttribute{Required: true, MarkdownDescription: "Имя бакета s3 Не изменяется после создания."},
|
||||
"cors_all": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Публичный доступ к чтению настроек позволяет любому пользователю интернета читать конфигурации CORS Не изменяется после создания."},
|
||||
"list_all": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Публичный доступ к листингу позволяет любому пользователю интернета получить список объектов в бакете. Не изменяется после создания."},
|
||||
"max_size": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("-1"), MarkdownDescription: "Максимальный размер бакета s3. Если поставить -1, будет безлимит. Размер указывается в Bytes Не изменяется после создания."},
|
||||
"placement": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("HOT"), MarkdownDescription: "Класс хранилища, который используется по умолчанию при загрузке объектов. Чем холоднее, тем дешевле место, но дороже обращения Не изменяется после создания."},
|
||||
"read_all": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Публичный доступ на чтение позволяет любому пользователю интернета скачивать объекты из бакета. Не изменяется после создания."},
|
||||
"s3_user_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UID Корневой услуги 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 *S3bucketResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
|
||||
if r.client == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var config *S3bucketModel
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if config == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var state *S3bucketModel
|
||||
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 S3bucketModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
planChanged := false
|
||||
if !plan.S3UserUid.IsNull() && !plan.S3UserUid.IsUnknown() {
|
||||
resolvedS3UserUid, err := r.client.ResolveRefSvcParamValue(ctx, 12, plan.S3UserUid.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddWarning("Failed to resolve s3_user_uid", err.Error())
|
||||
} else if resolvedS3UserUid != "" && resolvedS3UserUid != plan.S3UserUid.ValueString() {
|
||||
plan.S3UserUid = types.StringValue(resolvedS3UserUid)
|
||||
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.BucketName.IsNull() && !plan.BucketName.IsUnknown() && !state.BucketName.IsNull() && !state.BucketName.IsUnknown() {
|
||||
if plan.BucketName.ValueString() != state.BucketName.ValueString() {
|
||||
resp.Diagnostics.AddError("Нельзя изменить bucket_name", "Параметр задается при создании и не может быть изменен.")
|
||||
return
|
||||
}
|
||||
}
|
||||
if !plan.CorsAll.IsNull() && !plan.CorsAll.IsUnknown() && !state.CorsAll.IsNull() && !state.CorsAll.IsUnknown() {
|
||||
if plan.CorsAll.ValueBool() != state.CorsAll.ValueBool() {
|
||||
resp.Diagnostics.AddError("Нельзя изменить cors_all", "Параметр задается при создании и не может быть изменен.")
|
||||
return
|
||||
}
|
||||
}
|
||||
if !plan.ListAll.IsNull() && !plan.ListAll.IsUnknown() && !state.ListAll.IsNull() && !state.ListAll.IsUnknown() {
|
||||
if plan.ListAll.ValueBool() != state.ListAll.ValueBool() {
|
||||
resp.Diagnostics.AddError("Нельзя изменить list_all", "Параметр задается при создании и не может быть изменен.")
|
||||
return
|
||||
}
|
||||
}
|
||||
if !plan.MaxSize.IsNull() && !plan.MaxSize.IsUnknown() && !state.MaxSize.IsNull() && !state.MaxSize.IsUnknown() {
|
||||
if plan.MaxSize.ValueString() != state.MaxSize.ValueString() {
|
||||
resp.Diagnostics.AddError("Нельзя изменить max_size", "Параметр задается при создании и не может быть изменен.")
|
||||
return
|
||||
}
|
||||
}
|
||||
if !plan.Placement.IsNull() && !plan.Placement.IsUnknown() && !state.Placement.IsNull() && !state.Placement.IsUnknown() {
|
||||
if plan.Placement.ValueString() != state.Placement.ValueString() {
|
||||
resp.Diagnostics.AddError("Нельзя изменить placement", "Параметр задается при создании и не может быть изменен.")
|
||||
return
|
||||
}
|
||||
}
|
||||
if !plan.ReadAll.IsNull() && !plan.ReadAll.IsUnknown() && !state.ReadAll.IsNull() && !state.ReadAll.IsUnknown() {
|
||||
if plan.ReadAll.ValueBool() != state.ReadAll.ValueBool() {
|
||||
resp.Diagnostics.AddError("Нельзя изменить read_all", "Параметр задается при создании и не может быть изменен.")
|
||||
return
|
||||
}
|
||||
}
|
||||
if !plan.S3UserUid.IsNull() && !plan.S3UserUid.IsUnknown() && !state.S3UserUid.IsNull() && !state.S3UserUid.IsUnknown() {
|
||||
if plan.S3UserUid.ValueString() != state.S3UserUid.ValueString() {
|
||||
resp.Diagnostics.AddError("Нельзя изменить s3_user_uid", "Параметр задается при создании и не может быть изменен.")
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if config.BucketName.IsNull() || config.BucketName.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "bucket_name is required.")
|
||||
return
|
||||
}
|
||||
if config.S3UserUid.IsNull() || config.S3UserUid.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "s3_user_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.S3UserUid.IsNull() && !config.S3UserUid.IsUnknown() {
|
||||
resolvedS3UserUid, err := r.client.ResolveRefSvcParamValue(ctx, 12, config.S3UserUid.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddWarning("Failed to resolve s3_user_uid", err.Error())
|
||||
} else if resolvedS3UserUid != "" && resolvedS3UserUid != config.S3UserUid.ValueString() {
|
||||
config.S3UserUid = types.StringValue(resolvedS3UserUid)
|
||||
}
|
||||
}
|
||||
params := map[int]string{
|
||||
124: resources_core.FormatString(config.S3UserUid),
|
||||
125: resources_core.FormatString(config.BucketName),
|
||||
126: resources_core.FormatString(config.MaxSize),
|
||||
127: resources_core.FormatBool(config.ReadAll),
|
||||
128: resources_core.FormatBool(config.ListAll),
|
||||
129: resources_core.FormatBool(config.CorsAll),
|
||||
130: resources_core.FormatString(config.Placement),
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 13, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
|
||||
}
|
||||
|
||||
func (r *S3bucketResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
var data S3bucketModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if data.BucketName.IsNull() || data.BucketName.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "bucket_name is required.")
|
||||
return
|
||||
}
|
||||
if data.S3UserUid.IsNull() || data.S3UserUid.IsUnknown() {
|
||||
resp.Diagnostics.AddError("Missing required attribute", "s3_user_uid is required.")
|
||||
return
|
||||
}
|
||||
|
||||
resourceName := data.ResourceName.ValueString()
|
||||
resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnostics(ctx, r.client, 13, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
|
||||
|
||||
params := map[int]string{
|
||||
124: resources_core.FormatString(data.S3UserUid),
|
||||
125: resources_core.FormatString(data.BucketName),
|
||||
126: resources_core.FormatString(data.MaxSize),
|
||||
127: resources_core.FormatBool(data.ReadAll),
|
||||
128: resources_core.FormatBool(data.ListAll),
|
||||
129: resources_core.FormatBool(data.CorsAll),
|
||||
130: resources_core.FormatString(data.Placement),
|
||||
}
|
||||
|
||||
operationTimeout := ""
|
||||
if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
|
||||
operationTimeout = data.OperationTimeout.ValueString()
|
||||
}
|
||||
id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 13, 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, 13, 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: "bucketName", Field: "BucketName", Type: "string"},
|
||||
{Code: "corsAll", Field: "CorsAll", Type: "bool"},
|
||||
{Code: "listAll", Field: "ListAll", Type: "bool"},
|
||||
{Code: "maxSize", Field: "MaxSize", Type: "string"},
|
||||
{Code: "placement", Field: "Placement", Type: "string"},
|
||||
{Code: "readAll", Field: "ReadAll", Type: "bool"},
|
||||
})
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
|
||||
func (r *S3bucketResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
var state S3bucketModel
|
||||
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(), 13, 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: "bucketName", Field: "BucketName", Type: "string"},
|
||||
{Code: "corsAll", Field: "CorsAll", Type: "bool"},
|
||||
{Code: "listAll", Field: "ListAll", Type: "bool"},
|
||||
{Code: "maxSize", Field: "MaxSize", Type: "string"},
|
||||
{Code: "placement", Field: "Placement", Type: "string"},
|
||||
{Code: "readAll", Field: "ReadAll", Type: "bool"},
|
||||
})
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
|
||||
}
|
||||
|
||||
func (r *S3bucketResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
var plan S3bucketModel
|
||||
var state S3bucketModel
|
||||
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(), 13, 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: "bucketName", Field: "BucketName", Type: "string"},
|
||||
{Code: "corsAll", Field: "CorsAll", Type: "bool"},
|
||||
{Code: "listAll", Field: "ListAll", Type: "bool"},
|
||||
{Code: "maxSize", Field: "MaxSize", Type: "string"},
|
||||
{Code: "placement", Field: "Placement", Type: "string"},
|
||||
{Code: "readAll", Field: "ReadAll", Type: "bool"},
|
||||
})
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
|
||||
func (r *S3bucketResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
var state S3bucketModel
|
||||
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 *S3bucketResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
|
||||
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
|
||||
}
|
||||
|
||||
func (r *S3bucketResource) 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
|
||||
}
|
||||
@@ -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/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: valo_tenant
|
||||
// Service ID: 149
|
||||
|
||||
var _ resource.Resource = &ValoTenantResource{}
|
||||
var _ resource.ResourceWithModifyPlan = &ValoTenantResource{}
|
||||
var _ resource.ResourceWithImportState = &ValoTenantResource{}
|
||||
|
||||
type ValoTenantResource struct {
|
||||
client *core.UniversalClient
|
||||
}
|
||||
|
||||
type ValoTenantModel struct {
|
||||
ID types.String `tfsdk:"id"`
|
||||
ResourceName types.String `tfsdk:"resource_name"`
|
||||
OperationTimeout types.String `tfsdk:"operation_timeout"`
|
||||
Domain types.String `tfsdk:"domain"`
|
||||
ResourceRealm types.String `tfsdk:"resource_realm"`
|
||||
S3Storage types.Int64 `tfsdk:"s3_storage"`
|
||||
ValoOptions types.String `tfsdk:"valo_options"`
|
||||
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 NewValoTenantResource() resource.Resource {
|
||||
return &ValoTenantResource{}
|
||||
}
|
||||
|
||||
func (r *ValoTenantResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_valo_tenant"
|
||||
}
|
||||
|
||||
func (r *ValoTenantResource) 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: "Будет добавлено в зону valo.ngcloud.ru Не изменяется после создания."},
|
||||
"resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."},
|
||||
"s3_storage": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "Параметр указывается в `Gb`"},
|
||||
"valo_options": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{}")},
|
||||
"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 *ValoTenantResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
|
||||
if r.client == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var config *ValoTenantModel
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if config == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var state *ValoTenantModel
|
||||
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 ValoTenantModel
|
||||
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.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{
|
||||
655: resources_core.FormatString(config.ResourceRealm),
|
||||
656: resources_core.FormatString(config.Domain),
|
||||
657: resources_core.FormatString(config.ValoOptions),
|
||||
658: resources_core.FormatInt64(config.S3Storage),
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParams(ctx, r.client, 149, config.ResourceName.ValueString(), adoptExistingOnCreate, params)...)
|
||||
}
|
||||
|
||||
func (r *ValoTenantResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
var data ValoTenantModel
|
||||
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, 149, resourceName, data.AdoptExistingOnCreate.ValueBool())...)
|
||||
|
||||
params := map[int]string{
|
||||
655: resources_core.FormatString(data.ResourceRealm),
|
||||
656: resources_core.FormatString(data.Domain),
|
||||
657: resources_core.FormatString(data.ValoOptions),
|
||||
658: resources_core.FormatInt64(data.S3Storage),
|
||||
}
|
||||
|
||||
operationTimeout := ""
|
||||
if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() {
|
||||
operationTimeout = data.OperationTimeout.ValueString()
|
||||
}
|
||||
id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 149, 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, 149, 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: "resourceRealm", Field: "ResourceRealm", Type: "string"},
|
||||
{Code: "s3Storage", Field: "S3Storage", Type: "int64"},
|
||||
{Code: "valoOptions", Field: "ValoOptions", Type: "string"},
|
||||
})
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
|
||||
func (r *ValoTenantResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
var state ValoTenantModel
|
||||
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(), 149, 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: "resourceRealm", Field: "ResourceRealm", Type: "string"},
|
||||
{Code: "s3Storage", Field: "S3Storage", Type: "int64"},
|
||||
{Code: "valoOptions", Field: "ValoOptions", Type: "string"},
|
||||
})
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
|
||||
}
|
||||
|
||||
func (r *ValoTenantResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
var plan ValoTenantModel
|
||||
var state ValoTenantModel
|
||||
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.ValoOptions.IsNull() != state.ValoOptions.IsNull() || plan.ValoOptions.IsUnknown() != state.ValoOptions.IsUnknown() {
|
||||
hasServiceParamChanges = true
|
||||
} else if !plan.ValoOptions.IsNull() && !plan.ValoOptions.IsUnknown() && !state.ValoOptions.IsNull() && !state.ValoOptions.IsUnknown() {
|
||||
if plan.ValoOptions.ValueString() != state.ValoOptions.ValueString() {
|
||||
hasServiceParamChanges = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if !hasServiceParamChanges {
|
||||
if plan.S3Storage.IsNull() != state.S3Storage.IsNull() || plan.S3Storage.IsUnknown() != state.S3Storage.IsUnknown() {
|
||||
hasServiceParamChanges = true
|
||||
} else if !plan.S3Storage.IsNull() && !plan.S3Storage.IsUnknown() && !state.S3Storage.IsNull() && !state.S3Storage.IsUnknown() {
|
||||
if plan.S3Storage.ValueInt64() != state.S3Storage.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{
|
||||
659: resources_core.FormatString(plan.ValoOptions),
|
||||
660: resources_core.FormatInt64(plan.S3Storage),
|
||||
}
|
||||
|
||||
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(), 149, 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: "resourceRealm", Field: "ResourceRealm", Type: "string"},
|
||||
{Code: "s3Storage", Field: "S3Storage", Type: "int64"},
|
||||
{Code: "valoOptions", Field: "ValoOptions", Type: "string"},
|
||||
})
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
|
||||
func (r *ValoTenantResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
var state ValoTenantModel
|
||||
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 *ValoTenantResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
|
||||
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
|
||||
}
|
||||
|
||||
func (r *ValoTenantResource) 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
|
||||
}
|
||||
Reference in New Issue
Block a user