From 74d0b91fbf599a87682e2fcd42a2a4823fd7aa2d Mon Sep 17 00:00:00 2001 From: yupwei68 Date: Fri, 17 Jul 2020 09:58:13 +0800 Subject: [PATCH 01/11] update --- .../internal/services/mssql/client/client.go | 5 + .../services/mssql/mssql_database_resource.go | 29 +++- .../mssql/mssql_server_data_source.go | 126 ++++++++++++++++ .../services/mssql/mssql_server_resource.go | 32 ++++ .../internal/services/mssql/registration.go | 1 + .../tests/mssql_database_resource_test.go | 140 ++++++++++++++++++ .../tests/mssql_server_data_source_test.go | 75 ++++++++++ website/azurerm.erb | 4 + website/docs/d/mssql_server.html.markdown | 68 +++++++++ website/docs/r/mssql_database.html.markdown | 6 +- website/docs/r/mssql_server.html.markdown | 4 +- 11 files changed, 486 insertions(+), 4 deletions(-) create mode 100644 azurerm/internal/services/mssql/mssql_server_data_source.go create mode 100644 azurerm/internal/services/mssql/tests/mssql_server_data_source_test.go create mode 100644 website/docs/d/mssql_server.html.markdown diff --git a/azurerm/internal/services/mssql/client/client.go b/azurerm/internal/services/mssql/client/client.go index 9c3f834b3823..fbf5aad94bf0 100644 --- a/azurerm/internal/services/mssql/client/client.go +++ b/azurerm/internal/services/mssql/client/client.go @@ -12,6 +12,7 @@ type Client struct { DatabaseThreatDetectionPoliciesClient *sql.DatabaseThreatDetectionPoliciesClient ElasticPoolsClient *sql.ElasticPoolsClient DatabaseVulnerabilityAssessmentRuleBaselinesClient *sql.DatabaseVulnerabilityAssessmentRuleBaselinesClient + RestorableDroppedDatabasesClient *sql.RestorableDroppedDatabasesClient ServerAzureADAdministratorsClient *sql.ServerAzureADAdministratorsClient ServersClient *sql.ServersClient ServerExtendedBlobAuditingPoliciesClient *sql.ExtendedServerBlobAuditingPoliciesClient @@ -37,6 +38,9 @@ func NewClient(o *common.ClientOptions) *Client { elasticPoolsClient := sql.NewElasticPoolsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&elasticPoolsClient.Client, o.ResourceManagerAuthorizer) + restorableDroppedDatabasesClient := sql.NewRestorableDroppedDatabasesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&restorableDroppedDatabasesClient.Client, o.ResourceManagerAuthorizer) + serverSecurityAlertPoliciesClient := sql.NewServerSecurityAlertPoliciesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&serverSecurityAlertPoliciesClient.Client, o.ResourceManagerAuthorizer) @@ -64,6 +68,7 @@ func NewClient(o *common.ClientOptions) *Client { DatabaseThreatDetectionPoliciesClient: &databaseThreatDetectionPoliciesClient, DatabaseVulnerabilityAssessmentRuleBaselinesClient: &databaseVulnerabilityAssessmentRuleBaselinesClient, ElasticPoolsClient: &elasticPoolsClient, + RestorableDroppedDatabasesClient: &restorableDroppedDatabasesClient, ServerAzureADAdministratorsClient: &serverAzureADAdministratorsClient, ServersClient: &serversClient, ServerExtendedBlobAuditingPoliciesClient: &serverExtendedBlobAuditingPoliciesClient, diff --git a/azurerm/internal/services/mssql/mssql_database_resource.go b/azurerm/internal/services/mssql/mssql_database_resource.go index 1fcb658e07ec..d6befa408137 100644 --- a/azurerm/internal/services/mssql/mssql_database_resource.go +++ b/azurerm/internal/services/mssql/mssql_database_resource.go @@ -67,7 +67,6 @@ func resourceArmMsSqlDatabase() *schema.Resource { ValidateFunc: validate.MsSqlDatabaseAutoPauseDelay, }, - // recovery is not support in version 2017-10-01-preview "create_mode": { Type: schema.TypeString, Optional: true, @@ -79,6 +78,7 @@ func resourceArmMsSqlDatabase() *schema.Resource { string(sql.CreateModeOnlineSecondary), string(sql.CreateModePointInTimeRestore), string(sql.CreateModeRestore), + string(sql.CreateModeRecovery), string(sql.CreateModeRestoreExternalBackup), string(sql.CreateModeRestoreExternalBackupSecondary), string(sql.CreateModeRestoreLongTermRetentionBackup), @@ -134,6 +134,16 @@ func resourceArmMsSqlDatabase() *schema.Resource { ValidateFunc: validation.IsRFC3339Time, }, + "recoverable_database_id": { + Type: schema.TypeString, + Optional: true, + }, + + "restorable_dropped_database_id": { + Type: schema.TypeString, + Optional: true, + }, + "read_replica_count": { Type: schema.TypeInt, Optional: true, @@ -339,9 +349,16 @@ func resourceArmMsSqlDatabaseCreateUpdate(d *schema.ResourceData, meta interface } createMode, ok := d.GetOk("create_mode") - if _, dbok := d.GetOk("creation_source_database_id"); ok && (createMode.(string) == string(sql.CreateModeCopy) || createMode.(string) == string(sql.CreateModePointInTimeRestore) || createMode.(string) == string(sql.CreateModeRestore) || createMode.(string) == string(sql.CreateModeSecondary)) && !dbok { + if _, dbok := d.GetOk("creation_source_database_id"); ok && (createMode.(string) == string(sql.CreateModeCopy) || createMode.(string) == string(sql.CreateModePointInTimeRestore) || createMode.(string) == string(sql.CreateModeSecondary)) && !dbok { return fmt.Errorf("'creation_source_database_id' is required for create_mode %s", createMode.(string)) } + if _, dbok := d.GetOk("recoverable_database_id"); ok && createMode.(string) == string(sql.CreateModeRecovery) && !dbok { + return fmt.Errorf("'recoverable_database_id' is required for create_mode %s", createMode.(string)) + } + if _, dbok := d.GetOk("restorable_dropped_database_id"); ok && createMode.(string) == string(sql.CreateModeRestore) && !dbok { + return fmt.Errorf("'restorable_dropped_database_id' is required for create_mode %s", createMode.(string)) + } + params.DatabaseProperties.CreateMode = sql.CreateMode(createMode.(string)) auditingPolicies := d.Get("extended_auditing_policy").([]interface{}) @@ -377,6 +394,14 @@ func resourceArmMsSqlDatabaseCreateUpdate(d *schema.ResourceData, meta interface params.DatabaseProperties.SourceDatabaseID = utils.String(v.(string)) } + if v, ok := d.GetOk("recoverable_database_id"); ok { + params.DatabaseProperties.RecoverableDatabaseID = utils.String(v.(string)) + } + + if v, ok := d.GetOk("restorable_dropped_database_id"); ok { + params.DatabaseProperties.RestorableDroppedDatabaseID = utils.String(v.(string)) + } + future, err := client.CreateOrUpdate(ctx, serverId.ResourceGroup, serverId.Name, name, params) if err != nil { return fmt.Errorf("creating MsSql Database %q (Sql Server %q / Resource Group %q): %+v", name, serverId.Name, serverId.ResourceGroup, err) diff --git a/azurerm/internal/services/mssql/mssql_server_data_source.go b/azurerm/internal/services/mssql/mssql_server_data_source.go new file mode 100644 index 000000000000..e55d5bc19a53 --- /dev/null +++ b/azurerm/internal/services/mssql/mssql_server_data_source.go @@ -0,0 +1,126 @@ +package mssql + +import ( + "fmt" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/location" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func dataSourceMsSqlServer() *schema.Resource { + return &schema.Resource{ + Read: dataSourceArmMsSqlServerRead, + + Timeouts: &schema.ResourceTimeout{ + Read: schema.DefaultTimeout(5 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), + + "location": azure.SchemaLocationForDataSource(), + + "version": { + Type: schema.TypeString, + Computed: true, + }, + + "administrator_login": { + Type: schema.TypeString, + Computed: true, + }, + + "fully_qualified_domain_name": { + Type: schema.TypeString, + Computed: true, + }, + + "identity": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Computed: true, + }, + "principal_id": { + Type: schema.TypeString, + Computed: true, + }, + "tenant_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + + "restorable_dropped_databases": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "tags": tags.SchemaDataSource(), + }, + } +} + +func dataSourceArmMsSqlServerRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).MSSQL.ServersClient + restorableDroppedDatabasesClient := meta.(*clients.Client).MSSQL.RestorableDroppedDatabasesClient + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + resp, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("sql Server %q was not found in Resource Group %q", name, resourceGroup) + } + + return fmt.Errorf("retrieving Sql Server %q (Resource Group %q): %s", name, resourceGroup, err) + } + + if resp.ID == nil || *resp.ID == "" { + return fmt.Errorf("reading Ms Sql Server %q (Resource Group %q) ID is empty or nil", name, resourceGroup) + } + d.SetId(*resp.ID) + d.Set("location", location.NormalizeNilable(resp.Location)) + + if props := resp.ServerProperties; props != nil { + d.Set("version", props.Version) + d.Set("administrator_login", props.AdministratorLogin) + d.Set("fully_qualified_domain_name", props.FullyQualifiedDomainName) + } + + if err := d.Set("identity", flattenAzureRmSqlServerIdentity(resp.Identity)); err != nil { + return fmt.Errorf("setting `identity`: %+v", err) + } + + restorableResp, err := restorableDroppedDatabasesClient.ListByServer(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("listing SQL Server %s Restorable Dropped Databases: %v", name, err) + } + if err := d.Set("restorable_dropped_databases", flattenAzureRmSqlServerRestorableDatabases(restorableResp)); err != nil { + return fmt.Errorf("setting `restorable_dropped_databases`: %+v", err) + } + + return tags.FlattenAndSet(d, resp.Tags) +} diff --git a/azurerm/internal/services/mssql/mssql_server_resource.go b/azurerm/internal/services/mssql/mssql_server_resource.go index e27645b54c3a..b8b6420aebd6 100644 --- a/azurerm/internal/services/mssql/mssql_server_resource.go +++ b/azurerm/internal/services/mssql/mssql_server_resource.go @@ -150,6 +150,14 @@ func resourceArmMsSqlServer() *schema.Resource { Computed: true, }, + "restorable_dropped_databases": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "tags": tags.Schema(), }, } @@ -281,6 +289,7 @@ func resourceArmMsSqlServerRead(d *schema.ResourceData, meta interface{}) error auditingClient := meta.(*clients.Client).MSSQL.ServerExtendedBlobAuditingPoliciesClient connectionClient := meta.(*clients.Client).MSSQL.ServerConnectionPoliciesClient adminClient := meta.(*clients.Client).MSSQL.ServerAzureADAdministratorsClient + restorableDroppedDatabasesClient := meta.(*clients.Client).MSSQL.RestorableDroppedDatabasesClient ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() @@ -349,6 +358,14 @@ func resourceArmMsSqlServerRead(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error setting `extended_auditing_policy`: %+v", err) } + restorableResp, err := restorableDroppedDatabasesClient.ListByServer(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("listing SQL Server %s Restorable Dropped Databases: %v", name, err) + } + if err := d.Set("restorable_dropped_databases", flattenAzureRmSqlServerRestorableDatabases(restorableResp)); err != nil { + return fmt.Errorf("setting `restorable_dropped_databases`: %+v", err) + } + return tags.FlattenAndSet(d, resp.Tags) } @@ -446,3 +463,18 @@ func flatternAzureRmMsSqlServerAdministrator(admin sql.ServerAzureADAdministrato }, } } + +func flattenAzureRmSqlServerRestorableDatabases(resp sql.RestorableDroppedDatabaseListResult) []string { + if resp.Value == nil || len(*resp.Value) == 0 { + return []string{} + } + res := make([]string, 0) + for _, r := range *resp.Value { + var id string + if r.ID != nil { + id = *r.ID + } + res = append(res, id) + } + return res +} diff --git a/azurerm/internal/services/mssql/registration.go b/azurerm/internal/services/mssql/registration.go index 2de5cc43c579..61a058f341ee 100644 --- a/azurerm/internal/services/mssql/registration.go +++ b/azurerm/internal/services/mssql/registration.go @@ -23,6 +23,7 @@ func (r Registration) SupportedDataSources() map[string]*schema.Resource { return map[string]*schema.Resource{ "azurerm_mssql_database": dataSourceArmMsSqlDatabase(), "azurerm_mssql_elasticpool": dataSourceArmMsSqlElasticpool(), + "azurerm_mssql_server": dataSourceMsSqlServer(), } } diff --git a/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go b/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go index 0dea81c25c4d..fbedca3896c6 100644 --- a/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go +++ b/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go @@ -308,6 +308,46 @@ func TestAccAzureRMMsSqlDatabase_createSecondaryMode(t *testing.T) { }) } +func TestAccAzureRMMsSqlDatabase_createRestoreMode(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_mssql_database", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMMsSqlDatabaseDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMsSqlDatabase_createRestoreMode(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMsSqlDatabaseExists(data.ResourceName), + ), + }, + data.ImportStep("create_mode", "creation_source_database_id"), + + { + PreConfig: func() { time.Sleep(8 * time.Minute) }, + Config: testAccAzureRMMsSqlDatabase_createRestoreModeDBDeleted(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMsSqlDatabaseExists(data.ResourceName), + ), + }, + + data.ImportStep(), + + { + PreConfig: func() { time.Sleep(8 * time.Minute) }, + Config: testAccAzureRMMsSqlDatabase_createRestoreModeDBRestored(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMsSqlDatabaseExists(data.ResourceName), + testCheckAzureRMMsSqlDatabaseExists("azurerm_mssql_database.restore"), + ), + }, + + data.ImportStep("create_mode", "restorable_dropped_database_id"), + }, + }) +} + func TestAccAzureRMMsSqlDatabase_threatDetectionPolicy(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_mssql_database", "test") @@ -781,6 +821,106 @@ resource "azurerm_mssql_database" "secondary" { `, template, data.RandomInteger, data.Locations.Secondary) } +func testAccAzureRMMsSqlDatabase_createRestoreMode(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-mssql-%[1]d" + location = "%[2]s" +} + +resource "azurerm_mssql_server" "test" { + name = "acctest-sqlserver-%[1]d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + version = "12.0" + administrator_login = "mradministrator" + administrator_login_password = "thisIsDog11" +} + + +resource "azurerm_mssql_database" "test" { + name = "acctest-db-%[1]d" + server_id = azurerm_mssql_server.test.id +} + +resource "azurerm_mssql_database" "copy" { + name = "acctest-dbc-%[1]d" + server_id = azurerm_mssql_server.test.id + create_mode = "Copy" + creation_source_database_id = azurerm_mssql_database.test.id +} +`, data.RandomInteger, data.Locations.Primary) +} + +func testAccAzureRMMsSqlDatabase_createRestoreModeDBDeleted(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-mssql-%[1]d" + location = "%[2]s" +} + +resource "azurerm_mssql_server" "test" { + name = "acctest-sqlserver-%[1]d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + version = "12.0" + administrator_login = "mradministrator" + administrator_login_password = "thisIsDog11" +} + + +resource "azurerm_mssql_database" "test" { + name = "acctest-db-%[1]d" + server_id = azurerm_mssql_server.test.id +} + +`, data.RandomInteger, data.Locations.Primary) +} + +func testAccAzureRMMsSqlDatabase_createRestoreModeDBRestored(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-mssql-%[1]d" + location = "%[2]s" +} + +resource "azurerm_mssql_server" "test" { + name = "acctest-sqlserver-%[1]d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + version = "12.0" + administrator_login = "mradministrator" + administrator_login_password = "thisIsDog11" +} + + +resource "azurerm_mssql_database" "test" { + name = "acctest-db-%[1]d" + server_id = azurerm_mssql_server.test.id +} + +resource "azurerm_mssql_database" "restore" { + name = "acctest-dbr-%[1]d" + server_id = azurerm_mssql_server.test.id + create_mode = "Restore" + restorable_dropped_database_id = azurerm_mssql_server.test.restorable_dropped_databases[0] +} + +`, data.RandomInteger, data.Locations.Primary) +} + func testAccAzureRMMsSqlDatabase_threatDetectionPolicy(data acceptance.TestData, state string) string { template := testAccAzureRMMsSqlDatabase_template(data) return fmt.Sprintf(` diff --git a/azurerm/internal/services/mssql/tests/mssql_server_data_source_test.go b/azurerm/internal/services/mssql/tests/mssql_server_data_source_test.go new file mode 100644 index 000000000000..90a983ef4a23 --- /dev/null +++ b/azurerm/internal/services/mssql/tests/mssql_server_data_source_test.go @@ -0,0 +1,75 @@ +package tests + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance" +) + +func TestAccDataSourceAzureRMMsSqlServer_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_mssql_server", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMMsSqlServerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAzureRMMsSqlServer_basic(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMsSqlServerExists(data.ResourceName), + ), + }, + }, + }) +} + +func TestAccDataSourceAzureRMMsSqlServer_complete(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_mssql_server", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMMsSqlServerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAzureRMMsSqlServer_complete(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMsSqlServerExists(data.ResourceName), + resource.TestCheckResourceAttrSet(data.ResourceName, "version"), + resource.TestCheckResourceAttrSet(data.ResourceName, "administrator_login"), + resource.TestCheckResourceAttrSet(data.ResourceName, "fully_qualified_domain_name"), + resource.TestCheckResourceAttrSet(data.ResourceName, "tags.%"), + ), + }, + }, + }) +} + +func testAccDataSourceAzureRMMsSqlServer_basic(data acceptance.TestData) string { + template := testAccAzureRMMsSqlServer_basic(data) + return fmt.Sprintf(` +%s + +data "azurerm_mssql_server" "test" { + name = azurerm_mssql_server.test.name + resource_group_name = azurerm_resource_group.test.name +} + +`, template) +} + +func testAccDataSourceAzureRMMsSqlServer_complete(data acceptance.TestData) string { + template := testAccAzureRMMsSqlServer_complete(data) + return fmt.Sprintf(` +%s + +data "azurerm_mssql_server" "test" { + name = azurerm_mssql_server.test.name + resource_group_name = azurerm_resource_group.test.name +} + +`, template) +} diff --git a/website/azurerm.erb b/website/azurerm.erb index 96724b9ee936..4e24fcc6aca2 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -404,6 +404,10 @@
  • azurerm_mssql_elasticpool
  • + +
  • + azurerm_mssql_server +
  • azurerm_nat_gateway diff --git a/website/docs/d/mssql_server.html.markdown b/website/docs/d/mssql_server.html.markdown new file mode 100644 index 000000000000..d8139bb5386d --- /dev/null +++ b/website/docs/d/mssql_server.html.markdown @@ -0,0 +1,68 @@ +--- +subcategory: "Database" +layout: "azurerm" +page_title: "Azure Resource Manager: Data Source: azurerm_mssql_server" +description: |- + Gets information about an existing Microsoft SQL Server. +--- + +# Data Source: azurerm_mssql_server + +Use this data source to access information about an existing Microsoft SQL Server. + +## Example Usage + +```hcl +data "azurerm_mssql_server" "example" { + name = "existingMsSqlServer" + resource_group_name = "existingResGroup" +} + +output "id" { + value = data.azurerm_mssql_server.example.id +} +``` + +## Arguments Reference + +The following arguments are supported: + +* `name` - (Required) The name of this Microsoft SQL Server. + +* `resource_group_name` - (Required) The name of the Resource Group where the Microsoft SQL Server exists. + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the Microsoft SQL Server. + +* `administrator_login` - The administrator login name for the new server. + +* `fully_qualified_domain_name` - The fully qualified domain name of the Azure SQL Server. + +* `identity` - A `identity` block as defined below. + +* `location` - The Azure Region where the Microsoft SQL Server exists. + +* `restorable_dropped_databases` - A list of restorable database IDs of the server. + +* `tags` - A mapping of tags assigned to the Microsoft SQL Server. + +* `version` - The version for the server. + +--- + +A `identity` block exports the following: + +* `principal_id` - The Principal ID for the Service Principal associated with the Identity of this SQL Server. + +* `tenant_id` - The Tenant ID for the Service Principal associated with the Identity of this SQL Server. + +* `type` - The identity type of the Microsoft SQL Server. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: + +* `read` - (Defaults to 5 minutes) Used when retrieving the Microsoft SQL Server. diff --git a/website/docs/r/mssql_database.html.markdown b/website/docs/r/mssql_database.html.markdown index 760c0842ecd4..86099622647d 100644 --- a/website/docs/r/mssql_database.html.markdown +++ b/website/docs/r/mssql_database.html.markdown @@ -76,7 +76,7 @@ The following arguments are supported: * `auto_pause_delay_in_minutes` - (Optional) Time in minutes after which database is automatically paused. A value of `-1` means that automatic pause is disabled. This property is only settable for General Purpose Serverless databases. -* `create_mode` - (Optional) The create mode of the database. Possible values are `Copy`, `Default`, `OnlineSecondary`, `PointInTimeRestore`, `Restore`, `RestoreExternalBackup`, `RestoreExternalBackupSecondary`, `RestoreLongTermRetentionBackup` and `Secondary`. +* `create_mode` - (Optional) The create mode of the database. Possible values are `Copy`, `Default`, `OnlineSecondary`, `PointInTimeRestore`, `Recovery`, `Restore`, `RestoreExternalBackup`, `RestoreExternalBackupSecondary`, `RestoreLongTermRetentionBackup` and `Secondary`. * `creation_source_database_id` - (Optional) The id of the source database to be referred to create the new database. This should only be used for databases with `create_mode` values that use another database as reference. Changing this forces a new resource to be created. @@ -94,6 +94,10 @@ The following arguments are supported: * `restore_point_in_time` - (Required) Specifies the point in time (ISO8601 format) of the source database that will be restored to create the new database. This property is only settable for `create_mode`= `PointInTimeRestore` databases. +* `recoverable_database_id` - (Optional) The ID of the database to be recoveried. This property is only settable and required when `create_mode`=`Recovery`. + +* `restorable_dropped_database_id` - (Optional) The ID of the database to be restored. This property is only settable and required when `create_mode`=`Restore`. + * `read_replica_count` - (Optional) The number of readonly secondary replicas associated with the database to which readonly application intent connections may be routed. This property is only settable for Hyperscale edition databases. * `read_scale` - (Optional) If enabled, connections that have application intent set to readonly in their connection string may be routed to a readonly secondary replica. This property is only settable for Premium and Business Critical databases. diff --git a/website/docs/r/mssql_server.html.markdown b/website/docs/r/mssql_server.html.markdown index 8480c70b996f..28334c6c4f03 100644 --- a/website/docs/r/mssql_server.html.markdown +++ b/website/docs/r/mssql_server.html.markdown @@ -1,7 +1,7 @@ --- subcategory: "Database" layout: "azurerm" -page_title: "Azure Resource Manager: azurerm_sql_server" +page_title: "Azure Resource Manager: azurerm_mssql_server" description: |- Manages a Microsoft SQL Azure Database Server. @@ -99,6 +99,8 @@ The following attributes are exported: * `fully_qualified_domain_name` - The fully qualified domain name of the Azure SQL Server (e.g. myServerName.database.windows.net) +* `restorable_dropped_databases` - A list of restorable database IDs of the server. + --- `identity` exports the following: From 69e5c1c141ada8c267e34b58a3b23b4f5f49ad0a Mon Sep 17 00:00:00 2001 From: yupwei68 Date: Mon, 14 Sep 2020 11:49:06 +0800 Subject: [PATCH 02/11] r1 --- website/docs/d/mssql_server.html.markdown | 6 +++--- website/docs/r/mssql_server.html.markdown | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/website/docs/d/mssql_server.html.markdown b/website/docs/d/mssql_server.html.markdown index d8139bb5386d..a20d1b083dff 100644 --- a/website/docs/d/mssql_server.html.markdown +++ b/website/docs/d/mssql_server.html.markdown @@ -45,11 +45,11 @@ In addition to the Arguments listed above - the following Attributes are exporte * `location` - The Azure Region where the Microsoft SQL Server exists. -* `restorable_dropped_databases` - A list of restorable database IDs of the server. +* `restorable_dropped_databases` - A list of dropped restorable database IDs on the server. -* `tags` - A mapping of tags assigned to the Microsoft SQL Server. +* `tags` - A mapping of tags assigned to this Microsoft SQL Server. -* `version` - The version for the server. +* `version` - This servers MS SQL version. --- diff --git a/website/docs/r/mssql_server.html.markdown b/website/docs/r/mssql_server.html.markdown index 28334c6c4f03..a82da0a3ee78 100644 --- a/website/docs/r/mssql_server.html.markdown +++ b/website/docs/r/mssql_server.html.markdown @@ -65,9 +65,9 @@ The following arguments are supported: * `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. -* `version` - (Required) The version for the new server. Valid values are: 2.0 (for v11 server) and 12.0 (for v12 server). +* `version` - (Required) This servers MS SQL version. Valid values are: 2.0 (for v11 server) and 12.0 (for v12 server). -* `administrator_login` - (Required) The administrator login name for the new server. Changing this forces a new resource to be created. +* `administrator_login` - (Required) The administrator's login name for the new server. Changing this forces a new resource to be created. * `administrator_login_password` - (Required) The password associated with the `administrator_login` user. Needs to comply with Azure's [Password Policy](https://msdn.microsoft.com/library/ms161959.aspx) @@ -99,7 +99,7 @@ The following attributes are exported: * `fully_qualified_domain_name` - The fully qualified domain name of the Azure SQL Server (e.g. myServerName.database.windows.net) -* `restorable_dropped_databases` - A list of restorable database IDs of the server. +* `restorable_dropped_databases` - A list of dropped restorable database IDs on the server. --- From a0b0eaf6bb3fcaa1663719c26441d6f385016e77 Mon Sep 17 00:00:00 2001 From: yupwei68 Date: Tue, 15 Sep 2020 09:38:11 +0800 Subject: [PATCH 03/11] r2 --- .../internal/services/mssql/mssql_database_resource.go | 8 ++++---- .../internal/services/mssql/mssql_server_data_source.go | 6 +++--- azurerm/internal/services/mssql/mssql_server_resource.go | 6 +++--- .../services/mssql/tests/mssql_database_resource_test.go | 2 +- website/docs/d/mssql_server.html.markdown | 2 +- website/docs/r/mssql_database.html.markdown | 2 +- website/docs/r/mssql_server.html.markdown | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/azurerm/internal/services/mssql/mssql_database_resource.go b/azurerm/internal/services/mssql/mssql_database_resource.go index d6befa408137..5ea73b278d0d 100644 --- a/azurerm/internal/services/mssql/mssql_database_resource.go +++ b/azurerm/internal/services/mssql/mssql_database_resource.go @@ -134,7 +134,7 @@ func resourceArmMsSqlDatabase() *schema.Resource { ValidateFunc: validation.IsRFC3339Time, }, - "recoverable_database_id": { + "recover_database_id": { Type: schema.TypeString, Optional: true, }, @@ -352,8 +352,8 @@ func resourceArmMsSqlDatabaseCreateUpdate(d *schema.ResourceData, meta interface if _, dbok := d.GetOk("creation_source_database_id"); ok && (createMode.(string) == string(sql.CreateModeCopy) || createMode.(string) == string(sql.CreateModePointInTimeRestore) || createMode.(string) == string(sql.CreateModeSecondary)) && !dbok { return fmt.Errorf("'creation_source_database_id' is required for create_mode %s", createMode.(string)) } - if _, dbok := d.GetOk("recoverable_database_id"); ok && createMode.(string) == string(sql.CreateModeRecovery) && !dbok { - return fmt.Errorf("'recoverable_database_id' is required for create_mode %s", createMode.(string)) + if _, dbok := d.GetOk("recover_database_id"); ok && createMode.(string) == string(sql.CreateModeRecovery) && !dbok { + return fmt.Errorf("'recover_database_id' is required for create_mode %s", createMode.(string)) } if _, dbok := d.GetOk("restorable_dropped_database_id"); ok && createMode.(string) == string(sql.CreateModeRestore) && !dbok { return fmt.Errorf("'restorable_dropped_database_id' is required for create_mode %s", createMode.(string)) @@ -394,7 +394,7 @@ func resourceArmMsSqlDatabaseCreateUpdate(d *schema.ResourceData, meta interface params.DatabaseProperties.SourceDatabaseID = utils.String(v.(string)) } - if v, ok := d.GetOk("recoverable_database_id"); ok { + if v, ok := d.GetOk("recover_database_id"); ok { params.DatabaseProperties.RecoverableDatabaseID = utils.String(v.(string)) } diff --git a/azurerm/internal/services/mssql/mssql_server_data_source.go b/azurerm/internal/services/mssql/mssql_server_data_source.go index e55d5bc19a53..6331e3d57cb5 100644 --- a/azurerm/internal/services/mssql/mssql_server_data_source.go +++ b/azurerm/internal/services/mssql/mssql_server_data_source.go @@ -67,7 +67,7 @@ func dataSourceMsSqlServer() *schema.Resource { }, }, - "restorable_dropped_databases": { + "restore_dropped_database_id": { Type: schema.TypeList, Computed: true, Elem: &schema.Schema{ @@ -118,8 +118,8 @@ func dataSourceArmMsSqlServerRead(d *schema.ResourceData, meta interface{}) erro if err != nil { return fmt.Errorf("listing SQL Server %s Restorable Dropped Databases: %v", name, err) } - if err := d.Set("restorable_dropped_databases", flattenAzureRmSqlServerRestorableDatabases(restorableResp)); err != nil { - return fmt.Errorf("setting `restorable_dropped_databases`: %+v", err) + if err := d.Set("restore_dropped_database_id", flattenAzureRmSqlServerRestorableDatabases(restorableResp)); err != nil { + return fmt.Errorf("setting `restore_dropped_database_id`: %+v", err) } return tags.FlattenAndSet(d, resp.Tags) diff --git a/azurerm/internal/services/mssql/mssql_server_resource.go b/azurerm/internal/services/mssql/mssql_server_resource.go index b8b6420aebd6..16791722fc8f 100644 --- a/azurerm/internal/services/mssql/mssql_server_resource.go +++ b/azurerm/internal/services/mssql/mssql_server_resource.go @@ -150,7 +150,7 @@ func resourceArmMsSqlServer() *schema.Resource { Computed: true, }, - "restorable_dropped_databases": { + "restore_dropped_database_id": { Type: schema.TypeList, Computed: true, Elem: &schema.Schema{ @@ -362,8 +362,8 @@ func resourceArmMsSqlServerRead(d *schema.ResourceData, meta interface{}) error if err != nil { return fmt.Errorf("listing SQL Server %s Restorable Dropped Databases: %v", name, err) } - if err := d.Set("restorable_dropped_databases", flattenAzureRmSqlServerRestorableDatabases(restorableResp)); err != nil { - return fmt.Errorf("setting `restorable_dropped_databases`: %+v", err) + if err := d.Set("restore_dropped_database_id", flattenAzureRmSqlServerRestorableDatabases(restorableResp)); err != nil { + return fmt.Errorf("setting `restore_dropped_database_id`: %+v", err) } return tags.FlattenAndSet(d, resp.Tags) diff --git a/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go b/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go index fbedca3896c6..5f30ac1ce560 100644 --- a/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go +++ b/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go @@ -915,7 +915,7 @@ resource "azurerm_mssql_database" "restore" { name = "acctest-dbr-%[1]d" server_id = azurerm_mssql_server.test.id create_mode = "Restore" - restorable_dropped_database_id = azurerm_mssql_server.test.restorable_dropped_databases[0] + restorable_dropped_database_id = azurerm_mssql_server.test.restore_dropped_database_id[0] } `, data.RandomInteger, data.Locations.Primary) diff --git a/website/docs/d/mssql_server.html.markdown b/website/docs/d/mssql_server.html.markdown index a20d1b083dff..d05699207ead 100644 --- a/website/docs/d/mssql_server.html.markdown +++ b/website/docs/d/mssql_server.html.markdown @@ -45,7 +45,7 @@ In addition to the Arguments listed above - the following Attributes are exporte * `location` - The Azure Region where the Microsoft SQL Server exists. -* `restorable_dropped_databases` - A list of dropped restorable database IDs on the server. +* `restore_dropped_database_id` - A list of dropped restorable database IDs on the server. * `tags` - A mapping of tags assigned to this Microsoft SQL Server. diff --git a/website/docs/r/mssql_database.html.markdown b/website/docs/r/mssql_database.html.markdown index 86099622647d..50e3bc0c3b61 100644 --- a/website/docs/r/mssql_database.html.markdown +++ b/website/docs/r/mssql_database.html.markdown @@ -94,7 +94,7 @@ The following arguments are supported: * `restore_point_in_time` - (Required) Specifies the point in time (ISO8601 format) of the source database that will be restored to create the new database. This property is only settable for `create_mode`= `PointInTimeRestore` databases. -* `recoverable_database_id` - (Optional) The ID of the database to be recoveried. This property is only settable and required when `create_mode`=`Recovery`. +* `recover_database_id` - (Optional) The ID of the database to be recoveried. This property is only settable and required when `create_mode`=`Recovery`. * `restorable_dropped_database_id` - (Optional) The ID of the database to be restored. This property is only settable and required when `create_mode`=`Restore`. diff --git a/website/docs/r/mssql_server.html.markdown b/website/docs/r/mssql_server.html.markdown index a82da0a3ee78..2a578f664e7b 100644 --- a/website/docs/r/mssql_server.html.markdown +++ b/website/docs/r/mssql_server.html.markdown @@ -99,7 +99,7 @@ The following attributes are exported: * `fully_qualified_domain_name` - The fully qualified domain name of the Azure SQL Server (e.g. myServerName.database.windows.net) -* `restorable_dropped_databases` - A list of dropped restorable database IDs on the server. +* `restore_dropped_database_id` - A list of dropped restorable database IDs on the server. --- From 5dc57d7fb0b50ce5ab4294b1ed0301140273e0c7 Mon Sep 17 00:00:00 2001 From: yupwei68 Date: Wed, 16 Sep 2020 13:22:30 +0800 Subject: [PATCH 04/11] update --- .../internal/services/mssql/mssql_database_resource.go | 8 ++++---- .../services/mssql/tests/mssql_database_resource_test.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/azurerm/internal/services/mssql/mssql_database_resource.go b/azurerm/internal/services/mssql/mssql_database_resource.go index 5ea73b278d0d..56a858dd3116 100644 --- a/azurerm/internal/services/mssql/mssql_database_resource.go +++ b/azurerm/internal/services/mssql/mssql_database_resource.go @@ -139,7 +139,7 @@ func resourceArmMsSqlDatabase() *schema.Resource { Optional: true, }, - "restorable_dropped_database_id": { + "restore_dropped_database_id": { Type: schema.TypeString, Optional: true, }, @@ -355,8 +355,8 @@ func resourceArmMsSqlDatabaseCreateUpdate(d *schema.ResourceData, meta interface if _, dbok := d.GetOk("recover_database_id"); ok && createMode.(string) == string(sql.CreateModeRecovery) && !dbok { return fmt.Errorf("'recover_database_id' is required for create_mode %s", createMode.(string)) } - if _, dbok := d.GetOk("restorable_dropped_database_id"); ok && createMode.(string) == string(sql.CreateModeRestore) && !dbok { - return fmt.Errorf("'restorable_dropped_database_id' is required for create_mode %s", createMode.(string)) + if _, dbok := d.GetOk("restore_dropped_database_id"); ok && createMode.(string) == string(sql.CreateModeRestore) && !dbok { + return fmt.Errorf("'restore_dropped_database_id' is required for create_mode %s", createMode.(string)) } params.DatabaseProperties.CreateMode = sql.CreateMode(createMode.(string)) @@ -398,7 +398,7 @@ func resourceArmMsSqlDatabaseCreateUpdate(d *schema.ResourceData, meta interface params.DatabaseProperties.RecoverableDatabaseID = utils.String(v.(string)) } - if v, ok := d.GetOk("restorable_dropped_database_id"); ok { + if v, ok := d.GetOk("restore_dropped_database_id"); ok { params.DatabaseProperties.RestorableDroppedDatabaseID = utils.String(v.(string)) } diff --git a/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go b/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go index 5f30ac1ce560..b83570a4cfe7 100644 --- a/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go +++ b/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go @@ -343,7 +343,7 @@ func TestAccAzureRMMsSqlDatabase_createRestoreMode(t *testing.T) { ), }, - data.ImportStep("create_mode", "restorable_dropped_database_id"), + data.ImportStep("create_mode", "restore_dropped_database_id"), }, }) } @@ -915,7 +915,7 @@ resource "azurerm_mssql_database" "restore" { name = "acctest-dbr-%[1]d" server_id = azurerm_mssql_server.test.id create_mode = "Restore" - restorable_dropped_database_id = azurerm_mssql_server.test.restore_dropped_database_id[0] + restore_dropped_database_id = azurerm_mssql_server.test.restore_dropped_database_id[0] } `, data.RandomInteger, data.Locations.Primary) From 3f75f423f4f5823590cb15ee8be325a5d5364666 Mon Sep 17 00:00:00 2001 From: yupwei68 Date: Wed, 16 Sep 2020 13:32:18 +0800 Subject: [PATCH 05/11] cmt --- website/docs/r/mssql_database.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/mssql_database.html.markdown b/website/docs/r/mssql_database.html.markdown index 50e3bc0c3b61..80860318381d 100644 --- a/website/docs/r/mssql_database.html.markdown +++ b/website/docs/r/mssql_database.html.markdown @@ -96,7 +96,7 @@ The following arguments are supported: * `recover_database_id` - (Optional) The ID of the database to be recoveried. This property is only settable and required when `create_mode`=`Recovery`. -* `restorable_dropped_database_id` - (Optional) The ID of the database to be restored. This property is only settable and required when `create_mode`=`Restore`. +* `restore_dropped_database_id` - (Optional) The ID of the database to be restored. This property is only settable and required when `create_mode`=`Restore`. * `read_replica_count` - (Optional) The number of readonly secondary replicas associated with the database to which readonly application intent connections may be routed. This property is only settable for Hyperscale edition databases. From 1040d98b5c895c3e3f38c96d75416dc9807f212d Mon Sep 17 00:00:00 2001 From: yupwei68 Date: Wed, 16 Sep 2020 13:39:25 +0800 Subject: [PATCH 06/11] update --- website/docs/d/mssql_server.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/d/mssql_server.html.markdown b/website/docs/d/mssql_server.html.markdown index d05699207ead..9e3b656b199d 100644 --- a/website/docs/d/mssql_server.html.markdown +++ b/website/docs/d/mssql_server.html.markdown @@ -37,7 +37,7 @@ In addition to the Arguments listed above - the following Attributes are exporte * `id` - The ID of the Microsoft SQL Server. -* `administrator_login` - The administrator login name for the new server. +* `administrator_login` - The administrator's login name for the new server. * `fully_qualified_domain_name` - The fully qualified domain name of the Azure SQL Server. From f8520739f1cb09c9eb7cdd10f1bfb16d96fdcb1c Mon Sep 17 00:00:00 2001 From: yupwei68 Date: Wed, 16 Sep 2020 14:58:25 +0800 Subject: [PATCH 07/11] update --- .../services/mssql/tests/mssql_database_resource_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go b/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go index b83570a4cfe7..242d70dc36ab 100644 --- a/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go +++ b/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go @@ -912,9 +912,9 @@ resource "azurerm_mssql_database" "test" { } resource "azurerm_mssql_database" "restore" { - name = "acctest-dbr-%[1]d" - server_id = azurerm_mssql_server.test.id - create_mode = "Restore" + name = "acctest-dbr-%[1]d" + server_id = azurerm_mssql_server.test.id + create_mode = "Restore" restore_dropped_database_id = azurerm_mssql_server.test.restore_dropped_database_id[0] } From 0807b537cdf09bf06bdd195082fb4d808eeb3c31 Mon Sep 17 00:00:00 2001 From: yupwei68 Date: Fri, 18 Sep 2020 16:21:51 +0800 Subject: [PATCH 08/11] r3 --- .../services/mssql/mssql_database_resource.go | 10 +- .../internal/services/mssql/parse/mssql.go | 72 +++++++ .../services/mssql/parse/mssql_test.go | 176 ++++++++++++++++++ .../services/mssql/validate/mssql_database.go | 28 +++ 4 files changed, 282 insertions(+), 4 deletions(-) diff --git a/azurerm/internal/services/mssql/mssql_database_resource.go b/azurerm/internal/services/mssql/mssql_database_resource.go index d6befa408137..135626e23cb3 100644 --- a/azurerm/internal/services/mssql/mssql_database_resource.go +++ b/azurerm/internal/services/mssql/mssql_database_resource.go @@ -135,13 +135,15 @@ func resourceArmMsSqlDatabase() *schema.Resource { }, "recoverable_database_id": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.MsSqlRecoverableDatabaseID, }, "restorable_dropped_database_id": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.MsSqlRestorableDatabaseID, }, "read_replica_count": { diff --git a/azurerm/internal/services/mssql/parse/mssql.go b/azurerm/internal/services/mssql/parse/mssql.go index 70e8e20c17fa..23411e5e247e 100644 --- a/azurerm/internal/services/mssql/parse/mssql.go +++ b/azurerm/internal/services/mssql/parse/mssql.go @@ -2,6 +2,7 @@ package parse import ( "fmt" + "strings" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" ) @@ -23,6 +24,19 @@ type MsSqlElasticPoolId struct { ResourceGroup string } +type MsSqlRestorableDBId struct { + Name string + MsSqlServer string + ResourceGroup string + RestoreName string +} + +type MsSqlRecoverableDBId struct { + Name string + MsSqlServer string + ResourceGroup string +} + func MsSqlDatabaseID(input string) (*MsSqlDatabaseId, error) { id, err := azure.ParseAzureResourceID(input) if err != nil { @@ -119,3 +133,61 @@ func MssqlVmID(input string) (*MssqlVmId, error) { return &sqlvm, nil } + +func MssqlRestorableDBID(input string) (*MsSqlRestorableDBId, error) { + inputList := strings.Split(input, ",") + + if len(inputList) != 2 { + return nil, fmt.Errorf("[ERROR] Unable to parse Microsoft Sql Restorable DB ID %q, please refer to XX", input) + } + + restorableDBId := MsSqlRestorableDBId{ + RestoreName: inputList[1], + } + + id, err := azure.ParseAzureResourceID(inputList[0]) + if err != nil { + return nil, fmt.Errorf("[ERROR] Unable to parse Microsoft Sql Restorable DB ID %q: %+v", input, err) + } + + restorableDBId.ResourceGroup = id.ResourceGroup + + if restorableDBId.MsSqlServer, err = id.PopSegment("servers"); err != nil { + return nil, err + } + + if restorableDBId.Name, err = id.PopSegment("restorableDroppedDatabases"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(inputList[0]); err != nil { + return nil, err + } + + return &restorableDBId, nil +} + +func MssqlRecoverableDBID(input string) (*MsSqlRecoverableDBId, error) { + id, err := azure.ParseAzureResourceID(input) + if err != nil { + return nil, fmt.Errorf("[ERROR] Unable to parse Microsoft Sql Recoverable DB ID %q: %+v", input, err) + } + + recoverableDBId := MsSqlRecoverableDBId{ + ResourceGroup: id.ResourceGroup, + } + + if recoverableDBId.MsSqlServer, err = id.PopSegment("servers"); err != nil { + return nil, err + } + + if recoverableDBId.Name, err = id.PopSegment("recoverabledatabases"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &recoverableDBId, nil +} diff --git a/azurerm/internal/services/mssql/parse/mssql_test.go b/azurerm/internal/services/mssql/parse/mssql_test.go index 2dd56719b3a3..4e214935ed4c 100644 --- a/azurerm/internal/services/mssql/parse/mssql_test.go +++ b/azurerm/internal/services/mssql/parse/mssql_test.go @@ -222,3 +222,179 @@ func TestMsSqlVmID(t *testing.T) { } } } + +func TestMsSqlRestoreDBID(t *testing.T) { + testData := []struct { + Name string + Input string + Expected *MsSqlRestorableDBId + }{ + { + Name: "Empty", + Input: "", + Expected: nil, + }, + { + Name: "No Restore Name", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000", + Expected: nil, + }, + { + Name: "No Resource Groups Segment", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000,000000000000000000", + Expected: nil, + }, + { + Name: "No Resource Groups Value", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/,000000000000000000", + Expected: nil, + }, + { + Name: "Resource Group ID", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/,000000000000000000", + Expected: nil, + }, + { + Name: "Missing Sql Server Value", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Sql/servers/,000000000000000000", + Expected: nil, + }, + { + Name: "Missing Sql Restorable Database", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Sql/servers/sqlServer1,000000000000000000", + Expected: nil, + }, + { + Name: "Missing Sql Restorable Database Value", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Sql/servers/sqlServer1/restorableDroppedDatabases,000000000000000000", + Expected: nil, + }, + { + Name: "Sql Restorable Database ID", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Sql/servers/sqlServer1/restorableDroppedDatabases/sqlDB1,000000000000000000", + Expected: &MsSqlRestorableDBId{ + Name: "sqlDB1", + MsSqlServer: "sqlServer1", + ResourceGroup: "resGroup1", + RestoreName: "000000000000000000", + }, + }, + { + Name: "Wrong Casing", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Sql/servers/sqlServer1/RestorableDroppedDatabases/sqlDB1,000000000000000000", + Expected: nil, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Name) + + actual, err := MssqlRestorableDBID(v.Input) + if err != nil { + if v.Expected == nil { + continue + } + + t.Fatalf("Expected a value but got an error: %s", err) + } + + if actual.RestoreName != v.Expected.RestoreName { + t.Fatalf("Expected %q but got %q for Restore Name", v.Expected.Name, actual.Name) + } + + if actual.Name != v.Expected.Name { + t.Fatalf("Expected %q but got %q for Name", v.Expected.Name, actual.Name) + } + + if actual.MsSqlServer != v.Expected.MsSqlServer { + t.Fatalf("Expected %q but got %q for Sql Server", 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) + } + } +} + +func TestMssqlRecoverableDBID(t *testing.T) { + testData := []struct { + Name string + Input string + Expected *MsSqlRecoverableDBId + }{ + { + 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 Sql Server Value", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Sql/servers/", + Expected: nil, + }, + { + Name: "Missing Sql Recoverable Database", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Sql/servers/sqlServer1", + Expected: nil, + }, + { + Name: "Missing Sql Recoverable Database Value", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Sql/servers/sqlServer1/recoverabledatabases", + Expected: nil, + }, + { + Name: "Sql Database ID", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Sql/servers/sqlServer1/recoverabledatabases/sqlDB1", + Expected: &MsSqlRecoverableDBId{ + Name: "sqlDB1", + MsSqlServer: "sqlServer1", + ResourceGroup: "resGroup1", + }, + }, + { + Name: "Wrong Casing", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Sql/servers/sqlServer1/Recoverabledatabases/sqlDB1", + Expected: nil, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Name) + + actual, err := MssqlRecoverableDBID(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.MsSqlServer != v.Expected.MsSqlServer { + t.Fatalf("Expected %q but got %q for Sql Server", 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/mssql/validate/mssql_database.go b/azurerm/internal/services/mssql/validate/mssql_database.go index bf643b9bf6bb..cd23a035a9c2 100644 --- a/azurerm/internal/services/mssql/validate/mssql_database.go +++ b/azurerm/internal/services/mssql/validate/mssql_database.go @@ -54,3 +54,31 @@ func MsSqlDBCollation() schema.SchemaValidateFunc { `This is not a valid collation.`, ) } + +func MsSqlRestorableDatabaseID(i interface{}, k string) (warnings []string, errors []error) { + v, ok := i.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected type of %q to be string", k)) + return warnings, errors + } + + if _, err := parse.MssqlRestorableDBID(v); err != nil { + errors = append(errors, fmt.Errorf("Can not parse %q as a MsSql Restorable Database resource id: %v", k, err)) + } + + return warnings, errors +} + +func MsSqlRecoverableDatabaseID(i interface{}, k string) (warnings []string, errors []error) { + v, ok := i.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected type of %q to be string", k)) + return warnings, errors + } + + if _, err := parse.MssqlRecoverableDBID(v); err != nil { + errors = append(errors, fmt.Errorf("Can not parse %q as a MsSql Recoverable Database resource id: %v", k, err)) + } + + return warnings, errors +} From c7698f57b451b6f24b0a91c0f3c597e3a298d855 Mon Sep 17 00:00:00 2001 From: yupwei68 Date: Mon, 21 Sep 2020 09:55:43 +0800 Subject: [PATCH 09/11] r3 --- .../services/mssql/mssql_database_resource.go | 16 ++++++++-------- .../services/mssql/mssql_server_resource.go | 6 +++--- .../mssql/tests/mssql_database_resource_test.go | 10 +++++----- website/docs/d/mssql_server.html.markdown | 4 ++-- website/docs/r/mssql_database.html.markdown | 4 ++-- website/docs/r/mssql_server.html.markdown | 2 +- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/azurerm/internal/services/mssql/mssql_database_resource.go b/azurerm/internal/services/mssql/mssql_database_resource.go index 135626e23cb3..5c8767e2e572 100644 --- a/azurerm/internal/services/mssql/mssql_database_resource.go +++ b/azurerm/internal/services/mssql/mssql_database_resource.go @@ -134,13 +134,13 @@ func resourceArmMsSqlDatabase() *schema.Resource { ValidateFunc: validation.IsRFC3339Time, }, - "recoverable_database_id": { + "recover_database_id": { Type: schema.TypeString, Optional: true, ValidateFunc: validate.MsSqlRecoverableDatabaseID, }, - "restorable_dropped_database_id": { + "restore_dropped_database_id": { Type: schema.TypeString, Optional: true, ValidateFunc: validate.MsSqlRestorableDatabaseID, @@ -354,11 +354,11 @@ func resourceArmMsSqlDatabaseCreateUpdate(d *schema.ResourceData, meta interface if _, dbok := d.GetOk("creation_source_database_id"); ok && (createMode.(string) == string(sql.CreateModeCopy) || createMode.(string) == string(sql.CreateModePointInTimeRestore) || createMode.(string) == string(sql.CreateModeSecondary)) && !dbok { return fmt.Errorf("'creation_source_database_id' is required for create_mode %s", createMode.(string)) } - if _, dbok := d.GetOk("recoverable_database_id"); ok && createMode.(string) == string(sql.CreateModeRecovery) && !dbok { - return fmt.Errorf("'recoverable_database_id' is required for create_mode %s", createMode.(string)) + if _, dbok := d.GetOk("recover_database_id"); ok && createMode.(string) == string(sql.CreateModeRecovery) && !dbok { + return fmt.Errorf("'recover_database_id' is required for create_mode %s", createMode.(string)) } - if _, dbok := d.GetOk("restorable_dropped_database_id"); ok && createMode.(string) == string(sql.CreateModeRestore) && !dbok { - return fmt.Errorf("'restorable_dropped_database_id' is required for create_mode %s", createMode.(string)) + if _, dbok := d.GetOk("restore_dropped_database_id"); ok && createMode.(string) == string(sql.CreateModeRestore) && !dbok { + return fmt.Errorf("'restore_dropped_database_id' is required for create_mode %s", createMode.(string)) } params.DatabaseProperties.CreateMode = sql.CreateMode(createMode.(string)) @@ -396,11 +396,11 @@ func resourceArmMsSqlDatabaseCreateUpdate(d *schema.ResourceData, meta interface params.DatabaseProperties.SourceDatabaseID = utils.String(v.(string)) } - if v, ok := d.GetOk("recoverable_database_id"); ok { + if v, ok := d.GetOk("recover_database_id"); ok { params.DatabaseProperties.RecoverableDatabaseID = utils.String(v.(string)) } - if v, ok := d.GetOk("restorable_dropped_database_id"); ok { + if v, ok := d.GetOk("restore_dropped_database_id"); ok { params.DatabaseProperties.RestorableDroppedDatabaseID = utils.String(v.(string)) } diff --git a/azurerm/internal/services/mssql/mssql_server_resource.go b/azurerm/internal/services/mssql/mssql_server_resource.go index 272e149e2ece..b612a04ed949 100644 --- a/azurerm/internal/services/mssql/mssql_server_resource.go +++ b/azurerm/internal/services/mssql/mssql_server_resource.go @@ -150,7 +150,7 @@ func resourceArmMsSqlServer() *schema.Resource { Computed: true, }, - "restorable_dropped_database_id": { + "restorable_dropped_database_ids": { Type: schema.TypeList, Computed: true, Elem: &schema.Schema{ @@ -362,8 +362,8 @@ func resourceArmMsSqlServerRead(d *schema.ResourceData, meta interface{}) error if err != nil { return fmt.Errorf("listing SQL Server %s Restorable Dropped Databases: %v", name, err) } - if err := d.Set("restorable_dropped_database_id", flattenAzureRmSqlServerRestorableDatabases(restorableResp)); err != nil { - return fmt.Errorf("setting `restorable_dropped_database_id`: %+v", err) + if err := d.Set("restorable_dropped_database_ids", flattenAzureRmSqlServerRestorableDatabases(restorableResp)); err != nil { + return fmt.Errorf("setting `restorable_dropped_database_ids`: %+v", err) } return tags.FlattenAndSet(d, resp.Tags) diff --git a/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go b/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go index ef090f3386f6..242d70dc36ab 100644 --- a/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go +++ b/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go @@ -343,7 +343,7 @@ func TestAccAzureRMMsSqlDatabase_createRestoreMode(t *testing.T) { ), }, - data.ImportStep("create_mode", "restorable_dropped_database_id"), + data.ImportStep("create_mode", "restore_dropped_database_id"), }, }) } @@ -912,10 +912,10 @@ resource "azurerm_mssql_database" "test" { } resource "azurerm_mssql_database" "restore" { - name = "acctest-dbr-%[1]d" - server_id = azurerm_mssql_server.test.id - create_mode = "Restore" - restorable_dropped_database_id = azurerm_mssql_server.test.restorable_dropped_database_id[0] + name = "acctest-dbr-%[1]d" + server_id = azurerm_mssql_server.test.id + create_mode = "Restore" + restore_dropped_database_id = azurerm_mssql_server.test.restore_dropped_database_id[0] } `, data.RandomInteger, data.Locations.Primary) diff --git a/website/docs/d/mssql_server.html.markdown b/website/docs/d/mssql_server.html.markdown index d4a93faa2597..bcab06b0c49b 100644 --- a/website/docs/d/mssql_server.html.markdown +++ b/website/docs/d/mssql_server.html.markdown @@ -37,7 +37,7 @@ In addition to the Arguments listed above - the following Attributes are exporte * `id` - The ID of the Microsoft SQL Server. -* `administrator_login` - The administrator's login name for the new server. +* `administrator_login` - The server's administrator login name. * `fully_qualified_domain_name` - The fully qualified domain name of the Azure SQL Server. @@ -45,7 +45,7 @@ In addition to the Arguments listed above - the following Attributes are exporte * `location` - The Azure Region where the Microsoft SQL Server exists. -* `restorable_dropped_database_id` - A list of dropped restorable database IDs on the server. +* `restorable_dropped_database_ids` - A list of dropped restorable database IDs on the server. * `tags` - A mapping of tags assigned to this Microsoft SQL Server. diff --git a/website/docs/r/mssql_database.html.markdown b/website/docs/r/mssql_database.html.markdown index 86099622647d..5bb57bbe249f 100644 --- a/website/docs/r/mssql_database.html.markdown +++ b/website/docs/r/mssql_database.html.markdown @@ -94,9 +94,9 @@ The following arguments are supported: * `restore_point_in_time` - (Required) Specifies the point in time (ISO8601 format) of the source database that will be restored to create the new database. This property is only settable for `create_mode`= `PointInTimeRestore` databases. -* `recoverable_database_id` - (Optional) The ID of the database to be recoveried. This property is only settable and required when `create_mode`=`Recovery`. +* `recover_database_id` - (Optional) The ID of the database to be recovered. This property is only applicable when the `create_mode` is `Recovery`. -* `restorable_dropped_database_id` - (Optional) The ID of the database to be restored. This property is only settable and required when `create_mode`=`Restore`. +* `restore_dropped_database_id` - (Optional) The ID of the database to be restored. This property is only applicable when the `create_mode` is `Restore`. * `read_replica_count` - (Optional) The number of readonly secondary replicas associated with the database to which readonly application intent connections may be routed. This property is only settable for Hyperscale edition databases. diff --git a/website/docs/r/mssql_server.html.markdown b/website/docs/r/mssql_server.html.markdown index e4ef6e3d733d..2bafa7b8a038 100644 --- a/website/docs/r/mssql_server.html.markdown +++ b/website/docs/r/mssql_server.html.markdown @@ -99,7 +99,7 @@ The following attributes are exported: * `fully_qualified_domain_name` - The fully qualified domain name of the Azure SQL Server (e.g. myServerName.database.windows.net) -* `restorable_dropped_database_id` - A list of dropped restorable database IDs on the server. +* `restorable_dropped_database_ids` - A list of dropped restorable database IDs on the server. --- From 3decdb2cc51a0d8e32c9d0b41a94984b5a1e5966 Mon Sep 17 00:00:00 2001 From: yupwei68 Date: Mon, 21 Sep 2020 10:03:36 +0800 Subject: [PATCH 10/11] update --- azurerm/internal/services/mssql/mssql_server_data_source.go | 6 +++--- azurerm/internal/services/mssql/parse/mssql.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/azurerm/internal/services/mssql/mssql_server_data_source.go b/azurerm/internal/services/mssql/mssql_server_data_source.go index 3f46b00b99f8..46678e0273ab 100644 --- a/azurerm/internal/services/mssql/mssql_server_data_source.go +++ b/azurerm/internal/services/mssql/mssql_server_data_source.go @@ -67,7 +67,7 @@ func dataSourceMsSqlServer() *schema.Resource { }, }, - "restorable_dropped_database_id": { + "restorable_dropped_database_ids": { Type: schema.TypeList, Computed: true, Elem: &schema.Schema{ @@ -118,8 +118,8 @@ func dataSourceArmMsSqlServerRead(d *schema.ResourceData, meta interface{}) erro if err != nil { return fmt.Errorf("listing SQL Server %s Restorable Dropped Databases: %v", name, err) } - if err := d.Set("restorable_dropped_database_id", flattenAzureRmSqlServerRestorableDatabases(restorableResp)); err != nil { - return fmt.Errorf("setting `restorable_dropped_database_id`: %+v", err) + if err := d.Set("restorable_dropped_database_ids", flattenAzureRmSqlServerRestorableDatabases(restorableResp)); err != nil { + return fmt.Errorf("setting `restorable_dropped_database_ids`: %+v", err) } return tags.FlattenAndSet(d, resp.Tags) diff --git a/azurerm/internal/services/mssql/parse/mssql.go b/azurerm/internal/services/mssql/parse/mssql.go index 9db4a8808a8b..fe715f64a2ae 100644 --- a/azurerm/internal/services/mssql/parse/mssql.go +++ b/azurerm/internal/services/mssql/parse/mssql.go @@ -215,7 +215,7 @@ func MssqlRestorableDBID(input string) (*MsSqlRestorableDBId, error) { inputList := strings.Split(input, ",") if len(inputList) != 2 { - return nil, fmt.Errorf("[ERROR] Unable to parse Microsoft Sql Restorable DB ID %q, please refer to XX", input) + return nil, fmt.Errorf("[ERROR] Unable to parse Microsoft Sql Restorable DB ID %q, please refer to '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Sql/servers/sqlServer1/restorableDroppedDatabases/sqlDB1,000000000000000000'", input) } restorableDBId := MsSqlRestorableDBId{ From 746ffa9bd57d253ad511e388303b664bd91d6667 Mon Sep 17 00:00:00 2001 From: yupwei68 Date: Mon, 21 Sep 2020 11:41:18 +0800 Subject: [PATCH 11/11] update --- .../services/mssql/tests/mssql_database_resource_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go b/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go index 30f86a4252b2..dc6667d6efb0 100644 --- a/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go +++ b/azurerm/internal/services/mssql/tests/mssql_database_resource_test.go @@ -915,7 +915,7 @@ resource "azurerm_mssql_database" "restore" { name = "acctest-dbr-%[1]d" server_id = azurerm_mssql_server.test.id create_mode = "Restore" - restore_dropped_database_id = azurerm_mssql_server.test.restore_dropped_database_id[0] + restore_dropped_database_id = azurerm_mssql_server.test.restorable_dropped_database_ids[0] } `, data.RandomInteger, data.Locations.Primary)