helper/schema: limit ValidateFunc to primitives for now
I couldn't see a simple path get this working for Maps, Sets, and Lists, so lets land it as a primitive-only schema feature. I think validation on primitives comprises 80% of the use cases anyways.
This commit is contained in:
parent
49352db26f
commit
a4912cc51f
|
@ -136,6 +136,8 @@ type Schema struct {
|
||||||
// logic. It is yielded the provided config value as an interface{} that is
|
// logic. It is yielded the provided config value as an interface{} that is
|
||||||
// guaranteed to be of the proper Schema type, and it can yield warnings or
|
// guaranteed to be of the proper Schema type, and it can yield warnings or
|
||||||
// errors based on inspection of that value.
|
// errors based on inspection of that value.
|
||||||
|
//
|
||||||
|
// ValidateFunc currently only works for primitive types.
|
||||||
ValidateFunc SchemaValidateFunc
|
ValidateFunc SchemaValidateFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,6 +515,13 @@ func (m schemaMap) InternalValidate(topSchemaMap schemaMap) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v.ValidateFunc != nil {
|
||||||
|
switch v.Type {
|
||||||
|
case TypeList, TypeSet, TypeMap:
|
||||||
|
return fmt.Errorf("ValidateFunc is only supported on primitives.")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -1128,6 +1137,7 @@ func (m schemaMap) validatePrimitive(
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var decoded interface{}
|
||||||
switch schema.Type {
|
switch schema.Type {
|
||||||
case TypeBool:
|
case TypeBool:
|
||||||
// Verify that we can parse this as the correct type
|
// Verify that we can parse this as the correct type
|
||||||
|
@ -1135,28 +1145,36 @@ func (m schemaMap) validatePrimitive(
|
||||||
if err := mapstructure.WeakDecode(raw, &n); err != nil {
|
if err := mapstructure.WeakDecode(raw, &n); err != nil {
|
||||||
return nil, []error{err}
|
return nil, []error{err}
|
||||||
}
|
}
|
||||||
|
decoded = n
|
||||||
case TypeInt:
|
case TypeInt:
|
||||||
// Verify that we can parse this as an int
|
// Verify that we can parse this as an int
|
||||||
var n int
|
var n int
|
||||||
if err := mapstructure.WeakDecode(raw, &n); err != nil {
|
if err := mapstructure.WeakDecode(raw, &n); err != nil {
|
||||||
return nil, []error{err}
|
return nil, []error{err}
|
||||||
}
|
}
|
||||||
|
decoded = n
|
||||||
case TypeFloat:
|
case TypeFloat:
|
||||||
// Verify that we can parse this as an int
|
// Verify that we can parse this as an int
|
||||||
var n float64
|
var n float64
|
||||||
if err := mapstructure.WeakDecode(raw, &n); err != nil {
|
if err := mapstructure.WeakDecode(raw, &n); err != nil {
|
||||||
return nil, []error{err}
|
return nil, []error{err}
|
||||||
}
|
}
|
||||||
|
decoded = n
|
||||||
case TypeString:
|
case TypeString:
|
||||||
// Verify that we can parse this as a string
|
// Verify that we can parse this as a string
|
||||||
var n string
|
var n string
|
||||||
if err := mapstructure.WeakDecode(raw, &n); err != nil {
|
if err := mapstructure.WeakDecode(raw, &n); err != nil {
|
||||||
return nil, []error{err}
|
return nil, []error{err}
|
||||||
}
|
}
|
||||||
|
decoded = n
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("Unknown validation type: %#v", schema.Type))
|
panic(fmt.Sprintf("Unknown validation type: %#v", schema.Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if schema.ValidateFunc != nil {
|
||||||
|
return schema.ValidateFunc(decoded)
|
||||||
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1186,16 +1204,6 @@ func (m schemaMap) validateType(
|
||||||
"%q: [REMOVED] %s", k, schema.Removed))
|
"%q: [REMOVED] %s", k, schema.Removed))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(es) == 0 && schema.ValidateFunc != nil {
|
|
||||||
ws2, es2 := schema.ValidateFunc(raw)
|
|
||||||
for _, w := range ws2 {
|
|
||||||
ws = append(ws, fmt.Sprintf("%q: %s", k, w))
|
|
||||||
}
|
|
||||||
for _, e := range es2 {
|
|
||||||
es = append(es, fmt.Errorf("%q: %s", k, e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ws, es
|
return ws, es
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2796,6 +2796,20 @@ func TestSchemaMap_InternalValidate(t *testing.T) {
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ValidateFunc on non-primitive
|
||||||
|
{
|
||||||
|
map[string]*Schema{
|
||||||
|
"foo": &Schema{
|
||||||
|
Type: TypeMap,
|
||||||
|
Required: true,
|
||||||
|
ValidateFunc: func(v interface{}) (ws []string, es []error) {
|
||||||
|
return
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tc := range cases {
|
for i, tc := range cases {
|
||||||
|
@ -3435,7 +3449,7 @@ func TestSchemaMap_Validate(t *testing.T) {
|
||||||
},
|
},
|
||||||
Err: true,
|
Err: true,
|
||||||
Errors: []error{
|
Errors: []error{
|
||||||
fmt.Errorf(`"validate_me": something is not right here`),
|
fmt.Errorf(`something is not right here`),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -3455,6 +3469,23 @@ func TestSchemaMap_Validate(t *testing.T) {
|
||||||
},
|
},
|
||||||
Err: true,
|
Err: true,
|
||||||
},
|
},
|
||||||
|
"ValidateFunc gets decoded type": {
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"maybe": &Schema{
|
||||||
|
Type: TypeBool,
|
||||||
|
Required: true,
|
||||||
|
ValidateFunc: func(v interface{}) (ws []string, es []error) {
|
||||||
|
if _, ok := v.(bool); !ok {
|
||||||
|
t.Fatalf("Expected bool, got: %#v", v)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"maybe": "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for tn, tc := range cases {
|
for tn, tc := range cases {
|
||||||
|
|
Loading…
Reference in New Issue