Skip to content

Commit cb5edda

Browse files
authored
feat: Converts data sources (#24)
* datasources * refactor * rename resource to block * set use_replication_spec_per_shard in data sources * more tests
1 parent 25a2d7b commit cb5edda

File tree

6 files changed

+190
-44
lines changed

6 files changed

+190
-44
lines changed

internal/convert/const_names.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,5 @@ const (
4747
nZoneName = "zone_name"
4848
nKey = "key"
4949
nValue = "value"
50+
nUseRepSpecsPerShard = "use_replication_spec_per_shard"
5051
)

internal/convert/convert.go

Lines changed: 78 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,20 @@ import (
1414
)
1515

1616
const (
17-
resourceType = "resource"
18-
cluster = "mongodbatlas_cluster"
19-
advCluster = "mongodbatlas_advanced_cluster"
20-
valClusterType = "REPLICASET"
21-
valMaxPriority = 7
22-
valMinPriority = 1
23-
errFreeCluster = "free cluster (because no " + nRepSpecs + ")"
24-
errRepSpecs = "setting " + nRepSpecs
25-
errConfigs = "setting " + nConfig
26-
errPriority = "setting " + nPriority
27-
errNumShards = "setting " + nNumShards
17+
resourceType = "resource"
18+
dataSourceType = "data"
19+
cluster = "mongodbatlas_cluster"
20+
advCluster = "mongodbatlas_advanced_cluster"
21+
clusterPlural = "mongodbatlas_clusters"
22+
advClusterPlural = "mongodbatlas_advanced_clusters"
23+
valClusterType = "REPLICASET"
24+
valMaxPriority = 7
25+
valMinPriority = 1
26+
errFreeCluster = "free cluster (because no " + nRepSpecs + ")"
27+
errRepSpecs = "setting " + nRepSpecs
28+
errConfigs = "setting " + nConfig
29+
errPriority = "setting " + nPriority
30+
errNumShards = "setting " + nNumShards
2831
)
2932

3033
type attrVals struct {
@@ -42,35 +45,60 @@ func ClusterToAdvancedCluster(config []byte) ([]byte, error) {
4245
if err != nil {
4346
return nil, err
4447
}
45-
for _, resource := range parser.Body().Blocks() {
46-
labels := resource.Labels()
47-
resourceName := labels[0]
48-
if resource.Type() != resourceType || resourceName != cluster {
49-
continue
50-
}
51-
resourceb := resource.Body()
52-
if errDyn := checkDynamicBlock(resourceb); errDyn != nil {
53-
return nil, errDyn
54-
}
55-
labels[0] = advCluster
56-
resource.SetLabels(labels)
57-
58-
if resourceb.FirstMatchingBlock(nRepSpecs, nil) != nil {
59-
err = fillCluster(resourceb)
60-
} else {
61-
err = fillFreeTierCluster(resourceb)
62-
}
48+
for _, block := range parser.Body().Blocks() {
49+
converted, err := convertResource(block)
6350
if err != nil {
6451
return nil, err
6552
}
66-
67-
resourceb.AppendNewline()
68-
hcl.AppendComment(resourceb, "Generated by atlas-cli-plugin-terraform.")
69-
hcl.AppendComment(resourceb, "Please confirm that all references to this resource are updated.")
53+
converted = converted || convertDataSource(block)
54+
if converted {
55+
blockb := block.Body()
56+
blockb.AppendNewline()
57+
hcl.AppendComment(blockb, "Generated by atlas-cli-plugin-terraform.")
58+
hcl.AppendComment(blockb, "Please confirm that all references to this resource are updated.")
59+
}
7060
}
7161
return parser.Bytes(), nil
7262
}
7363

64+
func convertResource(block *hclwrite.Block) (bool, error) {
65+
if block.Type() != resourceType || getResourceName(block) != cluster {
66+
return false, nil
67+
}
68+
setResourceName(block, advCluster)
69+
blockb := block.Body()
70+
if errDyn := checkDynamicBlock(blockb); errDyn != nil {
71+
return false, errDyn
72+
}
73+
74+
var err error
75+
if blockb.FirstMatchingBlock(nRepSpecs, nil) != nil {
76+
err = fillCluster(blockb)
77+
} else {
78+
err = fillFreeTierCluster(blockb)
79+
}
80+
if err != nil {
81+
return false, err
82+
}
83+
return true, nil
84+
}
85+
86+
func convertDataSource(block *hclwrite.Block) bool {
87+
if block.Type() != dataSourceType {
88+
return false
89+
}
90+
convertMap := map[string]string{
91+
cluster: advCluster,
92+
clusterPlural: advClusterPlural,
93+
}
94+
if newName, found := convertMap[getResourceName(block)]; found {
95+
setResourceName(block, newName)
96+
block.Body().SetAttributeValue(nUseRepSpecsPerShard, cty.True)
97+
return true
98+
}
99+
return false
100+
}
101+
74102
// fillFreeTierCluster is the entry point to convert clusters in free tier
75103
func fillFreeTierCluster(resourceb *hclwrite.Body) error {
76104
resourceb.SetAttributeValue(nClusterType, cty.StringVal(valClusterType))
@@ -301,6 +329,23 @@ func getAutoScalingOpt(opt map[string]hclwrite.Tokens) hclwrite.Tokens {
301329
return hcl.TokensObject(fileb)
302330
}
303331

332+
func setResourceName(resource *hclwrite.Block, name string) {
333+
labels := resource.Labels()
334+
if len(labels) == 0 {
335+
return
336+
}
337+
labels[0] = name
338+
resource.SetLabels(labels)
339+
}
340+
341+
func getResourceName(resource *hclwrite.Block) string {
342+
labels := resource.Labels()
343+
if len(labels) == 0 {
344+
return ""
345+
}
346+
return labels[0]
347+
}
348+
304349
func checkDynamicBlock(body *hclwrite.Body) error {
305350
for _, block := range body.Blocks() {
306351
if block.Type() == "dynamic" {
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
data "mongodbatlas_cluster" "singular" {
2+
# data source content is kept - singular
3+
project_id = mongodbatlas_advanced_cluster.example.project_id
4+
name = mongodbatlas_advanced_cluster.example.name
5+
depends_on = [mongodbatlas_privatelink_endpoint_service.example_endpoint]
6+
}
7+
8+
data "mongodbatlas_clusters" "plural" {
9+
# data source content is kept - plural
10+
project_id = mongodbatlas_advanced_cluster.example.project_id
11+
}
12+
13+
data "mongodbatlas_advanced_cluster" "adv_singular" {
14+
# adv_cluster is not changed - adv_singular
15+
project_id = mongodbatlas_advanced_cluster.example.project_id
16+
name = mongodbatlas_advanced_cluster.example.name
17+
}
18+
19+
data "mongodbatlas_advanced_cluster" "adv_plural" {
20+
# adv_cluster is not changed - adv_plural
21+
project_id = mongodbatlas_advanced_cluster.example.project_id
22+
}
23+
24+
resource "random_resource" "random1" {
25+
# other resources are left unchanged - random1
26+
hi1 = "there1"
27+
}
28+
29+
data "random_datasource" "random2" {
30+
# other resources are left unchanged - random2
31+
hi2 = "there2"
32+
}
33+
34+
# comments out of resources are kept
35+
36+
unknown_block "hello" {
37+
# unkown block types are kept
38+
}
39+
40+
unknown_block {
41+
# plugin doesn't panic with unlabeled blocks - unknown_block
42+
}
43+
44+
resource {
45+
# plugin doesn't panic with unlabeled blocks - resource
46+
}
47+
48+
data {
49+
# plugin doesn't panic with unlabeled blocks - data
50+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
data "mongodbatlas_advanced_cluster" "singular" {
2+
# data source content is kept - singular
3+
project_id = mongodbatlas_advanced_cluster.example.project_id
4+
name = mongodbatlas_advanced_cluster.example.name
5+
depends_on = [mongodbatlas_privatelink_endpoint_service.example_endpoint]
6+
use_replication_spec_per_shard = true
7+
8+
# Generated by atlas-cli-plugin-terraform.
9+
# Please confirm that all references to this resource are updated.
10+
}
11+
12+
data "mongodbatlas_advanced_clusters" "plural" {
13+
# data source content is kept - plural
14+
project_id = mongodbatlas_advanced_cluster.example.project_id
15+
use_replication_spec_per_shard = true
16+
17+
# Generated by atlas-cli-plugin-terraform.
18+
# Please confirm that all references to this resource are updated.
19+
}
20+
21+
data "mongodbatlas_advanced_cluster" "adv_singular" {
22+
# adv_cluster is not changed - adv_singular
23+
project_id = mongodbatlas_advanced_cluster.example.project_id
24+
name = mongodbatlas_advanced_cluster.example.name
25+
}
26+
27+
data "mongodbatlas_advanced_cluster" "adv_plural" {
28+
# adv_cluster is not changed - adv_plural
29+
project_id = mongodbatlas_advanced_cluster.example.project_id
30+
}
31+
32+
resource "random_resource" "random1" {
33+
# other resources are left unchanged - random1
34+
hi1 = "there1"
35+
}
36+
37+
data "random_datasource" "random2" {
38+
# other resources are left unchanged - random2
39+
hi2 = "there2"
40+
}
41+
42+
# comments out of resources are kept
43+
44+
unknown_block "hello" {
45+
# unkown block types are kept
46+
}
47+
48+
unknown_block {
49+
# plugin doesn't panic with unlabeled blocks - unknown_block
50+
}
51+
52+
resource {
53+
# plugin doesn't panic with unlabeled blocks - resource
54+
}
55+
56+
data {
57+
# plugin doesn't panic with unlabeled blocks - data
58+
}

internal/convert/testdata/clu2adv/free_cluster_with_count.in.tf

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,13 @@ resource "resource1" "res1" {
44

55
resource "mongodbatlas_cluster" "free_cluster" { # comment in the resource
66
# comment in own line in the beginning
7-
count = local.use_free_cluster ? 1 : 0
8-
project_id = var.project_id # inline comment kept
9-
name = var.cluster_name
7+
count = local.use_free_cluster ? 1 : 0
8+
project_id = var.project_id # inline comment kept
9+
name = var.cluster_name
1010
# comment in own line in the middle is deleted
1111
provider_name = "TENANT" # inline comment for attribute moved is not kept
1212
backing_provider_name = "AWS"
1313
provider_region_name = var.region
1414
provider_instance_size_name = "M0"
1515
# comment in own line at the end happens before replication_specs
1616
}
17-
18-
data "mongodbatlas_cluster" "cluster2" {
19-
name = "name4"
20-
}

internal/convert/testdata/clu2adv/free_cluster_with_count.out.tf

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,3 @@ resource "mongodbatlas_advanced_cluster" "free_cluster" { # comment in the resou
2828
# Generated by atlas-cli-plugin-terraform.
2929
# Please confirm that all references to this resource are updated.
3030
}
31-
32-
data "mongodbatlas_cluster" "cluster2" {
33-
name = "name4"
34-
}

0 commit comments

Comments
 (0)