Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

azurerm_mssql_server and azurerm_mssql_database - upgrade from v5.0/sql to 2023-02-01-preview #23721

Merged
merged 56 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from 55 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
f3a1560
Initial Check-in...
WodansSon Oct 28, 2023
67d3d6a
Adding AAD clients...
WodansSon Oct 28, 2023
7f7d80f
Adding restorableDroppedDatabasesClient....
WodansSon Oct 28, 2023
0bc8f6c
Check-in progress...
WodansSon Oct 29, 2023
6adf29b
Checking-in progrss...
WodansSon Oct 29, 2023
50beff6
Update internal clients...
WodansSon Oct 30, 2023
48e721c
Fix tags...
WodansSon Oct 31, 2023
34941b2
Fix azuread_administrator update logic...
WodansSon Oct 31, 2023
800ce59
fix go lang error msg capitalization violations...
WodansSon Oct 31, 2023
e67614f
Remove superfluous subscriptionId declarations...
WodansSon Oct 31, 2023
5501102
Fix linting error...
WodansSon Oct 31, 2023
5b3be66
Adding 2023-02-01-preview/databases...
WodansSon Nov 2, 2023
8a5be7b
adding /2023-02-01-preview/replicationlinks...
WodansSon Nov 2, 2023
afbec78
Mod vendor...
WodansSon Nov 2, 2023
ac4e7e6
Fix database data source...
WodansSon Nov 3, 2023
9e3d25b
Update tags helper function name from FlattenTags to ExpandFromPointe…
WodansSon Nov 3, 2023
7331842
Fix database Exists function...
WodansSon Nov 3, 2023
e0af006
Fix extended auditing policy resource...
WodansSon Nov 3, 2023
13ebfb9
Update err logic for Read for extended auditing policy...
WodansSon Nov 3, 2023
24b0139
Adding serversecurityalertpolicies...
WodansSon Nov 3, 2023
cd12276
Adding transparentdataencryptions...
WodansSon Nov 3, 2023
a37fa1c
Adding geobackuppolicies...
WodansSon Nov 3, 2023
bab6b57
Adding databasesecurityalertpolicies...
WodansSon Nov 4, 2023
61f552e
Merge branch 'main' into e_sql_upgrade_deux
WodansSon Nov 4, 2023
29761c1
Adding long term and short term policies...
WodansSon Nov 4, 2023
e8df8cf
Add longtermpolicies...
WodansSon Nov 4, 2023
ae4c76c
Database fixed, now three more popped up...
WodansSon Nov 4, 2023
5b9d4bd
Remove reference to v5.0/sql from database...
WodansSon Nov 4, 2023
586b7a7
Use API helper function for connection policy...
WodansSon Nov 5, 2023
e6d302c
Expose legacy client...
WodansSon Nov 5, 2023
c239009
Fix lint issues...
WodansSon Nov 5, 2023
06775aa
Go mod vendor...
WodansSon Nov 5, 2023
47089e5
Cast int to Int64...
WodansSon Nov 6, 2023
f9cd346
Fix Read function...
WodansSon Nov 6, 2023
2aa5c5e
More updates to Read function...
WodansSon Nov 6, 2023
f4dc7cc
Fix lint error...
WodansSon Nov 6, 2023
a9311a0
Fix int to int64 cast in helper...
WodansSon Nov 6, 2023
b6a6643
Merge branch 'main' of https://github.com/hashicorp/terraform-provide…
WodansSon Nov 6, 2023
cc95403
Go mod tidy and vendor...
WodansSon Nov 6, 2023
7ab0fd3
Address most of the PR comments...
WodansSon Nov 7, 2023
f5ac348
Update FindDatabaseReplicationPartners logic...
WodansSon Nov 7, 2023
53f8078
Fix lint error...
WodansSon Nov 7, 2023
208816f
Fix handling of tags and remove helper funcs...
WodansSon Nov 7, 2023
f90b954
Progress on PR comments...
WodansSon Nov 8, 2023
68aa7f1
Address the last of the PR comments...
WodansSon Nov 8, 2023
799f70d
Unify text for x-ref comment...
WodansSon Nov 8, 2023
2a2e9f7
Update documentation Attributes Reference...
WodansSon Nov 8, 2023
b53005b
Fixed FindDatabaseReplicationPartners for new API
WodansSon Nov 9, 2023
1400bba
Fix Elastic Pool read...
WodansSon Nov 9, 2023
aafc1a0
Fix MinCapacity and TDE for new API...
WodansSon Nov 9, 2023
56f0ae7
Update to match old behaviors so tests will pass
WodansSon Nov 10, 2023
7866c4c
Address most of the new PR comments...
WodansSon Nov 15, 2023
c66ed82
Address the remaining PR comments...
WodansSon Nov 16, 2023
04967b0
Add test case to validate CMK tag updates...
WodansSon Nov 16, 2023
f8e71eb
Revert FindDatabaseReplicationPartners to use Resources API...
WodansSon Nov 18, 2023
3369ae1
Address the last two PR comments...
WodansSon Nov 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 132 additions & 73 deletions internal/services/mssql/client/client.go

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package custompollers

