From 7f14708e71b04bcc5bca0f394360eb2db647a753 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 14 Aug 2014 23:32:20 -0700 Subject: [PATCH] helper/schema: list ForceNew --- helper/schema/resource.go | 15 ++++++++++++ helper/schema/resource_test.go | 28 ++++++++++++++++++++++ helper/schema/schema.go | 12 ++++++++-- helper/schema/schema_test.go | 44 ++++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 2 deletions(-) diff --git a/helper/schema/resource.go b/helper/schema/resource.go index 63c2b1392..fd53cc485 100644 --- a/helper/schema/resource.go +++ b/helper/schema/resource.go @@ -50,6 +50,21 @@ func (r *Resource) InternalValidate() error { if v.Required && v.Computed { return fmt.Errorf("%s: Cannot be both Required and Computed", k) } + + if v.Type == TypeList { + if v.Elem == nil { + return fmt.Errorf("%s: Elem must be set for lists", k) + } + + switch t := v.Elem.(type) { + case *Schema: + bad := t.Computed || t.Optional || t.Required + if bad { + return fmt.Errorf( + "%s: Elem must have only Type set", k) + } + } + } } return nil diff --git a/helper/schema/resource_test.go b/helper/schema/resource_test.go index b73ab71d7..fa2c7d0a7 100644 --- a/helper/schema/resource_test.go +++ b/helper/schema/resource_test.go @@ -66,6 +66,34 @@ func TestResourceInternalValidate(t *testing.T) { }, false, }, + + // List element not set + { + &Resource{ + Schema: map[string]*Schema{ + "foo": &Schema{ + Type: TypeList, + }, + }, + }, + true, + }, + + // List element computed + { + &Resource{ + Schema: map[string]*Schema{ + "foo": &Schema{ + Type: TypeList, + Elem: &Schema{ + Type: TypeInt, + Computed: true, + }, + }, + }, + }, + true, + }, } for i, tc := range cases { diff --git a/helper/schema/schema.go b/helper/schema/schema.go index 6a7711dc6..9fe0d2f06 100644 --- a/helper/schema/schema.go +++ b/helper/schema/schema.go @@ -144,15 +144,23 @@ func (m schemaMap) diffList( } // Diff the count no matter what - m.diffString(k+".#", &Schema{Type: TypeInt}, diff, s, c) + countSchema := &Schema{ + Type: TypeInt, + ForceNew: schema.ForceNew, + } + m.diffString(k+".#", countSchema, diff, s, c) switch t := schema.Elem.(type) { case *Schema: + t2 := *t + t2.Computed = schema.Computed + t2.ForceNew = schema.ForceNew + // This is just a primitive element, so go through each and // just diff each. for i, _ := range vs { subK := fmt.Sprintf("%s.%d", k, i) - err := m.diff(subK, t, diff, s, c) + err := m.diff(subK, &t2, diff, s, c) if err != nil { return err } diff --git a/helper/schema/schema_test.go b/helper/schema/schema_test.go index 1976042a1..911c853f4 100644 --- a/helper/schema/schema_test.go +++ b/helper/schema/schema_test.go @@ -265,6 +265,50 @@ func TestSchemaMap_Diff(t *testing.T) { Err: false, }, + + { + Schema: map[string]*Schema{ + "ports": &Schema{ + Type: TypeList, + Required: true, + Elem: &Schema{Type: TypeInt}, + ForceNew: true, + }, + }, + + State: nil, + + Config: map[string]interface{}{ + "ports": []interface{}{1, 2, 5}, + }, + + Diff: &terraform.ResourceDiff{ + Attributes: map[string]*terraform.ResourceAttrDiff{ + "ports.#": &terraform.ResourceAttrDiff{ + Old: "", + New: "3", + RequiresNew: true, + }, + "ports.0": &terraform.ResourceAttrDiff{ + Old: "", + New: "1", + RequiresNew: true, + }, + "ports.1": &terraform.ResourceAttrDiff{ + Old: "", + New: "2", + RequiresNew: true, + }, + "ports.2": &terraform.ResourceAttrDiff{ + Old: "", + New: "5", + RequiresNew: true, + }, + }, + }, + + Err: false, + }, } for i, tc := range cases {