From ac80bacc1a9751a7fd0ccf47d0e13b5477441de9 Mon Sep 17 00:00:00 2001 From: The Magician Date: Tue, 10 Jan 2023 10:37:43 -0800 Subject: [PATCH] fix crash if ddl item is nil (#6805) (#13441) * fix crash if ddl item is nil * add fix to update * review comments * add pre_update when input=true Signed-off-by: Modular Magician Signed-off-by: Modular Magician --- .changelog/6805.txt | 3 ++ google/resource_compute_reservation.go | 12 ++++++ google/resource_spanner_database.go | 57 ++++++++++++++++---------- 3 files changed, 50 insertions(+), 22 deletions(-) create mode 100644 .changelog/6805.txt diff --git a/.changelog/6805.txt b/.changelog/6805.txt new file mode 100644 index 00000000000..8be186ba78a --- /dev/null +++ b/.changelog/6805.txt @@ -0,0 +1,3 @@ +```release-note:bug +spanner: fixed crash when `google_spanner_database.ddl` item was nil +``` diff --git a/google/resource_compute_reservation.go b/google/resource_compute_reservation.go index dbeb0e5ea98..af066a6db7a 100644 --- a/google/resource_compute_reservation.go +++ b/google/resource_compute_reservation.go @@ -504,6 +504,18 @@ func resourceComputeReservationUpdate(d *schema.ResourceData, meta interface{}) return err } + if d.HasChange("share_settings") { + url, err = replaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/zones/{{zone}}/reservations/{{name}}") + if err != nil { + return err + } + urlUpdateMask := obj["urlUpdateMask"] + if urlUpdateMask != nil { + url = url + urlUpdateMask.(string) + delete(obj, "urlUpdateMask") + } + } + // err == nil indicates that the billing_project value was found if bp, err := getBillingProject(d, config); err == nil { billingProject = bp diff --git a/google/resource_spanner_database.go b/google/resource_spanner_database.go index 828f785dc78..e1d66161324 100644 --- a/google/resource_spanner_database.go +++ b/google/resource_spanner_database.go @@ -339,7 +339,9 @@ func resourceSpannerDatabaseCreate(d *schema.ResourceData, meta interface{}) err if ddlOk { for i := 0; i < len(ddlStatements); i++ { - updateDdls = append(updateDdls, ddlStatements[i].(string)) + if ddlStatements[i] != nil { + updateDdls = append(updateDdls, ddlStatements[i].(string)) + } } } @@ -352,30 +354,33 @@ func resourceSpannerDatabaseCreate(d *schema.ResourceData, meta interface{}) err updateDdls = append(updateDdls, retentionDdl) } - log.Printf("[DEBUG] Applying extra DDL statements to the new Database: %#v", updateDdls) + // Skip API call if there are no new ddl entries (due to ignoring nil values) + if len(updateDdls) > 0 { + log.Printf("[DEBUG] Applying extra DDL statements to the new Database: %#v", updateDdls) - obj["statements"] = updateDdls + obj["statements"] = updateDdls - url, err = replaceVars(d, config, "{{SpannerBasePath}}projects/{{project}}/instances/{{instance}}/databases/{{name}}/ddl") - if err != nil { - return err - } + url, err = replaceVars(d, config, "{{SpannerBasePath}}projects/{{project}}/instances/{{instance}}/databases/{{name}}/ddl") + if err != nil { + return err + } - res, err = sendRequestWithTimeout(config, "PATCH", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutUpdate)) - if err != nil { - return fmt.Errorf("Error executing DDL statements on Database: %s", err) - } + res, err = sendRequestWithTimeout(config, "PATCH", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutUpdate)) + if err != nil { + return fmt.Errorf("Error executing DDL statements on Database: %s", err) + } - // Use the resource in the operation response to populate - // identity fields and d.Id() before read - var opRes map[string]interface{} - err = spannerOperationWaitTimeWithResponse( - config, res, &opRes, project, "Creating Database", userAgent, - d.Timeout(schema.TimeoutCreate)) - if err != nil { - // The resource didn't actually create - d.SetId("") - return fmt.Errorf("Error waiting to run DDL against newly-created Database: %s", err) + // Use the resource in the operation response to populate + // identity fields and d.Id() before read + var opRes map[string]interface{} + err = spannerOperationWaitTimeWithResponse( + config, res, &opRes, project, "Creating Database", userAgent, + d.Timeout(schema.TimeoutCreate)) + if err != nil { + // The resource didn't actually create + d.SetId("") + return fmt.Errorf("Error waiting to run DDL against newly-created Database: %s", err) + } } } @@ -501,6 +506,12 @@ func resourceSpannerDatabaseUpdate(d *schema.ResourceData, meta interface{}) err return err } + if len(obj["statements"].([]string)) == 0 { + // Return early to avoid making an API call that errors, + // due to containing no DDL SQL statements + return resourceSpannerDatabaseRead(d, meta) + } + // err == nil indicates that the billing_project value was found if bp, err := getBillingProject(d, config); err == nil { billingProject = bp @@ -717,7 +728,9 @@ func resourceSpannerDatabaseUpdateEncoder(d *schema.ResourceData, meta interface //Only new ddl statments to be add to update call for i := len(oldDdls); i < len(newDdls); i++ { - updateDdls = append(updateDdls, newDdls[i].(string)) + if newDdls[i] != nil { + updateDdls = append(updateDdls, newDdls[i].(string)) + } } //Add statement to update version_retention_period property, if needed