Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions internal/convert/adv2v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ func convertRepSpecs(resourceb *hclwrite.Body, diskSizeGB hclwrite.Tokens) error
return err
}
if dConfig.IsPresent() {
if len(collectBlocks(blockb, nConfig)) > 0 {
return errDynamicBlockAlone
}
transformReferences(dConfig.content.Body(), getResourceName(dConfig.block), nRegion)
copyAttributesSorted(dConfig.content.Body(), dConfig.content.Body().Attributes())
processAllSpecs(dConfig.content.Body(), diskSizeGB)
Expand Down Expand Up @@ -129,6 +132,9 @@ func convertRepSpecsWithDynamicBlock(resourceb *hclwrite.Body, diskSizeGB hclwri
if err != nil || !dSpec.IsPresent() {
return dynamicBlock{}, err
}
if len(collectBlocks(resourceb, nRepSpecs)) > 0 {
return dynamicBlock{}, errDynamicBlockAlone
}
transformReferences(dSpec.content.Body(), nRepSpecs, nSpec)
dConfig, err := convertConfigsWithDynamicBlock(dSpec.content.Body(), diskSizeGB)
if err != nil {
Expand All @@ -144,6 +150,9 @@ func convertConfigsWithDynamicBlock(specbSrc *hclwrite.Body, diskSizeGB hclwrite
if err != nil {
return dynamicBlock{}, err
}
if len(collectBlocks(specbSrc, nConfig)) > 0 {
return dynamicBlock{}, errDynamicBlockAlone
}
configBody := d.content.Body()
transformReferences(configBody, getResourceName(d.block), nRegion)
regionConfigBody := hclwrite.NewEmptyFile().Body()
Expand Down
6 changes: 6 additions & 0 deletions internal/convert/clu2adv.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@ func fillRepSpecsWithDynamicBlock(resourceb *hclwrite.Body, root attrVals) (dyna
if err != nil || !dSpec.IsPresent() {
return dynamicBlock{}, err
}
if len(collectBlocks(resourceb, nRepSpecs)) > 0 {
return dynamicBlock{}, errDynamicBlockAlone
}
transformReferences(dSpec.content.Body(), nRepSpecs, nSpec)
dConfig, err := fillConfigsWithDynamicRegion(dSpec.content.Body(), root, true)
if err != nil {
Expand All @@ -243,6 +246,9 @@ func fillConfigsWithDynamicRegion(specbSrc *hclwrite.Body, root attrVals, change
if err != nil || !d.IsPresent() {
return dynamicBlock{}, err
}
if len(collectBlocks(specbSrc, nConfigSrc)) > 0 {
return dynamicBlock{}, errDynamicBlockAlone
}
repSpecb := hclwrite.NewEmptyFile().Body()
if zoneName := hcl.GetAttrExpr(specbSrc.GetAttribute(nZoneName)); zoneName != "" {
repSpecb.SetAttributeRaw(nZoneName, hcl.TokensFromExpr(zoneName))
Expand Down
7 changes: 7 additions & 0 deletions internal/convert/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ func runConvertTests(t *testing.T, cmdName string, convert func(testName string,
require.NoError(t, err)
err = json.Unmarshal(errContent, &errMap)
require.NoError(t, err)
unusedErrors := make(map[string]struct{})
for name := range errMap {
unusedErrors[name] = struct{}{}
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sure all items in errors.json are used

g := goldie.New(t,
goldie.WithFixtureDir(root),
goldie.WithNameSuffix(outSuffix))
Expand All @@ -46,7 +51,9 @@ func runConvertTests(t *testing.T, cmdName string, convert func(testName string,
errMsg, found := errMap[testName]
assert.True(t, found, "error not found in file %s for test %s, errMsg: %v", errFilename, testName, err)
assert.Contains(t, err.Error(), errMsg)
delete(unusedErrors, testName)
}
})
}
assert.Empty(t, unusedErrors, "some errors are not being used")
}
5 changes: 5 additions & 0 deletions internal/convert/shared.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package convert

import (
"errors"
"fmt"
"slices"
"strings"
Expand All @@ -9,6 +10,10 @@ import (
"github.com/mongodb-labs/atlas-cli-plugin-terraform/internal/hcl"
)

var (
errDynamicBlockAlone = errors.New("dynamic block must be the only block, see docs for more information")
)

// hasVariableNumShards checks if any block has a variable (non-literal) num_shards attribute
func hasVariableNumShards(blocks []*hclwrite.Block) bool {
for _, block := range blocks {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
resource "mongodbatlas_advanced_cluster" "multiple_blocks" {
project_id = var.project_id
name = var.cluster_name
cluster_type = var.cluster_type
replication_specs {
num_shards = var.replication_specs.num_shards
dynamic "region_configs" {
for_each = var.replication_specs.region_configs
content {
priority = region_configs.value.priority
provider_name = region_configs.value.provider_name
region_name = region_configs.value.region_name
electable_specs {
instance_size = region_configs.value.instance_size
node_count = region_configs.value.electable_node_count
}
}
}
region_configs { # inline block is not allowed with dynamic blocks
priority = 0
provider_name = "AWS"
region_name = "US_EAST_1"
read_only_specs {
instance_size = var.instance_size
node_count = 1
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
resource "mongodbatlas_advanced_cluster" "multiple_blocks" {
project_id = var.project_id
name = var.cluster_name
cluster_type = var.cluster_type
dynamic "replication_specs" {
for_each = var.replication_specs
content {
num_shards = replication_specs.value.num_shards
dynamic "region_configs" {
for_each = replication_specs.value.region_configs
content {
priority = region_configs.value.priority
provider_name = region_configs.value.provider_name
region_name = region_configs.value.region_name
electable_specs {
instance_size = region_configs.value.instance_size
node_count = region_configs.value.electable_node_count
}
}
}
}
}
replication_specs { # inline block is not allowed with dynamic blocks
region_configs {
priority = 7
provider_name = "AWS"
region_name = "EU_WEST_1"
electable_specs {
instance_size = "M10"
node_count = 3
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
resource "mongodbatlas_advanced_cluster" "multiple_blocks" {
project_id = var.project_id
name = var.cluster_name
cluster_type = var.cluster_type
dynamic "replication_specs" {
for_each = var.replication_specs
content {
num_shards = replication_specs.value.num_shards
dynamic "region_configs" {
for_each = replication_specs.value.region_configs
content {
priority = region_configs.value.priority
provider_name = region_configs.value.provider_name
region_name = region_configs.value.region_name
electable_specs {
instance_size = region_configs.value.instance_size
node_count = region_configs.value.electable_node_count
}
}
}
region_configs { # inline block is not allowed with dynamic blocks
priority = 0
provider_name = "AWS"
region_name = "US_EAST_1"
read_only_specs {
instance_size = var.instance_size
node_count = 1
}
}
}
}
}
5 changes: 4 additions & 1 deletion internal/convert/testdata/adv2v2/errors.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@
"configuration_file_error": "failed to parse Terraform config file",
"replication_specs_missing_region_configs": "replication_specs must have at least one region_configs",
"missing_replication_specs": "must have at least one replication_specs",
"dynamic_unsupported_tag": "dynamic blocks are not supported for advanced_configuration"
"dynamic_unsupported_tag": "dynamic blocks are not supported for advanced_configuration",
"dynamic_regions_config_invalid_multiple_blocks": "dynamic block must be the only block",
"dynamic_replication_specs_invalid_multiple_blocks": "dynamic block must be the only block",
"dynamic_replication_specs_invalid_multiple_config_blocks": "dynamic block must be the only block"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
resource "mongodbatlas_cluster" "multiple_blocks" {
project_id = var.project_id
name = "cluster"
cluster_type = "SHARDED"
provider_name = "AWS"
provider_instance_size_name = "M10"
replication_specs {
num_shards = var.replication_specs.num_shards
dynamic "regions_config" {
for_each = var.replication_specs.regions_config
content {
region_name = regions_config.value.region_name
electable_nodes = regions_config.value.electable_nodes
priority = regions_config.value.prio
read_only_nodes = regions_config.value.read_only_nodes
}
}
regions_config { # inline block is not allowed with dynamic blocks
region_name = "US_EAST_1"
read_only_nodes = 1
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Based on https://github.com/mongodb/terraform-provider-mongodbatlas/blob/master/examples/migrate_cluster_to_advanced_cluster/module_maintainer/v1/main.tf
resource "mongodbatlas_cluster" "this" {
project_id = var.project_id
name = var.cluster_name
auto_scaling_disk_gb_enabled = var.auto_scaling_disk_gb_enabled
cluster_type = var.cluster_type
disk_size_gb = var.disk_size
mongo_db_major_version = var.mongo_db_major_version
provider_instance_size_name = var.instance_size
provider_name = var.provider_name
dynamic "replication_specs" {
for_each = var.replication_specs
content {
num_shards = replication_specs.value.num_shards
zone_name = replication_specs.value.zone_name
dynamic "regions_config" {
for_each = replication_specs.value.regions_config
content {
electable_nodes = regions_config.value.electable_nodes
priority = regions_config.value.priority
read_only_nodes = regions_config.value.read_only_nodes
region_name = regions_config.value.region_name
}
}
}
}
replication_specs { # inline block is not allowed with dynamic blocks
num_shards = 1
regions_config {
region_name = "US_EAST_1"
electable_nodes = 3
priority = 7
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Based on https://github.com/mongodb/terraform-provider-mongodbatlas/blob/master/examples/migrate_cluster_to_advanced_cluster/module_maintainer/v1/main.tf
resource "mongodbatlas_cluster" "this" {
project_id = var.project_id
name = var.cluster_name
auto_scaling_disk_gb_enabled = var.auto_scaling_disk_gb_enabled
cluster_type = var.cluster_type
disk_size_gb = var.disk_size
mongo_db_major_version = var.mongo_db_major_version
provider_instance_size_name = var.instance_size
provider_name = var.provider_name
dynamic "replication_specs" {
for_each = var.replication_specs
content {
num_shards = replication_specs.value.num_shards
zone_name = replication_specs.value.zone_name
dynamic "regions_config" {
for_each = replication_specs.value.regions_config
content {
electable_nodes = regions_config.value.electable_nodes
priority = regions_config.value.priority
read_only_nodes = regions_config.value.read_only_nodes
region_name = regions_config.value.region_name
}
}
regions_config { # inline block is not allowed with dynamic blocks
region_name = "US_EAST_1"
read_only_nodes = 1
}
}
}
}
5 changes: 4 additions & 1 deletion internal/convert/testdata/clu2adv/errors.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@
"regions_config_missing_priority": "setting replication_specs: attribute priority not found",
"replication_specs_missing_num_shards": "num_shards not found",
"replication_specs_missing_regions_config": "setting replication_specs: regions_config not found",
"dynamic_unsupported_tag": "dynamic blocks are not supported for advanced_configuration"
"dynamic_unsupported_tag": "dynamic blocks are not supported for advanced_configuration",
"dynamic_regions_config_invalid_multiple_blocks": "dynamic block must be the only block",
"dynamic_replication_specs_invalid_multiple_blocks": "dynamic block must be the only block",
"dynamic_replication_specs_invalid_multiple_config_blocks": "dynamic block must be the only block"
}