From 7664ff46c17d720463f45f739aa0a2e84497c795 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Wed, 18 Dec 2024 13:54:39 +0100 Subject: [PATCH] convert between list and first element --- .../model_ClusterDescription20240805.go | 4 ++- ...l_ClusterDescriptionProcessArgs20240805.go | 11 +++++--- .../model_to_ClusterDescription20240805.go | 6 ++++- .../service/advancedclustertpf/resource.go | 17 ++++++++++--- internal/service/advancedclustertpf/schema.go | 25 +++++++++++++++---- 5 files changed, 49 insertions(+), 14 deletions(-) diff --git a/internal/service/advancedclustertpf/model_ClusterDescription20240805.go b/internal/service/advancedclustertpf/model_ClusterDescription20240805.go index c039f5c1bc..c102fc46c9 100644 --- a/internal/service/advancedclustertpf/model_ClusterDescription20240805.go +++ b/internal/service/advancedclustertpf/model_ClusterDescription20240805.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion" @@ -29,11 +30,12 @@ type ExtraAPIInfo struct { } func NewTFModel(ctx context.Context, input *admin.ClusterDescription20240805, timeout timeouts.Value, diags *diag.Diagnostics, apiInfo ExtraAPIInfo) *TFModel { - biConnector := NewBiConnectorConfigObjType(ctx, input.BiConnector, diags) connectionStrings := NewConnectionStringsObjType(ctx, input.ConnectionStrings, diags) labels := NewLabelsObjType(ctx, input.Labels, diags) replicationSpecs := NewReplicationSpecsObjType(ctx, input.ReplicationSpecs, diags, &apiInfo) tags := NewTagsObjType(ctx, input.Tags, diags) + biConnector, diagsLocal := types.ListValue(BiConnectorConfigObjType, []attr.Value{NewBiConnectorConfigObjType(ctx, input.BiConnector, diags)}) + diags.Append(diagsLocal...) if diags.HasError() { return nil } diff --git a/internal/service/advancedclustertpf/model_ClusterDescriptionProcessArgs20240805.go b/internal/service/advancedclustertpf/model_ClusterDescriptionProcessArgs20240805.go index ff14a68650..f84df0494a 100644 --- a/internal/service/advancedclustertpf/model_ClusterDescriptionProcessArgs20240805.go +++ b/internal/service/advancedclustertpf/model_ClusterDescriptionProcessArgs20240805.go @@ -3,6 +3,7 @@ package advancedclustertpf import ( "context" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion" @@ -22,8 +23,11 @@ func AddAdvancedConfig(ctx context.Context, tfModel *TFModel, input *admin.Clust // When MongoDBMajorVersion is not 4.4 or lower, the API response for fail_index_key_too_long will always be null, to ensure no consistency issues, we need to match the config failIndexKeyTooLong := inputLegacy.GetFailIndexKeyTooLong() if tfModel != nil { - stateConfig := tfModel.AdvancedConfiguration - stateConfigSDK := NewAtlasReqAdvancedConfigurationLegacy(ctx, &stateConfig, diags) + stateConfig := getListUniqueElement(diags, &tfModel.AdvancedConfiguration) + if diags.HasError() { + return + } + stateConfigSDK := NewAtlasReqAdvancedConfigurationLegacy(ctx, stateConfig, diags) if diags.HasError() { return } @@ -48,5 +52,6 @@ func AddAdvancedConfig(ctx context.Context, tfModel *TFModel, input *admin.Clust } objType, diagsLocal := types.ObjectValueFrom(ctx, AdvancedConfigurationObjType.AttrTypes, advancedConfig) diags.Append(diagsLocal...) - tfModel.AdvancedConfiguration = objType + tfModel.AdvancedConfiguration, diagsLocal = types.ListValue(AdvancedConfigurationObjType, []attr.Value{objType}) + diags.Append(diagsLocal...) } diff --git a/internal/service/advancedclustertpf/model_to_ClusterDescription20240805.go b/internal/service/advancedclustertpf/model_to_ClusterDescription20240805.go index a0bf99fc5a..2e3bc11a40 100644 --- a/internal/service/advancedclustertpf/model_to_ClusterDescription20240805.go +++ b/internal/service/advancedclustertpf/model_to_ClusterDescription20240805.go @@ -23,10 +23,14 @@ func NewAtlasReq(ctx context.Context, input *TFModel, diags *diag.Diagnostics) * majorVersionFormatted := FormatMongoDBMajorVersion(*majorVersion) majorVersion = &majorVersionFormatted } + biConnectorConfig := getListUniqueElement(diags, &input.BiConnectorConfig) + if diags.HasError() { + return nil + } return &admin.ClusterDescription20240805{ AcceptDataRisksAndForceReplicaSetReconfig: acceptDataRisksAndForceReplicaSetReconfig, BackupEnabled: conversion.NilForUnknown(input.BackupEnabled, input.BackupEnabled.ValueBoolPointer()), - BiConnector: newBiConnector(ctx, input.BiConnectorConfig, diags), + BiConnector: newBiConnector(ctx, *biConnectorConfig, diags), ClusterType: input.ClusterType.ValueStringPointer(), ConfigServerManagementMode: conversion.NilForUnknown(input.ConfigServerManagementMode, input.ConfigServerManagementMode.ValueStringPointer()), EncryptionAtRestProvider: conversion.NilForUnknown(input.EncryptionAtRestProvider, input.EncryptionAtRestProvider.ValueStringPointer()), diff --git a/internal/service/advancedclustertpf/resource.go b/internal/service/advancedclustertpf/resource.go index 9142317f62..ec340380de 100644 --- a/internal/service/advancedclustertpf/resource.go +++ b/internal/service/advancedclustertpf/resource.go @@ -233,8 +233,12 @@ func (r *rs) createCluster(ctx context.Context, plan *TFModel, diags *diag.Diagn if pauseAfter { clusterResp = r.updateAndWait(ctx, &pauseRequest, diags, plan) } + planAdvancedConfiguration := getListUniqueElement(diags, &plan.AdvancedConfiguration) + if diags.HasError() { + return nil + } var legacyAdvConfig *admin20240530.ClusterDescriptionProcessArgs - legacyAdvConfigUpdate := NewAtlasReqAdvancedConfigurationLegacy(ctx, &plan.AdvancedConfiguration, diags) + legacyAdvConfigUpdate := NewAtlasReqAdvancedConfigurationLegacy(ctx, planAdvancedConfiguration, diags) if !update.IsZeroValues(legacyAdvConfigUpdate) { legacyAdvConfig, _, err = api20240530.UpdateClusterAdvancedConfiguration(ctx, projectID, clusterName, legacyAdvConfigUpdate).Execute() if err != nil { @@ -248,7 +252,7 @@ func (r *rs) createCluster(ctx context.Context, plan *TFModel, diags *diag.Diagn } } - advConfigUpdate := NewAtlasReqAdvancedConfiguration(ctx, &plan.AdvancedConfiguration, diags) + advConfigUpdate := NewAtlasReqAdvancedConfiguration(ctx, planAdvancedConfiguration, diags) var advConfig *admin.ClusterDescriptionProcessArgs20240805 if !update.IsZeroValues(advConfigUpdate) { advConfig, _, err = api.UpdateClusterAdvancedConfiguration(ctx, projectID, clusterName, advConfigUpdate).Execute() @@ -306,7 +310,12 @@ func (r *rs) applyAdvancedConfigurationChanges(ctx context.Context, diags *diag. advConfig *admin.ClusterDescriptionProcessArgs20240805 legacyAdvConfig *admin20240530.ClusterDescriptionProcessArgs ) - patchReqProcessArgs := update.PatchPayloadTpf(ctx, diags, &state.AdvancedConfiguration, &plan.AdvancedConfiguration, NewAtlasReqAdvancedConfiguration) + stateAdvancedConfiguration := getListUniqueElement(diags, &state.AdvancedConfiguration) + planAdvancedConfiguration := getListUniqueElement(diags, &plan.AdvancedConfiguration) + if diags.HasError() { + return nil, nil, false + } + patchReqProcessArgs := update.PatchPayloadTpf(ctx, diags, stateAdvancedConfiguration, planAdvancedConfiguration, NewAtlasReqAdvancedConfiguration) if !update.IsZeroValues(patchReqProcessArgs) { changed = true advConfig, _, err = api.UpdateClusterAdvancedConfiguration(ctx, projectID, clusterName, patchReqProcessArgs).Execute() @@ -319,7 +328,7 @@ func (r *rs) applyAdvancedConfigurationChanges(ctx context.Context, diags *diag. return nil, nil, false } } - patchReqProcessArgsLegacy := update.PatchPayloadTpf(ctx, diags, &state.AdvancedConfiguration, &plan.AdvancedConfiguration, NewAtlasReqAdvancedConfigurationLegacy) + patchReqProcessArgsLegacy := update.PatchPayloadTpf(ctx, diags, stateAdvancedConfiguration, planAdvancedConfiguration, NewAtlasReqAdvancedConfigurationLegacy) if !update.IsZeroValues(patchReqProcessArgsLegacy) { changed = true legacyAdvConfig, _, err = r.Client.AtlasV220240530.ClustersApi.UpdateClusterAdvancedConfiguration(ctx, projectID, clusterName, patchReqProcessArgsLegacy).Execute() diff --git a/internal/service/advancedclustertpf/schema.go b/internal/service/advancedclustertpf/schema.go index 59d9879fb8..78df597071 100644 --- a/internal/service/advancedclustertpf/schema.go +++ b/internal/service/advancedclustertpf/schema.go @@ -2,6 +2,7 @@ package advancedclustertpf import ( "context" + "fmt" "regexp" "github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts" @@ -10,6 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/attr" dsschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" @@ -305,8 +307,8 @@ func resourceSchema(ctx context.Context) schema.Schema { NestedObject: schema.NestedBlockObject{ Attributes: map[string]schema.Attribute{ "change_stream_options_pre_and_post_images_expire_after_seconds": schema.Int64Attribute{ - Optional: true, Computed: true, + Optional: true, MarkdownDescription: "The minimum pre- and post-image retention time in seconds.", Default: int64default.StaticInt64(-1), // in case the user removes the value, we should set it to -1, a special value used by the backend to use its default behavior PlanModifiers: []planmodifier.Int64{ @@ -552,12 +554,12 @@ type TFModel struct { MongoDBVersion types.String `tfsdk:"mongo_db_version"` Name types.String `tfsdk:"name"` VersionReleaseSystem types.String `tfsdk:"version_release_system"` - BiConnectorConfig types.Object `tfsdk:"bi_connector_config"` + BiConnectorConfig types.List `tfsdk:"bi_connector_config"` ConfigServerType types.String `tfsdk:"config_server_type"` ReplicaSetScalingStrategy types.String `tfsdk:"replica_set_scaling_strategy"` ClusterType types.String `tfsdk:"cluster_type"` RootCertType types.String `tfsdk:"root_cert_type"` - AdvancedConfiguration types.Object `tfsdk:"advanced_configuration"` + AdvancedConfiguration types.List `tfsdk:"advanced_configuration"` PinnedFCV types.Object `tfsdk:"pinned_fcv"` TerminationProtectionEnabled types.Bool `tfsdk:"termination_protection_enabled"` Paused types.Bool `tfsdk:"paused"` @@ -576,8 +578,8 @@ type TFModelDS struct { Tags types.Set `tfsdk:"tags"` ReplicaSetScalingStrategy types.String `tfsdk:"replica_set_scaling_strategy"` Name types.String `tfsdk:"name"` - AdvancedConfiguration types.Object `tfsdk:"advanced_configuration"` - BiConnectorConfig types.Object `tfsdk:"bi_connector_config"` + AdvancedConfiguration types.List `tfsdk:"advanced_configuration"` + BiConnectorConfig types.List `tfsdk:"bi_connector_config"` RootCertType types.String `tfsdk:"root_cert_type"` ClusterType types.String `tfsdk:"cluster_type"` MongoDBMajorVersion types.String `tfsdk:"mongo_db_major_version"` @@ -798,3 +800,16 @@ var PinnedFCVObjType = types.ObjectType{AttrTypes: map[string]attr.Type{ "version": types.StringType, "expiration_date": types.StringType, }} + +func getListUniqueElement(diags *diag.Diagnostics, list *types.List) *types.Object { + if len(list.Elements()) != 1 { + diags.AddError("getListUniqueElement", fmt.Sprintf("expected list length 1, got %d", len(list.Elements()))) + return nil + } + obj, ok := list.Elements()[0].(types.Object) + if !ok { + diags.AddError("getListUniqueElement", "expected list element to be an object") + return nil + } + return &obj +}