From 4c6ceef9b8352ffbff62a2fcbd6ba81362dbd5fa Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Sun, 27 Dec 2015 10:41:08 +0100 Subject: [PATCH] helper/schema: Allow identification of a new resource in update func --- helper/schema/resource.go | 1 + helper/schema/resource_data.go | 9 ++++ helper/schema/resource_test.go | 81 ++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/helper/schema/resource.go b/helper/schema/resource.go index a7b8cfe1e..ea325334f 100644 --- a/helper/schema/resource.go +++ b/helper/schema/resource.go @@ -142,6 +142,7 @@ func (r *Resource) Apply( err = nil if data.Id() == "" { // We're creating, it is a new resource. + data.MarkNewResource() err = r.Create(data, meta) } else { if r.Update == nil { diff --git a/helper/schema/resource_data.go b/helper/schema/resource_data.go index 5c05a155b..1554d424d 100644 --- a/helper/schema/resource_data.go +++ b/helper/schema/resource_data.go @@ -30,6 +30,7 @@ type ResourceData struct { partial bool partialMap map[string]struct{} once sync.Once + isNew bool } // getResult is the internal structure that is generated when a Get @@ -171,6 +172,14 @@ func (d *ResourceData) SetPartial(k string) { } } +func (d *ResourceData) MarkNewResource() { + d.isNew = true +} + +func (d *ResourceData) IsNewResource() bool { + return d.isNew +} + // Id returns the ID of the resource. func (d *ResourceData) Id() string { var result string diff --git a/helper/schema/resource_test.go b/helper/schema/resource_test.go index ecfede51b..0b91cd79a 100644 --- a/helper/schema/resource_test.go +++ b/helper/schema/resource_test.go @@ -312,6 +312,87 @@ func TestResourceApply_updateNoCallback(t *testing.T) { } } +func TestResourceApply_isNewResource(t *testing.T) { + r := &Resource{ + Schema: map[string]*Schema{ + "foo": &Schema{ + Type: TypeString, + Optional: true, + }, + }, + } + + updateFunc := func(d *ResourceData, m interface{}) error { + d.Set("foo", "updated") + if d.IsNewResource() { + d.Set("foo", "new-resource") + } + return nil + } + r.Create = func(d *ResourceData, m interface{}) error { + d.SetId("foo") + d.Set("foo", "created") + return updateFunc(d, m) + } + r.Update = updateFunc + + d := &terraform.InstanceDiff{ + Attributes: map[string]*terraform.ResourceAttrDiff{ + "foo": &terraform.ResourceAttrDiff{ + New: "bla-blah", + }, + }, + } + + // positive test + var s *terraform.InstanceState = nil + + actual, err := r.Apply(s, d, nil) + if err != nil { + t.Fatalf("err: %s", err) + } + + expected := &terraform.InstanceState{ + ID: "foo", + Attributes: map[string]string{ + "id": "foo", + "foo": "new-resource", + }, + } + + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("actual: %#v\nexpected: %#v", + actual, expected) + } + + // negative test + s = &terraform.InstanceState{ + ID: "foo", + Attributes: map[string]string{ + "id": "foo", + "foo": "new-resource", + }, + } + + actual, err = r.Apply(s, d, nil) + if err != nil { + t.Fatalf("err: %s", err) + } + + expected = &terraform.InstanceState{ + ID: "foo", + Attributes: map[string]string{ + "id": "foo", + "foo": "updated", + }, + } + + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("actual: %#v\nexpected: %#v", + actual, expected) + } +} + func TestResourceInternalValidate(t *testing.T) { cases := []struct { In *Resource