config: validate resource variables in output

This commit is contained in:
Mitchell Hashimoto 2014-07-04 10:53:36 -07:00
parent cc2bb950a1
commit a4f38a3933
3 changed files with 52 additions and 26 deletions

View File

@ -106,17 +106,19 @@ func (c *Config) Validate() error {
// Check for references to user variables that do not actually // Check for references to user variables that do not actually
// exist and record those errors. // exist and record those errors.
for source, v := range vars { for source, vs := range vars {
uv, ok := v.(*UserVariable) for _, v := range vs {
if !ok { uv, ok := v.(*UserVariable)
continue if !ok {
} continue
}
if _, ok := c.Variables[uv.Name]; !ok { if _, ok := c.Variables[uv.Name]; !ok {
errs = append(errs, fmt.Errorf( errs = append(errs, fmt.Errorf(
"%s: unknown variable referenced: %s", "%s: unknown variable referenced: %s",
source, source,
uv.Name)) uv.Name))
}
} }
} }
@ -125,22 +127,26 @@ func (c *Config) Validate() error {
for _, r := range c.Resources { for _, r := range c.Resources {
resources[r.Id()] = struct{}{} resources[r.Id()] = struct{}{}
} }
for source, v := range vars { for source, vs := range vars {
rv, ok := v.(*ResourceVariable) for _, v := range vs {
if !ok { rv, ok := v.(*ResourceVariable)
continue if !ok {
} continue
}
id := fmt.Sprintf("%s.%s", rv.Type, rv.Name) id := fmt.Sprintf("%s.%s", rv.Type, rv.Name)
if _, ok := resources[id]; !ok { if _, ok := resources[id]; !ok {
errs = append(errs, fmt.Errorf( errs = append(errs, fmt.Errorf(
"%s: unknown resource '%s' referenced in variable %s", "%s: unknown resource '%s' referenced in variable %s",
source, source,
id, id,
rv.FullKey())) rv.FullKey()))
}
} }
} }
// Check that all outputs are valid
if len(errs) > 0 { if len(errs) > 0 {
return &multierror.Error{Errors: errs} 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 // allVariables is a helper that returns a mapping of all the interpolated
// variables within the configuration. This is used to verify references // variables within the configuration. This is used to verify references
// are valid in the Validate step. // are valid in the Validate step.
func (c *Config) allVariables() map[string]InterpolatedVariable { func (c *Config) allVariables() map[string][]InterpolatedVariable {
result := make(map[string]InterpolatedVariable) result := make(map[string][]InterpolatedVariable)
for n, pc := range c.ProviderConfigs { for n, pc := range c.ProviderConfigs {
source := fmt.Sprintf("provider config '%s'", n) source := fmt.Sprintf("provider config '%s'", n)
for _, v := range pc.RawConfig.Variables { for _, v := range pc.RawConfig.Variables {
result[source] = v result[source] = append(result[source], v)
} }
} }
for _, rc := range c.Resources { for _, rc := range c.Resources {
source := fmt.Sprintf("resource '%s'", rc.Id()) source := fmt.Sprintf("resource '%s'", rc.Id())
for _, v := range rc.RawConfig.Variables { 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)
} }
} }

View File

@ -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) { func TestConfigValidate_unknownVar(t *testing.T) {
c := testConfig(t, "validate-unknownvar") c := testConfig(t, "validate-unknownvar")
if err := c.Validate(); err == nil { if err := c.Validate(); err == nil {

View File

@ -0,0 +1,6 @@
resource "aws_instance" "web" {
}
output "ip" {
value = "${aws_instance.loadbalancer.foo}"
}