diff --git a/helper/config/validator.go b/helper/config/validator.go new file mode 100644 index 000000000..095a0bbcb --- /dev/null +++ b/helper/config/validator.go @@ -0,0 +1,48 @@ +package config + +import ( + "fmt" + + "github.com/hashicorp/terraform/terraform" +) + +// Validator is a helper that helps you validate the configuration +// of your resource, resource provider, etc. +type Validator struct { + Required []string + Optional []string +} + +func (v *Validator) Validate( + c *terraform.ResourceConfig) (ws []string, es []error) { + keySet := make(map[string]bool) + reqSet := make(map[string]struct{}) + for _, k := range v.Required { + keySet[k] = true + reqSet[k] = struct{}{} + } + for _, k := range v.Optional { + keySet[k] = false + } + + // Find any unknown keys used and mark off required keys that + // we have set. + for k, _ := range c.Raw { + _, ok := keySet[k] + if !ok { + es = append(es, fmt.Errorf( + "Unknown configuration key: %s", k)) + continue + } + + delete(reqSet, k) + } + + // Check what keys are required that we didn't set + for k, _ := range reqSet { + es = append(es, fmt.Errorf( + "Required key is not set: %s", k)) + } + + return +} diff --git a/helper/config/validator_test.go b/helper/config/validator_test.go new file mode 100644 index 000000000..8a42e8d2e --- /dev/null +++ b/helper/config/validator_test.go @@ -0,0 +1,67 @@ +package config + +import ( + "testing" + + "github.com/hashicorp/terraform/config" + "github.com/hashicorp/terraform/terraform" +) + +func TestValidator(t *testing.T) { + v := &Validator{ + Required: []string{"foo"}, + Optional: []string{"bar"}, + } + + var c *terraform.ResourceConfig + + // Valid + c = testConfig(t, map[string]interface{}{ + "foo": "bar", + }) + testValid(t, v, c) + + // Missing required + c = testConfig(t, map[string]interface{}{ + "bar": "baz", + }) + testInvalid(t, v, c) + + // Unknown key + c = testConfig(t, map[string]interface{}{ + "foo": "bar", + "what": "what", + }) + testInvalid(t, v, c) +} + +func testConfig( + t *testing.T, + c map[string]interface{}) *terraform.ResourceConfig { + r, err := config.NewRawConfig(c) + if err != nil { + t.Fatalf("bad: %s", err) + } + + return terraform.NewResourceConfig(r) +} + +func testInvalid(t *testing.T, v *Validator, c *terraform.ResourceConfig) { + ws, es := v.Validate(c) + if len(ws) > 0 { + t.Fatalf("bad: %#v", ws) + } + if len(es) == 0 { + t.Fatalf("bad: %#v", es) + } +} + +func testValid(t *testing.T, v *Validator, c *terraform.ResourceConfig) { + ws, es := v.Validate(c) + if len(ws) > 0 { + t.Fatalf("bad: %#v", ws) + } + if len(es) > 0 { + t.Fatalf("bad: %#v", es) + } +}