From 00a52318354fe60774305a53606a7c2f7ff6a9d3 Mon Sep 17 00:00:00 2001 From: The Magician Date: Tue, 8 Oct 2024 15:38:34 -0700 Subject: [PATCH] pubsub: fix permadiff with configuring an empty retry_policy. (#11834) (#19784) [upstream:2c219b6d3cf2720fde86ff8b1d65abca8752f7d8] Signed-off-by: Modular Magician --- .changelog/11834.txt | 3 ++ .../pubsub/resource_pubsub_subscription.go | 14 ++++--- .../resource_pubsub_subscription_test.go | 40 +++++++++++++++++++ 3 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 .changelog/11834.txt diff --git a/.changelog/11834.txt b/.changelog/11834.txt new file mode 100644 index 00000000000..ca35a216a49 --- /dev/null +++ b/.changelog/11834.txt @@ -0,0 +1,3 @@ +```release-note:bug +pubsub: fix permadiff with configuring an empty `retry_policy`. +``` \ No newline at end of file diff --git a/google/services/pubsub/resource_pubsub_subscription.go b/google/services/pubsub/resource_pubsub_subscription.go index c93c0957831..249c5522673 100644 --- a/google/services/pubsub/resource_pubsub_subscription.go +++ b/google/services/pubsub/resource_pubsub_subscription.go @@ -630,7 +630,7 @@ func resourcePubsubSubscriptionCreate(d *schema.ResourceData, meta interface{}) retryPolicyProp, err := expandPubsubSubscriptionRetryPolicy(d.Get("retry_policy"), d, config) if err != nil { return err - } else if v, ok := d.GetOkExists("retry_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(retryPolicyProp)) && (ok || !reflect.DeepEqual(v, retryPolicyProp)) { + } else if v, ok := d.GetOkExists("retry_policy"); ok || !reflect.DeepEqual(v, retryPolicyProp) { obj["retryPolicy"] = retryPolicyProp } enableMessageOrderingProp, err := expandPubsubSubscriptionEnableMessageOrdering(d.Get("enable_message_ordering"), d, config) @@ -914,7 +914,7 @@ func resourcePubsubSubscriptionUpdate(d *schema.ResourceData, meta interface{}) retryPolicyProp, err := expandPubsubSubscriptionRetryPolicy(d.Get("retry_policy"), d, config) if err != nil { return err - } else if v, ok := d.GetOkExists("retry_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, retryPolicyProp)) { + } else if v, ok := d.GetOkExists("retry_policy"); ok || !reflect.DeepEqual(v, retryPolicyProp) { obj["retryPolicy"] = retryPolicyProp } enableExactlyOnceDeliveryProp, err := expandPubsubSubscriptionEnableExactlyOnceDelivery(d.Get("enable_exactly_once_delivery"), d, config) @@ -1434,9 +1434,6 @@ func flattenPubsubSubscriptionRetryPolicy(v interface{}, d *schema.ResourceData, return nil } original := v.(map[string]interface{}) - if len(original) == 0 { - return nil - } transformed := make(map[string]interface{}) transformed["minimum_backoff"] = flattenPubsubSubscriptionRetryPolicyMinimumBackoff(original["minimumBackoff"], d, config) @@ -1927,9 +1924,14 @@ func expandPubsubSubscriptionDeadLetterPolicyMaxDeliveryAttempts(v interface{}, func expandPubsubSubscriptionRetryPolicy(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { l := v.([]interface{}) - if len(l) == 0 || l[0] == nil { + if len(l) == 0 { return nil, nil } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } raw := l[0] original := raw.(map[string]interface{}) transformed := make(map[string]interface{}) diff --git a/google/services/pubsub/resource_pubsub_subscription_test.go b/google/services/pubsub/resource_pubsub_subscription_test.go index 60b3c5d06c2..4c23339680f 100644 --- a/google/services/pubsub/resource_pubsub_subscription_test.go +++ b/google/services/pubsub/resource_pubsub_subscription_test.go @@ -38,6 +38,30 @@ func TestAccPubsubSubscription_emptyTTL(t *testing.T) { }) } +func TestAccPubsubSubscription_emptyRetryPolicy(t *testing.T) { + t.Parallel() + + topic := fmt.Sprintf("tf-test-topic-%s", acctest.RandString(t, 10)) + subscription := fmt.Sprintf("tf-test-sub-%s", acctest.RandString(t, 10)) + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckPubsubSubscriptionDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccPubsubSubscription_emptyRetryPolicy(topic, subscription), + }, + { + ResourceName: "google_pubsub_subscription.foo", + ImportStateId: subscription, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccPubsubSubscription_basic(t *testing.T) { t.Parallel() @@ -496,6 +520,22 @@ resource "google_pubsub_subscription" "foo" { `, topic, subscription) } +func testAccPubsubSubscription_emptyRetryPolicy(topic, subscription string) string { + return fmt.Sprintf(` +resource "google_pubsub_topic" "foo" { + name = "%s" +} + +resource "google_pubsub_subscription" "foo" { + name = "%s" + topic = google_pubsub_topic.foo.id + + retry_policy { + } +} +`, topic, subscription) +} + func testAccPubsubSubscription_push(topicFoo, saAccount, subscription string) string { return fmt.Sprintf(` data "google_project" "project" { }