From abb41c4dcedf0ed2f69ab7b7f7a1c29b3085a0e6 Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Mon, 8 Jun 2020 09:50:58 +0200 Subject: [PATCH] r/eventhub_namespace_authorization_rule: adding a state migration Updating the ID from `authorizationRules` to `AuthorizationRules`, also splitting out a Parser from this - since it seems like as good-a-time-as-any --- ...b_namespace_authorization_rule_resource.go | 48 +++++----- .../namespace_authorization_rule_v0.go | 41 +++++++++ .../parse/namespace_authorization_rule.go | 34 +++++++ .../namespace_authorization_rule_test.go | 90 +++++++++++++++++++ 4 files changed, 189 insertions(+), 24 deletions(-) create mode 100644 azurerm/internal/services/eventhub/migration/namespace_authorization_rule_v0.go create mode 100644 azurerm/internal/services/eventhub/parse/namespace_authorization_rule.go create mode 100644 azurerm/internal/services/eventhub/parse/namespace_authorization_rule_test.go diff --git a/azurerm/internal/services/eventhub/eventhub_namespace_authorization_rule_resource.go b/azurerm/internal/services/eventhub/eventhub_namespace_authorization_rule_resource.go index e75a340e7fa2..59e577757cb2 100644 --- a/azurerm/internal/services/eventhub/eventhub_namespace_authorization_rule_resource.go +++ b/azurerm/internal/services/eventhub/eventhub_namespace_authorization_rule_resource.go @@ -3,7 +3,6 @@ package eventhub import ( "fmt" "log" - "net/http" "time" "github.com/Azure/azure-sdk-for-go/services/eventhub/mgmt/2017-04-01/eventhub" @@ -13,6 +12,8 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/eventhub/migration" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/eventhub/parse" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -28,6 +29,15 @@ func resourceArmEventHubNamespaceAuthorizationRule() *schema.Resource { State: schema.ImportStatePassthrough, }, + SchemaVersion: 1, + StateUpgraders: []schema.StateUpgrader{ + { + Type: migration.EventHubNamespaceAuthorizationRuleUpgradeV0Schema().CoreConfigSchema().ImpliedType(), + Upgrade: migration.EventHubNamespaceAuthorizationRuleUpgradeV0ToV1, + Version: 0, + }, + }, + Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(30 * time.Minute), Read: schema.DefaultTimeout(5 * time.Minute), @@ -114,27 +124,23 @@ func resourceArmEventHubNamespaceAuthorizationRuleRead(d *schema.ResourceData, m ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := azure.ParseAzureResourceID(d.Id()) + id, err := parse.NamespaceAuthorizationRuleID(d.Id()) if err != nil { return err } - name := id.Path["authorizationRules"] - resourceGroup := id.ResourceGroup - namespaceName := id.Path["namespaces"] - - resp, err := client.GetAuthorizationRule(ctx, resourceGroup, namespaceName, name) + resp, err := client.GetAuthorizationRule(ctx, id.ResourceGroup, id.NamespaceName, id.Name) if err != nil { if utils.ResponseWasNotFound(resp.Response) { d.SetId("") return nil } - return fmt.Errorf("Error making Read request on Azure EventHub Authorization Rule %s: %+v", name, err) + return fmt.Errorf("retrieving Authorization Rule %q (EventHub Namespace %q / Resource Group %q) : %+v", id.Name, id.NamespaceName, id.ResourceGroup, err) } - d.Set("name", name) - d.Set("namespace_name", namespaceName) - d.Set("resource_group_name", resourceGroup) + d.Set("name", id.Name) + d.Set("namespace_name", id.NamespaceName) + d.Set("resource_group_name", id.ResourceGroup) if properties := resp.AuthorizationRuleProperties; properties != nil { listen, send, manage := azure.FlattenEventHubAuthorizationRuleRights(properties.Rights) @@ -143,9 +149,9 @@ func resourceArmEventHubNamespaceAuthorizationRuleRead(d *schema.ResourceData, m d.Set("send", send) } - keysResp, err := client.ListKeys(ctx, resourceGroup, namespaceName, name) + keysResp, err := client.ListKeys(ctx, id.ResourceGroup, id.NamespaceName, id.Name) if err != nil { - return fmt.Errorf("Error making Read request on Azure EventHub Authorization Rule List Keys %s: %+v", name, err) + return fmt.Errorf("retrieving Keys for Authorization Rule %q (EventHub Namespace %q / Resource Group %q): %+v", id.Name, id.NamespaceName, id.ResourceGroup, err) } d.Set("primary_key", keysResp.PrimaryKey) @@ -163,22 +169,16 @@ func resourceArmEventHubNamespaceAuthorizationRuleDelete(d *schema.ResourceData, ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := azure.ParseAzureResourceID(d.Id()) + id, err := parse.NamespaceAuthorizationRuleID(d.Id()) if err != nil { return err } - name := id.Path["authorizationRules"] - resourceGroup := id.ResourceGroup - namespaceName := id.Path["namespaces"] - - locks.ByName(namespaceName, eventHubNamespaceResourceName) - defer locks.UnlockByName(namespaceName, eventHubNamespaceResourceName) - - resp, err := eventhubClient.DeleteAuthorizationRule(ctx, resourceGroup, namespaceName, name) + locks.ByName(id.NamespaceName, eventHubNamespaceResourceName) + defer locks.UnlockByName(id.NamespaceName, eventHubNamespaceResourceName) - if resp.StatusCode != http.StatusOK { - return fmt.Errorf("Error issuing Azure ARM delete request of EventHub Authorization Rule '%s': %+v", name, err) + if _, err := eventhubClient.DeleteAuthorizationRule(ctx, id.ResourceGroup, id.NamespaceName, id.Name); err != nil { + return fmt.Errorf("deleting Authorization Rule %q (EventHub Namespace %q / Resource Group %q): %+v", id.Name, id.NamespaceName, id.ResourceGroup, err) } return nil diff --git a/azurerm/internal/services/eventhub/migration/namespace_authorization_rule_v0.go b/azurerm/internal/services/eventhub/migration/namespace_authorization_rule_v0.go new file mode 100644 index 000000000000..f4a5ca872932 --- /dev/null +++ b/azurerm/internal/services/eventhub/migration/namespace_authorization_rule_v0.go @@ -0,0 +1,41 @@ +package migration + +import ( + "log" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" +) + +func EventHubNamespaceAuthorizationRuleUpgradeV0Schema() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "namespace_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + }, + } +} + +func EventHubNamespaceAuthorizationRuleUpgradeV0ToV1(rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) { + oldId := rawState["id"].(string) + + newId := strings.Replace(rawState["id"].(string), "/authorizationRules/", "/AuthorizationRules/", 1) + + log.Printf("[DEBUG] Updating ID from %q to %q", oldId, newId) + + rawState["id"] = newId + + return rawState, nil +} diff --git a/azurerm/internal/services/eventhub/parse/namespace_authorization_rule.go b/azurerm/internal/services/eventhub/parse/namespace_authorization_rule.go new file mode 100644 index 000000000000..fe5c0442f964 --- /dev/null +++ b/azurerm/internal/services/eventhub/parse/namespace_authorization_rule.go @@ -0,0 +1,34 @@ +package parse + +import "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + +type NamespaceAuthorizationRuleId struct { + ResourceGroup string + NamespaceName string + Name string +} + +func NamespaceAuthorizationRuleID(input string) (*NamespaceAuthorizationRuleId, error) { + id, err := azure.ParseAzureResourceID(input) + if err != nil { + return nil, err + } + + rule := NamespaceAuthorizationRuleId{ + ResourceGroup: id.ResourceGroup, + } + + if rule.NamespaceName, err = id.PopSegment("namespaces"); err != nil { + return nil, err + } + + if rule.Name, err = id.PopSegment("AuthorizationRules"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &rule, nil +} diff --git a/azurerm/internal/services/eventhub/parse/namespace_authorization_rule_test.go b/azurerm/internal/services/eventhub/parse/namespace_authorization_rule_test.go new file mode 100644 index 000000000000..3723d78076fe --- /dev/null +++ b/azurerm/internal/services/eventhub/parse/namespace_authorization_rule_test.go @@ -0,0 +1,90 @@ +package parse + +import ( + "testing" +) + +func TestNamespaceAuthorizationRuleID(t *testing.T) { + testData := []struct { + Name string + Input string + Error bool + Expect *NamespaceAuthorizationRuleId + }{ + { + Name: "Empty", + Input: "", + Error: true, + }, + { + Name: "No Resource Groups Segment", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000", + Error: true, + }, + { + Name: "No Resource Groups Value", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/", + Error: true, + }, + { + Name: "Resource Group ID", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/", + Error: true, + }, + { + Name: "Missing Namespaces Key", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.EventHub/namespaces/", + Error: true, + }, + { + Name: "Missing Namespaces Value", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.EventHub/namespaces/namespace1", + Error: true, + }, + { + Name: "Missing AuthorizationRules Key", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.EventHub/namespaces/namespace1/AuthorizationRules", + Error: true, + }, + { + Name: "Namespace Authorization Rule ID", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.EventHub/namespaces/namespace1/AuthorizationRules/rule1", + Error: false, + Expect: &NamespaceAuthorizationRuleId{ + ResourceGroup: "group1", + NamespaceName: "namespace1", + Name: "rule1", + }, + }, + { + Name: "Wrong Casing", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.EventHub/namespaces/namespace1/authorizationRules/rule1", + Error: true, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Name) + + actual, err := NamespaceAuthorizationRuleID(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expected a value but got an error: %s", err) + } + + if actual.Name != v.Expect.Name { + t.Fatalf("Expected %q but got %q for Name", v.Expect.Name, actual.Name) + } + + if actual.NamespaceName != v.Expect.NamespaceName { + t.Fatalf("Expected %q but got %q for Name", v.Expect.NamespaceName, actual.NamespaceName) + } + + if actual.ResourceGroup != v.Expect.ResourceGroup { + t.Fatalf("Expected %q but got %q for Resource Group", v.Expect.ResourceGroup, actual.ResourceGroup) + } + } +}