diff --git a/azurerm/internal/services/signalr/parse/signalr_service.go b/azurerm/internal/services/signalr/parse/signalr_service.go new file mode 100644 index 000000000000..3ae134cb29f4 --- /dev/null +++ b/azurerm/internal/services/signalr/parse/signalr_service.go @@ -0,0 +1,33 @@ +package parse + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" +) + +type SignalRServiceId struct { + ResourceGroup string + Name string +} + +func SignalRServiceID(input string) (*SignalRServiceId, error) { + id, err := azure.ParseAzureResourceID(input) + if err != nil { + return nil, fmt.Errorf("[ERROR] Unable to parse SignalR Service ID %q: %+v", input, err) + } + + service := SignalRServiceId{ + ResourceGroup: id.ResourceGroup, + } + + if service.Name, err = id.PopSegment("signalR"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &service, nil +} diff --git a/azurerm/internal/services/signalr/parse/signalr_service_test.go b/azurerm/internal/services/signalr/parse/signalr_service_test.go new file mode 100644 index 000000000000..461b75fcafaa --- /dev/null +++ b/azurerm/internal/services/signalr/parse/signalr_service_test.go @@ -0,0 +1,73 @@ +package parse + +import ( + "testing" +) + +func TestSignalRServiceId(t *testing.T) { + testData := []struct { + Name string + Input string + Expected *SignalRServiceId + }{ + { + Name: "Empty", + Input: "", + Expected: nil, + }, + { + Name: "No Resource Groups Segment", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000", + Expected: nil, + }, + { + Name: "No Resource Groups Value", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/", + Expected: nil, + }, + { + Name: "Resource Group ID", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/", + Expected: nil, + }, + { + Name: "Missing SignalR Value", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.SignalRService/signalR/", + Expected: nil, + }, + { + Name: "SignalR Service ID", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.SignalRService/signalR/Service1", + Expected: &SignalRServiceId{ + Name: "Service1", + ResourceGroup: "resGroup1", + }, + }, + { + Name: "Wrong Casing", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.SignalRService/SignalR/Service1", + Expected: nil, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Name) + + actual, err := SignalRServiceID(v.Input) + if err != nil { + if v.Expected == nil { + continue + } + + t.Fatalf("Expected a value but got an error: %s", err) + } + + if actual.Name != v.Expected.Name { + t.Fatalf("Expected %q but got %q for Name", v.Expected.Name, actual.Name) + } + + if actual.ResourceGroup != v.Expected.ResourceGroup { + t.Fatalf("Expected %q but got %q for Resource Group", v.Expected.ResourceGroup, actual.ResourceGroup) + } + } +} diff --git a/azurerm/internal/services/signalr/resource_arm_signalr_service.go b/azurerm/internal/services/signalr/resource_arm_signalr_service.go index 878a3babe46d..ce3e45dd9ad3 100644 --- a/azurerm/internal/services/signalr/resource_arm_signalr_service.go +++ b/azurerm/internal/services/signalr/resource_arm_signalr_service.go @@ -13,7 +13,9 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "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/services/signalr/parse" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + azSchema "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -25,10 +27,6 @@ func resourceArmSignalRService() *schema.Resource { Update: resourceArmSignalRServiceCreateUpdate, Delete: resourceArmSignalRServiceDelete, - Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, - }, - Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(30 * time.Minute), Read: schema.DefaultTimeout(5 * time.Minute), @@ -36,6 +34,11 @@ func resourceArmSignalRService() *schema.Resource { Delete: schema.DefaultTimeout(30 * time.Minute), }, + Importer: azSchema.ValidateResourceIDPriorToImport(func(id string) error { + _, err := parse.SignalRServiceID(id) + return err + }), + Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, @@ -224,30 +227,28 @@ func resourceArmSignalRServiceRead(d *schema.ResourceData, meta interface{}) err ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := azure.ParseAzureResourceID(d.Id()) + id, err := parse.SignalRServiceID(d.Id()) if err != nil { return err } - resourceGroup := id.ResourceGroup - name := id.Path["SignalR"] - resp, err := client.Get(ctx, resourceGroup, name) + resp, err := client.Get(ctx, id.ResourceGroup, id.Name) if err != nil { if utils.ResponseWasNotFound(resp.Response) { - log.Printf("[DEBUG] SignalR %q was not found in Resource Group %q - removing from state!", name, resourceGroup) + log.Printf("[DEBUG] SignalR %q was not found in Resource Group %q - removing from state!", id.Name, id.ResourceGroup) d.SetId("") return nil } - return fmt.Errorf("Error getting SignalR %q (Resource Group %q): %+v", name, resourceGroup, err) + return fmt.Errorf("Error getting SignalR %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err) } - keys, err := client.ListKeys(ctx, resourceGroup, name) + keys, err := client.ListKeys(ctx, id.ResourceGroup, id.Name) if err != nil { - return fmt.Errorf("Error getting keys of SignalR %q (Resource Group %q): %+v", name, resourceGroup, err) + return fmt.Errorf("Error getting keys of SignalR %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err) } - d.Set("name", name) - d.Set("resource_group_name", resourceGroup) + d.Set("name", id.Name) + d.Set("resource_group_name", id.ResourceGroup) if location := resp.Location; location != nil { d.Set("location", azure.NormalizeLocation(*location)) @@ -285,23 +286,21 @@ func resourceArmSignalRServiceDelete(d *schema.ResourceData, meta interface{}) e ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := azure.ParseAzureResourceID(d.Id()) + id, err := parse.SignalRServiceID(d.Id()) if err != nil { return err } - resourceGroup := id.ResourceGroup - name := id.Path["SignalR"] - future, err := client.Delete(ctx, resourceGroup, name) + future, err := client.Delete(ctx, id.ResourceGroup, id.Name) if err != nil { if !response.WasNotFound(future.Response()) { - return fmt.Errorf("Error deleting SignalR %q (Resource Group %q): %+v", name, resourceGroup, err) + return fmt.Errorf("Error deleting SignalR %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err) } return nil } if err := future.WaitForCompletionRef(ctx, client.Client); err != nil { if !response.WasNotFound(future.Response()) { - return fmt.Errorf("Error waiting for the deletion of SignalR %q (Resource Group %q): %+v", name, resourceGroup, err) + return fmt.Errorf("Error waiting for the deletion of SignalR %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err) } } diff --git a/azurerm/internal/services/signalr/tests/resource_arm_signalr_service_test.go b/azurerm/internal/services/signalr/tests/resource_arm_signalr_service_test.go index 0633f9ff9db4..c6a67d6d05f1 100644 --- a/azurerm/internal/services/signalr/tests/resource_arm_signalr_service_test.go +++ b/azurerm/internal/services/signalr/tests/resource_arm_signalr_service_test.go @@ -10,6 +10,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance" "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/services/signalr/parse" ) func TestAccAzureRMSignalRService_basic(t *testing.T) { @@ -488,10 +489,12 @@ func testCheckAzureRMSignalRServiceDestroy(s *terraform.State) error { continue } - name := rs.Primary.Attributes["name"] - resourceGroup := rs.Primary.Attributes["resource_group_name"] + id, err := parse.SignalRServiceID(rs.Primary.ID) + if err != nil { + return err + } - resp, err := conn.Get(ctx, resourceGroup, name) + resp, err := conn.Get(ctx, id.ResourceGroup, id.Name) if err != nil { return nil } @@ -513,18 +516,17 @@ func testCheckAzureRMSignalRServiceExists(resourceName string) resource.TestChec return fmt.Errorf("Not found: %s", resourceName) } - name := rs.Primary.Attributes["name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for SignalR service: %s", name) + id, err := parse.SignalRServiceID(rs.Primary.ID) + if err != nil { + return err } - resp, err := conn.Get(ctx, resourceGroup, name) + resp, err := conn.Get(ctx, id.ResourceGroup, id.Name) if err != nil { return fmt.Errorf("Bad: Get on signalRClient: %+v", err) } if resp.StatusCode == http.StatusNotFound { - return fmt.Errorf("Bad: SignalR service %q (resource group: %q) does not exist", name, resourceGroup) + return fmt.Errorf("Bad: SignalR service %q (resource group: %q) does not exist", id.Name, id.ResourceGroup) } return nil