From 59196374566745d575651008a4ee5bf25827fa28 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 9 Sep 2014 21:17:29 -0700 Subject: [PATCH] helper/schema: Defaults [GH-245] --- helper/schema/schema.go | 15 +++++++++++ helper/schema/schema_test.go | 51 ++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/helper/schema/schema.go b/helper/schema/schema.go index 60848b969d..0e3d4cb9f3 100644 --- a/helper/schema/schema.go +++ b/helper/schema/schema.go @@ -62,6 +62,10 @@ type Schema struct { Optional bool Required bool + // If this is non-nil, then this will be a default value that is used + // when this item is not set in the configuration/state. + Default interface{} + // The fields below relate to diffs. // // If Computed is true, then the result of this value is computed @@ -280,6 +284,10 @@ func (m schemaMap) InternalValidate() error { return fmt.Errorf("%s: One of optional, required, or computed must be set", k) } + if v.Computed && v.Default != nil { + return fmt.Errorf("%s: Default must be nil if computed", k) + } + if len(v.ComputedWhen) > 0 && !v.Computed { return fmt.Errorf("%s: ComputedWhen can only be set with Computed", k) } @@ -289,6 +297,10 @@ func (m schemaMap) InternalValidate() error { return fmt.Errorf("%s: Elem must be set for lists", k) } + if v.Default != nil { + return fmt.Errorf("%s: Default is not valid for lists or sets", k) + } + if v.Type == TypeList && v.Set != nil { return fmt.Errorf("%s: Set can only be set for TypeSet", k) } else if v.Type == TypeSet && v.Set == nil { @@ -492,6 +504,9 @@ func (m schemaMap) diffString( var originalN interface{} var os, ns string o, n, _ := d.diffChange(k) + if n == nil { + n = schema.Default + } if schema.StateFunc != nil { originalN = n n = schema.StateFunc(n) diff --git a/helper/schema/schema_test.go b/helper/schema/schema_test.go index c7fe069601..94a9d0901c 100644 --- a/helper/schema/schema_test.go +++ b/helper/schema/schema_test.go @@ -98,6 +98,32 @@ func TestSchemaMap_Diff(t *testing.T) { Err: false, }, + // Default + { + Schema: map[string]*Schema{ + "availability_zone": &Schema{ + Type: TypeString, + Optional: true, + Default: "foo", + }, + }, + + State: nil, + + Config: nil, + + Diff: &terraform.ResourceDiff{ + Attributes: map[string]*terraform.ResourceAttrDiff{ + "availability_zone": &terraform.ResourceAttrDiff{ + Old: "", + New: "foo", + }, + }, + }, + + Err: false, + }, + // String with StateFunc { Schema: map[string]*Schema{ @@ -1016,6 +1042,19 @@ func TestSchemaMap_InternalValidate(t *testing.T) { false, }, + // Computed but has default + { + map[string]*Schema{ + "foo": &Schema{ + Type: TypeInt, + Optional: true, + Computed: true, + Default: "foo", + }, + }, + true, + }, + // List element not set { map[string]*Schema{ @@ -1026,6 +1065,18 @@ func TestSchemaMap_InternalValidate(t *testing.T) { true, }, + // List default + { + map[string]*Schema{ + "foo": &Schema{ + Type: TypeList, + Elem: &Schema{Type: TypeInt}, + Default: "foo", + }, + }, + true, + }, + // List element computed { map[string]*Schema{