import (
"context"
"fmt"
"strings"
"time"

"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
"github.com/hashicorp/go-azure-sdk/resource-manager/sql/2023-02-01-preview/serverazureadonlyauthentications"
"github.com/hashicorp/go-azure-sdk/sdk/client/pollers"
)

var _ pollers.PollerType = &MsSqlServerDeleteServerAzureADOnlyAuthenticationPoller{}

func NewMsSqlServerDeleteServerAzureADOnlyAuthenticationPoller(client *serverazureadonlyauthentications.ServerAzureADOnlyAuthenticationsClient, serverId commonids.SqlServerId) *MsSqlServerDeleteServerAzureADOnlyAuthenticationPoller {
return &MsSqlServerDeleteServerAzureADOnlyAuthenticationPoller{
client: client,
serverId: serverId,
}
}

type MsSqlServerDeleteServerAzureADOnlyAuthenticationPoller struct {
client *serverazureadonlyauthentications.ServerAzureADOnlyAuthenticationsClient
serverId commonids.SqlServerId
}

func (p *MsSqlServerDeleteServerAzureADOnlyAuthenticationPoller) Poll(ctx context.Context) (*pollers.PollResult, error) {
resp, err := p.client.Get(ctx, p.serverId)
if err != nil {
return nil, fmt.Errorf("retrieving %s: %+v", p.serverId, err)
}

if resp.Model == nil {
return nil, fmt.Errorf("retrieving %s: `model` was nil", p.serverId)
}

name := pointer.From(resp.Model.Name)
azureAdOnlyAuthentication := true
if props := resp.Model.Properties; props != nil {
azureAdOnlyAuthentication = props.AzureADOnlyAuthentication
}

if !azureAdOnlyAuthentication && strings.EqualFold(name, "Default") {
return &pollers.PollResult{
Status: pollers.PollingStatusSucceeded,
PollInterval: 5 * time.Second,
}, nil
}

return &pollers.PollResult{
Status: pollers.PollingStatusInProgress,
PollInterval: 5 * time.Second,
}, nil
}
6 changes: 3 additions & 3 deletions internal/services/mssql/helper/elasticpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,14 +269,14 @@ func MSSQLElasticPoolValidateSKU(diff *pluginsdk.ResourceDiff) error {

// Universal check for both DTU and vCore based SKUs
if !nameTierIsValid(s) {
return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be '%s'", s.Name, s.Tier, getTierFromName[strings.ToLower(s.Name)])
return fmt.Errorf("mismatch between SKU name '%s' and tier '%s', expected 'tier' to be '%s'", s.Name, s.Tier, getTierFromName[strings.ToLower(s.Name)])
}

// Verify that Family is valid
if s.SkuType == DTU && s.Family != "" {
return fmt.Errorf("Invalid attribute 'family'(%s) for service tier '%s', remove the 'family' attribute from the configuration file", s.Family, s.Tier)
return fmt.Errorf("invalid attribute 'family'(%s) for service tier '%s', remove the 'family' attribute from the configuration file", s.Family, s.Tier)
} else if s.SkuType == VCore && !nameContainsFamily(s) {
return fmt.Errorf("Mismatch between SKU name '%s' and family '%s', expected '%s'", s.Name, s.Family, getFamilyFromName(s))
return fmt.Errorf("mismatch between SKU name '%s' and family '%s', expected '%s'", s.Name, s.Family, getFamilyFromName(s))
}

// get max GB and do validation based on SKU type
Expand Down
97 changes: 50 additions & 47 deletions internal/services/mssql/helper/sql_retention_policies.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import (
"strconv"
"strings"

"github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/v5.0/sql" // nolint: staticcheck
"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-sdk/resource-manager/sql/2023-02-01-preview/backupshorttermretentionpolicies"
"github.com/hashicorp/go-azure-sdk/resource-manager/sql/2023-02-01-preview/longtermretentionpolicies"
"github.com/hashicorp/terraform-provider-azurerm/helpers/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

func LongTermRetentionPolicySchema() *pluginsdk.Schema {
Expand Down Expand Up @@ -98,62 +99,62 @@ func ShortTermRetentionPolicySchema() *pluginsdk.Schema {
}
}

func ExpandLongTermRetentionPolicy(input []interface{}) *sql.BaseLongTermRetentionPolicyProperties {
func ExpandLongTermRetentionPolicy(input []interface{}) *longtermretentionpolicies.LongTermRetentionPolicyProperties {
if len(input) == 0 || input[0] == nil {
return nil
}

longTermRetentionPolicy := input[0].(map[string]interface{})
policy := input[0].(map[string]interface{})

longTermPolicyProperties := sql.BaseLongTermRetentionPolicyProperties{
WeeklyRetention: utils.String("PT0S"),
MonthlyRetention: utils.String("PT0S"),
YearlyRetention: utils.String("PT0S"),
WeekOfYear: utils.Int32(1),
output := longtermretentionpolicies.LongTermRetentionPolicyProperties{
WeeklyRetention: pointer.To("PT0S"),
MonthlyRetention: pointer.To("PT0S"),
YearlyRetention: pointer.To("PT0S"),
WeekOfYear: pointer.To(int64(1)),
}

if v, ok := longTermRetentionPolicy["weekly_retention"]; ok {
longTermPolicyProperties.WeeklyRetention = utils.String(v.(string))
if v, ok := policy["weekly_retention"]; ok {
output.WeeklyRetention = pointer.To(v.(string))
}

if v, ok := longTermRetentionPolicy["monthly_retention"]; ok {
longTermPolicyProperties.MonthlyRetention = utils.String(v.(string))
if v, ok := policy["monthly_retention"]; ok {
output.MonthlyRetention = pointer.To(v.(string))
}

if v, ok := longTermRetentionPolicy["yearly_retention"]; ok {
longTermPolicyProperties.YearlyRetention = utils.String(v.(string))
if v, ok := policy["yearly_retention"]; ok {
output.YearlyRetention = pointer.To(v.(string))
}

if v, ok := longTermRetentionPolicy["week_of_year"]; ok {
longTermPolicyProperties.WeekOfYear = utils.Int32(int32(v.(int)))
if v, ok := policy["week_of_year"]; ok {
output.WeekOfYear = pointer.To(int64(v.(int)))
}

return &longTermPolicyProperties
return pointer.To(output)
}

func FlattenLongTermRetentionPolicy(longTermRetentionPolicy *sql.LongTermRetentionPolicy, d *pluginsdk.ResourceData) []interface{} {
if longTermRetentionPolicy == nil {
func FlattenLongTermRetentionPolicy(input *longtermretentionpolicies.LongTermRetentionPolicy) []interface{} {
if input == nil {
return []interface{}{}
}

monthlyRetention := "PT0S"
if longTermRetentionPolicy.MonthlyRetention != nil {
monthlyRetention = *longTermRetentionPolicy.MonthlyRetention
if input.Properties.MonthlyRetention != nil {
monthlyRetention = pointer.From(input.Properties.MonthlyRetention)
}

weeklyRetention := "PT0S"
if longTermRetentionPolicy.WeeklyRetention != nil {
weeklyRetention = *longTermRetentionPolicy.WeeklyRetention
if input.Properties.WeeklyRetention != nil {
weeklyRetention = pointer.From(input.Properties.WeeklyRetention)
}

weekOfYear := int32(1)
if longTermRetentionPolicy.WeekOfYear != nil && *longTermRetentionPolicy.WeekOfYear != 0 {
weekOfYear = *longTermRetentionPolicy.WeekOfYear
weekOfYear := int64(1)
if input.Properties.WeekOfYear != nil && pointer.From(input.Properties.WeekOfYear) != 0 {
weekOfYear = pointer.From(input.Properties.WeekOfYear)
}

yearlyRetention := "PT0S"
if longTermRetentionPolicy.YearlyRetention != nil {
yearlyRetention = *longTermRetentionPolicy.YearlyRetention
if input.Properties.YearlyRetention != nil {
yearlyRetention = *input.Properties.YearlyRetention
}

return []interface{}{
Expand All @@ -166,45 +167,47 @@ func FlattenLongTermRetentionPolicy(longTermRetentionPolicy *sql.LongTermRetenti
}
}

func ExpandShortTermRetentionPolicy(input []interface{}) *sql.BackupShortTermRetentionPolicyProperties {
func ExpandShortTermRetentionPolicy(input []interface{}) *backupshorttermretentionpolicies.BackupShortTermRetentionPolicyProperties {
if len(input) == 0 || input[0] == nil {
return nil
}

shortTermRetentionPolicy := input[0].(map[string]interface{})
policy := input[0].(map[string]interface{})

shortTermPolicyProperties := sql.BackupShortTermRetentionPolicyProperties{
RetentionDays: utils.Int32(7),
props := backupshorttermretentionpolicies.BackupShortTermRetentionPolicyProperties{
RetentionDays: pointer.To(int64(7)),
}

if v, ok := shortTermRetentionPolicy["retention_days"]; ok {
shortTermPolicyProperties.RetentionDays = utils.Int32(int32(v.(int)))
if v, ok := policy["retention_days"]; ok {
props.RetentionDays = pointer.To(int64(v.(int)))
}

if v, ok := shortTermRetentionPolicy["backup_interval_in_hours"]; ok {
shortTermPolicyProperties.DiffBackupIntervalInHours = utils.Int32(int32(v.(int)))
if v, ok := policy["backup_interval_in_hours"]; ok {
props.DiffBackupIntervalInHours = pointer.To(backupshorttermretentionpolicies.DiffBackupIntervalInHours(int64(v.(int))))
}

return &shortTermPolicyProperties
return &props
}

func FlattenShortTermRetentionPolicy(shortTermRetentionPolicy *sql.BackupShortTermRetentionPolicy, d *pluginsdk.ResourceData) []interface{} {
func FlattenShortTermRetentionPolicy(input *backupshorttermretentionpolicies.BackupShortTermRetentionPolicy) []interface{} {
result := make([]interface{}, 0)

if shortTermRetentionPolicy == nil {
if input == nil {
return result
}

flattenShortTermRetentionPolicy := map[string]interface{}{}
output := map[string]interface{}{}

flattenShortTermRetentionPolicy["retention_days"] = int32(7)
if shortTermRetentionPolicy.RetentionDays != nil {
flattenShortTermRetentionPolicy["retention_days"] = *shortTermRetentionPolicy.RetentionDays
output["retention_days"] = int64(7)
if input.Properties.RetentionDays != nil {
output["retention_days"] = pointer.From(input.Properties.RetentionDays)
}

if shortTermRetentionPolicy.DiffBackupIntervalInHours != nil {
flattenShortTermRetentionPolicy["backup_interval_in_hours"] = *shortTermRetentionPolicy.DiffBackupIntervalInHours
if input.Properties.DiffBackupIntervalInHours != nil {
output["backup_interval_in_hours"] = pointer.From(input.Properties.DiffBackupIntervalInHours)
}
result = append(result, flattenShortTermRetentionPolicy)

result = append(result, output)

return result
}
71 changes: 45 additions & 26 deletions internal/services/mssql/mssql_database_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ import (
"fmt"
"time"

"github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/v5.0/sql" // nolint: staticcheck
"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema"
"github.com/hashicorp/go-azure-helpers/resourcemanager/tags"
"github.com/hashicorp/go-azure-sdk/resource-manager/sql/2023-02-01-preview/databases"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/mssql/parse"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/mssql/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/tags"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/timeouts"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

func dataSourceMsSqlDatabase() *pluginsdk.Resource {
Expand Down Expand Up @@ -83,7 +85,7 @@ func dataSourceMsSqlDatabase() *pluginsdk.Resource {
Computed: true,
},

"tags": tags.SchemaDataSource(),
"tags": commonschema.TagsDataSource(),
},
}
}
Expand All @@ -95,41 +97,58 @@ func dataSourceMsSqlDatabaseRead(d *pluginsdk.ResourceData, meta interface{}) er

name := d.Get("name").(string)
mssqlServerId := d.Get("server_id").(string)
serverId, err := parse.ServerID(mssqlServerId)
serverId, err := commonids.ParseSqlServerID(mssqlServerId)
if err != nil {
return err
}

resp, err := client.Get(ctx, serverId.ResourceGroup, serverId.Name, name)
databaseId := commonids.NewSqlDatabaseID(serverId.SubscriptionId, serverId.ResourceGroupName, serverId.ServerName, name)

resp, err := client.Get(ctx, databaseId, databases.DefaultGetOperationOptions())
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("Database %q (Resource Group %q, SQL Server %q) was not found", name, serverId.ResourceGroup, serverId.Name)
if response.WasNotFound(resp.HttpResponse) {
return fmt.Errorf("%s was not found", databaseId)
}

return fmt.Errorf("making Read request on AzureRM Database %s (Resource Group %q, SQL Server %q): %+v", name, serverId.ResourceGroup, serverId.Name, err)
return fmt.Errorf("making Read request on AzureRM %s: %+v", databaseId, err)
}

d.SetId(parse.NewDatabaseID(serverId.SubscriptionId, serverId.ResourceGroup, serverId.Name, name).ID())
d.SetId(databaseId.ID())
d.Set("name", name)
d.Set("server_id", mssqlServerId)

if props := resp.DatabaseProperties; props != nil {
d.Set("collation", props.Collation)
d.Set("elastic_pool_id", props.ElasticPoolID)
d.Set("license_type", props.LicenseType)
if props.MaxSizeBytes != nil {
d.Set("max_size_gb", int32((*props.MaxSizeBytes)/int64(1073741824)))
if model := resp.Model; model != nil {
if props := model.Properties; props != nil {
d.Set("collation", props.Collation)
d.Set("elastic_pool_id", props.ElasticPoolId)
d.Set("license_type", string(pointer.From(props.LicenseType)))
d.Set("read_replica_count", props.HighAvailabilityReplicaCount)
d.Set("sku_name", props.CurrentServiceObjectiveName)
d.Set("zone_redundant", props.ZoneRedundant)

maxSizeGb := int64(0)
if props.MaxSizeBytes != nil {
maxSizeGb = (pointer.From(props.MaxSizeBytes)) / int64(1073741824)
}
d.Set("max_size_gb", maxSizeGb)

readScale := databases.DatabaseReadScaleDisabled
if props.ReadScale != nil {
readScale = pointer.From(props.ReadScale)
}
d.Set("read_scale", readScale == databases.DatabaseReadScaleEnabled)

storageAccountType := string(databases.BackupStorageRedundancyGeo)
if props.CurrentBackupStorageRedundancy != nil {
storageAccountType = string(pointer.From(props.CurrentBackupStorageRedundancy))
}
d.Set("storage_account_type", storageAccountType)
}
d.Set("read_replica_count", props.HighAvailabilityReplicaCount)
if props.ReadScale == sql.DatabaseReadScaleEnabled {
d.Set("read_scale", true)
} else if props.ReadScale == sql.DatabaseReadScaleDisabled {
d.Set("read_scale", false)

if err := tags.FlattenAndSet(d, model.Tags); err != nil {
return err
}
d.Set("sku_name", props.CurrentServiceObjectiveName)
d.Set("storage_account_type", sql.RequestedBackupStorageRedundancy(props.CurrentBackupStorageRedundancy))
d.Set("zone_redundant", props.ZoneRedundant)
}

return tags.FlattenAndSet(d, resp.Tags)
return nil
}
Loading
Loading