@@ -2,16 +2,29 @@ package hcl
22
33import (
44 "fmt"
5+ "strconv"
56
67 "github.com/hashicorp/hcl/v2"
78 "github.com/hashicorp/hcl/v2/hclsyntax"
89 "github.com/hashicorp/hcl/v2/hclwrite"
10+ "github.com/zclconf/go-cty/cty"
911)
1012
1113const (
12- resourceType = "resource"
13- cluster = "mongodbatlas_cluster"
14- advCluster = "mongodbatlas_advanced_cluster"
14+ resourceType = "resource"
15+ cluster = "mongodbatlas_cluster"
16+ advCluster = "mongodbatlas_advanced_cluster"
17+ strReplicationSpecs = "replication_specs"
18+ strRegionConfigs = "region_configs"
19+ strElectableSpecs = "electable_specs"
20+ strProviderRegionName = "provider_region_name"
21+ strRegionName = "region_name"
22+ strProviderName = "provider_name"
23+ strBackingProviderName = "backing_provider_name"
24+ strProviderInstanceSizeName = "provider_instance_size_name"
25+ strInstanceSize = "instance_size"
26+
27+ errFreeCluster = "free cluster"
1528)
1629
1730// ClusterToAdvancedCluster transforms all mongodbatlas_cluster definitions in a
@@ -34,13 +47,97 @@ func ClusterToAdvancedCluster(config []byte) ([]byte, error) {
3447 // TODO: Do the full transformation
3548 labels [0 ] = advCluster
3649 resource .SetLabels (labels )
50+
51+ if resourceBody .FirstMatchingBlock (strReplicationSpecs , nil ) == nil {
52+ if err := fillFreeTier (resourceBody ); err != nil {
53+ return nil , err
54+ }
55+ }
56+
3757 resourceBody .AppendNewline ()
3858 appendComment (resourceBody , "Generated by atlas-cli-plugin-terraform." )
3959 appendComment (resourceBody , "Please confirm that all references to this resource are updated." )
4060 }
4161 return parser .Bytes (), nil
4262}
4363
64+ func fillFreeTier (resourceBody * hclwrite.Body ) error {
65+ resourceBody .SetAttributeValue ("cluster_type" , cty .StringVal ("REPLICASET" ))
66+
67+ regionConfig := hclwrite .NewEmptyFile ()
68+ regionConfigBody := regionConfig .Body ()
69+ setAttrInt (regionConfig .Body (), "priority" , 7 )
70+ if err := moveAttribute (strProviderRegionName , strRegionName , resourceBody , regionConfigBody , errFreeCluster ); err != nil {
71+ return err
72+ }
73+ if err := moveAttribute (strProviderName , strProviderName , resourceBody , regionConfigBody , errFreeCluster ); err != nil {
74+ return err
75+ }
76+ if err := moveAttribute (strBackingProviderName , strBackingProviderName , resourceBody , regionConfigBody , errFreeCluster ); err != nil {
77+ return err
78+ }
79+
80+ electableSpec := hclwrite .NewEmptyFile ()
81+ if err := moveAttribute (strProviderInstanceSizeName , strInstanceSize , resourceBody , electableSpec .Body (), errFreeCluster ); err != nil {
82+ return err
83+ }
84+ regionConfig .Body ().SetAttributeRaw (strElectableSpecs , objectTokens (electableSpec ))
85+
86+ replicationSpec := hclwrite .NewEmptyFile ()
87+ replicationSpec .Body ().SetAttributeRaw (strRegionConfigs , singleArrayTokens (regionConfig ))
88+
89+ resourceBody .SetAttributeRaw (strReplicationSpecs , singleArrayTokens (replicationSpec ))
90+ return nil
91+ }
92+
93+ func moveAttribute (fromAttrName , toAttrName string , fromBody , toBody * hclwrite.Body , errPrefix string ) error {
94+ attr := fromBody .GetAttribute (fromAttrName )
95+ if attr == nil {
96+ return fmt .Errorf ("%s: attribute %s not found" , errPrefix , fromAttrName )
97+ }
98+ fromBody .RemoveAttribute (fromAttrName )
99+ toBody .SetAttributeRaw (toAttrName , attr .Expr ().BuildTokens (nil ))
100+ return nil
101+ }
102+
103+ func setAttrExpr (body * hclwrite.Body , attrName , expression string ) {
104+ tokens := hclwrite.Tokens {
105+ {Type : hclsyntax .TokenIdent , Bytes : []byte (expression )},
106+ }
107+ body .SetAttributeRaw (attrName , tokens )
108+ }
109+
110+ func setAttrInt (body * hclwrite.Body , attrName string , number int ) {
111+ tokens := hclwrite.Tokens {
112+ {Type : hclsyntax .TokenNumberLit , Bytes : []byte (strconv .Itoa (number ))},
113+ }
114+ body .SetAttributeRaw (attrName , tokens )
115+ }
116+
117+ func singleArrayTokens (file * hclwrite.File ) hclwrite.Tokens {
118+ ret := hclwrite.Tokens {
119+ {Type : hclsyntax .TokenOBrack , Bytes : []byte ("[" )},
120+ {Type : hclsyntax .TokenOBrack , Bytes : []byte ("{" )},
121+ {Type : hclsyntax .TokenNewline , Bytes : []byte ("\n " )},
122+ }
123+ ret = append (ret , file .BuildTokens (nil )... )
124+ ret = append (ret ,
125+ & hclwrite.Token {Type : hclsyntax .TokenCBrack , Bytes : []byte ("}" )},
126+ & hclwrite.Token {Type : hclsyntax .TokenCBrack , Bytes : []byte ("]" )})
127+ return ret
128+ }
129+
130+ func objectTokens (file * hclwrite.File ) hclwrite.Tokens {
131+ ret := hclwrite.Tokens {
132+ {Type : hclsyntax .TokenOBrack , Bytes : []byte ("{" )},
133+ {Type : hclsyntax .TokenNewline , Bytes : []byte ("\n " )},
134+ }
135+ ret = append (ret , file .BuildTokens (nil )... )
136+ ret = append (ret ,
137+ & hclwrite.Token {Type : hclsyntax .TokenCBrack , Bytes : []byte ("}" )})
138+ return ret
139+ }
140+
44141func getParser (config []byte ) (* hclwrite.File , error ) {
45142 parser , diags := hclwrite .ParseConfig (config , "" , hcl.Pos {Line : 1 , Column : 1 })
46143 if diags .HasErrors () {
0 commit comments