From a4f38a3933f0cfe99682240fdd85085d86fe3c1e Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 4 Jul 2014 10:53:36 -0700 Subject: [PATCH] config: validate resource variables in output --- config/config.go | 65 +++++++++++-------- config/config_test.go | 7 ++ .../main.tf | 6 ++ 3 files changed, 52 insertions(+), 26 deletions(-) create mode 100644 config/test-fixtures/validate-unknown-resource-var-output/main.tf diff --git a/config/config.go b/config/config.go index 737ec0916..dba3c0012 100644 --- a/config/config.go +++ b/config/config.go @@ -106,17 +106,19 @@ func (c *Config) Validate() error { // Check for references to user variables that do not actually // exist and record those errors. - for source, v := range vars { - uv, ok := v.(*UserVariable) - if !ok { - continue - } + for source, vs := range vars { + for _, v := range vs { + uv, ok := v.(*UserVariable) + if !ok { + continue + } - if _, ok := c.Variables[uv.Name]; !ok { - errs = append(errs, fmt.Errorf( - "%s: unknown variable referenced: %s", - source, - uv.Name)) + if _, ok := c.Variables[uv.Name]; !ok { + errs = append(errs, fmt.Errorf( + "%s: unknown variable referenced: %s", + source, + uv.Name)) + } } } @@ -125,22 +127,26 @@ func (c *Config) Validate() error { for _, r := range c.Resources { resources[r.Id()] = struct{}{} } - for source, v := range vars { - rv, ok := v.(*ResourceVariable) - if !ok { - continue - } + for source, vs := range vars { + for _, v := range vs { + rv, ok := v.(*ResourceVariable) + if !ok { + continue + } - id := fmt.Sprintf("%s.%s", rv.Type, rv.Name) - if _, ok := resources[id]; !ok { - errs = append(errs, fmt.Errorf( - "%s: unknown resource '%s' referenced in variable %s", - source, - id, - rv.FullKey())) + id := fmt.Sprintf("%s.%s", rv.Type, rv.Name) + if _, ok := resources[id]; !ok { + errs = append(errs, fmt.Errorf( + "%s: unknown resource '%s' referenced in variable %s", + source, + id, + rv.FullKey())) + } } } + // Check that all outputs are valid + if len(errs) > 0 { return &multierror.Error{Errors: errs} } @@ -151,19 +157,26 @@ func (c *Config) Validate() error { // allVariables is a helper that returns a mapping of all the interpolated // variables within the configuration. This is used to verify references // are valid in the Validate step. -func (c *Config) allVariables() map[string]InterpolatedVariable { - result := make(map[string]InterpolatedVariable) +func (c *Config) allVariables() map[string][]InterpolatedVariable { + result := make(map[string][]InterpolatedVariable) for n, pc := range c.ProviderConfigs { source := fmt.Sprintf("provider config '%s'", n) for _, v := range pc.RawConfig.Variables { - result[source] = v + result[source] = append(result[source], v) } } for _, rc := range c.Resources { source := fmt.Sprintf("resource '%s'", rc.Id()) for _, v := range rc.RawConfig.Variables { - result[source] = v + result[source] = append(result[source], v) + } + } + + for _, o := range c.Outputs { + source := fmt.Sprintf("output '%s'", o.Name) + for _, v := range o.RawConfig.Variables { + result[source] = append(result[source], v) } } diff --git a/config/config_test.go b/config/config_test.go index 4974b7276..f784d0df5 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -22,6 +22,13 @@ func TestConfigValidate_unknownResourceVar(t *testing.T) { } } +func TestConfigValidate_unknownResourceVar_output(t *testing.T) { + c := testConfig(t, "validate-unknown-resource-var-output") + if err := c.Validate(); err == nil { + t.Fatal("should not be valid") + } +} + func TestConfigValidate_unknownVar(t *testing.T) { c := testConfig(t, "validate-unknownvar") if err := c.Validate(); err == nil { diff --git a/config/test-fixtures/validate-unknown-resource-var-output/main.tf b/config/test-fixtures/validate-unknown-resource-var-output/main.tf new file mode 100644 index 000000000..d79c65712 --- /dev/null +++ b/config/test-fixtures/validate-unknown-resource-var-output/main.tf @@ -0,0 +1,6 @@ +resource "aws_instance" "web" { +} + +output "ip" { + value = "${aws_instance.loadbalancer.foo}" +}