helper/schema: validate maps properly [GH-461]

This commit is contained in:
Mitchell Hashimoto 2014-10-19 20:33:00 -07:00
parent 3e1169db61
commit deec7194a3
2 changed files with 105 additions and 0 deletions

View File

@ -767,6 +767,44 @@ func (m schemaMap) validateList(
return ws, es
}
func (m schemaMap) validateMap(
k string,
raw interface{},
schema *Schema,
c *terraform.ResourceConfig) ([]string, []error) {
// We use reflection to verify the slice because you can't
// case to []interface{} unless the slice is exactly that type.
rawV := reflect.ValueOf(raw)
switch rawV.Kind() {
case reflect.Map:
case reflect.Slice:
default:
return nil, []error{fmt.Errorf(
"%s: should be a map", k)}
}
// If it is not a slice, it is valid
if rawV.Kind() != reflect.Slice {
return nil, nil
}
// It is a slice, verify that all the elements are maps
raws := make([]interface{}, rawV.Len())
for i, _ := range raws {
raws[i] = rawV.Index(i).Interface()
}
for _, raw := range raws {
v := reflect.ValueOf(raw)
if v.Kind() != reflect.Map {
return nil, []error{fmt.Errorf(
"%s: should be a map", k)}
}
}
return nil, nil
}
func (m schemaMap) validateObject(
k string,
schema map[string]*Schema,
@ -823,6 +861,8 @@ func (m schemaMap) validatePrimitive(
fallthrough
case TypeList:
return m.validateList(k, raw, schema, c)
case TypeMap:
return m.validateMap(k, raw, schema, c)
case TypeBool:
// Verify that we can parse this as the correct type
var n bool

View File

@ -2009,6 +2009,71 @@ func TestSchemaMap_Validate(t *testing.T) {
Err: true,
},
// Maps
{
Schema: map[string]*Schema{
"user_data": &Schema{
Type: TypeMap,
Optional: true,
},
},
Config: map[string]interface{}{
"user_data": "foo",
},
Err: true,
},
{
Schema: map[string]*Schema{
"user_data": &Schema{
Type: TypeMap,
Optional: true,
},
},
Config: map[string]interface{}{
"user_data": []interface{}{
map[string]interface{}{
"foo": "bar",
},
},
},
},
{
Schema: map[string]*Schema{
"user_data": &Schema{
Type: TypeMap,
Optional: true,
},
},
Config: map[string]interface{}{
"user_data": map[string]interface{}{
"foo": "bar",
},
},
},
{
Schema: map[string]*Schema{
"user_data": &Schema{
Type: TypeMap,
Optional: true,
},
},
Config: map[string]interface{}{
"user_data": []interface{}{
"foo",
},
},
Err: true,
},
}
for i, tc := range cases {