Skip to content

Commit 434a163

Browse files
hcl2template: fix func to get vars from a config
The previous implementation of the GetVarsByType function worked only on top-level attributes, ignoring the nested blocks in the structure. This implies that if a datasource depends on another through an expression within a nested block, we may not execute it first, and then executing this datasource before its dependent is possible, resulting in an error in the end. This commit is an attempt at making this more reliable for HCL configs, but only works on configs lifted from HCL files for now. We need to make this more reliable for later iterations.
1 parent 51ec786 commit 434a163

File tree

1 file changed

+39
-13
lines changed

1 file changed

+39
-13
lines changed

hcl2template/utils.go

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/gobwas/glob"
1313
"github.com/hashicorp/hcl/v2"
14+
"github.com/hashicorp/hcl/v2/hclsyntax"
1415
"github.com/hashicorp/packer/hcl2template/repl"
1516
hcl2shim "github.com/hashicorp/packer/hcl2template/shim"
1617
"github.com/zclconf/go-cty/cty"
@@ -187,22 +188,47 @@ func ConvertPluginConfigValueToHCLValue(v interface{}) (cty.Value, error) {
187188
return buildValue, nil
188189
}
189190

191+
// GetVarsByType walks through a hcl body, and gathers all the Traversals that
192+
// have a root type matching one of the specified top-level labels.
193+
//
194+
// This will only work on finite, expanded, HCL bodies.
190195
func GetVarsByType(block *hcl.Block, topLevelLabels ...string) []hcl.Traversal {
191-
attributes, _ := block.Body.JustAttributes()
192-
193-
var vars []hcl.Traversal
194-
195-
for _, attr := range attributes {
196-
for _, variable := range attr.Expr.Variables() {
197-
rootLabel := variable.RootName()
198-
for _, label := range topLevelLabels {
199-
if label == rootLabel {
200-
vars = append(vars, variable)
201-
break
202-
}
196+
var travs []hcl.Traversal
197+
198+
switch body := block.Body.(type) {
199+
case *hclsyntax.Body:
200+
travs = getVarsByTypeForHCLSyntaxBody(body)
201+
default:
202+
attrs, _ := body.JustAttributes()
203+
for _, attr := range attrs {
204+
travs = append(travs, attr.Expr.Variables()...)
205+
}
206+
}
207+
208+
var rets []hcl.Traversal
209+
for _, t := range travs {
210+
varRootname := t.RootName()
211+
for _, lbl := range topLevelLabels {
212+
if varRootname == lbl {
213+
rets = append(rets, t)
214+
break
203215
}
204216
}
205217
}
206218

207-
return vars
219+
return rets
220+
}
221+
222+
func getVarsByTypeForHCLSyntaxBody(body *hclsyntax.Body) []hcl.Traversal {
223+
var rets []hcl.Traversal
224+
225+
for _, attr := range body.Attributes {
226+
rets = append(rets, attr.Expr.Variables()...)
227+
}
228+
229+
for _, block := range body.Blocks {
230+
rets = append(rets, getVarsByTypeForHCLSyntaxBody(block.Body)...)
231+
}
232+
233+
return rets
208234
}

0 commit comments

Comments
 (0)