-
Notifications
You must be signed in to change notification settings - Fork 1
feat: Supports dynamic blocks in tags and labels #31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 18 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
620f40b
tags
lantoli 22379fc
Merge branch 'main' into CLOUDP-303941_dynamic
lantoli 664eed7
pass tests
lantoli 03fbcbd
allow expressions
lantoli dec580c
expression_individual
lantoli 2437da2
change format style
lantoli 2dfed12
pass tests
lantoli 3a28a96
full example
lantoli d013a5f
refactor
lantoli 63af914
small refactors
lantoli dbd46b6
rename var
lantoli 1b6cfba
readme
lantoli 89a81f1
typo
lantoli ec67f71
doc for update plugin
lantoli ea74e84
typo
lantoli 53fddb2
doc examples link
lantoli c2d5d12
change v2 to 2.0.0
lantoli 5e18776
changelog
lantoli 24b5389
refactor key / value attributes in dynamic blocks
lantoli File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,9 @@ | ||
## (Unreleased) | ||
|
||
ENHANCEMENTS: | ||
|
||
* Supports `dynamic` block for `tags` and `labels` | ||
|
||
## 1.0.0 (Mar 6, 2025) | ||
|
||
NOTES: | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
package convert | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"slices" | ||
"sort" | ||
"strconv" | ||
"strings" | ||
|
@@ -36,13 +36,17 @@ const ( | |
commentRemovedOld = "Note: Remember to remove or comment out the old cluster definitions." | ||
) | ||
|
||
var ( | ||
dynamicBlockAllowList = []string{nTags, nLabels} | ||
) | ||
|
||
type attrVals struct { | ||
req map[string]hclwrite.Tokens | ||
opt map[string]hclwrite.Tokens | ||
} | ||
|
||
// ClusterToAdvancedCluster transforms all mongodbatlas_cluster definitions in a | ||
// Terraform configuration file into mongodbatlas_advanced_cluster schema v2 definitions. | ||
// Terraform configuration file into mongodbatlas_advanced_cluster schema 2.0.0. | ||
// All other resources and data sources are left untouched. | ||
// Note: hclwrite.Tokens are used instead of cty.Value so expressions with interpolations like var.region can be preserved. | ||
// cty.Value only supports literal expressions. | ||
|
@@ -224,6 +228,53 @@ func fillReplicationSpecs(resourceb *hclwrite.Body, root attrVals) error { | |
} | ||
|
||
func fillTagsLabelsOpt(resourceb *hclwrite.Body, name string) error { | ||
tokensDynamic, err := extractTagsLabelsDynamicBlock(resourceb, name) | ||
if err != nil { | ||
return err | ||
} | ||
tokensIndividual, err := extractTagsLabelsIndividual(resourceb, name) | ||
if err != nil { | ||
return err | ||
} | ||
if tokensDynamic != nil && tokensIndividual != nil { | ||
resourceb.SetAttributeRaw(name, hcl.TokensFuncMerge(tokensDynamic, tokensIndividual)) | ||
return nil | ||
} | ||
if tokensDynamic != nil { | ||
resourceb.SetAttributeRaw(name, tokensDynamic) | ||
} | ||
if tokensIndividual != nil { | ||
resourceb.SetAttributeRaw(name, tokensIndividual) | ||
} | ||
return nil | ||
} | ||
|
||
func extractTagsLabelsDynamicBlock(resourceb *hclwrite.Body, name string) (hclwrite.Tokens, error) { | ||
d, err := getDynamicBlock(resourceb, name) | ||
if err != nil || d.forEach == nil { | ||
return nil, err | ||
} | ||
key := d.content.Body().GetAttribute(nKey) | ||
value := d.content.Body().GetAttribute(nValue) | ||
if key == nil || value == nil { | ||
return nil, fmt.Errorf("dynamic block %s: %s or %s not found", name, nKey, nValue) | ||
} | ||
collectionExpr := strings.TrimSpace(string(d.forEach.Expr().BuildTokens(nil).Bytes())) | ||
keyExpr := strings.TrimSpace(strings.ReplaceAll(string(key.Expr().BuildTokens(nil).Bytes()), | ||
fmt.Sprintf("%s.%s", name, nKey), nKey)) // e.g. occurrences of tags.key are changed to key to be valid in the for expression | ||
valueExpr := strings.TrimSpace(strings.ReplaceAll(string(value.Expr().BuildTokens(nil).Bytes()), | ||
fmt.Sprintf("%s.%s", name, nValue), nValue)) | ||
forExpr := strings.TrimSpace(fmt.Sprintf("for key, value in %s : %s => %s", | ||
collectionExpr, keyExpr, valueExpr)) | ||
tokens := hcl.TokensObjectFromExpr(forExpr) | ||
if keyExpr == nKey && valueExpr == nValue { // expression can be simplified and use for_each expression | ||
tokens = hcl.TokensFromExpr(collectionExpr) | ||
} | ||
resourceb.RemoveBlock(d.block) | ||
return tokens, nil | ||
} | ||
|
||
func extractTagsLabelsIndividual(resourceb *hclwrite.Body, name string) (hclwrite.Tokens, error) { | ||
var ( | ||
file = hclwrite.NewEmptyFile() | ||
fileb = file.Body() | ||
|
@@ -237,16 +288,16 @@ func fillTagsLabelsOpt(resourceb *hclwrite.Body, name string) error { | |
key := block.Body().GetAttribute(nKey) | ||
value := block.Body().GetAttribute(nValue) | ||
if key == nil || value == nil { | ||
return fmt.Errorf("%s: %s or %s not found", name, nKey, nValue) | ||
return nil, fmt.Errorf("%s: %s or %s not found", name, nKey, nValue) | ||
} | ||
setKeyValue(fileb, key, value) | ||
resourceb.RemoveBlock(block) | ||
found = true | ||
} | ||
if found { | ||
resourceb.SetAttributeRaw(name, hcl.TokensObject(fileb)) | ||
if !found { | ||
return nil, nil | ||
} | ||
return nil | ||
return hcl.TokensObject(fileb), nil | ||
} | ||
|
||
func fillBlockOpt(resourceb *hclwrite.Body, name string) { | ||
|
@@ -394,13 +445,40 @@ func getResourceLabel(resource *hclwrite.Block) string { | |
|
||
func checkDynamicBlock(body *hclwrite.Body) error { | ||
for _, block := range body.Blocks() { | ||
if block.Type() == "dynamic" { | ||
return errors.New("dynamic blocks are not supported") | ||
name := getResourceName(block) | ||
if block.Type() != nDynamic || slices.Contains(dynamicBlockAllowList, name) { | ||
continue | ||
} | ||
return fmt.Errorf("dynamic blocks are not supported for %s", name) | ||
} | ||
return nil | ||
} | ||
|
||
type dynamicBlock struct { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice abstraction! |
||
block *hclwrite.Block | ||
forEach *hclwrite.Attribute | ||
content *hclwrite.Block | ||
} | ||
|
||
func getDynamicBlock(body *hclwrite.Body, name string) (dynamicBlock, error) { | ||
for _, block := range body.Blocks() { | ||
if block.Type() != nDynamic || name != getResourceName(block) { | ||
continue | ||
} | ||
blockb := block.Body() | ||
forEach := blockb.GetAttribute(nForEach) | ||
if forEach == nil { | ||
return dynamicBlock{}, fmt.Errorf("dynamic block %s: attribute %s not found", name, nForEach) | ||
} | ||
content := blockb.FirstMatchingBlock(nContent, nil) | ||
if content == nil { | ||
return dynamicBlock{}, fmt.Errorf("dynamic block %s: block %s not found", name, nContent) | ||
} | ||
return dynamicBlock{forEach: forEach, block: block, content: content}, nil | ||
} | ||
return dynamicBlock{}, nil | ||
} | ||
|
||
func setKeyValue(body *hclwrite.Body, key, value *hclwrite.Attribute) { | ||
keyStr, err := hcl.GetAttrString(key, "") | ||
if err == nil { | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A lot happening on this line. Maybe create an intermediate variable?
Or
Extract this into a function. for example,
removeDynamicVarPrefx()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks, changed here: 24b5389