Skip to content

Commit feeff66

Browse files
committed
some refactors
1 parent 4d843b9 commit feeff66

File tree

3 files changed

+21
-150
lines changed

3 files changed

+21
-150
lines changed

internal/convert/adv2v2.go

Lines changed: 3 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
// AdvancedClusterToV2 transforms all mongodbatlas_advanced_cluster resource definitions in a
1212
// Terraform configuration file from SDKv2 schema to TPF (Terraform Plugin Framework) schema.
1313
// All other resources and data sources are left untouched.
14-
// TODO: Not implemented yet.
1514
func AdvancedClusterToV2(config []byte) ([]byte, error) {
1615
parser, err := hcl.GetParser(config)
1716
if err != nil {
@@ -58,7 +57,6 @@ func updateResource(resource *hclwrite.Block) (bool, error) {
5857
}
5958

6059
func convertRepSpecs(resourceb *hclwrite.Body, diskSizeGB hclwrite.Tokens) error {
61-
// Handle dynamic blocks for replication_specs
6260
dSpec, err := getDynamicBlock(resourceb, nRepSpecs)
6361
if err != nil {
6462
return err
@@ -67,17 +65,12 @@ func convertRepSpecs(resourceb *hclwrite.Body, diskSizeGB hclwrite.Tokens) error
6765
return convertDynamicRepSpecs(resourceb, dSpec, diskSizeGB)
6866
}
6967

70-
// Collect all replication_specs blocks first
7168
repSpecBlocks := collectBlocks(resourceb, nRepSpecs)
72-
7369
if len(repSpecBlocks) == 0 {
7470
return fmt.Errorf("must have at least one replication_specs")
7571
}
7672

77-
// Check if any replication_specs has a variable num_shards
78-
hasVariableNumShards := HasVariableNumShards(repSpecBlocks)
79-
80-
if hasVariableNumShards {
73+
if hasVariableNumShards(repSpecBlocks) {
8174
var concatParts []hclwrite.Tokens
8275

8376
for _, block := range repSpecBlocks {
@@ -89,7 +82,7 @@ func convertRepSpecs(resourceb *hclwrite.Body, diskSizeGB hclwrite.Tokens) error
8982
return err
9083
}
9184

92-
tokens, err := ProcessNumShards(numShardsAttr, blockb)
85+
tokens, err := processNumShards(numShardsAttr, blockb)
9386
if err != nil {
9487
return err
9588
}
@@ -125,10 +118,7 @@ func convertRepSpecs(resourceb *hclwrite.Body, diskSizeGB hclwrite.Tokens) error
125118
}
126119

127120
func convertDynamicRepSpecs(resourceb *hclwrite.Body, dSpec dynamicBlock, diskSizeGB hclwrite.Tokens) error {
128-
// Transform references from replication_specs.value.* to spec.*
129121
transformDynamicBlockReferences(dSpec.content.Body(), nRepSpecs, nSpec)
130-
131-
// Check for dynamic region_configs within this dynamic replication_specs
132122
dConfig, err := getDynamicBlock(dSpec.content.Body(), nConfig)
133123
if err != nil {
134124
return err
@@ -139,150 +129,98 @@ func convertDynamicRepSpecs(resourceb *hclwrite.Body, dSpec dynamicBlock, diskSi
139129
return err
140130
}
141131
}
142-
143132
if dConfig.IsPresent() {
144-
// Handle nested dynamic block for region_configs
145133
return convertDynamicRepSpecsWithDynamicConfig(resourceb, dSpec, dConfig, diskSizeGB)
146134
}
147-
148-
// Get num_shards from the dynamic block content
149135
numShardsAttr := dSpec.content.Body().GetAttribute(nNumShards)
150136
if numShardsAttr != nil {
151137
numShardsExpr := replaceDynamicBlockReferences(hcl.GetAttrExpr(numShardsAttr), nRepSpecs, nSpec)
152138
dSpec.content.Body().RemoveAttribute(nNumShards)
153-
154-
// Convert region_configs inside the dynamic block
155139
if err := convertConfig(dSpec.content.Body(), diskSizeGB); err != nil {
156140
return err
157141
}
158-
159-
// Create the for expression for the flattened replication_specs
160142
outerFor := buildForExpr(nSpec, hcl.GetAttrExpr(dSpec.forEach))
161143
innerFor := buildForExpr("i", fmt.Sprintf("range(%s)", numShardsExpr))
162144
forExpr := fmt.Sprintf("%s [\n %s ", outerFor, innerFor)
163145
tokens := hcl.TokensFromExpr(forExpr)
164146
tokens = append(tokens, hcl.TokensObject(dSpec.content.Body())...)
165147
tokens = append(tokens, hcl.TokensFromExpr("\n ]\n]")...)
166-
167148
resourceb.RemoveBlock(dSpec.block)
168149
resourceb.SetAttributeRaw(nRepSpecs, hcl.TokensFuncFlatten(tokens))
169150
return nil
170151
}
171-
// No num_shards, default to 1
172152
dSpec.content.Body().RemoveAttribute(nNumShards)
173-
174-
// Convert region_configs inside the dynamic block
175153
if err := convertConfig(dSpec.content.Body(), diskSizeGB); err != nil {
176154
return err
177155
}
178-
179-
// Create the for expression without num_shards
180156
forExpr := buildForExpr(nSpec, hcl.GetAttrExpr(dSpec.forEach))
181157
tokens := hcl.TokensFromExpr(forExpr)
182158
tokens = append(tokens, hcl.TokensObject(dSpec.content.Body())...)
183159
tokens = hcl.EncloseBracketsNewLines(tokens)
184-
185160
resourceb.RemoveBlock(dSpec.block)
186161
resourceb.SetAttributeRaw(nRepSpecs, tokens)
187162
return nil
188163
}
189164

190-
// Helper function to process blocks for region configs
191165
func processRegionConfigBlocks(targetBody *hclwrite.Body, blocks []*hclwrite.Block, diskSizeGB hclwrite.Tokens) {
192166
for _, block := range blocks {
193167
blockType := block.Type()
194168
blockFile := hclwrite.NewEmptyFile()
195169
blockBody := blockFile.Body()
196-
197-
// Copy all attributes in deterministic order
198170
copyAttributesSorted(blockBody, block.Body().Attributes())
199-
200-
// Add disk_size_gb to specs blocks if needed
201171
if diskSizeGB != nil && (blockType == nElectableSpecs ||
202172
blockType == nReadOnlySpecs || blockType == nAnalyticsSpecs) {
203173
blockBody.SetAttributeRaw(nDiskSizeGB, diskSizeGB)
204174
}
205-
206175
targetBody.SetAttributeRaw(blockType, hcl.TokensObject(blockBody))
207176
}
208177
}
209178

210179
func convertDynamicRepSpecsWithDynamicConfig(resourceb *hclwrite.Body, dSpec, dConfig dynamicBlock,
211180
diskSizeGB hclwrite.Tokens) error {
212-
// Get the block name from the dynamic block
213181
configBlockName := getResourceName(dConfig.block)
214-
215-
// Get num_shards expression
216182
numShardsAttr := dSpec.content.Body().GetAttribute(nNumShards)
217183
if numShardsAttr != nil {
218184
numShardsExpr := replaceDynamicBlockReferences(hcl.GetAttrExpr(numShardsAttr), nRepSpecs, nSpec)
219-
220-
// Transform references in place for the dynamic config content
221185
transformDynamicBlockReferencesRecursive(dConfig.content.Body(), configBlockName, nRegion)
222-
// Also transform outer references (with deterministic ordering)
223186
transform := func(expr string) string {
224187
return replaceDynamicBlockReferences(expr, nRepSpecs, nSpec)
225188
}
226189
transformAttributesSorted(dConfig.content.Body(), dConfig.content.Body().Attributes(), transform)
227190
for _, block := range dConfig.content.Body().Blocks() {
228191
transformAttributesSorted(block.Body(), block.Body().Attributes(), transform)
229192
}
230-
231-
// Build the expression using HCL functions
232-
// Use standardized property name (region_configs) instead of the actual for_each collection
233193
configForEach := fmt.Sprintf("%s.%s", nSpec, nConfig)
234-
235-
// Create the inner region_configs body
236194
regionConfigFile := hclwrite.NewEmptyFile()
237195
regionConfigBody := regionConfigFile.Body()
238-
239-
// Copy all attributes in deterministic order
240196
copyAttributesSorted(regionConfigBody, dConfig.content.Body().Attributes())
241-
242-
// Add all blocks generically as objects
243197
processRegionConfigBlocks(regionConfigBody, dConfig.content.Body().Blocks(), diskSizeGB)
244-
245-
// Build the region_configs for expression
246198
regionForExpr := buildForExpr(nRegion, configForEach)
247199
regionTokens := hcl.TokensFromExpr(regionForExpr)
248200
regionTokens = append(regionTokens, hcl.TokensObject(regionConfigBody)...)
249-
250-
// Create the replication spec body
251201
repSpecFile := hclwrite.NewEmptyFile()
252202
repSpecBody := repSpecFile.Body()
253-
254203
if zoneNameAttr := dSpec.content.Body().GetAttribute(nZoneName); zoneNameAttr != nil {
255204
zoneNameExpr := replaceDynamicBlockReferences(hcl.GetAttrExpr(zoneNameAttr), nRepSpecs, nSpec)
256205
repSpecBody.SetAttributeRaw(nZoneName, hcl.TokensFromExpr(zoneNameExpr))
257206
}
258-
259207
repSpecBody.SetAttributeRaw(nConfig, hcl.EncloseBracketsNewLines(regionTokens))
260-
261-
// Build the inner for expression with range
262208
innerForExpr := buildForExpr("i", fmt.Sprintf("range(%s)", numShardsExpr))
263209
innerTokens := hcl.TokensFromExpr(innerForExpr)
264210
innerTokens = append(innerTokens, hcl.TokensObject(repSpecBody)...)
265-
266-
// Build the outer for expression
267211
outerForExpr := buildForExpr(nSpec, hcl.GetAttrExpr(dSpec.forEach))
268212
outerTokens := hcl.TokensFromExpr(fmt.Sprintf("%s ", outerForExpr))
269213
outerTokens = append(outerTokens, hcl.EncloseBracketsNewLines(innerTokens)...)
270-
271-
// Apply flatten to the entire expression
272214
tokens := hcl.TokensFuncFlatten(outerTokens)
273-
274215
resourceb.RemoveBlock(dSpec.block)
275216
resourceb.SetAttributeRaw(nRepSpecs, tokens)
276217
return nil
277218
}
278-
// No num_shards, handle like without nested shards
279219
return convertDynamicRepSpecsWithoutNumShards(resourceb, dSpec, dConfig, diskSizeGB, configBlockName)
280220
}
281221

282-
// Helper function to add attributes with transformation
283222
func addAttributesWithTransform(targetBody *hclwrite.Body, sourceAttrs map[string]*hclwrite.Attribute,
284223
configBlockName string) {
285-
// Apply transformations in order
286224
transform1 := func(expr string) string {
287225
return replaceDynamicBlockReferences(expr, configBlockName, nRegion)
288226
}
@@ -294,59 +232,36 @@ func addAttributesWithTransform(targetBody *hclwrite.Body, sourceAttrs map[strin
294232

295233
func convertDynamicRepSpecsWithoutNumShards(resourceb *hclwrite.Body, dSpec, dConfig dynamicBlock,
296234
diskSizeGB hclwrite.Tokens, configBlockName string) error {
297-
// Get zone_name if present
298235
repSpecFile := hclwrite.NewEmptyFile()
299236
repSpecb := repSpecFile.Body()
300-
301237
if zoneNameAttr := dSpec.content.Body().GetAttribute(nZoneName); zoneNameAttr != nil {
302238
zoneNameExpr := replaceDynamicBlockReferences(hcl.GetAttrExpr(zoneNameAttr), nRepSpecs, nSpec)
303239
repSpecb.SetAttributeRaw(nZoneName, hcl.TokensFromExpr(zoneNameExpr))
304240
}
305-
306-
// Create config content with transformed references
307241
configFile := hclwrite.NewEmptyFile()
308242
configb := configFile.Body()
309-
310-
// Copy and transform attributes
311243
addAttributesWithTransform(configb, dConfig.content.Body().Attributes(), configBlockName)
312-
313-
// Process blocks and transform their references
314244
for _, block := range dConfig.content.Body().Blocks() {
315245
newBlock := configb.AppendNewBlock(block.Type(), block.Labels())
316246
newBlockb := newBlock.Body()
317247
addAttributesWithTransform(newBlockb, block.Body().Attributes(), configBlockName)
318248
}
319-
320-
// Process specs
321249
processAllSpecs(configb, diskSizeGB)
322-
323-
// Build the nested for expression for region_configs
324-
// Use standardized property name (region_configs) instead of the actual for_each collection
325250
configForEach := fmt.Sprintf("%s.%s", nSpec, nConfig)
326-
327-
// Build the region_configs for expression
328251
regionForExpr := buildForExpr(nRegion, configForEach)
329252
regionTokens := hcl.TokensFromExpr(regionForExpr)
330253
regionTokens = append(regionTokens, hcl.TokensObject(configb)...)
331-
332254
repSpecb.SetAttributeRaw(nConfig, hcl.EncloseBracketsNewLines(regionTokens))
333-
334-
// Build the for expression as an array wrapped in flatten
335-
// Format: flatten([for spec in ... : [ { ... } ] ])
336255
forExpr := buildForExpr(nSpec, hcl.GetAttrExpr(dSpec.forEach))
337256
innerTokens := hcl.TokensFromExpr(fmt.Sprintf("%s ", forExpr))
338257
innerTokens = append(innerTokens, hcl.TokensArraySingle(repSpecb)...)
339-
340-
// Apply flatten to the entire expression
341258
tokens := hcl.TokensFuncFlatten(innerTokens)
342-
343259
resourceb.RemoveBlock(dSpec.block)
344260
resourceb.SetAttributeRaw(nRepSpecs, tokens)
345261
return nil
346262
}
347263

348264
func convertConfig(repSpecs *hclwrite.Body, diskSizeGB hclwrite.Tokens) error {
349-
// Check for dynamic region_configs block (can be either "region_configs" or "regions_config")
350265
dConfig, err := getDynamicBlock(repSpecs, nConfig)
351266
if err != nil {
352267
return err
@@ -357,12 +272,9 @@ func convertConfig(repSpecs *hclwrite.Body, diskSizeGB hclwrite.Tokens) error {
357272
return err
358273
}
359274
}
360-
361275
if dConfig.IsPresent() {
362-
// Handle dynamic region_configs
363276
return convertDynamicConfig(repSpecs, dConfig, diskSizeGB)
364277
}
365-
366278
var configs []*hclwrite.Body
367279
for _, block := range collectBlocks(repSpecs, nConfig) {
368280
blockb := block.Body()
@@ -377,21 +289,13 @@ func convertConfig(repSpecs *hclwrite.Body, diskSizeGB hclwrite.Tokens) error {
377289
}
378290

379291
func convertDynamicConfig(repSpecs *hclwrite.Body, dConfig dynamicBlock, diskSizeGB hclwrite.Tokens) error {
380-
// Get the block name from the dynamic block itself
381292
blockName := getResourceName(dConfig.block)
382-
383-
// Transform the references in attributes and blocks
384293
transformDynamicBlockReferencesRecursive(dConfig.content.Body(), blockName, nRegion)
385-
386-
// Process specs
387294
processAllSpecs(dConfig.content.Body(), diskSizeGB)
388-
389-
// Build the for expression
390295
forExpr := buildForExpr(nRegion, hcl.GetAttrExpr(dConfig.forEach))
391296
tokens := hcl.TokensFromExpr(forExpr)
392297
tokens = append(tokens, hcl.TokensObject(dConfig.content.Body())...)
393298
tokens = hcl.EncloseBracketsNewLines(tokens)
394-
395299
repSpecs.RemoveBlock(dConfig.block)
396300
repSpecs.SetAttributeRaw(nConfig, tokens)
397301
return nil
@@ -401,15 +305,7 @@ func convertDynamicConfig(repSpecs *hclwrite.Body, dConfig dynamicBlock, diskSiz
401305
// exist as attributes in the resource body. In that case conversion is not done
402306
// as advanced cluster is not in a valid SDKv2 configuration.
403307
func hasExpectedBlocksAsAttributes(resourceb *hclwrite.Body) bool {
404-
expectedBlocks := []string{
405-
nRepSpecs,
406-
nTags,
407-
nLabels,
408-
nAdvConfig,
409-
nBiConnector,
410-
nPinnedFCV,
411-
nTimeouts,
412-
}
308+
expectedBlocks := []string{nRepSpecs, nTags, nLabels, nAdvConfig, nBiConnector, nPinnedFCV, nTimeouts}
413309
for name := range resourceb.Attributes() {
414310
if slices.Contains(expectedBlocks, name) {
415311
return true

internal/convert/clu2adv.go

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -181,26 +181,16 @@ func fillReplicationSpecs(resourceb *hclwrite.Body, root attrVals) error {
181181
resourceb.SetAttributeRaw(nRepSpecs, d.tokens)
182182
return nil
183183
}
184-
185-
// Collect all replication_specs blocks first
186184
repSpecBlocks := collectBlocks(resourceb, nRepSpecs)
187-
188185
if len(repSpecBlocks) == 0 {
189186
return fmt.Errorf("%s: no replication_specs found", errRepSpecs)
190187
}
191-
192-
// Check if any replication_specs has a variable num_shards
193-
hasVariableNumShards := HasVariableNumShards(repSpecBlocks)
194-
195-
if hasVariableNumShards {
188+
if hasVariableNumShards(repSpecBlocks) {
196189
var concatParts []hclwrite.Tokens
197-
198190
for _, block := range repSpecBlocks {
199191
spec := hclwrite.NewEmptyFile()
200192
specb := spec.Body()
201193
specbSrc := block.Body()
202-
203-
// Check for dynamic region configs
204194
d, err := fillWithDynamicRegionConfigs(specbSrc, root, false)
205195
if err != nil {
206196
return err
@@ -209,21 +199,15 @@ func fillReplicationSpecs(resourceb *hclwrite.Body, root attrVals) error {
209199
concatParts = append(concatParts, d.tokens)
210200
continue
211201
}
212-
213-
// Handle zone_name
214202
_ = hcl.MoveAttr(specbSrc, specb, nZoneName, nZoneName, errRepSpecs)
215-
216-
// Handle num_shards
217203
shardsAttr := specbSrc.GetAttribute(nNumShards)
218204
if shardsAttr == nil {
219205
return fmt.Errorf("%s: %s not found", errRepSpecs, nNumShards)
220206
}
221-
222207
if errConfig := fillRegionConfigs(specb, specbSrc, root); errConfig != nil {
223208
return errConfig
224209
}
225-
226-
tokens, err := ProcessNumShards(shardsAttr, specb)
210+
tokens, err := processNumShards(shardsAttr, specb)
227211
if err != nil {
228212
return err
229213
}

0 commit comments

Comments
 (0)