From 61fee6735dffcda9e9e27c1ff5cd2d1f4a9f3981 Mon Sep 17 00:00:00 2001 From: Paul Hinze Date: Sun, 7 Jun 2015 20:49:15 -0500 Subject: [PATCH] helper/schema: ValidateFunc Allows provider authors to implement arbitrary per-field validation warnings or errors. --- helper/schema/schema.go | 17 ++++++++++++++++ helper/schema/schema_test.go | 38 +++++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/helper/schema/schema.go b/helper/schema/schema.go index 729fb0980..8766e10b0 100644 --- a/helper/schema/schema.go +++ b/helper/schema/schema.go @@ -131,6 +131,9 @@ type Schema struct { // This string is the message shown to the user with instructions on // what do to about the removed attribute. Removed string + + // ValidateFunc allows individual fields to validate + ValidateFunc SchemaValidateFunc } // SchemaDefaultFunc is a function called to return a default value for @@ -173,6 +176,10 @@ type SchemaSetFunc func(interface{}) int // to be stored in the state. type SchemaStateFunc func(interface{}) string +// SchemaValidateFunc is a function used to validate a single field in the +// schema. +type SchemaValidateFunc func(interface{}) ([]string, []error) + func (s *Schema) GoString() string { return fmt.Sprintf("*%#v", *s) } @@ -1176,6 +1183,16 @@ func (m schemaMap) validateType( "%q: [REMOVED] %s", k, schema.Removed)) } + if 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 } diff --git a/helper/schema/schema_test.go b/helper/schema/schema_test.go index 9a77cda2f..e23f51279 100644 --- a/helper/schema/schema_test.go +++ b/helper/schema/schema_test.go @@ -3399,7 +3399,43 @@ func TestSchemaMap_Validate(t *testing.T) { Err: true, Errors: []error{ - fmt.Errorf("\"optional_att\": conflicts with required_att (\"required-val\")"), + fmt.Errorf(`"optional_att": conflicts with required_att ("required-val")`), + }, + }, + + "Good with ValidateFunc": { + Schema: map[string]*Schema{ + "validate_me": &Schema{ + Type: TypeString, + Required: true, + ValidateFunc: func(v interface{}) (ws []string, es []error) { + return + }, + }, + }, + Config: map[string]interface{}{ + "validate_me": "valid", + }, + Err: false, + }, + + "Bad with ValidateFunc": { + Schema: map[string]*Schema{ + "validate_me": &Schema{ + Type: TypeString, + Required: true, + ValidateFunc: func(v interface{}) (ws []string, es []error) { + es = append(es, fmt.Errorf("something is not right here")) + return + }, + }, + }, + Config: map[string]interface{}{ + "validate_me": "invalid", + }, + Err: true, + Errors: []error{ + fmt.Errorf(`"validate_me": something is not right here`), }, }, }