helper/schema: detect invalid/unknown keys

This commit is contained in:
Mitchell Hashimoto 2014-08-15 22:15:10 -07:00
parent 4af387b986
commit 90f462e609
2 changed files with 42 additions and 16 deletions

View File

@ -2,6 +2,7 @@ package schema
import ( import (
"fmt" "fmt"
"strings"
"github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/terraform"
"github.com/mitchellh/mapstructure" "github.com/mitchellh/mapstructure"
@ -104,20 +105,7 @@ func (m schemaMap) Diff(
// Validate validates the configuration against this schema mapping. // Validate validates the configuration against this schema mapping.
func (m schemaMap) Validate(c *terraform.ResourceConfig) ([]string, []error) { func (m schemaMap) Validate(c *terraform.ResourceConfig) ([]string, []error) {
var ws []string return m.validateObject("", m, c)
var es []error
for k, schema := range m {
ws2, es2 := m.validate(k, schema, c)
if len(ws2) > 0 {
ws = append(ws, ws2...)
}
if len(es2) > 0 {
es = append(es, es2...)
}
}
return ws, es
} }
func (m schemaMap) diff( func (m schemaMap) diff(
@ -345,9 +333,12 @@ func (m schemaMap) validateObject(
var ws []string var ws []string
var es []error var es []error
for subK, s := range schema { for subK, s := range schema {
key := fmt.Sprintf("%s.%s", k, subK) key := subK
ws2, es2 := m.validate(key, s, c) if k != "" {
key = fmt.Sprintf("%s.%s", k, subK)
}
ws2, es2 := m.validate(key, s, c)
if len(ws2) > 0 { if len(ws2) > 0 {
ws = append(ws, ws2...) ws = append(ws, ws2...)
} }
@ -356,6 +347,23 @@ func (m schemaMap) validateObject(
} }
} }
// Detect any extra/unknown keys and report those as errors.
prefix := k + "."
for configK, _ := range c.Raw {
if k != "" {
if !strings.HasPrefix(configK, prefix) {
continue
}
configK = configK[len(prefix):]
}
if _, ok := schema[configK]; !ok {
es = append(es, fmt.Errorf(
"%s: invalid or unknown key: %s", k, configK))
}
}
return ws, es return ws, es
} }

View File

@ -604,6 +604,24 @@ func TestSchemaMap_Validate(t *testing.T) {
Err: false, Err: false,
}, },
// Invalid/unknown field
{
Schema: map[string]*Schema{
"availability_zone": &Schema{
Type: TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
},
Config: map[string]interface{}{
"foo": "bar",
},
Err: true,
},
} }
for i, tc := range cases { for i, tc := range cases {