From 36cede09f7d8f664efdc542e41b147fa4108d0da Mon Sep 17 00:00:00 2001 From: James Bardin Date: Tue, 30 Oct 2018 14:53:02 -0400 Subject: [PATCH 1/2] add provider tests for SuppressDiffFunc --- builtin/providers/test/provider.go | 1 + .../providers/test/resource_diff_suppress.go | 57 +++++++++++++++++++ .../test/resource_diff_suppress_test.go | 47 +++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 builtin/providers/test/resource_diff_suppress.go create mode 100644 builtin/providers/test/resource_diff_suppress_test.go diff --git a/builtin/providers/test/provider.go b/builtin/providers/test/provider.go index 1f005b24f..d69ae95f9 100644 --- a/builtin/providers/test/provider.go +++ b/builtin/providers/test/provider.go @@ -21,6 +21,7 @@ func Provider() terraform.ResourceProvider { "test_resource_gh12183": testResourceGH12183(), "test_resource_with_custom_diff": testResourceCustomDiff(), "test_resource_timeout": testResourceTimeout(), + "test_resource_diff_suppress": testResourceDiffSuppress(), }, DataSourcesMap: map[string]*schema.Resource{ "test_data_source": testDataSource(), diff --git a/builtin/providers/test/resource_diff_suppress.go b/builtin/providers/test/resource_diff_suppress.go new file mode 100644 index 000000000..5c01a1d09 --- /dev/null +++ b/builtin/providers/test/resource_diff_suppress.go @@ -0,0 +1,57 @@ +package test + +import ( + "strings" + + "github.com/hashicorp/terraform/helper/schema" +) + +func testResourceDiffSuppress() *schema.Resource { + return &schema.Resource{ + Create: testResourceDiffSuppressCreate, + Read: testResourceDiffSuppressRead, + Update: testResourceDiffSuppressUpdate, + Delete: testResourceDiffSuppressDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "val_to_upper": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + StateFunc: func(val interface{}) string { + return strings.ToUpper(val.(string)) + }, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + return strings.ToUpper(old) == strings.ToUpper(new) + }, + }, + "optional": { + Type: schema.TypeString, + Optional: true, + }, + }, + } +} + +func testResourceDiffSuppressCreate(d *schema.ResourceData, meta interface{}) error { + d.SetId("testId") + + return testResourceRead(d, meta) +} + +func testResourceDiffSuppressRead(d *schema.ResourceData, meta interface{}) error { + return nil +} + +func testResourceDiffSuppressUpdate(d *schema.ResourceData, meta interface{}) error { + return nil +} + +func testResourceDiffSuppressDelete(d *schema.ResourceData, meta interface{}) error { + d.SetId("") + return nil +} diff --git a/builtin/providers/test/resource_diff_suppress_test.go b/builtin/providers/test/resource_diff_suppress_test.go new file mode 100644 index 000000000..59490e358 --- /dev/null +++ b/builtin/providers/test/resource_diff_suppress_test.go @@ -0,0 +1,47 @@ +package test + +import ( + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestResourceDiffSuppress_create(t *testing.T) { + resource.UnitTest(t, resource.TestCase{ + Providers: testAccProviders, + CheckDestroy: testAccCheckResourceDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: strings.TrimSpace(` +resource "test_resource_diff_suppress" "foo" { + val_to_upper = "foo" +} + `), + }, + }, + }) +} +func TestResourceDiffSuppress_update(t *testing.T) { + resource.UnitTest(t, resource.TestCase{ + Providers: testAccProviders, + CheckDestroy: testAccCheckResourceDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: strings.TrimSpace(` +resource "test_resource_diff_suppress" "foo" { + val_to_upper = "foo" +} + `), + }, + resource.TestStep{ + Config: strings.TrimSpace(` +resource "test_resource_diff_suppress" "foo" { + val_to_upper = "bar" + optional = "more" +} + `), + }, + }, + }) +} From e0ea2a5d069eb0837b124131ef3796291d5c8f57 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Tue, 30 Oct 2018 15:58:00 -0400 Subject: [PATCH 2/2] if there is no plan diff, prefer the prior state The prior state may contain customizations made by the provider. If there is no prior state, then take the proposed state. --- helper/plugin/grpc_provider.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/helper/plugin/grpc_provider.go b/helper/plugin/grpc_provider.go index 136336e45..7669cb628 100644 --- a/helper/plugin/grpc_provider.go +++ b/helper/plugin/grpc_provider.go @@ -476,11 +476,16 @@ func (s *GRPCProviderServer) PlanResourceChange(_ context.Context, req *proto.Pl } if diff == nil { - // schema.Provider.Diff returns nil if it ends up making a diff with - // no changes, but our new interface wants us to return an actual - // change description that _shows_ there are no changes, so we return - // the proposed change that produces no diff. - resp.PlannedState = req.ProposedNewState + // schema.Provider.Diff returns nil if it ends up making a diff with no + // changes, but our new interface wants us to return an actual change + // description that _shows_ there are no changes. This is usually the + // PriorSate, however if there was no prior state and no diff, then we + // use the ProposedNewState. + if !priorStateVal.IsNull() { + resp.PlannedState = req.PriorState + } else { + resp.PlannedState = req.ProposedNewState + } return resp, nil }