diff --git a/azurerm/internal/services/postgres/parse/database.go b/azurerm/internal/services/postgres/parse/database.go new file mode 100644 index 0000000000000..0b288f6ea6b39 --- /dev/null +++ b/azurerm/internal/services/postgres/parse/database.go @@ -0,0 +1,56 @@ +package parse + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" +) + +type DatabaseId struct { + SubscriptionId string + ResourceGroup string + ServerName string + Name string +} + +func NewDatabaseID(subscriptionId, resourceGroup, serverName, name string) DatabaseId { + return DatabaseId{ + SubscriptionId: subscriptionId, + ResourceGroup: resourceGroup, + ServerName: serverName, + Name: name, + } +} + +func (id DatabaseId) ID(_ string) string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.DBforPostgreSQL/servers/%s/databases/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.ServerName, id.Name) +} + +// DatabaseID parses a Database ID into an DatabaseId struct +func DatabaseID(input string) (*DatabaseId, error) { + id, err := azure.ParseAzureResourceID(input) + if err != nil { + return nil, err + } + + resourceId := DatabaseId{ + SubscriptionId: id.SubscriptionID, + ResourceGroup: id.ResourceGroup, + } + + if resourceId.ServerName, err = id.PopSegment("servers"); err != nil { + return nil, err + } + if resourceId.Name, err = id.PopSegment("databases"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &resourceId, nil +} diff --git a/azurerm/internal/services/postgres/parse/database_test.go b/azurerm/internal/services/postgres/parse/database_test.go new file mode 100644 index 0000000000000..f19f32369e93c --- /dev/null +++ b/azurerm/internal/services/postgres/parse/database_test.go @@ -0,0 +1,128 @@ +package parse + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid" +) + +var _ resourceid.Formatter = DatabaseId{} + +func TestDatabaseIDFormatter(t *testing.T) { + actual := NewDatabaseID("12345678-1234-9876-4563-123456789012", "resGroup1", "server1", "database1").ID("") + expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.DBforPostgreSQL/servers/server1/databases/database1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + +func TestDatabaseID(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *DatabaseId + }{ + + { + // empty + Input: "", + Error: true, + }, + + { + // missing SubscriptionId + Input: "/", + Error: true, + }, + + { + // missing value for SubscriptionId + Input: "/subscriptions/", + Error: true, + }, + + { + // missing ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/", + Error: true, + }, + + { + // missing value for ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/", + Error: true, + }, + + { + // missing ServerName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.DBforPostgreSQL/", + Error: true, + }, + + { + // missing value for ServerName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.DBforPostgreSQL/servers/", + Error: true, + }, + + { + // missing Name + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.DBforPostgreSQL/servers/server1/", + Error: true, + }, + + { + // missing value for Name + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.DBforPostgreSQL/servers/server1/databases/", + Error: true, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.DBforPostgreSQL/servers/server1/databases/database1", + Expected: &DatabaseId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "resGroup1", + ServerName: "server1", + Name: "database1", + }, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESGROUP1/PROVIDERS/MICROSOFT.DBFORPOSTGRESQL/SERVERS/SERVER1/DATABASES/DATABASE1", + Error: true, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := DatabaseID(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expect a value but got an error: %s", err) + } + if v.Error { + t.Fatal("Expect an error but didn't get one") + } + + if actual.SubscriptionId != v.Expected.SubscriptionId { + t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId) + } + if actual.ResourceGroup != v.Expected.ResourceGroup { + t.Fatalf("Expected %q but got %q for ResourceGroup", v.Expected.ResourceGroup, actual.ResourceGroup) + } + if actual.ServerName != v.Expected.ServerName { + t.Fatalf("Expected %q but got %q for ServerName", v.Expected.ServerName, actual.ServerName) + } + if actual.Name != v.Expected.Name { + t.Fatalf("Expected %q but got %q for Name", v.Expected.Name, actual.Name) + } + } +} diff --git a/azurerm/internal/services/postgres/postgresql_database_resource.go b/azurerm/internal/services/postgres/postgresql_database_resource.go index 5ff90b15b5b9b..eee97bf4e25d6 100644 --- a/azurerm/internal/services/postgres/postgresql_database_resource.go +++ b/azurerm/internal/services/postgres/postgresql_database_resource.go @@ -12,7 +12,9 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "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/services/postgres/parse" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/postgres/validate" + 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" ) @@ -22,9 +24,10 @@ func resourceArmPostgreSQLDatabase() *schema.Resource { Create: resourceArmPostgreSQLDatabaseCreate, Read: resourceArmPostgreSQLDatabaseRead, Delete: resourceArmPostgreSQLDatabaseDelete, - Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, - }, + Importer: azSchema.ValidateResourceIDPriorToImport(func(id string) error { + _, err := parse.DatabaseID(id) + return err + }), Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(60 * time.Minute), @@ -125,28 +128,25 @@ func resourceArmPostgreSQLDatabaseRead(d *schema.ResourceData, meta interface{}) ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := azure.ParseAzureResourceID(d.Id()) + id, err := parse.DatabaseID(d.Id()) if err != nil { return err } - resGroup := id.ResourceGroup - serverName := id.Path["servers"] - name := id.Path["databases"] - resp, err := client.Get(ctx, resGroup, serverName, name) + resp, err := client.Get(ctx, id.ResourceGroup, id.ServerName, id.Name) if err != nil { if utils.ResponseWasNotFound(resp.Response) { - log.Printf("[WARN] PostgreSQL Database '%s' was not found (resource group '%s')", name, resGroup) + log.Printf("[WARN] PostgreSQL Database %q was not found (Server %q / Resource Group %q)", id.Name, id.ServerName, id.ResourceGroup) d.SetId("") return nil } - return fmt.Errorf("Error making Read request on Azure PostgreSQL Database %s: %+v", name, err) + return fmt.Errorf("retrieving PostgreSQL Database %q (Server %q / Resource Group %q): %+v", id.Name, id.ServerName, id.ResourceGroup, err) } - d.Set("name", resp.Name) - d.Set("resource_group_name", resGroup) - d.Set("server_name", serverName) + d.Set("name", id.Name) + d.Set("server_name", id.ServerName) + d.Set("resource_group_name", id.ResourceGroup) if props := resp.DatabaseProperties; props != nil { d.Set("charset", props.Charset) @@ -161,15 +161,12 @@ func resourceArmPostgreSQLDatabaseDelete(d *schema.ResourceData, meta interface{ ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := azure.ParseAzureResourceID(d.Id()) + id, err := parse.DatabaseID(d.Id()) if err != nil { return err } - resGroup := id.ResourceGroup - serverName := id.Path["servers"] - name := id.Path["databases"] - future, err := client.Delete(ctx, resGroup, serverName, name) + future, err := client.Delete(ctx, id.ResourceGroup, id.ServerName, id.Name) if err != nil { if response.WasNotFound(future.Response()) { return nil diff --git a/azurerm/internal/services/postgres/resourceids.go b/azurerm/internal/services/postgres/resourceids.go index c965d77a747bf..8ef541043173d 100644 --- a/azurerm/internal/services/postgres/resourceids.go +++ b/azurerm/internal/services/postgres/resourceids.go @@ -2,6 +2,7 @@ package postgres //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=AzureActiveDirectoryAdministrator -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.DBforPostgreSQL/servers/server1/Administrators/activeDirectory //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=Configuration -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.DBforPostgreSQL/servers/server1/configurations/configuration1 +//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=Database -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.DBforPostgreSQL/servers/server1/databases/database1 //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=FirewallRule -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.DBforPostgreSQL/servers/server1/firewallRules/firewallRule1 //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=Server -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.DBforPostgreSQL/servers/server1 //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=ServerKey -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.DBforPostgreSQL/servers/server1/keys/key1