From 3be26baf381dbba22a739002aeec11391539a4f6 Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Tue, 6 Jun 2023 10:00:34 +1000 Subject: [PATCH] resource/cloudflare_ruleset: handle `Import` operations with missing values In the event a user provides an invalid import string, we should provide a nice error message stating which part is missing. Unfortunately, we were attempting to perform assignments on those index parts which, when they are missing, will cause a panic. This moves the assignment to under the checks and uses the raw indexes for the values _if_ required. --- .changelog/2503.txt | 3 +++ .../framework/service/rulesets/resource.go | 4 ++-- .../service/rulesets/resource_test.go | 21 +++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 .changelog/2503.txt diff --git a/.changelog/2503.txt b/.changelog/2503.txt new file mode 100644 index 0000000000..e5ef98826c --- /dev/null +++ b/.changelog/2503.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/cloudflare_ruleset: handle `Import` operations where the required values are missing for providing a nicer error message +``` diff --git a/internal/framework/service/rulesets/resource.go b/internal/framework/service/rulesets/resource.go index dabdd5910f..9825226130 100644 --- a/internal/framework/service/rulesets/resource.go +++ b/internal/framework/service/rulesets/resource.go @@ -267,15 +267,15 @@ func (r *RulesetResource) Delete(ctx context.Context, req resource.DeleteRequest func (r *RulesetResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { idParts := strings.Split(req.ID, "/") - resourceLevel, resourceIdentifier, rulesetID := idParts[0], idParts[1], idParts[2] - if len(idParts) != 3 || resourceLevel == "" || resourceIdentifier == "" || rulesetID == "" { + if len(idParts) != 3 || idParts[0] == "" || idParts[1] == "" || idParts[2] == "" { resp.Diagnostics.AddError( "invalid import identifier", fmt.Sprintf("expected import identifier to be resourceLevel/resourceIdentifier/rulesetID. got: %q", req.ID), ) return } + resourceLevel, resourceIdentifier, rulesetID := idParts[0], idParts[1], idParts[2] resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("id"), rulesetID)...) if resourceLevel == "zone" { diff --git a/internal/framework/service/rulesets/resource_test.go b/internal/framework/service/rulesets/resource_test.go index ee2a83ea6e..51193a5401 100644 --- a/internal/framework/service/rulesets/resource_test.go +++ b/internal/framework/service/rulesets/resource_test.go @@ -2197,6 +2197,27 @@ func TestAccCloudflareRuleset_CacheSettingsDefinedQueryStringIncludeKeys(t *test }) } +func TestAccCloudflareRuleset_ImportHandlesMissingValues(t *testing.T) { + rnd := utils.GenerateRandomResourceName() + zoneID := os.Getenv("CLOUDFLARE_ZONE_ID") + zoneName := os.Getenv("CLOUDFLARE_DOMAIN") + name := "cloudflare_ruleset." + rnd + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.TestAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccCheckCloudflareRulesetTransformationRuleResponseHeaders(rnd, "broken", zoneID, zoneName), + ExpectError: regexp.MustCompile(`invalid import identifier`), + ImportState: true, + ImportStateId: rnd, + ResourceName: name, + }, + }, + }) +} + func testAccCheckCloudflareRulesetMagicTransitSingle(rnd, name, accountID string) string { return fmt.Sprintf(` resource "cloudflare_ruleset" "%[1]s" {