Skip to content

Commit

Permalink
azurerm_mssql_managed_instance - add support for `maintenance_confi…
Browse files Browse the repository at this point in the history
…guration_name` (#16832)

* add support for maintenance config

* use id.SubscriptionId
  • Loading branch information
catriona-m authored May 18, 2022
1 parent 42701a2 commit 5d49be5
Show file tree
Hide file tree
Showing 8 changed files with 349 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package parse

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"fmt"
"strings"

"github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids"
)

type PublicMaintenanceConfigurationId struct {
SubscriptionId string
Name string
}

func NewPublicMaintenanceConfigurationID(subscriptionId, name string) PublicMaintenanceConfigurationId {
return PublicMaintenanceConfigurationId{
SubscriptionId: subscriptionId,
Name: name,
}
}

func (id PublicMaintenanceConfigurationId) String() string {
segments := []string{
fmt.Sprintf("Name %q", id.Name),
}
segmentsStr := strings.Join(segments, " / ")
return fmt.Sprintf("%s: (%s)", "Public Maintenance Configuration", segmentsStr)
}

func (id PublicMaintenanceConfigurationId) ID() string {
fmtString := "/subscriptions/%s/providers/Microsoft.Maintenance/publicMaintenanceConfigurations/%s"
return fmt.Sprintf(fmtString, id.SubscriptionId, id.Name)
}

// PublicMaintenanceConfigurationID parses a PublicMaintenanceConfiguration ID into an PublicMaintenanceConfigurationId struct
func PublicMaintenanceConfigurationID(input string) (*PublicMaintenanceConfigurationId, error) {
id, err := resourceids.ParseAzureResourceID(input)
if err != nil {
return nil, err
}

resourceId := PublicMaintenanceConfigurationId{
SubscriptionId: id.SubscriptionID,
}

if resourceId.SubscriptionId == "" {
return nil, fmt.Errorf("ID was missing the 'subscriptions' element")
}

if resourceId.Name, err = id.PopSegment("publicMaintenanceConfigurations"); err != nil {
return nil, err
}

if err := id.ValidateNoEmptySegments(input); err != nil {
return nil, err
}

return &resourceId, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package parse

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"testing"

"github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids"
)

var _ resourceids.Id = PublicMaintenanceConfigurationId{}

func TestPublicMaintenanceConfigurationIDFormatter(t *testing.T) {
actual := NewPublicMaintenanceConfigurationID("12345678-1234-9876-4563-123456789012", "publicMaintenanceConfiguration1").ID()
expected := "/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.Maintenance/publicMaintenanceConfigurations/publicMaintenanceConfiguration1"
if actual != expected {
t.Fatalf("Expected %q but got %q", expected, actual)
}
}

func TestPublicMaintenanceConfigurationID(t *testing.T) {
testData := []struct {
Input string
Error bool
Expected *PublicMaintenanceConfigurationId
}{

{
// empty
Input: "",
Error: true,
},

{
// missing SubscriptionId
Input: "/",
Error: true,
},

{
// missing value for SubscriptionId
Input: "/subscriptions/",
Error: true,
},

{
// missing Name
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.Maintenance/",
Error: true,
},

{
// missing value for Name
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.Maintenance/publicMaintenanceConfigurations/",
Error: true,
},

{
// valid
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.Maintenance/publicMaintenanceConfigurations/publicMaintenanceConfiguration1",
Expected: &PublicMaintenanceConfigurationId{
SubscriptionId: "12345678-1234-9876-4563-123456789012",
Name: "publicMaintenanceConfiguration1",
},
},

{
// upper-cased
Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/PROVIDERS/MICROSOFT.MAINTENANCE/PUBLICMAINTENANCECONFIGURATIONS/PUBLICMAINTENANCECONFIGURATION1",
Error: true,
},
}

for _, v := range testData {
t.Logf("[DEBUG] Testing %q", v.Input)

actual, err := PublicMaintenanceConfigurationID(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.Name != v.Expected.Name {
t.Fatalf("Expected %q but got %q for Name", v.Expected.Name, actual.Name)
}
}
}
1 change: 1 addition & 0 deletions internal/services/maintenance/resourceids.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
package maintenance

//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=MaintenanceConfiguration -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Maintenance/maintenanceConfigurations/maintenanceConfiguration1 -rewrite=true
//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=PublicMaintenanceConfiguration -id=/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.Maintenance/publicMaintenanceConfigurations/publicMaintenanceConfiguration1
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package validate

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"fmt"

"github.com/hashicorp/terraform-provider-azurerm/internal/services/maintenance/parse"
)

