helper/schema: validate maps properly [GH-461]
This commit is contained in:
parent
3e1169db61
commit
deec7194a3
|
@ -767,6 +767,44 @@ func (m schemaMap) validateList(
|
||||||
return ws, es
|
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(
|
func (m schemaMap) validateObject(
|
||||||
k string,
|
k string,
|
||||||
schema map[string]*Schema,
|
schema map[string]*Schema,
|
||||||
|
@ -823,6 +861,8 @@ func (m schemaMap) validatePrimitive(
|
||||||
fallthrough
|
fallthrough
|
||||||
case TypeList:
|
case TypeList:
|
||||||
return m.validateList(k, raw, schema, c)
|
return m.validateList(k, raw, schema, c)
|
||||||
|
case TypeMap:
|
||||||
|
return m.validateMap(k, raw, schema, c)
|
||||||
case TypeBool:
|
case TypeBool:
|
||||||
// Verify that we can parse this as the correct type
|
// Verify that we can parse this as the correct type
|
||||||
var n bool
|
var n bool
|
||||||
|
|
|
@ -2009,6 +2009,71 @@ func TestSchemaMap_Validate(t *testing.T) {
|
||||||
|
|
||||||
Err: true,
|
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 {
|
for i, tc := range cases {
|
||||||
|
|
Loading…
Reference in New Issue