From a2e40ad731d790408f73e0287729a92c8689c32e Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 15 Jan 2015 09:39:52 -0800 Subject: [PATCH] config: multi-variable access in slice validation fixed [GH-798] --- config/config.go | 21 +++++++++++++++++++ config/config_test.go | 7 +++++++ .../validate-var-multi-func/main.tf | 7 +++++++ 3 files changed, 35 insertions(+) create mode 100644 config/test-fixtures/validate-var-multi-func/main.tf diff --git a/config/config.go b/config/config.go index c67b58a459a1..7c22ee6bf52c 100644 --- a/config/config.go +++ b/config/config.go @@ -478,10 +478,31 @@ func (c *Config) rawConfigs() map[string]*RawConfig { func (c *Config) validateVarContextFn( source string, errs *[]error) interpolationWalkerContextFunc { return func(loc reflectwalk.Location, node ast.Node) { + // If we're in a slice element, then its fine, since you can do + // anything in there. if loc == reflectwalk.SliceElem { return } + // Otherwise, let's check if there is a splat resource variable + // at the top level in here. We do this by doing a transform that + // replaces everything with a noop node unless its a variable + // access or concat. This should turn the AST into a flat tree + // of Concat(Noop, ...). If there are any variables left that are + // multi-access, then its still broken. + node = node.Accept(func(n ast.Node) ast.Node { + // If it is a concat or variable access, we allow it. + switch n.(type) { + case *ast.Concat: + return n + case *ast.VariableAccess: + return n + } + + // Otherwise, noop + return &noopNode{} + }) + vars, err := DetectVariables(node) if err != nil { // Ignore it since this will be caught during parse. This diff --git a/config/config_test.go b/config/config_test.go index 41ca569e374e..22cb75d0e784 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -249,6 +249,13 @@ func TestConfigValidate_varMultiNonSlice(t *testing.T) { } } +func TestConfigValidate_varMultiFunctionCall(t *testing.T) { + c := testConfig(t, "validate-var-multi-func") + if err := c.Validate(); err != nil { + t.Fatalf("should be valid: %s", err) + } +} + func TestConfigValidate_varModule(t *testing.T) { c := testConfig(t, "validate-var-module") if err := c.Validate(); err != nil { diff --git a/config/test-fixtures/validate-var-multi-func/main.tf b/config/test-fixtures/validate-var-multi-func/main.tf new file mode 100644 index 000000000000..8b820e965ec4 --- /dev/null +++ b/config/test-fixtures/validate-var-multi-func/main.tf @@ -0,0 +1,7 @@ +resource "aws_instance" "foo" { + count = 3 +} + +resource "aws_instance" "bar" { + foo = "${element(aws_instance.foo.*.id, 0)}" +}