func PublicMaintenanceConfigurationID(input interface{}, key string) (warnings []string, errors []error) {
v, ok := input.(string)
if !ok {
errors = append(errors, fmt.Errorf("expected %q to be a string", key))
return
}

if _, err := parse.PublicMaintenanceConfigurationID(v); err != nil {
errors = append(errors, err)
}

return
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package validate

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import "testing"

func TestPublicMaintenanceConfigurationID(t *testing.T) {
cases := []struct {
Input string
Valid bool
}{

{
// empty
Input: "",
Valid: false,
},

{
// missing SubscriptionId
Input: "/",
Valid: false,
},

{
// missing value for SubscriptionId
Input: "/subscriptions/",
Valid: false,
},

{
// missing Name
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.Maintenance/",
Valid: false,
},

{
// missing value for Name
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.Maintenance/publicMaintenanceConfigurations/",
Valid: false,
},

{
// valid
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.Maintenance/publicMaintenanceConfigurations/publicMaintenanceConfiguration1",
Valid: true,
},

{
// upper-cased
Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/PROVIDERS/MICROSOFT.MAINTENANCE/PUBLICMAINTENANCECONFIGURATIONS/PUBLICMAINTENANCECONFIGURATION1",
Valid: false,
},
}
for _, tc := range cases {
t.Logf("[DEBUG] Testing Value %s", tc.Input)
_, errors := PublicMaintenanceConfigurationID(tc.Input, "test")
valid := len(errors) == 0

if tc.Valid != valid {
t.Fatalf("Expected %t but got %t", tc.Valid, valid)
}
}
}
74 changes: 54 additions & 20 deletions internal/services/mssql/mssql_managed_instance_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-azurerm/helpers/azure"
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
maintenanceParse "github.com/hashicorp/terraform-provider-azurerm/internal/services/maintenance/parse"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/mssql/validate"
networkValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/sql/parse"
Expand All @@ -24,26 +25,27 @@ import (
)

type MsSqlManagedInstanceModel struct {
AdministratorLogin string `tfschema:"administrator_login"`
AdministratorLoginPassword string `tfschema:"administrator_login_password"`
Collation string `tfschema:"collation"`
DnsZonePartnerId string `tfschema:"dns_zone_partner_id"`
Fqdn string `tfschema:"fqdn"`
Identity []identity.SystemAssigned `tfschema:"identity"`
LicenseType string `tfschema:"license_type"`
Location string `tfschema:"location"`
MinimumTlsVersion string `tfschema:"minimum_tls_version"`
Name string `tfschema:"name"`
ProxyOverride string `tfschema:"proxy_override"`
PublicDataEndpointEnabled bool `tfschema:"public_data_endpoint_enabled"`
ResourceGroupName string `tfschema:"resource_group_name"`
SkuName string `tfschema:"sku_name"`
StorageAccountType string `tfschema:"storage_account_type"`
StorageSizeInGb int `tfschema:"storage_size_in_gb"`
SubnetId string `tfschema:"subnet_id"`
Tags map[string]string `tfschema:"tags"`
TimezoneId string `tfschema:"timezone_id"`
VCores int `tfschema:"vcores"`
AdministratorLogin string `tfschema:"administrator_login"`
AdministratorLoginPassword string `tfschema:"administrator_login_password"`
Collation string `tfschema:"collation"`
DnsZonePartnerId string `tfschema:"dns_zone_partner_id"`
Fqdn string `tfschema:"fqdn"`
Identity []identity.SystemAssigned `tfschema:"identity"`
LicenseType string `tfschema:"license_type"`
Location string `tfschema:"location"`
MaintenanceConfigurationName string `tfschema:"maintenance_configuration_name"`
MinimumTlsVersion string `tfschema:"minimum_tls_version"`
Name string `tfschema:"name"`
ProxyOverride string `tfschema:"proxy_override"`
PublicDataEndpointEnabled bool `tfschema:"public_data_endpoint_enabled"`
ResourceGroupName string `tfschema:"resource_group_name"`
SkuName string `tfschema:"sku_name"`
StorageAccountType string `tfschema:"storage_account_type"`
StorageSizeInGb int `tfschema:"storage_size_in_gb"`
SubnetId string `tfschema:"subnet_id"`
Tags map[string]string `tfschema:"tags"`
TimezoneId string `tfschema:"timezone_id"`
VCores int `tfschema:"vcores"`
}

var _ sdk.Resource = MsSqlManagedInstanceResource{}
Expand Down Expand Up @@ -159,6 +161,23 @@ func (r MsSqlManagedInstanceResource) Arguments() map[string]*pluginsdk.Schema {

"identity": commonschema.SystemAssignedIdentityOptional(),

"maintenance_configuration_name": {
Type: schema.TypeString,
Optional: true,
Default: "SQL_Default",
ValidateFunc: validation.StringInSlice([]string{"SQL_Default", "SQL_EastUS_MI_1", "SQL_EastUS2_MI_1", "SQL_WestUS2_MI_1", "SQL_SoutheastAsia_MI_1", "SQL_AustraliaEast_MI_1", "SQL_NorthEurope_MI_1", "SQL_SouthCentralUS_MI_1",
"SQL_UKSouth_MI_1", "SQL_WestEurope_MI_1", "SQL_EastUS_MI_2", "SQL_EastUS2_MI_2", "SQL_WestUS2_MI_2", "SQL_SoutheastAsia_MI_2", "SQL_NorthEurope_MI_2", "SQL_SouthCentralUS_MI_2",
"SQL_UKSouth_MI_2", "SQL_WestEurope_MI_2", "SQL_AustraliaSoutheast_MI_1", "SQL_BrazilSouth_MI_1", "SQL_CanadaCentral_MI_1", "SQL_CanadaEast_MI_1", "SQL_CentralUS_MI_1", "SQL_EastAsia_MI_1",
"SQL_FranceCentral_MI_1", "SQL_GermanyWestCentral_MI_1", "SQL_CentralIndia_MI_1", "SQL_JapanEast_MI_1", "SQL_JapanWest_MI_1", "SQL_NorthCentralUS_MI_1", "SQL_UKWest_MI_1", "SQL_WestUS_MI_1",
"SQL_AustraliaSoutheast_MI_2", "SQL_BrazilSouth_MI_2", "SQL_CanadaCentral_MI_2", "SQL_CanadaEast_MI_2", "SQL_CentralUS_MI_2", "SQL_EastAsia_MI_2", "SQL_FranceCentral_MI_2", "SQL_GermanyWestCentral_MI_2",
"SQL_CentralIndia_MI_2", "SQL_JapanEast_MI_2", "SQL_JapanWest_MI_2", "SQL_NorthCentralUS_MI_2", "SQL_UKWest_MI_2", "SQL_WestUS_MI_2", "SQL_KoreaCentral_MI_1", "SQL_KoreaCentral_MI_2",
"SQL_WestCentralUS_MI_1", "SQL_WestCentralUS_MI_2", "SQL_UAENorth_MI_1", "SQL_SwitzerlandWest_MI_1", "SQL_SwitzerlandNorth_MI_1", "SQL_UAENorth_MI_2", "SQL_SwitzerlandWest_MI_2",
"SQL_SwitzerlandNorth_MI_2", "SQL_FranceSouth_MI_1", "SQL_FranceSouth_MI_2", "SQL_SouthAfricaNorth_MI_1", "SQL_KoreaSouth_MI_1", "SQL_UAECentral_MI_1", "SQL_SouthAfricaNorth_MI_2",
"SQL_KoreaSouth_MI_2", "SQL_UAECentral_MI_2", "SQL_SouthIndia_MI_1", "SQL_SouthIndia_MI_2", "SQL_AustraliaCentral_MI_1", "SQL_AustraliaCentral2_MI_1", "SQL_AustraliaCentral_MI_2",
"SQL_AustraliaCentral2_MI_2", "SQL_WestIndia_MI_1", "SQL_WestIndia_MI_2", "SQL_SouthAfricaWest_MI_1", "SQL_SouthAfricaWest_MI_2", "SQL_GermanyNorth_MI_1", "SQL_GermanyNorth_MI_2", "SQL_NorwayEast_MI_1",
"SQL_BrazilSoutheast_MI_1", "SQL_NorwayWest_MI_1", "SQL_WestUS3_MI_1", "SQL_NorwayEast_MI_2", "SQL_BrazilSoutheast_MI_2", "SQL_NorwayWest_MI_2", "SQL_WestUS3_MI_2"}, false),
},

"minimum_tls_version": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -274,6 +293,8 @@ func (r MsSqlManagedInstanceResource) Create() sdk.ResourceFunc {
return fmt.Errorf("expanding `sku_name` for SQL Managed Instance Server %q: %v", id.ID(), err)
}

maintenanceConfigId := maintenanceParse.NewPublicMaintenanceConfigurationID(subscriptionId, model.MaintenanceConfigurationName)

parameters := sql.ManagedInstance{
Sku: sku,
Identity: r.expandIdentity(model.Identity),
Expand All @@ -284,6 +305,7 @@ func (r MsSqlManagedInstanceResource) Create() sdk.ResourceFunc {
Collation: utils.String(model.Collation),
DNSZonePartner: utils.String(model.DnsZonePartnerId),
LicenseType: sql.ManagedInstanceLicenseType(model.LicenseType),
MaintenanceConfigurationID: utils.String(maintenanceConfigId.ID()),
MinimalTLSVersion: utils.String(model.MinimumTlsVersion),
ProxyOverride: sql.ManagedInstanceProxyOverride(model.ProxyOverride),
PublicDataEndpointEnabled: utils.Bool(model.PublicDataEndpointEnabled),
Expand Down Expand Up @@ -357,6 +379,11 @@ func (r MsSqlManagedInstanceResource) Update() sdk.ResourceFunc {
Tags: tags.FromTypedObject(state.Tags),
}

if metadata.ResourceData.HasChange("maintenance_configuration_name") {
maintenanceConfigId := maintenanceParse.NewPublicMaintenanceConfigurationID(id.SubscriptionId, state.MaintenanceConfigurationName)
properties.MaintenanceConfigurationID = utils.String(maintenanceConfigId.ID())
}

if metadata.ResourceData.HasChange("administrator_password") {
properties.AdministratorLoginPassword = utils.String(state.AdministratorLoginPassword)
}
Expand Down Expand Up @@ -431,6 +458,13 @@ func (r MsSqlManagedInstanceResource) Read() sdk.ResourceFunc {
if props.FullyQualifiedDomainName != nil {
model.Fqdn = *props.FullyQualifiedDomainName
}
if props.MaintenanceConfigurationID != nil {
maintenanceConfigId, err := maintenanceParse.PublicMaintenanceConfigurationID(*props.MaintenanceConfigurationID)
if err != nil {
return err
}
model.MaintenanceConfigurationName = maintenanceConfigId.Name
}
if props.MinimalTLSVersion != nil {
model.MinimumTlsVersion = *props.MinimalTLSVersion
}
Expand Down
Loading

0 comments on commit 5d49be5

Please sign in to comment.