mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
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
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user