From 6983e27b7906f6b4d6e8f291d96abd618d03c4b4 Mon Sep 17 00:00:00 2001 From: EspenAlbert Date: Fri, 12 Jul 2024 10:13:28 +0100 Subject: [PATCH 1/2] test: Support AdvancedConfiguration, MongoDBMajorVersion, RetainBackupsEnabled, EbsVolumeType in cluster --- internal/testutil/acc/cluster.go | 10 ++++- internal/testutil/acc/config_formatter.go | 33 ++++++++++++++- .../testutil/acc/config_formatter_test.go | 42 ++++++++++++++----- 3 files changed, 70 insertions(+), 15 deletions(-) diff --git a/internal/testutil/acc/cluster.go b/internal/testutil/acc/cluster.go index 0786d03963..c3ad33cbf7 100644 --- a/internal/testutil/acc/cluster.go +++ b/internal/testutil/acc/cluster.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/mongodb/terraform-provider-mongodbatlas/internal/common/constant" + "github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion" "go.mongodb.org/atlas-sdk/v20240530002/admin" ) @@ -13,12 +14,15 @@ type ClusterRequest struct { Tags map[string]string ProjectID string ResourceSuffix string + AdvancedConfiguration map[string]any ResourceDependencyName string ClusterName string + MongoDBMajorVersion string ReplicationSpecs []ReplicationSpecRequest DiskSizeGb int CloudBackup bool Geosharded bool + RetainBackupsEnabled bool PitEnabled bool } @@ -94,6 +98,7 @@ type ReplicationSpecRequest struct { Region string InstanceSize string ProviderName string + EbsVolumeType string ExtraRegionConfigs []ReplicationSpecRequest NodeCount int AutoScalingDiskGbEnabled bool @@ -145,8 +150,9 @@ func CloudRegionConfig(req ReplicationSpecRequest) admin.CloudRegionConfig { RegionName: &req.Region, ProviderName: &req.ProviderName, ElectableSpecs: &admin.HardwareSpec{ - InstanceSize: &req.InstanceSize, - NodeCount: &req.NodeCount, + InstanceSize: &req.InstanceSize, + NodeCount: &req.NodeCount, + EbsVolumeType: conversion.StringPtr(req.EbsVolumeType), }, AutoScaling: &admin.AdvancedAutoScalingSettings{ DiskGB: &admin.DiskGBAutoScaling{Enabled: &req.AutoScalingDiskGbEnabled}, diff --git a/internal/testutil/acc/config_formatter.go b/internal/testutil/acc/config_formatter.go index d2052ddfdb..f780122611 100644 --- a/internal/testutil/acc/config_formatter.go +++ b/internal/testutil/acc/config_formatter.go @@ -76,8 +76,16 @@ func ToSnakeCase(str string) string { return strings.ToLower(snake) } +var ( + ClusterAdvConfigOplogMinRetentionHours = "oplog_min_retention_hours" + knownAdvancedConfig = map[string]bool{ + ClusterAdvConfigOplogMinRetentionHours: true, + } +) + func ClusterResourceHcl(req *ClusterRequest) (configStr, clusterName, resourceName string, err error) { - if req == nil || req.ProjectID == "" { + projectID := req.ProjectID + if req == nil || projectID == "" { return "", "", "", errors.New("must specify a ClusterRequest with at least ProjectID set") } req.AddDefaults() @@ -98,17 +106,38 @@ func ClusterResourceHcl(req *ClusterRequest) (configStr, clusterName, resourceNa resourceType := "mongodbatlas_advanced_cluster" cluster := root.AppendNewBlock("resource", []string{resourceType, resourceSuffix}).Body() clusterRootAttributes := map[string]any{ - "project_id": req.ProjectID, "cluster_type": clusterTypeStr, "name": clusterName, "backup_enabled": req.CloudBackup, "pit_enabled": req.PitEnabled, + "mongo_db_major_version": req.MongoDBMajorVersion, + } + if strings.Contains(req.ProjectID, ".") { + err = setAttributeHcl(cluster, fmt.Sprintf("project_id = %s", projectID)) + if err != nil { + return "", "", "", fmt.Errorf("failed to set project_id = %s", projectID) + } + } else { + clusterRootAttributes["project_id"] = projectID } if req.DiskSizeGb != 0 { clusterRootAttributes["disk_size_gb"] = req.DiskSizeGb } + if req.RetainBackupsEnabled { + clusterRootAttributes["retain_backups_enabled"] = req.RetainBackupsEnabled + } addPrimitiveAttributes(cluster, clusterRootAttributes) cluster.AppendNewline() + if len(req.AdvancedConfiguration) > 0 { + for _, key := range sortStringMapKeysAny(req.AdvancedConfiguration) { + if !knownAdvancedConfig[key] { + return "", "", "", fmt.Errorf("unknown key in advanced configuration: %s", key) + } + } + advancedClusterBlock := cluster.AppendNewBlock("advanced_configuration", nil).Body() + addPrimitiveAttributes(advancedClusterBlock, req.AdvancedConfiguration) + cluster.AppendNewline() + } for i, spec := range specs { err = writeReplicationSpec(cluster, spec) if err != nil { diff --git a/internal/testutil/acc/config_formatter_test.go b/internal/testutil/acc/config_formatter_test.go index 2c5f7b9283..ac555d465a 100644 --- a/internal/testutil/acc/config_formatter_test.go +++ b/internal/testutil/acc/config_formatter_test.go @@ -137,11 +137,17 @@ resource "mongodbatlas_advanced_cluster" "cluster_info" { ` var overrideClusterResource = ` resource "mongodbatlas_advanced_cluster" "cluster_info" { - backup_enabled = true - cluster_type = "GEOSHARDED" - name = "my-name" - pit_enabled = true - project_id = "project" + project_id = mongodbatlas_project.test.id + backup_enabled = true + cluster_type = "GEOSHARDED" + mongo_db_major_version = "6.0" + name = "my-name" + pit_enabled = true + retain_backups_enabled = true + + advanced_configuration { + oplog_min_retention_hours = 8 + } replication_specs { num_shards = 1 @@ -155,8 +161,9 @@ resource "mongodbatlas_advanced_cluster" "cluster_info" { disk_gb_enabled = false } electable_specs { - instance_size = "M30" - node_count = 30 + ebs_volume_type = "STANDARD" + instance_size = "M30" + node_count = 30 } } } @@ -374,9 +381,20 @@ func Test_ClusterResourceHcl(t *testing.T) { }, "overrideClusterResource": { overrideClusterResource, - acc.ClusterRequest{ClusterName: clusterName, Geosharded: true, PitEnabled: true, CloudBackup: true, ReplicationSpecs: []acc.ReplicationSpecRequest{ - {Region: "MY_REGION_1", ZoneName: "Zone X", InstanceSize: "M30", NodeCount: 30, ProviderName: constant.AZURE}, - }}, + acc.ClusterRequest{ + ProjectID: "mongodbatlas_project.test.id", + ClusterName: clusterName, + Geosharded: true, + CloudBackup: true, + MongoDBMajorVersion: "6.0", + RetainBackupsEnabled: true, + ReplicationSpecs: []acc.ReplicationSpecRequest{ + {Region: "MY_REGION_1", ZoneName: "Zone X", InstanceSize: "M30", NodeCount: 30, ProviderName: constant.AZURE, EbsVolumeType: "STANDARD"}, + }, + AdvancedConfiguration: map[string]any{ + acc.ClusterAdvConfigOplogMinRetentionHours: 8, + }, + }, }, "twoRegionConfigs": { twoRegionConfigs, @@ -403,7 +421,9 @@ func Test_ClusterResourceHcl(t *testing.T) { for name, tc := range testCases { t.Run(name, func(t *testing.T) { req := tc.req - req.ProjectID = "project" + if req.ProjectID == "" { + req.ProjectID = "project" + } config, actualClusterName, actualResourceName, err := acc.ClusterResourceHcl(&req) require.NoError(t, err) assert.Equal(t, "mongodbatlas_advanced_cluster.cluster_info", actualResourceName) From b60cc3d334a9b158a3de8e35506534beacaccaec Mon Sep 17 00:00:00 2001 From: EspenAlbert Date: Fri, 12 Jul 2024 07:55:49 +0100 Subject: [PATCH 2/2] test: refactor test to use GetClusterInfo --- .../resource_backup_compliance_policy_test.go | 103 ++++++------------ internal/testutil/acc/config_formatter.go | 12 +- .../testutil/acc/config_formatter_test.go | 7 +- 3 files changed, 41 insertions(+), 81 deletions(-) diff --git a/internal/service/backupcompliancepolicy/resource_backup_compliance_policy_test.go b/internal/service/backupcompliancepolicy/resource_backup_compliance_policy_test.go index bd0c81dc53..fc97eae941 100644 --- a/internal/service/backupcompliancepolicy/resource_backup_compliance_policy_test.go +++ b/internal/service/backupcompliancepolicy/resource_backup_compliance_policy_test.go @@ -14,8 +14,9 @@ import ( ) const ( - resourceName = "mongodbatlas_backup_compliance_policy.backup_policy_res" - dataSourceName = "data.mongodbatlas_backup_compliance_policy.backup_policy" + resourceName = "mongodbatlas_backup_compliance_policy.backup_policy_res" + dataSourceName = "data.mongodbatlas_backup_compliance_policy.backup_policy" + projectIDTerraform = "mongodbatlas_project.test.id" ) func TestAccBackupCompliancePolicy_basic(t *testing.T) { @@ -61,6 +62,20 @@ func TestAccBackupCompliancePolicy_overwriteBackupPolicies(t *testing.T) { orgID = os.Getenv("MONGODB_ATLAS_ORG_ID") projectName = acc.RandomProjectName() // No ProjectIDExecution to avoid conflicts with backup compliance policy projectOwnerID = os.Getenv("MONGODB_ATLAS_PROJECT_OWNER_ID") + req = acc.ClusterRequest{ + AdvancedConfiguration: map[string]any{ + acc.ClusterAdvConfigOplogMinRetentionHours: 8, + }, + ProjectID: projectIDTerraform, + MongoDBMajorVersion: "6.0", + CloudBackup: true, + DiskSizeGb: 12, + RetainBackupsEnabled: true, + ReplicationSpecs: []acc.ReplicationSpecRequest{ + {EbsVolumeType: "STANDARD", AutoScalingDiskGbEnabled: true, NodeCount: 3}, + }, + } + clusterInfo = acc.GetClusterInfo(t, &req) ) resource.ParallelTest(t, resource.TestCase{ @@ -68,10 +83,10 @@ func TestAccBackupCompliancePolicy_overwriteBackupPolicies(t *testing.T) { ProtoV6ProviderFactories: acc.TestAccProviderV6Factories, Steps: []resource.TestStep{ { - Config: configClusterWithBackupSchedule(projectName, orgID, projectOwnerID), + Config: configClusterWithBackupSchedule(projectName, orgID, projectOwnerID, &clusterInfo), }, { - Config: configOverwriteIncompatibleBackupPoliciesError(projectName, orgID, projectOwnerID), + Config: configOverwriteIncompatibleBackupPoliciesError(projectName, orgID, projectOwnerID, &clusterInfo), ExpectError: regexp.MustCompile(`BACKUP_POLICIES_NOT_MEETING_BACKUP_COMPLIANCE_POLICY_REQUIREMENTS`), }, }, @@ -324,39 +339,11 @@ func configWithoutRestoreDays(projectName, orgID, projectOwnerID string) string ` } -func configOverwriteIncompatibleBackupPoliciesError(projectName, orgID, projectOwnerID string) string { - return acc.ConfigProjectWithSettings(projectName, orgID, projectOwnerID, false) + ` - resource "mongodbatlas_cluster" "test" { - project_id = mongodbatlas_project.test.id - name = "test1" - provider_name = "AWS" - cluster_type = "REPLICASET" - mongo_db_major_version = "6.0" - provider_instance_size_name = "M10" - auto_scaling_compute_enabled = false - cloud_backup = true - auto_scaling_disk_gb_enabled = true - disk_size_gb = 12 - provider_volume_type = "STANDARD" - retain_backups_enabled = true - - advanced_configuration { - oplog_min_retention_hours = 8 - } - - replication_specs { - num_shards = 1 - regions_config { - region_name = "US_EAST_1" - electable_nodes = 3 - priority = 7 - read_only_nodes = 0 - } - } - } - +func configOverwriteIncompatibleBackupPoliciesError(projectName, orgID, projectOwnerID string, info *acc.ClusterInfo) string { + return acc.ConfigProjectWithSettings(projectName, orgID, projectOwnerID, false) + fmt.Sprintf(` + %[1]s resource "mongodbatlas_cloud_backup_schedule" "test" { - cluster_name = mongodbatlas_cluster.test.name + cluster_name = %[2]s.name project_id = mongodbatlas_project.test.id reference_hour_of_day = 3 @@ -367,7 +354,7 @@ func configOverwriteIncompatibleBackupPoliciesError(projectName, orgID, projectO cloud_provider = "AWS" frequencies = ["DAILY"] region_name = "US_WEST_1" - replication_spec_id = one(mongodbatlas_cluster.test.replication_specs).id + replication_spec_id = one(%[2]s.replication_specs).id should_copy_oplogs = false } } @@ -393,42 +380,14 @@ func configOverwriteIncompatibleBackupPoliciesError(projectName, orgID, projectO retention_value = 1 } } - ` + `, info.ClusterTerraformStr, info.ClusterResourceName) } -func configClusterWithBackupSchedule(projectName, orgID, projectOwnerID string) string { - return acc.ConfigProjectWithSettings(projectName, orgID, projectOwnerID, false) + ` - resource "mongodbatlas_cluster" "test" { - project_id = mongodbatlas_project.test.id - name = "test1" - provider_name = "AWS" - cluster_type = "REPLICASET" - mongo_db_major_version = "6.0" - provider_instance_size_name = "M10" - auto_scaling_compute_enabled = false - cloud_backup = true - auto_scaling_disk_gb_enabled = true - disk_size_gb = 12 - provider_volume_type = "STANDARD" - retain_backups_enabled = true - - advanced_configuration { - oplog_min_retention_hours = 8 - } - - replication_specs { - num_shards = 1 - regions_config { - region_name = "US_EAST_1" - electable_nodes = 3 - priority = 7 - read_only_nodes = 0 - } - } - } - +func configClusterWithBackupSchedule(projectName, orgID, projectOwnerID string, info *acc.ClusterInfo) string { + return acc.ConfigProjectWithSettings(projectName, orgID, projectOwnerID, false) + fmt.Sprintf(` + %[1]s resource "mongodbatlas_cloud_backup_schedule" "test" { - cluster_name = mongodbatlas_cluster.test.name + cluster_name = %[2]s.name project_id = mongodbatlas_project.test.id reference_hour_of_day = 3 @@ -439,11 +398,11 @@ func configClusterWithBackupSchedule(projectName, orgID, projectOwnerID string) cloud_provider = "AWS" frequencies = ["DAILY"] region_name = "US_WEST_1" - replication_spec_id = one(mongodbatlas_cluster.test.replication_specs).id + replication_spec_id = one(%[2]s.replication_specs).id should_copy_oplogs = false } } - ` + `, info.ClusterTerraformStr, info.ClusterResourceName) } func basicChecks() []resource.TestCheckFunc { diff --git a/internal/testutil/acc/config_formatter.go b/internal/testutil/acc/config_formatter.go index f780122611..6662fe4fd6 100644 --- a/internal/testutil/acc/config_formatter.go +++ b/internal/testutil/acc/config_formatter.go @@ -84,10 +84,10 @@ var ( ) func ClusterResourceHcl(req *ClusterRequest) (configStr, clusterName, resourceName string, err error) { - projectID := req.ProjectID - if req == nil || projectID == "" { + if req == nil || req.ProjectID == "" { return "", "", "", errors.New("must specify a ClusterRequest with at least ProjectID set") } + projectID := req.ProjectID req.AddDefaults() specRequests := req.ReplicationSpecs specs := make([]admin.ReplicationSpec, len(specRequests)) @@ -106,10 +106,10 @@ func ClusterResourceHcl(req *ClusterRequest) (configStr, clusterName, resourceNa resourceType := "mongodbatlas_advanced_cluster" cluster := root.AppendNewBlock("resource", []string{resourceType, resourceSuffix}).Body() clusterRootAttributes := map[string]any{ - "cluster_type": clusterTypeStr, - "name": clusterName, - "backup_enabled": req.CloudBackup, - "pit_enabled": req.PitEnabled, + "cluster_type": clusterTypeStr, + "name": clusterName, + "backup_enabled": req.CloudBackup, + "pit_enabled": req.PitEnabled, "mongo_db_major_version": req.MongoDBMajorVersion, } if strings.Contains(req.ProjectID, ".") { diff --git a/internal/testutil/acc/config_formatter_test.go b/internal/testutil/acc/config_formatter_test.go index ac555d465a..9f43d131e1 100644 --- a/internal/testutil/acc/config_formatter_test.go +++ b/internal/testutil/acc/config_formatter_test.go @@ -391,6 +391,7 @@ func Test_ClusterResourceHcl(t *testing.T) { ReplicationSpecs: []acc.ReplicationSpecRequest{ {Region: "MY_REGION_1", ZoneName: "Zone X", InstanceSize: "M30", NodeCount: 30, ProviderName: constant.AZURE, EbsVolumeType: "STANDARD"}, }, + PitEnabled: true, AdvancedConfiguration: map[string]any{ acc.ClusterAdvConfigOplogMinRetentionHours: 8, }, @@ -421,9 +422,9 @@ func Test_ClusterResourceHcl(t *testing.T) { for name, tc := range testCases { t.Run(name, func(t *testing.T) { req := tc.req - if req.ProjectID == "" { - req.ProjectID = "project" - } + if req.ProjectID == "" { + req.ProjectID = "project" + } config, actualClusterName, actualResourceName, err := acc.ClusterResourceHcl(&req) require.NoError(t, err) assert.Equal(t, "mongodbatlas_advanced_cluster.cluster_info", actualResourceName)