diff --git a/internal/convert/clu2adv.go b/internal/convert/clu2adv.go index 914ef64..63862ee 100644 --- a/internal/convert/clu2adv.go +++ b/internal/convert/clu2adv.go @@ -69,8 +69,8 @@ func convertResource(block *hclwrite.Block) (bool, error) { } func isFreeTierCluster(resourceb *hclwrite.Body) bool { - d, _ := getDynamicBlock(resourceb, nRepSpecs, true) - return resourceb.FirstMatchingBlock(nRepSpecs, nil) == nil && !d.IsPresent() + providerName, _ := hcl.GetAttrString(resourceb.GetAttribute(nProviderName)) + return providerName == nTenant } func convertDataSource(block *hclwrite.Block) bool { @@ -107,6 +107,32 @@ func fillMovedBlocks(body *hclwrite.Body, moveLabels []string) { } } +// createDefaultRepSpec creates a default replication_specs for clusters without any +// (e.g. upgraded from free tier). +func createDefaultRepSpec(resourceb *hclwrite.Body, root attrVals) error { + resourceb.SetAttributeValue(nClusterType, cty.StringVal(valClusterType)) + configb := hclwrite.NewEmptyFile().Body() + hcl.SetAttrInt(configb, nPriority, valMaxPriority) + if err := hcl.MoveAttr(resourceb, configb, nRegionNameSrc, nRegionName, errRoot); err != nil { + return err + } + if providerNameTokens, found := root.req[nProviderName]; found { + configb.SetAttributeRaw(nProviderName, providerNameTokens) + } + + electableSpecb := hclwrite.NewEmptyFile().Body() + if instanceSizeTokens, found := root.req[nInstanceSizeSrc]; found { + electableSpecb.SetAttributeRaw(nInstanceSize, instanceSizeTokens) + } + electableSpecb.SetAttributeValue(nNodeCount, cty.NumberIntVal(valDefaultNodeCount)) + configb.SetAttributeRaw(nElectableSpecs, hcl.TokensObject(electableSpecb)) + + repSpecsb := hclwrite.NewEmptyFile().Body() + repSpecsb.SetAttributeRaw(nConfig, hcl.TokensArraySingle(configb)) + resourceb.SetAttributeRaw(nRepSpecs, hcl.TokensArraySingle(repSpecsb)) + return nil +} + // fillFreeTierCluster is the entry point to convert clusters in free tier func processFreeTierCluster(resourceb *hclwrite.Body) error { resourceb.SetAttributeValue(nClusterType, cty.StringVal(valClusterType)) @@ -160,7 +186,7 @@ func processRepSpecsCluster(resourceb *hclwrite.Body, root attrVals) error { } repSpecBlocks := collectBlocks(resourceb, nRepSpecs) if len(repSpecBlocks) == 0 { - return fmt.Errorf("must have at least one replication_specs") + return createDefaultRepSpec(resourceb, root) } dConfig, err := processConfigsWithDynamicRegion(repSpecBlocks[0].Body(), root, false) if err != nil { diff --git a/internal/convert/const.go b/internal/convert/const.go index 350f210..2337ea6 100644 --- a/internal/convert/const.go +++ b/internal/convert/const.go @@ -1,20 +1,21 @@ package convert const ( - resourceType = "resource" - dataSourceType = "data" - cluster = "mongodbatlas_cluster" - advCluster = "mongodbatlas_advanced_cluster" - clusterPlural = "mongodbatlas_clusters" - advClusterPlural = "mongodbatlas_advanced_clusters" - valClusterType = "REPLICASET" - valMaxPriority = 7 - valMinPriority = 0 - errFreeCluster = "free cluster (because no " + nRepSpecs + ")" - errRepSpecs = "setting " + nRepSpecs - errPriority = "setting " + nPriority - errNumShards = "setting " + nNumShards - errRoot = "setting root attributes" + resourceType = "resource" + dataSourceType = "data" + cluster = "mongodbatlas_cluster" + advCluster = "mongodbatlas_advanced_cluster" + clusterPlural = "mongodbatlas_clusters" + advClusterPlural = "mongodbatlas_advanced_clusters" + valClusterType = "REPLICASET" + valMaxPriority = 7 + valMinPriority = 0 + valDefaultNodeCount = 3 + errFreeCluster = "free cluster (because no " + nRepSpecs + ")" + errRepSpecs = "setting " + nRepSpecs + errPriority = "setting " + nPriority + errNumShards = "setting " + nNumShards + errRoot = "setting root attributes" commentGeneratedBy = "Generated by atlas-cli-plugin-terraform." commentConfirmReferences = "Please review the changes and confirm that references to this resource are updated." @@ -80,4 +81,5 @@ const ( nSpec = "spec" nFailIndexKeyTooLong = "fail_index_key_too_long" nDefaultReadConcern = "default_read_concern" + nTenant = "TENANT" ) diff --git a/internal/convert/testdata/clu2adv/free_cluster_with_count.in.tf b/internal/convert/testdata/clu2adv/comments.in.tf similarity index 83% rename from internal/convert/testdata/clu2adv/free_cluster_with_count.in.tf rename to internal/convert/testdata/clu2adv/comments.in.tf index 4702169..d3f38e8 100644 --- a/internal/convert/testdata/clu2adv/free_cluster_with_count.in.tf +++ b/internal/convert/testdata/clu2adv/comments.in.tf @@ -1,7 +1,3 @@ -resource "resource1" "res1" { - name = "name1" -} - resource "mongodbatlas_cluster" "free_cluster" { # comment in the resource # comment in own line in the beginning count = local.use_free_cluster ? 1 : 0 @@ -14,3 +10,8 @@ resource "mongodbatlas_cluster" "free_cluster" { # comment in the resource provider_instance_size_name = "M0" # comment in own line at the end happens before replication_specs } + +resource "another_resource" "res1" { + # comment in own line in the middle is not deleted in unprocessed resource + name = "name1" +} diff --git a/internal/convert/testdata/clu2adv/free_cluster_with_count.out.tf b/internal/convert/testdata/clu2adv/comments.out.tf similarity index 88% rename from internal/convert/testdata/clu2adv/free_cluster_with_count.out.tf rename to internal/convert/testdata/clu2adv/comments.out.tf index c7dbdbf..8a689a4 100644 --- a/internal/convert/testdata/clu2adv/free_cluster_with_count.out.tf +++ b/internal/convert/testdata/clu2adv/comments.out.tf @@ -1,7 +1,3 @@ -resource "resource1" "res1" { - name = "name1" -} - resource "mongodbatlas_advanced_cluster" "free_cluster" { # comment in the resource # comment in own line in the beginning count = local.use_free_cluster ? 1 : 0 @@ -28,3 +24,8 @@ resource "mongodbatlas_advanced_cluster" "free_cluster" { # comment in the resou # Generated by atlas-cli-plugin-terraform. # Please review the changes and confirm that references to this resource are updated. } + +resource "another_resource" "res1" { + # comment in own line in the middle is not deleted in unprocessed resource + name = "name1" +} diff --git a/internal/convert/testdata/clu2adv/free_cluster.in.tf b/internal/convert/testdata/clu2adv/free_cluster.in.tf new file mode 100644 index 0000000..0e62d39 --- /dev/null +++ b/internal/convert/testdata/clu2adv/free_cluster.in.tf @@ -0,0 +1,42 @@ +resource "mongodbatlas_cluster" "free_cluster" { + project_id = var.project_id + name = var.cluster_name + provider_name = "TENANT" + backing_provider_name = "AWS" + provider_region_name = var.region + provider_instance_size_name = "M0" +} + +resource "mongodbatlas_cluster" "count" { + count = local.use_free_cluster ? 1 : 0 + project_id = var.project_id + name = var.cluster_name + provider_name = "TENANT" + backing_provider_name = "AWS" + provider_region_name = var.region + provider_instance_size_name = "M0" +} + + +resource "mongodbatlas_cluster" "upgrade_from_free_cluster" { + # upgraded free cluster to dedicated + project_id = var.project_id + name = var.cluster_name + provider_name = "AWS" # changed from TENANT to AWS + provider_instance_size_name = "M10" # changed from M0 to M10 + # removed backing_provider_name = AWS" + provider_region_name = var.region +} + +resource "mongodbatlas_cluster" "upgrade_from_free_cluster_with_variables" { + # upgraded free cluster to dedicated, using variables in all attributes + project_id = var.project_id + name = var.cluster_name + provider_name = var.provider_name + provider_instance_size_name = var.instance_size + provider_region_name = var.region +} + +resource "another_resource" "res1" { + name = "name1" +} diff --git a/internal/convert/testdata/clu2adv/free_cluster.out.tf b/internal/convert/testdata/clu2adv/free_cluster.out.tf new file mode 100644 index 0000000..6cd06ee --- /dev/null +++ b/internal/convert/testdata/clu2adv/free_cluster.out.tf @@ -0,0 +1,103 @@ +resource "mongodbatlas_advanced_cluster" "free_cluster" { + project_id = var.project_id + name = var.cluster_name + cluster_type = "REPLICASET" + replication_specs = [ + { + region_configs = [ + { + priority = 7 + region_name = var.region + provider_name = "TENANT" + backing_provider_name = "AWS" + electable_specs = { + instance_size = "M0" + } + } + ] + } + ] + + # Generated by atlas-cli-plugin-terraform. + # Please review the changes and confirm that references to this resource are updated. +} + +resource "mongodbatlas_advanced_cluster" "count" { + count = local.use_free_cluster ? 1 : 0 + project_id = var.project_id + name = var.cluster_name + cluster_type = "REPLICASET" + replication_specs = [ + { + region_configs = [ + { + priority = 7 + region_name = var.region + provider_name = "TENANT" + backing_provider_name = "AWS" + electable_specs = { + instance_size = "M0" + } + } + ] + } + ] + + # Generated by atlas-cli-plugin-terraform. + # Please review the changes and confirm that references to this resource are updated. +} + + +resource "mongodbatlas_advanced_cluster" "upgrade_from_free_cluster" { + # upgraded free cluster to dedicated + project_id = var.project_id + name = var.cluster_name + cluster_type = "REPLICASET" + replication_specs = [ + { + region_configs = [ + { + priority = 7 + region_name = var.region + provider_name = "AWS" + electable_specs = { + instance_size = "M10" + node_count = 3 + } + } + ] + } + ] + + # Generated by atlas-cli-plugin-terraform. + # Please review the changes and confirm that references to this resource are updated. +} + +resource "mongodbatlas_advanced_cluster" "upgrade_from_free_cluster_with_variables" { + # upgraded free cluster to dedicated, using variables in all attributes + project_id = var.project_id + name = var.cluster_name + cluster_type = "REPLICASET" + replication_specs = [ + { + region_configs = [ + { + priority = 7 + region_name = var.region + provider_name = var.provider_name + electable_specs = { + instance_size = var.instance_size + node_count = 3 + } + } + ] + } + ] + + # Generated by atlas-cli-plugin-terraform. + # Please review the changes and confirm that references to this resource are updated. +} + +resource "another_resource" "res1" { + name = "name1" +} diff --git a/internal/convert/testdata/clu2adv/free_cluster_missing_attribute.in.tf b/internal/convert/testdata/clu2adv/free_cluster_missing_attribute.in.tf index 2f17b21..50ed2c1 100644 --- a/internal/convert/testdata/clu2adv/free_cluster_missing_attribute.in.tf +++ b/internal/convert/testdata/clu2adv/free_cluster_missing_attribute.in.tf @@ -1,19 +1,8 @@ -resource "resource1" "res1" { - name = "name1" -} - -resource "mongodbatlas_cluster" "free_cluster" { # comment in the resource - # comment in own line in the beginning - count = local.use_free_cluster ? 1 : 0 - project_id = var.project_id # inline comment kept - name = var.cluster_name - # comment in own line in the middle is deleted - provider_name = "TENANT" # inline comment for attribute moved is not kept +resource "mongodbatlas_cluster" "free_cluster" { + project_id = var.project_id + name = var.cluster_name + provider_name = "TENANT" provider_region_name = var.region provider_instance_size_name = "M0" - # comment in own line at the end happens before replication_specs -} - -data "mongodbatlas_cluster" "cluster2" { - name = "name4" + # missing backing_provider_name }