From b6e14baba7359ca8fc324995f7b5225f255cd6db Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 21 Nov 2024 00:20:25 +0000 Subject: [PATCH 01/39] WIP: Initial commit for AVG Oracle --- internal/services/netapp/models/models.go | 21 + .../netapp_volume_group_oracle_data_source.go | 280 +++ ...pp_volume_group_oracle_data_source_test.go | 42 + .../netapp_volume_group_oracle_resource.go | 619 ++++++ ...etapp_volume_group_oracle_resource_test.go | 1788 +++++++++++++++++ .../services/netapp/netapp_volume_helper.go | 14 +- internal/services/netapp/registration.go | 2 + .../netapp/validate/validate_helper.go | 33 + ...oracle_volumes_export_policy_validation.go | 38 + ...e_volumes_export_policy_validation_test.go | 104 + .../volume_group_oracle_volumes_validation.go | 169 ++ ...me_group_oracle_volumes_validation_test.go | 864 ++++++++ ...olume_group_sap_hana_volumes_validation.go | 25 - 13 files changed, 3973 insertions(+), 26 deletions(-) create mode 100644 internal/services/netapp/netapp_volume_group_oracle_data_source.go create mode 100644 internal/services/netapp/netapp_volume_group_oracle_data_source_test.go create mode 100644 internal/services/netapp/netapp_volume_group_oracle_resource.go create mode 100644 internal/services/netapp/netapp_volume_group_oracle_resource_test.go create mode 100644 internal/services/netapp/validate/validate_helper.go create mode 100644 internal/services/netapp/validate/volume_group_oracle_volumes_export_policy_validation.go create mode 100644 internal/services/netapp/validate/volume_group_oracle_volumes_export_policy_validation_test.go create mode 100644 internal/services/netapp/validate/volume_group_oracle_volumes_validation.go create mode 100644 internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go diff --git a/internal/services/netapp/models/models.go b/internal/services/netapp/models/models.go index 8637074b2efb..8641aa2624ab 100644 --- a/internal/services/netapp/models/models.go +++ b/internal/services/netapp/models/models.go @@ -40,6 +40,7 @@ type NetAppVolumeGroupVolume struct { MountIpAddresses []string `tfschema:"mount_ip_addresses"` DataProtectionReplication []DataProtectionReplication `tfschema:"data_protection_replication"` DataProtectionSnapshotPolicy []DataProtectionSnapshotPolicy `tfschema:"data_protection_snapshot_policy"` + Zone string `tfschema:"zone"` } type NetAppVolumeGroupSapHanaModel struct { @@ -62,6 +63,26 @@ type NetAppVolumeGroupSapHanaDataSourceModel struct { Volumes []NetAppVolumeGroupVolume `tfschema:"volume"` } +type NetAppVolumeGroupOracleModel struct { + Name string `tfschema:"name"` + ResourceGroupName string `tfschema:"resource_group_name"` + Location string `tfschema:"location"` + AccountName string `tfschema:"account_name"` + GroupDescription string `tfschema:"group_description"` + ApplicationIdentifier string `tfschema:"application_identifier"` + Volumes []NetAppVolumeGroupVolume `tfschema:"volume"` +} + +type NetAppVolumeGroupOracleDataSourceModel struct { + Name string `tfschema:"name"` + ResourceGroupName string `tfschema:"resource_group_name"` + Location string `tfschema:"location"` + AccountName string `tfschema:"account_name"` + GroupDescription string `tfschema:"group_description"` + ApplicationIdentifier string `tfschema:"application_identifier"` + Volumes []NetAppVolumeGroupVolume `tfschema:"volume"` +} + type ExportPolicyRule struct { RuleIndex int64 `tfschema:"rule_index"` AllowedClients string `tfschema:"allowed_clients"` diff --git a/internal/services/netapp/netapp_volume_group_oracle_data_source.go b/internal/services/netapp/netapp_volume_group_oracle_data_source.go new file mode 100644 index 000000000000..09855344953f --- /dev/null +++ b/internal/services/netapp/netapp_volume_group_oracle_data_source.go @@ -0,0 +1,280 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package netapp + +import ( + "context" + "fmt" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" + "github.com/hashicorp/go-azure-helpers/resourcemanager/location" + "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/volumegroups" + "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" + netAppModels "github.com/hashicorp/terraform-provider-azurerm/internal/services/netapp/models" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" +) + +var _ sdk.DataSource = NetAppVolumeGroupOracleDataSource{} + +type NetAppVolumeGroupOracleDataSource struct{} + +func (r NetAppVolumeGroupOracleDataSource) ResourceType() string { + return "azurerm_netapp_volume_group_oracle" +} + +func (r NetAppVolumeGroupOracleDataSource) ModelObject() interface{} { + return &netAppModels.NetAppVolumeGroupOracleDataSourceModel{} +} + +func (r NetAppVolumeGroupOracleDataSource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return volumegroups.ValidateVolumeGroupID +} + +func (r NetAppVolumeGroupOracleDataSource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + }, + + "resource_group_name": commonschema.ResourceGroupName(), + + "account_name": { + Type: pluginsdk.TypeString, + Required: true, + }, + } +} + +func (r NetAppVolumeGroupOracleDataSource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "location": commonschema.LocationComputed(), + + "group_description": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "application_identifier": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "volume": { + Type: pluginsdk.TypeList, + Computed: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "id": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "name": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "capacity_pool_id": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "proximity_placement_group_id": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "zone": commonschema.ZoneSingleComputed(), + + "volume_spec_name": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "volume_path": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "service_level": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "subnet_id": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "protocols": { + Type: pluginsdk.TypeList, + Computed: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "security_style": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "storage_quota_in_gb": { + Type: pluginsdk.TypeInt, + Computed: true, + }, + + "throughput_in_mibps": { + Type: pluginsdk.TypeFloat, + Required: true, + }, + + "export_policy_rule": { + Type: pluginsdk.TypeList, + Computed: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "rule_index": { + Type: pluginsdk.TypeInt, + Computed: true, + }, + + "allowed_clients": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "nfsv3_enabled": { + Type: pluginsdk.TypeBool, + Computed: true, + }, + + "nfsv41_enabled": { + Type: pluginsdk.TypeBool, + Computed: true, + }, + + "unix_read_only": { + Type: pluginsdk.TypeBool, + Computed: true, + }, + + "unix_read_write": { + Type: pluginsdk.TypeBool, + Computed: true, + }, + + "root_access_enabled": { + Type: pluginsdk.TypeBool, + Computed: true, + }, + }, + }, + }, + + "tags": commonschema.TagsDataSource(), + + "snapshot_directory_visible": { + Type: pluginsdk.TypeBool, + Computed: true, + }, + + "mount_ip_addresses": { + Type: pluginsdk.TypeList, + Computed: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "data_protection_replication": { + Type: pluginsdk.TypeList, + Computed: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "endpoint_type": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "remote_volume_location": commonschema.LocationComputed(), + + "remote_volume_resource_id": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "replication_frequency": { + Type: pluginsdk.TypeString, + Computed: true, + }, + }, + }, + }, + + "data_protection_snapshot_policy": { + Type: pluginsdk.TypeList, + Computed: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "snapshot_policy_id": { + Type: pluginsdk.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + } +} + +func (r NetAppVolumeGroupOracleDataSource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.NetApp.VolumeGroupClient + + var state netAppModels.NetAppVolumeGroupOracleDataSourceModel + if err := metadata.Decode(&state); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + id := volumegroups.NewVolumeGroupID(metadata.Client.Account.SubscriptionId, state.ResourceGroupName, state.AccountName, state.Name) + + resp, err := client.Get(ctx, id) + if err != nil { + if response.WasNotFound(resp.HttpResponse) { + return fmt.Errorf("%s was not found", id) + } + return fmt.Errorf("retrieving %s: %v", id, err) + } + + if model := resp.Model; model != nil { + state.Location = location.Normalize(pointer.From(model.Location)) + if props := model.Properties; props != nil { + if groupMetaData := props.GroupMetaData; groupMetaData != nil { + state.ApplicationIdentifier = pointer.From(groupMetaData.ApplicationIdentifier) + state.GroupDescription = pointer.From(groupMetaData.GroupDescription) + } + + volumes, err := flattenNetAppVolumeGroupVolumes(ctx, props.Volumes, metadata) + if err != nil { + return fmt.Errorf("setting `volume`: %+v", err) + } + state.Volumes = volumes + } + } + + metadata.SetID(id) + + return metadata.Encode(&state) + }, + } +} diff --git a/internal/services/netapp/netapp_volume_group_oracle_data_source_test.go b/internal/services/netapp/netapp_volume_group_oracle_data_source_test.go new file mode 100644 index 000000000000..a0afa4c59575 --- /dev/null +++ b/internal/services/netapp/netapp_volume_group_oracle_data_source_test.go @@ -0,0 +1,42 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package netapp_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" +) + +type NetAppVolumeGroupOracleDataSource struct{} + +func TestAccNetAppVolumeGroupOracleDataSource_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_netapp_volume_group_oracle", "test") + d := NetAppVolumeGroupOracleDataSource{} + + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: d.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).Key("name").Exists(), + check.That(data.ResourceName).Key("resource_group_name").Exists(), + check.That(data.ResourceName).Key("volume.1.volume_spec_name").HasValue("log"), + ), + }, + }) +} + +func (d NetAppVolumeGroupOracleDataSource) basic(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +data "azurerm_netapp_volume_group_oracle" "test" { + name = azurerm_netapp_volume_group_oracle.test.name + resource_group_name = azurerm_netapp_volume_group_oracle.test.resource_group_name + account_name = azurerm_netapp_volume_group_oracle.test.account_name +} +`, NetAppVolumeGroupOracleResource{}.basic(data)) +} diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource.go b/internal/services/netapp/netapp_volume_group_oracle_resource.go new file mode 100644 index 000000000000..cf5098563645 --- /dev/null +++ b/internal/services/netapp/netapp_volume_group_oracle_resource.go @@ -0,0 +1,619 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package netapp + +import ( + "context" + "fmt" + "log" + "strings" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" + "github.com/hashicorp/go-azure-helpers/resourcemanager/location" + "github.com/hashicorp/go-azure-helpers/resourcemanager/tags" + "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/capacitypools" + "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/volumegroups" + "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/volumes" + "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/volumesreplication" + "github.com/hashicorp/terraform-provider-azurerm/helpers/azure" + "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" + netAppModels "github.com/hashicorp/terraform-provider-azurerm/internal/services/netapp/models" + netAppValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/netapp/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" +) + +type NetAppVolumeGroupOracleResource struct{} + +var _ sdk.Resource = NetAppVolumeGroupOracleResource{} + +func (r NetAppVolumeGroupOracleResource) ModelObject() interface{} { + return &netAppModels.NetAppVolumeGroupOracleModel{} +} + +func (r NetAppVolumeGroupOracleResource) ResourceType() string { + return "azurerm_netapp_volume_group_oracle" +} + +func (r NetAppVolumeGroupOracleResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return volumegroups.ValidateVolumeGroupID +} + +func (r NetAppVolumeGroupOracleResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: netAppValidate.VolumeGroupName, + }, + + "resource_group_name": commonschema.ResourceGroupName(), + + "location": commonschema.Location(), + + "account_name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: netAppValidate.AccountName, + }, + + "group_description": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "application_identifier": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 3), + }, + + "volume": { + Type: pluginsdk.TypeList, + Required: true, + MinItems: 2, + MaxItems: 12, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "id": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: netAppValidate.VolumeName, + }, + + "capacity_pool_id": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + }, + + "proximity_placement_group_id": { + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + ConflictsWith: []string{"zone"}, + }, + + "zone": commonschema.ZoneSingleOptionalForceNew(), + + "volume_spec_name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice(netAppValidate.PossibleValuesForVolumeSpecNameOracle(), false), + }, + + "volume_path": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: netAppValidate.VolumePath, + }, + + "service_level": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(volumegroups.ServiceLevelPremium), + string(volumegroups.ServiceLevelStandard), + string(volumegroups.ServiceLevelUltra), + }, false), + }, + + "subnet_id": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + }, + + "protocols": { + Type: pluginsdk.TypeList, + ForceNew: true, + Required: true, + MinItems: 1, + MaxItems: 1, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + ValidateFunc: validation.StringInSlice(netAppValidate.PossibleValuesForProtocolTypeVolumeGroupOracle(), false), + }, + }, + + "security_style": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice(volumegroups.PossibleValuesForSecurityStyle(), false), + }, + + "storage_quota_in_gb": { + Type: pluginsdk.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(100, 102400), + }, + + "throughput_in_mibps": { + Type: pluginsdk.TypeFloat, + Required: true, + ValidateFunc: validation.FloatAtLeast(0.1), + }, + + "export_policy_rule": { + Type: pluginsdk.TypeList, + Required: true, + MinItems: 1, + MaxItems: 5, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "rule_index": { + Type: pluginsdk.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(1, 5), + }, + + "allowed_clients": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "nfsv3_enabled": { + Type: pluginsdk.TypeBool, + Required: true, + }, + + "nfsv41_enabled": { + Type: pluginsdk.TypeBool, + Required: true, + }, + + "unix_read_only": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, + + "unix_read_write": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: true, + }, + + "root_access_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: true, + }, + }, + }, + }, + + "tags": commonschema.Tags(), + + "snapshot_directory_visible": { + Type: pluginsdk.TypeBool, + Required: true, + ForceNew: true, + }, + + "mount_ip_addresses": { + Type: pluginsdk.TypeList, + Computed: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "data_protection_replication": { + Type: pluginsdk.TypeList, + Optional: true, + MaxItems: 1, + ForceNew: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "endpoint_type": { + Type: pluginsdk.TypeString, + Optional: true, + Default: string(volumegroups.EndpointTypeDst), + ValidateFunc: validation.StringInSlice(volumegroups.PossibleValuesForEndpointType(), false), + }, + + "remote_volume_location": commonschema.LocationWithoutForceNew(), + + "remote_volume_resource_id": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, + }, + + "replication_frequency": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(netAppModels.PossibleValuesForReplicationSchedule(), false), + }, + }, + }, + }, + + "data_protection_snapshot_policy": { + Type: pluginsdk.TypeList, + Optional: true, + MaxItems: 1, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "snapshot_policy_id": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, + }, + }, + }, + }, + }, + }, + }, + } +} + +func (r NetAppVolumeGroupOracleResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{} +} + +func (r NetAppVolumeGroupOracleResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 90 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.NetApp.VolumeGroupClient + replicationClient := metadata.Client.NetApp.VolumeReplicationClient + + subscriptionId := metadata.Client.Account.SubscriptionId + + var model netAppModels.NetAppVolumeGroupOracleModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + id := volumegroups.NewVolumeGroupID(subscriptionId, model.ResourceGroupName, model.AccountName, model.Name) + + metadata.Logger.Infof("Import check for %s", id) + existing, err := client.Get(ctx, id) + if err != nil && !response.WasNotFound(existing.HttpResponse) { + return fmt.Errorf("checking for presence of existing %s: %+v", id, err) + } + + if existing.Model != nil && existing.Model.Id != nil && *existing.Model.Id != "" { + return metadata.ResourceRequiresImport(r.ResourceType(), id) + } + + volumeList, err := expandNetAppVolumeGroupVolumes(model.Volumes) + if err != nil { + return err + } + + // Performing some basic validations that are not possible in the schema + if errorList := netAppValidate.ValidateNetAppVolumeGroupOracleVolumes(volumeList); len(errorList) > 0 { + return fmt.Errorf("one or more issues found while performing deeper validations for %s:\n%+v", id, errorList) + } + + // Parse volume list to set secondary volumes for CRR + for i, volumeCrr := range pointer.From(volumeList) { + if volumeCrr.Properties.DataProtection != nil && + volumeCrr.Properties.DataProtection.Replication != nil && + strings.EqualFold(string(pointer.From(volumeCrr.Properties.DataProtection.Replication.EndpointType)), string(volumegroups.EndpointTypeDst)) { + // Modify volumeType as data protection type on main volumeList + // so it gets created correctly as data protection volume + (pointer.From(volumeList))[i].Properties.VolumeType = utils.String("DataProtection") + } + } + + parameters := volumegroups.VolumeGroupDetails{ + Location: utils.String(location.Normalize(model.Location)), + Properties: &volumegroups.VolumeGroupProperties{ + GroupMetaData: &volumegroups.VolumeGroupMetaData{ + GroupDescription: utils.String(model.GroupDescription), + ApplicationType: pointer.To(volumegroups.ApplicationTypeORACLE), + ApplicationIdentifier: utils.String(model.ApplicationIdentifier), + }, + Volumes: volumeList, + }, + } + + err = client.CreateThenPoll(ctx, id, parameters) + if err != nil { + return fmt.Errorf("creating %s: %+v", id, err) + } + + // Waiting for volume group be completely provisioned + if err := waitForVolumeGroupCreateOrUpdate(ctx, client, id); err != nil { + return err + } + + // CRR - Authorizing secondaries from primary volumes + for _, volumeCrr := range pointer.From(volumeList) { + if volumeCrr.Properties.DataProtection != nil && + volumeCrr.Properties.DataProtection.Replication != nil && + strings.EqualFold(string(pointer.From(volumeCrr.Properties.DataProtection.Replication.EndpointType)), string(volumegroups.EndpointTypeDst)) { + capacityPoolId, err := capacitypools.ParseCapacityPoolID(pointer.From(volumeCrr.Properties.CapacityPoolResourceId)) + if err != nil { + return err + } + + // Getting secondary volume resource id + secondaryId := volumes.NewVolumeID(subscriptionId, + model.ResourceGroupName, + model.AccountName, + capacityPoolId.CapacityPoolName, + getUserDefinedVolumeName(volumeCrr.Name), + ) + + // Getting primary resource id + primaryId, err := volumesreplication.ParseVolumeID(volumeCrr.Properties.DataProtection.Replication.RemoteVolumeResourceId) + if err != nil { + return err + } + + // Authorizing + if err = replicationClient.VolumesAuthorizeReplicationThenPoll(ctx, pointer.From(primaryId), volumesreplication.AuthorizeRequest{ + RemoteVolumeResourceId: utils.String(secondaryId.ID()), + }, + ); err != nil { + return fmt.Errorf("cannot authorize volume replication: %v", err) + } + + // Wait for volume replication authorization to complete + log.Printf("[DEBUG] Waiting for replication authorization on %s to complete", id) + if err := waitForReplAuthorization(ctx, replicationClient, pointer.From(primaryId)); err != nil { + return err + } + } + } + + metadata.SetID(id) + + return nil + }, + } +} + +func (r NetAppVolumeGroupOracleResource) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 120 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + volumeClient := metadata.Client.NetApp.VolumeClient + + id, err := volumegroups.ParseVolumeGroupID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + metadata.Logger.Infof("Decoding state for %s", id) + var state netAppModels.NetAppVolumeGroupOracleModel + if err := metadata.Decode(&state); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + metadata.Logger.Infof("Updating %s", id) + + if metadata.ResourceData.HasChange("volume") { + // Iterating over each volume and performing individual patch + for i := 0; i < metadata.ResourceData.Get("volume.#").(int); i++ { + // Checking if individual volume has a change + volumeItem := fmt.Sprintf("volume.%v", i) + + capacityPoolId, err := capacitypools.ParseCapacityPoolID(metadata.ResourceData.Get(fmt.Sprintf("%v.capacity_pool_id", volumeItem)).(string)) + if err != nil { + return err + } + + if metadata.ResourceData.HasChange(volumeItem) { + volumeId := volumes.NewVolumeID(id.SubscriptionId, + id.ResourceGroupName, + id.NetAppAccountName, + capacityPoolId.CapacityPoolName, + metadata.ResourceData.Get(fmt.Sprintf("%v.name", volumeItem)).(string)) + + update := volumes.VolumePatch{ + Properties: &volumes.VolumePatchProperties{}, + } + + if metadata.ResourceData.HasChange(fmt.Sprintf("%v.storage_quota_in_gb", volumeItem)) { + storageQuotaInBytes := int64(metadata.ResourceData.Get(fmt.Sprintf("%v.storage_quota_in_gb", volumeItem)).(int) * 1073741824) + update.Properties.UsageThreshold = utils.Int64(storageQuotaInBytes) + } + + if metadata.ResourceData.HasChange(fmt.Sprintf("%v.export_policy_rule", volumeItem)) { + exportPolicyRuleRaw := metadata.ResourceData.Get(fmt.Sprintf("%v.export_policy_rule", volumeItem)).([]interface{}) + + // Validating export policy rules + volumeProtocolRaw := (metadata.ResourceData.Get(fmt.Sprintf("%v.protocols", volumeItem)).([]interface{}))[0] + volumeProtocol := volumeProtocolRaw.(string) + + errors := make([]error, 0) + for _, ruleRaw := range exportPolicyRuleRaw { + if ruleRaw != nil { + rule := volumegroups.ExportPolicyRule{} + + v := ruleRaw.(map[string]interface{}) + rule.Nfsv3 = utils.Bool(v["nfsv3_enabled"].(bool)) + rule.Nfsv41 = utils.Bool(v["nfsv41_enabled"].(bool)) + + errors = append(errors, netAppValidate.ValidateNetAppVolumeGroupExportPolicyRuleOracle(rule, volumeProtocol)...) + } + } + + if len(errors) > 0 { + return fmt.Errorf("one or more issues found while performing export policies validations for %s:\n%+v", id, errors) + } + + exportPolicyRule := expandNetAppVolumeGroupVolumeExportPolicyRulePatch(exportPolicyRuleRaw) + update.Properties.ExportPolicy = exportPolicyRule + } + + if metadata.ResourceData.HasChange(fmt.Sprintf("%v.data_protection_snapshot_policy", volumeItem)) { + // Validating that snapshot policies are not being created in a data protection volume + dataProtectionReplicationRaw := metadata.ResourceData.Get(fmt.Sprintf("%v.data_protection_replication", volumeItem)).([]interface{}) + dataProtectionReplication := expandNetAppVolumeDataProtectionReplication(dataProtectionReplicationRaw) + + if dataProtectionReplication != nil && + dataProtectionReplication.Replication != nil && + dataProtectionReplication.Replication.EndpointType != nil && + strings.EqualFold(string(pointer.From(dataProtectionReplication.Replication.EndpointType)), string(volumegroups.EndpointTypeDst)) { + return fmt.Errorf("snapshot policy cannot be enabled on a data protection volume, %s", volumeId) + } + + dataProtectionSnapshotPolicyRaw := metadata.ResourceData.Get(fmt.Sprintf("%v.data_protection_snapshot_policy", volumeItem)).([]interface{}) + dataProtectionSnapshotPolicy := expandNetAppVolumeDataProtectionSnapshotPolicyPatch(dataProtectionSnapshotPolicyRaw) + update.Properties.DataProtection = dataProtectionSnapshotPolicy + } + + if metadata.ResourceData.HasChange(fmt.Sprintf("%v.throughput_in_mibps", volumeItem)) { + throughputMibps := metadata.ResourceData.Get(fmt.Sprintf("%v.throughput_in_mibps", volumeItem)) + update.Properties.ThroughputMibps = utils.Float(throughputMibps.(float64)) + } + + if metadata.ResourceData.HasChange(fmt.Sprintf("%v.tags", volumeItem)) { + tagsRaw := metadata.ResourceData.Get(fmt.Sprintf("%v.tags", volumeItem)).(map[string]interface{}) + update.Tags = tags.Expand(tagsRaw) + } + + if err = volumeClient.UpdateThenPoll(ctx, volumeId, update); err != nil { + return fmt.Errorf("updating %s: %+v", volumeId, err) + } + } + } + } + + return nil + }, + } +} + +func (r NetAppVolumeGroupOracleResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.NetApp.VolumeGroupClient + + id, err := volumegroups.ParseVolumeGroupID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + metadata.Logger.Infof("Decoding state for %s", id) + var state netAppModels.NetAppVolumeGroupOracleModel + if err := metadata.Decode(&state); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + existing, err := client.Get(ctx, pointer.From(id)) + if err != nil { + if response.WasNotFound(existing.HttpResponse) { + return metadata.MarkAsGone(id) + } + return fmt.Errorf("retrieving %s: %v", id, err) + } + + model := netAppModels.NetAppVolumeGroupOracleModel{ + Name: id.VolumeGroupName, + AccountName: id.NetAppAccountName, + Location: location.NormalizeNilable(existing.Model.Location), + ResourceGroupName: id.ResourceGroupName, + } + + if props := existing.Model.Properties; props != nil { + model.GroupDescription = pointer.From(props.GroupMetaData.GroupDescription) + model.ApplicationIdentifier = pointer.From(props.GroupMetaData.ApplicationIdentifier) + + volumes, err := flattenNetAppVolumeGroupVolumes(ctx, props.Volumes, metadata) + if err != nil { + return fmt.Errorf("setting `volume`: %+v", err) + } + + model.Volumes = volumes + } + + metadata.SetID(id) + + return metadata.Encode(&model) + }, + } +} + +func (r NetAppVolumeGroupOracleResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 120 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.NetApp.VolumeGroupClient + + id, err := volumegroups.ParseVolumeGroupID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + existing, err := client.Get(ctx, pointer.From(id)) + if err != nil { + if response.WasNotFound(existing.HttpResponse) { + return metadata.MarkAsGone(id) + } + return fmt.Errorf("retrieving %s: %v", id, err) + } + + // Removing volumes before deleting volume group + if props := existing.Model.Properties; props != nil { + if volumeList := props.Volumes; volumeList != nil { + for _, volume := range *volumeList { + if err := deleteVolume(ctx, metadata, pointer.From(volume.Id)); err != nil { + return fmt.Errorf("deleting `volume`: %+v", err) + } + } + } + } + + // Removing Volume Group + if err = client.DeleteThenPoll(ctx, pointer.From(id)); err != nil { + return fmt.Errorf("deleting %s: %+v", pointer.From(id), err) + } + + return nil + }, + } +} diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go new file mode 100644 index 000000000000..509832faae96 --- /dev/null +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -0,0 +1,1788 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package netapp_test + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/volumegroups" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +type NetAppVolumeGroupOracleResource struct{} + +func TestAccNetAppVolumeGroupOracle_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") + r := NetAppVolumeGroupOracleResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccNetAppVolumeGroupOracle_backupVolumeSpecsNfsv3(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") + r := NetAppVolumeGroupOracleResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.backupVolumeSpecsNfsv3(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccNetAppVolumeGroupOracle_snapshotPolicy(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") + r := NetAppVolumeGroupOracleResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.avgSnapshotPolicy(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccNetAppVolumeGroupOracle_snapshotPolicyUpdate(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") + r := NetAppVolumeGroupOracleResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.updateAvgSnapshotPolicy(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccNetAppVolumeGroupOracle_volumeUpdates(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") + r := NetAppVolumeGroupOracleResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.updateVolumes(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("volume.0.storage_quota_in_gb").HasValue("1200"), + check.That(data.ResourceName).Key("volume.1.export_policy_rule.0.allowed_clients").HasValue("10.0.0.0/8"), + check.That(data.ResourceName).Key("volume.2.tags.CreatedOnDate").HasValue("2022-07-27T12:00:00Z"), + check.That(data.ResourceName).Key("volume.4.storage_quota_in_gb").HasValue("1200"), + check.That(data.ResourceName).Key("volume.4.export_policy_rule.0.allowed_clients").HasValue("192.168.0.0/24"), + check.That(data.ResourceName).Key("volume.4.tags.CreatedOnDate").HasValue("2022-07-28T11:00:00Z"), + ), + }, + data.ImportStep(), + }) +} + +func TestAccNetAppVolumeGroupOracle_crossRegionReplication(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test_secondary") + r := NetAppVolumeGroupOracleResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.crossRegionReplication(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func (t NetAppVolumeGroupOracleResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { + id, err := volumegroups.ParseVolumeGroupID(state.ID) + if err != nil { + return nil, err + } + + resp, err := clients.NetApp.VolumeGroupClient.Get(ctx, *id) + if err != nil { + if response.WasNotFound(resp.HttpResponse) { + return utils.Bool(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + + return utils.Bool(true), nil +} + +func (NetAppVolumeGroupOracleResource) basic(data acceptance.TestData) string { + template := NetAppVolumeGroupOracleResource{}.templatePPG(data) + return fmt.Sprintf(` +%[1]s + +resource "azurerm_netapp_volume_group_oracle" "test" { + name = "acctest-NetAppVolumeGroup-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + group_description = "Test volume group" + application_identifier = "TST" + + volume { + name = "acctest-NetAppVolume-1-%[2]d" + volume_path = "my-unique-file-path-1-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "data" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-2-%[2]d" + volume_path = "my-unique-file-path-2-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-3-%[2]d" + volume_path = "my-unique-file-path-3-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "shared" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-4-%[2]d" + volume_path = "my-unique-file-path-4-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + volume_spec_name = "data-backup" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-5-%[2]d" + volume_path = "my-unique-file-path-5-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + volume_spec_name = "log-backup" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + depends_on = [ + azurerm_linux_virtual_machine.test, + azurerm_proximity_placement_group.test + ] +} +`, template, data.RandomInteger) +} + +func (NetAppVolumeGroupOracleResource) backupVolumeSpecsNfsv3(data acceptance.TestData) string { + template := NetAppVolumeGroupOracleResource{}.templatePPG(data) + return fmt.Sprintf(` +%[1]s + +resource "azurerm_netapp_volume_group_oracle" "test" { + name = "acctest-NetAppVolumeGroup-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + group_description = "Test volume group" + application_identifier = "TST" + + volume { + name = "acctest-NetAppVolume-1-%[2]d" + volume_path = "my-unique-file-path-1-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "data" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-2-%[2]d" + volume_path = "my-unique-file-path-2-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-3-%[2]d" + volume_path = "my-unique-file-path-3-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "shared" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-4-%[2]d" + volume_path = "my-unique-file-path-4-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + volume_spec_name = "data-backup" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv3"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = true + nfsv41_enabled = false + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-5-%[2]d" + volume_path = "my-unique-file-path-5-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + volume_spec_name = "log-backup" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv3"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = true + nfsv41_enabled = false + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + depends_on = [ + azurerm_linux_virtual_machine.test, + azurerm_proximity_placement_group.test + ] +} +`, template, data.RandomInteger) +} + +func (NetAppVolumeGroupOracleResource) avgSnapshotPolicy(data acceptance.TestData) string { + template := NetAppVolumeGroupOracleResource{}.templatePPG(data) + return fmt.Sprintf(` +%[1]s + +resource "azurerm_netapp_snapshot_policy" "test" { + name = "acctest-NetAppSnapshotPolicy-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + enabled = true + + monthly_schedule { + snapshots_to_keep = 1 + days_of_month = [15, 30] + hour = 23 + minute = 30 + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_netapp_volume_group_oracle" "test" { + name = "acctest-NetAppVolumeGroup-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + group_description = "Test volume group" + application_identifier = "TST" + + volume { + name = "acctest-NetAppVolume-1-%[2]d" + volume_path = "my-unique-file-path-1-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "data" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + data_protection_snapshot_policy { + snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-2-%[2]d" + volume_path = "my-unique-file-path-2-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + data_protection_snapshot_policy { + snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-3-%[2]d" + volume_path = "my-unique-file-path-3-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "shared" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + data_protection_snapshot_policy { + snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-4-%[2]d" + volume_path = "my-unique-file-path-4-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + volume_spec_name = "data-backup" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + data_protection_snapshot_policy { + snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-5-%[2]d" + volume_path = "my-unique-file-path-5-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + volume_spec_name = "log-backup" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + data_protection_snapshot_policy { + snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + depends_on = [ + azurerm_linux_virtual_machine.test, + azurerm_proximity_placement_group.test + ] +} +`, template, data.RandomInteger) +} + +func (NetAppVolumeGroupOracleResource) updateAvgSnapshotPolicy(data acceptance.TestData) string { + template := NetAppVolumeGroupOracleResource{}.templatePPG(data) + return fmt.Sprintf(` +%[1]s + +resource "azurerm_netapp_snapshot_policy" "test" { + name = "acctest-NetAppSnapshotPolicy-New-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + enabled = true + + monthly_schedule { + snapshots_to_keep = 3 + days_of_month = [10, 25] + hour = 23 + minute = 30 + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_netapp_volume_group_oracle" "test" { + name = "acctest-NetAppVolumeGroup-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + group_description = "Test volume group" + application_identifier = "TST" + + volume { + name = "acctest-NetAppVolume-1-%[2]d" + volume_path = "my-unique-file-path-1-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "data" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + data_protection_snapshot_policy { + snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-2-%[2]d" + volume_path = "my-unique-file-path-2-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + data_protection_snapshot_policy { + snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-3-%[2]d" + volume_path = "my-unique-file-path-3-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "shared" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + data_protection_snapshot_policy { + snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-4-%[2]d" + volume_path = "my-unique-file-path-4-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + volume_spec_name = "data-backup" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + data_protection_snapshot_policy { + snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-5-%[2]d" + volume_path = "my-unique-file-path-5-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + volume_spec_name = "log-backup" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + data_protection_snapshot_policy { + snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + depends_on = [ + azurerm_linux_virtual_machine.test, + azurerm_proximity_placement_group.test + ] +} +`, template, data.RandomInteger) +} + +func (NetAppVolumeGroupOracleResource) updateVolumes(data acceptance.TestData) string { + template := NetAppVolumeGroupOracleResource{}.templatePPG(data) + return fmt.Sprintf(` +%[1]s + +resource "azurerm_netapp_volume_group_oracle" "test" { + name = "acctest-NetAppVolumeGroup-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + group_description = "Test volume group" + application_identifier = "TST" + + volume { + name = "acctest-NetAppVolume-1-%[2]d" + volume_path = "my-unique-file-path-1-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "data" + storage_quota_in_gb = 1200 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-2-%[2]d" + volume_path = "my-unique-file-path-2-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "10.0.0.0/8" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-3-%[2]d" + volume_path = "my-unique-file-path-3-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "shared" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-27T12:00:00Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-4-%[2]d" + volume_path = "my-unique-file-path-4-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + volume_spec_name = "data-backup" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-5-%[2]d" + volume_path = "my-unique-file-path-5-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + volume_spec_name = "log-backup" + storage_quota_in_gb = 1200 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "192.168.0.0/24" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-28T11:00:00Z", + "SkipASMAzSecPack" = "true" + } + } + + depends_on = [ + azurerm_linux_virtual_machine.test, + azurerm_proximity_placement_group.test + ] +} +`, template, data.RandomInteger) +} + +func (NetAppVolumeGroupOracleResource) crossRegionReplication(data acceptance.TestData) string { + template := NetAppVolumeGroupOracleResource{}.templateForAvgCrossRegionReplication(data) + return fmt.Sprintf(` +%[1]s + +resource "azurerm_netapp_volume_group_oracle" "test_primary" { + name = "acctest-NetAppVolumeGroup-Primary-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + group_description = "Test volume group" + application_identifier = "TST" + + volume { + name = "acctest-NetAppVolume-1-Primary-%[2]d" + volume_path = "my-unique-file-path-1-Primary-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "data" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-2-Primary-%[2]d" + volume_path = "my-unique-file-path-2-Primary-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-3-Primary-%[2]d" + volume_path = "my-unique-file-path-3-Primary-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "shared" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-4-Primary-%[2]d" + volume_path = "my-unique-file-path-4-Primary-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + volume_spec_name = "data-backup" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-5-Primary-%[2]d" + volume_path = "my-unique-file-path-5-Primary-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + volume_spec_name = "log-backup" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + depends_on = [ + azurerm_linux_virtual_machine.test, + azurerm_proximity_placement_group.test + ] +} + +resource "azurerm_netapp_volume_group_oracle" "test_secondary" { + name = "acctest-NetAppVolumeGroup-Secondary-%[2]d" + location = "%[3]s" + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test_secondary.name + group_description = "Test volume group" + application_identifier = "TST" + + volume { + name = "acctest-NetAppVolume-1-Secondary-%[2]d" + volume_path = "my-unique-file-path-1-Secondary-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test_secondary.id + subnet_id = azurerm_subnet.test_secondary.id + proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id + volume_spec_name = "data" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + data_protection_replication { + endpoint_type = "dst" + remote_volume_location = azurerm_netapp_volume_group_oracle.test_primary.location + remote_volume_resource_id = azurerm_netapp_volume_group_oracle.test_primary.volume[0].id + replication_frequency = "10minutes" + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-2-Secondary-%[2]d" + volume_path = "my-unique-file-path-2-Secondary-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test_secondary.id + subnet_id = azurerm_subnet.test_secondary.id + proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id + volume_spec_name = "log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-3-Secondary-%[2]d" + volume_path = "my-unique-file-path-3-Secondary-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test_secondary.id + subnet_id = azurerm_subnet.test_secondary.id + proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id + volume_spec_name = "shared" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + data_protection_replication { + endpoint_type = "dst" + remote_volume_location = azurerm_netapp_volume_group_oracle.test_primary.location + remote_volume_resource_id = azurerm_netapp_volume_group_oracle.test_primary.volume[2].id + replication_frequency = "10minutes" + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-4-Secondary-%[2]d" + volume_path = "my-unique-file-path-4-Secondary-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test_secondary.id + subnet_id = azurerm_subnet.test_secondary.id + volume_spec_name = "data-backup" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + data_protection_replication { + endpoint_type = "dst" + remote_volume_location = azurerm_netapp_volume_group_oracle.test_primary.location + remote_volume_resource_id = azurerm_netapp_volume_group_oracle.test_primary.volume[3].id + replication_frequency = "10minutes" + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + volume { + name = "acctest-NetAppVolume-5-Secondary-%[2]d" + volume_path = "my-unique-file-path-5-Secondary-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test_secondary.id + subnet_id = azurerm_subnet.test_secondary.id + volume_spec_name = "log-backup" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + data_protection_replication { + endpoint_type = "dst" + remote_volume_location = azurerm_netapp_volume_group_oracle.test_primary.location + remote_volume_resource_id = azurerm_netapp_volume_group_oracle.test_primary.volume[4].id + replication_frequency = "10minutes" + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + + depends_on = [ + azurerm_linux_virtual_machine.test_secondary, + azurerm_proximity_placement_group.test_secondary, + + ] +} + + +`, template, data.RandomInteger, "westus") +} + +func (r NetAppVolumeGroupOracleResource) templateForAvgCrossRegionReplication(data acceptance.TestData) string { + template := NetAppVolumeGroupOracleResource{}.templatePPG(data) + return fmt.Sprintf(` +%[1]s + +resource "azurerm_network_security_group" "test_secondary" { + name = "acctest-NSG-Secondary-%[2]d" + location = "%[3]s" + resource_group_name = azurerm_resource_group.test.name + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_virtual_network" "test_secondary" { + name = "acctest-VirtualNetwork-Secondary-%[2]d" + location = "%[3]s" + resource_group_name = azurerm_resource_group.test.name + address_space = ["10.6.0.0/16"] + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_subnet" "test_secondary" { + name = "acctest-DelegatedSubnet-%[2]d" + resource_group_name = azurerm_resource_group.test.name + virtual_network_name = azurerm_virtual_network.test_secondary.name + address_prefixes = ["10.6.2.0/24"] + + delegation { + name = "testdelegation" + + service_delegation { + name = "Microsoft.Netapp/volumes" + actions = ["Microsoft.Network/networkinterfaces/*", "Microsoft.Network/virtualNetworks/subnets/join/action"] + } + } +} + +resource "azurerm_subnet" "test1_secondary" { + name = "acctest-HostsSubnet-%[2]d" + resource_group_name = azurerm_resource_group.test.name + virtual_network_name = azurerm_virtual_network.test_secondary.name + address_prefixes = ["10.6.1.0/24"] +} + +resource "azurerm_subnet_network_security_group_association" "test_secondary" { + subnet_id = azurerm_subnet.test1_secondary.id + network_security_group_id = azurerm_network_security_group.test_secondary.id +} + +resource "azurerm_proximity_placement_group" "test_secondary" { + name = "acctest-PPG-Secondary-%[2]d" + location = "%[3]s" + resource_group_name = azurerm_resource_group.test.name + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_availability_set" "test_secondary" { + name = "acctest-avset-Secondary-%[2]d" + location = "%[3]s" + resource_group_name = azurerm_resource_group.test.name + + proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_network_interface" "test_secondary" { + name = "acctest-nic-Secondary-%[2]d" + resource_group_name = azurerm_resource_group.test.name + location = "%[3]s" + + ip_configuration { + name = "internal" + subnet_id = azurerm_subnet.test1_secondary.id + private_ip_address_allocation = "Dynamic" + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_linux_virtual_machine" "test_secondary" { + name = "acctest-vm-secondary-%[2]d" + resource_group_name = azurerm_resource_group.test.name + location = "%[3]s" + size = "Standard_M8ms" + admin_username = local.admin_username + admin_password = local.admin_password + disable_password_authentication = false + proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id + availability_set_id = azurerm_availability_set.test_secondary.id + network_interface_ids = [ + azurerm_network_interface.test_secondary.id + ] + + source_image_reference { + publisher = "Canonical" + offer = "0001-com-ubuntu-server-jammy" + sku = "22_04-lts" + version = "latest" + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + tags = { + "platformsettings.host_environment.service.platform_optedin_for_rootcerts" = "true", + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true", + "Owner" = "pmarques" + } +} + +resource "azurerm_netapp_account" "test_secondary" { + name = "acctest-NetAppAccount-Secondary-%[2]d" + location = "%[3]s" + resource_group_name = azurerm_resource_group.test.name + + depends_on = [ + azurerm_subnet.test_secondary, + azurerm_subnet.test1_secondary + ] + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_netapp_pool" "test_secondary" { + name = "acctest-NetAppPool-Secondary-%[2]d" + location = "%[3]s" + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test_secondary.name + service_level = "Standard" + size_in_tb = 8 + qos_type = "Manual" + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} +`, template, data.RandomInteger, "westus") +} + +func (NetAppVolumeGroupOracleResource) templatePPG(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + alias = "all2" + features { + resource_group { + prevent_deletion_if_contains_resources = false + } + netapp { + prevent_volume_destruction = false + delete_backups_on_backup_vault_destroy = true + } + } +} + +locals { + admin_username = "testadmin%[1]d" + admin_password = "Password1234!%[1]d" +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-netapp-%[1]d" + location = "%[2]s" + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true", + "SkipNRMSNSG" = "true" + } +} + +resource "azurerm_network_security_group" "test" { + name = "acctest-NSG-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_virtual_network" "test" { + name = "acctest-VirtualNetwork-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + address_space = ["10.6.0.0/16"] + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_subnet" "test" { + name = "acctest-DelegatedSubnet-%[1]d" + resource_group_name = azurerm_resource_group.test.name + virtual_network_name = azurerm_virtual_network.test.name + address_prefixes = ["10.6.2.0/24"] + + delegation { + name = "testdelegation" + + service_delegation { + name = "Microsoft.Netapp/volumes" + actions = ["Microsoft.Network/networkinterfaces/*", "Microsoft.Network/virtualNetworks/subnets/join/action"] + } + } +} + +resource "azurerm_subnet" "test1" { + name = "acctest-HostsSubnet-%[1]d" + resource_group_name = azurerm_resource_group.test.name + virtual_network_name = azurerm_virtual_network.test.name + address_prefixes = ["10.6.1.0/24"] +} + +resource "azurerm_subnet_network_security_group_association" "public" { + subnet_id = azurerm_subnet.test.id + network_security_group_id = azurerm_network_security_group.test.id +} + +resource "azurerm_proximity_placement_group" "test" { + name = "acctest-PPG-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_availability_set" "test" { + name = "acctest-avset-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_network_interface" "test" { + name = "acctest-nic-%[1]d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + + ip_configuration { + name = "internal" + subnet_id = azurerm_subnet.test1.id + private_ip_address_allocation = "Dynamic" + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_linux_virtual_machine" "test" { + name = "acctest-vm-%[1]d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + size = "Standard_M8ms" + admin_username = local.admin_username + admin_password = local.admin_password + disable_password_authentication = false + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + availability_set_id = azurerm_availability_set.test.id + network_interface_ids = [ + azurerm_network_interface.test.id + ] + + source_image_reference { + publisher = "Canonical" + offer = "0001-com-ubuntu-server-jammy" + sku = "22_04-lts" + version = "latest" + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + tags = { + "platformsettings.host_environment.service.platform_optedin_for_rootcerts" = "true", + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true", + "Owner" = "pmarques" + } +} + +resource "azurerm_netapp_account" "test" { + name = "acctest-NetAppAccount-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + depends_on = [ + azurerm_subnet.test, + azurerm_subnet.test1 + ] + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_netapp_pool" "test" { + name = "acctest-NetAppPool-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + service_level = "Standard" + size_in_tb = 8 + qos_type = "Manual" + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} +`, data.RandomInteger, "eastus") +} diff --git a/internal/services/netapp/netapp_volume_helper.go b/internal/services/netapp/netapp_volume_helper.go index 67c93b7cfe42..3deca81ae113 100644 --- a/internal/services/netapp/netapp_volume_helper.go +++ b/internal/services/netapp/netapp_volume_helper.go @@ -147,6 +147,10 @@ func expandNetAppVolumeGroupVolumes(input []netAppModels.NetAppVolumeGroupVolume volumeProperties.Properties.ProximityPlacementGroup = pointer.To(pointer.From(pointer.To(v))) } + if v := item.Zone; v != "" { + volumeProperties.Zones = pointer.To([]string{v}) + } + results = append(results, *volumeProperties) } @@ -346,7 +350,15 @@ func flattenNetAppVolumeGroupVolumes(ctx context.Context, input *[]volumegroups. volumeGroupVolume.SnapshotDirectoryVisible = pointer.From(props.SnapshotDirectoryVisible) volumeGroupVolume.ThroughputInMibps = pointer.From(props.ThroughputMibps) volumeGroupVolume.Tags = pointer.From(item.Tags) - volumeGroupVolume.ProximityPlacementGroupId = pointer.From(props.ProximityPlacementGroup) + + if props.ProximityPlacementGroup != nil { + volumeGroupVolume.ProximityPlacementGroupId = pointer.From(props.ProximityPlacementGroup) + } + + if item.Zones != nil && len(pointer.From(item.Zones)) > 0 { + volumeGroupVolume.Zone = (pointer.From(item.Zones))[0] + } + volumeGroupVolume.VolumeSpecName = pointer.From(props.VolumeSpecName) if props.UsageThreshold > 0 { diff --git a/internal/services/netapp/registration.go b/internal/services/netapp/registration.go index 9b0e86bee0e8..6c2801cd75ec 100644 --- a/internal/services/netapp/registration.go +++ b/internal/services/netapp/registration.go @@ -57,6 +57,7 @@ func (r Registration) DataSources() []sdk.DataSource { NetAppAccountEncryptionDataSource{}, NetAppBackupVaultDataSource{}, NetAppBackupPolicyDataSource{}, + NetAppVolumeGroupOracleDataSource{}, } } @@ -68,5 +69,6 @@ func (r Registration) Resources() []sdk.Resource { NetAppAccountEncryptionResource{}, NetAppBackupVaultResource{}, NetAppBackupPolicyResource{}, + NetAppVolumeGroupOracleResource{}, } } diff --git a/internal/services/netapp/validate/validate_helper.go b/internal/services/netapp/validate/validate_helper.go new file mode 100644 index 000000000000..56acb77edd21 --- /dev/null +++ b/internal/services/netapp/validate/validate_helper.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validate + +import ( + "strings" +) + +type ProtocolType string + +const ( + ProtocolTypeNfsV41 ProtocolType = "NFSv4.1" + ProtocolTypeNfsV3 ProtocolType = "NFSv3" + ProtocolTypeCifs ProtocolType = "CIFS" +) + +func PossibleValuesForProtocolType() []string { + return []string{ + string(ProtocolTypeNfsV41), + string(ProtocolTypeNfsV3), + string(ProtocolTypeCifs), + } +} + +func findStringInSlice(slice []string, val string) bool { + for _, item := range slice { + if strings.EqualFold(item, val) { + return true + } + } + return false +} diff --git a/internal/services/netapp/validate/volume_group_oracle_volumes_export_policy_validation.go b/internal/services/netapp/validate/volume_group_oracle_volumes_export_policy_validation.go new file mode 100644 index 000000000000..d7e13ede32a3 --- /dev/null +++ b/internal/services/netapp/validate/volume_group_oracle_volumes_export_policy_validation.go @@ -0,0 +1,38 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validate + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/volumegroups" +) + +func ValidateNetAppVolumeGroupExportPolicyRuleOracle(rule volumegroups.ExportPolicyRule, protocolType string) []error { + errors := make([]error, 0) + + // Validating that nfsv3 and nfsv4.1 are not enabled in the same rule + if pointer.From(rule.Nfsv3) && pointer.From(rule.Nfsv41) { + errors = append(errors, fmt.Errorf("'nfsv3 and nfsv4.1 cannot be enabled at the same time'")) + } + + // Validating that nfsv3 and nfsv4.1 are not disabled in the same rule + if !pointer.From(rule.Nfsv3) && !pointer.From(rule.Nfsv41) { + errors = append(errors, fmt.Errorf("'nfsv3 and nfsv4.1 cannot be enabled at the same time'")) + } + + // Validating that nfsv4.1 export policy is not set on nfsv3 volume + if pointer.From(rule.Nfsv41) && strings.EqualFold(protocolType, string(ProtocolTypeNfsV3)) { + errors = append(errors, fmt.Errorf("'nfsv4.1 export policy cannot be enabled on nfsv3 volume'")) + } + + // Validating that nfsv3 export policy is not set on nfsv4.1 volume + if pointer.From(rule.Nfsv3) && strings.EqualFold(protocolType, string(ProtocolTypeNfsV41)) { + errors = append(errors, fmt.Errorf("'nfsv3 export policy cannot be enabled on nfsv4.1 volume'")) + } + + return errors +} diff --git a/internal/services/netapp/validate/volume_group_oracle_volumes_export_policy_validation_test.go b/internal/services/netapp/validate/volume_group_oracle_volumes_export_policy_validation_test.go new file mode 100644 index 000000000000..efdb816460ea --- /dev/null +++ b/internal/services/netapp/validate/volume_group_oracle_volumes_export_policy_validation_test.go @@ -0,0 +1,104 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validate + +import ( + "testing" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/volumegroups" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +func TestValidateNetAppVolumeGroupExportPolicyRuleOracle(t *testing.T) { + cases := []struct { + Name string + Protocol string + Rule volumegroups.ExportPolicyRule + Errors int + }{ + { + Name: "ValidateNFSv41EnabledOnNFSv41Volume", + Protocol: string(ProtocolTypeNfsV41), + Rule: volumegroups.ExportPolicyRule{ + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + Errors: 0, + }, + { + Name: "ValidateNFSv3EnabledOnNFSv3Volume", + Protocol: string(ProtocolTypeNfsV3), + Rule: volumegroups.ExportPolicyRule{ + Nfsv3: pointer.To(true), + Nfsv41: utils.Bool(false), + }, + Errors: 0, + }, + { + Name: "ValidateBothProtocolsNotEnabledAtSameTimeOnNFSv41Volume", + Protocol: string(ProtocolTypeNfsV41), + Rule: volumegroups.ExportPolicyRule{ + Nfsv3: pointer.To(true), + Nfsv41: utils.Bool(true), + }, + Errors: 2, + }, + { + Name: "ValidateBothProtocolsNotEnabledAtSameTimeOnNFSv3Volume", + Protocol: string(ProtocolTypeNfsV3), + Rule: volumegroups.ExportPolicyRule{ + Nfsv3: pointer.To(true), + Nfsv41: utils.Bool(true), + }, + Errors: 2, + }, + { + Name: "ValidateBothProtocolsNotDisabledAtSameTimeOnNFSv3Volume", + Protocol: string(ProtocolTypeNfsV3), + Rule: volumegroups.ExportPolicyRule{ + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(false), + }, + Errors: 1, + }, + { + Name: "ValidateBothProtocolsNotDisabledAtSameTimeOnNFSv41Volume", + Protocol: string(ProtocolTypeNfsV41), + Rule: volumegroups.ExportPolicyRule{ + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(false), + }, + Errors: 1, + }, + { + Name: "ValidateNFSv3NotEnabledOnNFSv41Volume", + Protocol: string(ProtocolTypeNfsV41), + Rule: volumegroups.ExportPolicyRule{ + Nfsv3: pointer.To(true), + Nfsv41: utils.Bool(false), + }, + Errors: 1, + }, + { + Name: "ValidateNFSv41NotEnabledOnNFSv3Volume", + Protocol: string(ProtocolTypeNfsV3), + Rule: volumegroups.ExportPolicyRule{ + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + Errors: 1, + }, + } + + for _, tc := range cases { + t.Run(tc.Name, func(t *testing.T) { + errors := ValidateNetAppVolumeGroupExportPolicyRuleOracle(tc.Rule, tc.Protocol) + + if len(errors) != tc.Errors { + t.Fatalf("expected ValidateNetAppVolumeGroupOracleVolumes to return %d error(s) not %d", tc.Errors, len(errors)) + } + }) + } +} diff --git a/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go b/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go new file mode 100644 index 000000000000..cd3b033c0cba --- /dev/null +++ b/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go @@ -0,0 +1,169 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validate + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/volumegroups" +) + +type VolumeSpecNameOracle string + +const ( + VolumeSpecNameOracleData1 VolumeSpecNameOracle = "ora-data1" + VolumeSpecNameOracleData2 VolumeSpecNameOracle = "ora-data2" + VolumeSpecNameOracleData3 VolumeSpecNameOracle = "ora-data3" + VolumeSpecNameOracleData4 VolumeSpecNameOracle = "ora-data4" + VolumeSpecNameOracleData5 VolumeSpecNameOracle = "ora-data5" + VolumeSpecNameOracleData6 VolumeSpecNameOracle = "ora-data6" + VolumeSpecNameOracleData7 VolumeSpecNameOracle = "ora-data7" + VolumeSpecNameOracleData8 VolumeSpecNameOracle = "ora-data8" + VolumeSpecNameOracleLog VolumeSpecNameOracle = "ora-log" + VolumeSpecNameOracleMirror VolumeSpecNameOracle = "ora-log-mirror" + VolumeSpecNameOracleBinary VolumeSpecNameOracle = "ora-binary" + VolumeSpecNameOracleBackup VolumeSpecNameOracle = "ora-backup" +) + +func PossibleValuesForVolumeSpecNameOracle() []string { + return []string{ + string(VolumeSpecNameOracleData1), + string(VolumeSpecNameOracleData2), + string(VolumeSpecNameOracleData3), + string(VolumeSpecNameOracleData4), + string(VolumeSpecNameOracleData5), + string(VolumeSpecNameOracleData6), + string(VolumeSpecNameOracleData7), + string(VolumeSpecNameOracleData8), + string(VolumeSpecNameOracleLog), + string(VolumeSpecNameOracleMirror), + string(VolumeSpecNameOracleBinary), + string(VolumeSpecNameOracleBackup), + } +} + +func RequiredVolumesForOracle() []string { + return []string{ + string(VolumeSpecNameOracleData1), + string(VolumeSpecNameOracleLog), + } +} + +func PossibleValuesForProtocolTypeVolumeGroupOracle() []string { + return []string{ + string(ProtocolTypeNfsV41), + string(ProtocolTypeNfsV3), + } +} + +func ValidateNetAppVolumeGroupOracleVolumes(volumeList *[]volumegroups.VolumeGroupVolumeProperties) []error { + errors := make([]error, 0) + volumeSpecRepeatCount := make(map[string]int) + applicationType := string(volumegroups.ApplicationTypeSAPNegativeHANA) + + // Validating minimum volume count + if len(*volumeList) < len(RequiredVolumesForOracle()) { + errors = append(errors, fmt.Errorf("'minimum %v volumes are required for %v'", len(RequiredVolumesForOracle()), applicationType)) + } + + // Validating each volume + for _, volume := range pointer.From(volumeList) { + // Get protocol list + protocolTypeList := pointer.From(volume.Properties.ProtocolTypes) + protocolType := "" + + // Validate protocol list is not empty + if len(protocolTypeList) == 0 { + errors = append(errors, fmt.Errorf("'protocol type list cannot be empty'")) + } + + // Validate protocol list is not > 1 + if len(protocolTypeList) > 1 { + errors = append(errors, fmt.Errorf("'multi-protocol volumes are not supported, protocol count is %v'", len(protocolTypeList))) + } + + // Getting protocol for next validations + if len(protocolTypeList) > 0 { + protocolType = protocolTypeList[0] + } + + // Validate protocol list does not contain invalid protocols + for _, protocol := range protocolTypeList { + if !findStringInSlice(PossibleValuesForProtocolType(), protocolType) { + errors = append(errors, fmt.Errorf("'protocol %v is invalid'", protocol)) + } + } + + // Validate that protocol is valid for SAP Hana + if !findStringInSlice(PossibleValuesForProtocolTypeVolumeGroupOracle(), protocolType) { + errors = append(errors, fmt.Errorf("'protocol %v is invalid for Oracle'", protocolType)) + } + + // TODO: // Can't be nfsv3 on data, log and share volumes + // if strings.EqualFold(protocolType, string(ProtocolTypeNfsV3)) && + // (strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleData)) || + // strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleShared)) || + // strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleLog))) { + // errors = append(errors, fmt.Errorf("'nfsv3 on data, log and shared volumes for %v is not supported on volume %v'", applicationType, pointer.From(volume.Name))) + // } + + // Validating export policies + if volume.Properties.ExportPolicy != nil { + for _, rule := range pointer.From(volume.Properties.ExportPolicy.Rules) { + errors = append(errors, ValidateNetAppVolumeGroupExportPolicyRuleOracle(rule, protocolType)...) + } + } + + // Checking CRR rule that log cannot be DataProtection type + if strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleLog)) && + volume.Properties.DataProtection != nil && + volume.Properties.DataProtection.Replication != nil && + strings.EqualFold(string(pointer.From(volume.Properties.DataProtection.Replication.EndpointType)), string(volumegroups.EndpointTypeDst)) { + errors = append(errors, fmt.Errorf("'log volume spec type cannot be DataProtection type for %v on volume %v'", applicationType, pointer.From(volume.Name))) + } + + // Validating that snapshot policies are not being created in a data protection volume + if volume.Properties.DataProtection != nil && + volume.Properties.DataProtection.Snapshot != nil && + (volume.Properties.DataProtection.Replication != nil && strings.EqualFold(string(pointer.From(volume.Properties.DataProtection.Replication.EndpointType)), string(volumegroups.EndpointTypeDst))) { + errors = append(errors, fmt.Errorf("'snapshot policy cannot be enabled on a data protection volume for %v on volume %v'", applicationType, pointer.From(volume.Name))) + } + + // TODO: // Validating that data-backup and log-backup don't have PPG defined + // if (strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleDataBackup)) || + // strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleLogBackup))) && + // pointer.From(volume.Properties.ProximityPlacementGroup) != "" { + // errors = append(errors, fmt.Errorf("'%v volume spec type cannot have PPG defined for %v on volume %v'", pointer.From(volume.Properties.VolumeSpecName), applicationType, pointer.From(volume.Name))) + // } + + // TODO: // Validating that data, log and shared have PPG defined. + // if (strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleData)) || + // strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleLog)) || + // strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleShared))) && + // pointer.From(volume.Properties.ProximityPlacementGroup) == "" { + // errors = append(errors, fmt.Errorf("'%v volume spec type must have PPG defined for %v on volume %v'", pointer.From(volume.Properties.VolumeSpecName), applicationType, pointer.From(volume.Name))) + // } + + // Adding volume spec name to hashmap for post volume loop check + volumeSpecRepeatCount[pointer.From(volume.Properties.VolumeSpecName)] += 1 + } + + // Validating required volume spec types + for _, requiredVolumeSpec := range RequiredVolumesForOracle() { + if _, ok := volumeSpecRepeatCount[requiredVolumeSpec]; !ok { + errors = append(errors, fmt.Errorf("'required volume spec type %v is not present for %v'", requiredVolumeSpec, applicationType)) + } + } + + // Validating that volume spec does not repeat + for volumeSpecName, count := range volumeSpecRepeatCount { + if count > 1 { + errors = append(errors, fmt.Errorf("'volume spec type %v cannot be repeated for %v'", volumeSpecName, applicationType)) + } + } + + return errors +} diff --git a/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go b/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go new file mode 100644 index 000000000000..bf903e4bfee5 --- /dev/null +++ b/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go @@ -0,0 +1,864 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validate + +import ( + "fmt" + "testing" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/volumegroups" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +func TestValidateNetAppVolumeGroupOracleVolumes(t *testing.T) { + cases := []struct { + Name string + VolumesData []volumegroups.VolumeGroupVolumeProperties + Errors int + }{ + { + Name: "ValidateCorrectSettingsAllVolumesPPG", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + }, + }, + { // data2 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData2))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData2)), + }, + }, + { // data3 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData3))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData3)), + }, + }, + { // data4 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData4))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData4)), + }, + }, + { // data5 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData5))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData5)), + }, + }, + { // data6 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData6))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData6)), + }, + }, + { // data7 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData7))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData7)), + }, + }, + { // data8 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData8))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData8)), + }, + }, + { // log + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + }, + }, + { // binary + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleBinary))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleBinary)), + }, + }, + { // mirror + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleMirror))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleMirror)), + }, + }, + { // backup + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleBackup))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleBackup)), + }, + }, + }, + Errors: 0, + }, + { + Name: "ValidateCorrectSettingsAllVolumesAvailabilityZone", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + }, + Zones: pointer.To([]string{"1"}), + }, + { // data2 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData2))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData2)), + }, + Zones: pointer.To([]string{"1"}), + }, + { // data3 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData3))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData3)), + }, + Zones: pointer.To([]string{"1"}), + }, + { // data4 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData4))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData4)), + }, + Zones: pointer.To([]string{"1"}), + }, + { // data5 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData5))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData5)), + }, + Zones: pointer.To([]string{"1"}), + }, + { // data6 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData6))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData6)), + }, + Zones: pointer.To([]string{"1"}), + }, + { // data7 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData7))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData7)), + }, + Zones: pointer.To([]string{"1"}), + }, + { // data8 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData8))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData8)), + }, + Zones: pointer.To([]string{"1"}), + }, + { // log + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + }, + Zones: pointer.To([]string{"1"}), + }, + { // binary + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleBinary))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleBinary)), + }, + Zones: pointer.To([]string{"1"}), + }, + { // mirror + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleMirror))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleMirror)), + }, + Zones: pointer.To([]string{"1"}), + }, + { // backup + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleBackup))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleBackup)), + }, + Zones: pointer.To([]string{"1"}), + }, + }, + Errors: 0, + }, + { + Name: "ValidateMinimumVolumes", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + }, + }, + { // log + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + }, + }, + }, + Errors: 0, + }, + { + Name: "ValidateRequiredVolumeSpecs", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // mirror + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleMirror))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleMirror)), + }, + }, + { // binary + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleBinary))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleBinary)), + }, + }, + }, + Errors: 2, + }, + { + Name: "ValidateLessThanMinimumVolumes", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + }, + }, + }, + Errors: 2, + }, + { + Name: "ValidateMultiProtocolFails", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1", "NFSv3"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + }, + }, + }, + Errors: 3, + }, + { + Name: "ValidateNoProtocolFails", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + }, + }, + }, + Errors: 4, + }, + { + Name: "ValidateInvalidProtocolList", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1", "InvalidProtocol"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + }, + }, + }, + Errors: 3, + }, + { + Name: "ValidateInvalidProtocol", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"InvalidProtocol"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + }, + }, + }, + Errors: 4, + }, + { + Name: "ValidateCIFSInvalidProtocolForOracle", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"CIFS"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + }, + }, + }, + Errors: 3, + }, + // TODO: + // { + // Name: "ValidateNoNfsVersionThreeOnDataLogAndSharedVolumes", + // VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + // { // data + // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData))), + // Properties: volumegroups.VolumeProperties{ + // ProtocolTypes: pointer.To([]string{"NFSv3"}), + // ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData)), + // }, + // }, + // { // log + // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + // Properties: volumegroups.VolumeProperties{ + // ProtocolTypes: pointer.To([]string{"NFSv3"}), + // ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + // }, + // }, + // { // shared + // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleShared))), + // Properties: volumegroups.VolumeProperties{ + // ProtocolTypes: pointer.To([]string{"NFSv3"}), + // ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleShared)), + // }, + // }, + // }, + // Errors: 3, + // }, + // TODO: + // { + // Name: "ValidateNoPPGBackupVolumes", + // VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + // { // data + // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData))), + // Properties: volumegroups.VolumeProperties{ + // ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + // ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + // SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData)), + // }, + // }, + // { // log + // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + // Properties: volumegroups.VolumeProperties{ + // ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + // ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + // SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + // }, + // }, + // { // data-backup + // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleDataBackup))), + // Properties: volumegroups.VolumeProperties{ + // ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + // ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleDataBackup)), + // }, + // }, + // { // log-backup + // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLogBackup))), + // Properties: volumegroups.VolumeProperties{ + // ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + // ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLogBackup)), + // }, + // }, + // }, + // Errors: 2, + // }, + // TODO: + //{ + // Name: "ValidateRequiredPpgForNonBackupVolumes", + // VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + // { // data + // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData))), + // Properties: volumegroups.VolumeProperties{ + // ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + // SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData)), + // }, + // }, + // { // log + // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + // Properties: volumegroups.VolumeProperties{ + // ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + // SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + // }, + // }, + // { // shared + // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleShared))), + // Properties: volumegroups.VolumeProperties{ + // ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + // SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleShared)), + // }, + // }, + // }, + // Errors: 3, + // }, + { + Name: "ValidateVolumeSpecCantRepeat", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + }, + }, + { // log + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + }, + }, + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + }, + }, + }, + Errors: 1, + }, + { + Name: "ValidateEndpointDstNotEnabledOnLogVolume", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + }, + }, + { // log + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + DataProtection: &volumegroups.VolumePropertiesDataProtection{ + Replication: &volumegroups.ReplicationObject{ + EndpointType: pointer.To(volumegroups.EndpointTypeDst), + }, + }, + }, + }, + }, + Errors: 1, + }, + { + Name: "ValidateSnapshotPolicyNotEnabledOnEndpointDstVolume", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + DataProtection: &volumegroups.VolumePropertiesDataProtection{ + Replication: &volumegroups.ReplicationObject{ + EndpointType: pointer.To(volumegroups.EndpointTypeDst), + }, + Snapshot: &volumegroups.VolumeSnapshotProperties{ + SnapshotPolicyId: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.NetApp/netAppAccounts/account1/capacityPools/pool1/volumes/volume1/snapshotPolicies/snapshotPolicy1"), + }, + }, + }, + }, + { // log + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + }, + }, + }, + Errors: 1, + }, + } + + for _, tc := range cases { + t.Run(tc.Name, func(t *testing.T) { + errors := ValidateNetAppVolumeGroupOracleVolumes(pointer.To(tc.VolumesData)) + + if len(errors) != tc.Errors { + t.Fatalf("expected ValidateNetAppVolumeGroupOracleVolumes to return %d error(s) not %d\nError List: \n%v", tc.Errors, len(errors), errors) + } + }) + } +} diff --git a/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation.go b/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation.go index be863b92a9b8..1716968cd013 100644 --- a/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation.go +++ b/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation.go @@ -38,22 +38,6 @@ func RequiredVolumesForSAPHANA() []string { } } -type ProtocolType string - -const ( - ProtocolTypeNfsV41 ProtocolType = "NFSv4.1" - ProtocolTypeNfsV3 ProtocolType = "NFSv3" - ProtocolTypeCifs ProtocolType = "CIFS" -) - -func PossibleValuesForProtocolType() []string { - return []string{ - string(ProtocolTypeNfsV41), - string(ProtocolTypeNfsV3), - string(ProtocolTypeCifs), - } -} - func PossibleValuesForProtocolTypeVolumeGroupSapHana() []string { return []string{ string(ProtocolTypeNfsV41), @@ -169,12 +153,3 @@ func ValidateNetAppVolumeGroupSAPHanaVolumes(volumeList *[]volumegroups.VolumeGr return errors } - -func findStringInSlice(slice []string, val string) bool { - for _, item := range slice { - if strings.EqualFold(item, val) { - return true - } - } - return false -} From 695a063e34ca57f0d10fd116e0341d74df5ee95c Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 27 Nov 2024 18:07:43 +0000 Subject: [PATCH 02/39] WIP: AVG for Oracle support --- .../netapp_volume_group_oracle_resource.go | 108 +- ...etapp_volume_group_oracle_resource_test.go | 3072 ++++++++++------- .../netapp_volume_group_sap_hana_resource.go | 2 +- ...e_volumes_export_policy_validation_test.go | 2 +- .../volume_group_oracle_volumes_validation.go | 24 +- ...me_group_oracle_volumes_validation_test.go | 226 +- ...p_hana_volumes_export_policy_validation.go | 38 - ...a_volumes_export_policy_validation_test.go | 2 +- ...olume_group_sap_hana_volumes_validation.go | 2 +- ...group_volumes_export_policy_validation.go} | 2 +- 10 files changed, 1970 insertions(+), 1508 deletions(-) delete mode 100644 internal/services/netapp/validate/volume_group_sap_hana_volumes_export_policy_validation.go rename internal/services/netapp/validate/{volume_group_oracle_volumes_export_policy_validation.go => volume_group_volumes_export_policy_validation.go} (91%) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource.go b/internal/services/netapp/netapp_volume_group_oracle_resource.go index cf5098563645..7fa85024ef1d 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource.go @@ -6,8 +6,6 @@ package netapp import ( "context" "fmt" - "log" - "strings" "time" "github.com/hashicorp/go-azure-helpers/lang/pointer" @@ -18,7 +16,6 @@ import ( "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/capacitypools" "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/volumegroups" "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/volumes" - "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/volumesreplication" "github.com/hashicorp/terraform-provider-azurerm/helpers/azure" "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" netAppModels "github.com/hashicorp/terraform-provider-azurerm/internal/services/netapp/models" @@ -105,11 +102,9 @@ func (r NetAppVolumeGroupOracleResource) Arguments() map[string]*pluginsdk.Schem }, "proximity_placement_group_id": { - Type: pluginsdk.TypeString, - Optional: true, - ForceNew: true, - ValidateFunc: azure.ValidateResourceID, - ConflictsWith: []string{"zone"}, + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, }, "zone": commonschema.ZoneSingleOptionalForceNew(), @@ -243,37 +238,6 @@ func (r NetAppVolumeGroupOracleResource) Arguments() map[string]*pluginsdk.Schem }, }, - "data_protection_replication": { - Type: pluginsdk.TypeList, - Optional: true, - MaxItems: 1, - ForceNew: true, - Elem: &pluginsdk.Resource{ - Schema: map[string]*pluginsdk.Schema{ - "endpoint_type": { - Type: pluginsdk.TypeString, - Optional: true, - Default: string(volumegroups.EndpointTypeDst), - ValidateFunc: validation.StringInSlice(volumegroups.PossibleValuesForEndpointType(), false), - }, - - "remote_volume_location": commonschema.LocationWithoutForceNew(), - - "remote_volume_resource_id": { - Type: pluginsdk.TypeString, - Required: true, - ValidateFunc: azure.ValidateResourceID, - }, - - "replication_frequency": { - Type: pluginsdk.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice(netAppModels.PossibleValuesForReplicationSchedule(), false), - }, - }, - }, - }, - "data_protection_snapshot_policy": { Type: pluginsdk.TypeList, Optional: true, @@ -303,7 +267,7 @@ func (r NetAppVolumeGroupOracleResource) Create() sdk.ResourceFunc { Timeout: 90 * time.Minute, Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { client := metadata.Client.NetApp.VolumeGroupClient - replicationClient := metadata.Client.NetApp.VolumeReplicationClient + //replicationClient := metadata.Client.NetApp.VolumeReplicationClient subscriptionId := metadata.Client.Account.SubscriptionId @@ -334,17 +298,6 @@ func (r NetAppVolumeGroupOracleResource) Create() sdk.ResourceFunc { return fmt.Errorf("one or more issues found while performing deeper validations for %s:\n%+v", id, errorList) } - // Parse volume list to set secondary volumes for CRR - for i, volumeCrr := range pointer.From(volumeList) { - if volumeCrr.Properties.DataProtection != nil && - volumeCrr.Properties.DataProtection.Replication != nil && - strings.EqualFold(string(pointer.From(volumeCrr.Properties.DataProtection.Replication.EndpointType)), string(volumegroups.EndpointTypeDst)) { - // Modify volumeType as data protection type on main volumeList - // so it gets created correctly as data protection volume - (pointer.From(volumeList))[i].Properties.VolumeType = utils.String("DataProtection") - } - } - parameters := volumegroups.VolumeGroupDetails{ Location: utils.String(location.Normalize(model.Location)), Properties: &volumegroups.VolumeGroupProperties{ @@ -367,46 +320,6 @@ func (r NetAppVolumeGroupOracleResource) Create() sdk.ResourceFunc { return err } - // CRR - Authorizing secondaries from primary volumes - for _, volumeCrr := range pointer.From(volumeList) { - if volumeCrr.Properties.DataProtection != nil && - volumeCrr.Properties.DataProtection.Replication != nil && - strings.EqualFold(string(pointer.From(volumeCrr.Properties.DataProtection.Replication.EndpointType)), string(volumegroups.EndpointTypeDst)) { - capacityPoolId, err := capacitypools.ParseCapacityPoolID(pointer.From(volumeCrr.Properties.CapacityPoolResourceId)) - if err != nil { - return err - } - - // Getting secondary volume resource id - secondaryId := volumes.NewVolumeID(subscriptionId, - model.ResourceGroupName, - model.AccountName, - capacityPoolId.CapacityPoolName, - getUserDefinedVolumeName(volumeCrr.Name), - ) - - // Getting primary resource id - primaryId, err := volumesreplication.ParseVolumeID(volumeCrr.Properties.DataProtection.Replication.RemoteVolumeResourceId) - if err != nil { - return err - } - - // Authorizing - if err = replicationClient.VolumesAuthorizeReplicationThenPoll(ctx, pointer.From(primaryId), volumesreplication.AuthorizeRequest{ - RemoteVolumeResourceId: utils.String(secondaryId.ID()), - }, - ); err != nil { - return fmt.Errorf("cannot authorize volume replication: %v", err) - } - - // Wait for volume replication authorization to complete - log.Printf("[DEBUG] Waiting for replication authorization on %s to complete", id) - if err := waitForReplAuthorization(ctx, replicationClient, pointer.From(primaryId)); err != nil { - return err - } - } - } - metadata.SetID(id) return nil @@ -476,7 +389,7 @@ func (r NetAppVolumeGroupOracleResource) Update() sdk.ResourceFunc { rule.Nfsv3 = utils.Bool(v["nfsv3_enabled"].(bool)) rule.Nfsv41 = utils.Bool(v["nfsv41_enabled"].(bool)) - errors = append(errors, netAppValidate.ValidateNetAppVolumeGroupExportPolicyRuleOracle(rule, volumeProtocol)...) + errors = append(errors, netAppValidate.ValidateNetAppVolumeGroupExportPolicyRule(rule, volumeProtocol)...) } } @@ -489,17 +402,6 @@ func (r NetAppVolumeGroupOracleResource) Update() sdk.ResourceFunc { } if metadata.ResourceData.HasChange(fmt.Sprintf("%v.data_protection_snapshot_policy", volumeItem)) { - // Validating that snapshot policies are not being created in a data protection volume - dataProtectionReplicationRaw := metadata.ResourceData.Get(fmt.Sprintf("%v.data_protection_replication", volumeItem)).([]interface{}) - dataProtectionReplication := expandNetAppVolumeDataProtectionReplication(dataProtectionReplicationRaw) - - if dataProtectionReplication != nil && - dataProtectionReplication.Replication != nil && - dataProtectionReplication.Replication.EndpointType != nil && - strings.EqualFold(string(pointer.From(dataProtectionReplication.Replication.EndpointType)), string(volumegroups.EndpointTypeDst)) { - return fmt.Errorf("snapshot policy cannot be enabled on a data protection volume, %s", volumeId) - } - dataProtectionSnapshotPolicyRaw := metadata.ResourceData.Get(fmt.Sprintf("%v.data_protection_snapshot_policy", volumeItem)).([]interface{}) dataProtectionSnapshotPolicy := expandNetAppVolumeDataProtectionSnapshotPolicyPatch(dataProtectionSnapshotPolicyRaw) update.Properties.DataProtection = dataProtectionSnapshotPolicy diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index 509832faae96..4ac05de8c9b4 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -34,13 +34,13 @@ func TestAccNetAppVolumeGroupOracle_basic(t *testing.T) { }) } -func TestAccNetAppVolumeGroupOracle_backupVolumeSpecsNfsv3(t *testing.T) { +func TestAccNetAppVolumeGroupOracle_nfsv3(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") r := NetAppVolumeGroupOracleResource{} data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.backupVolumeSpecsNfsv3(data), + Config: r.nfsv3(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), @@ -49,85 +49,100 @@ func TestAccNetAppVolumeGroupOracle_backupVolumeSpecsNfsv3(t *testing.T) { }) } -func TestAccNetAppVolumeGroupOracle_snapshotPolicy(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") - r := NetAppVolumeGroupOracleResource{} - - data.ResourceTest(t, r, []acceptance.TestStep{ - { - Config: r.avgSnapshotPolicy(data), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).ExistsInAzure(r), - ), - }, - data.ImportStep(), - }) -} - -func TestAccNetAppVolumeGroupOracle_snapshotPolicyUpdate(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") - r := NetAppVolumeGroupOracleResource{} - - data.ResourceTest(t, r, []acceptance.TestStep{ - { - Config: r.basic(data), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).ExistsInAzure(r), - ), - }, - data.ImportStep(), - { - Config: r.updateAvgSnapshotPolicy(data), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).ExistsInAzure(r), - ), - }, - data.ImportStep(), - }) -} - -func TestAccNetAppVolumeGroupOracle_volumeUpdates(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") - r := NetAppVolumeGroupOracleResource{} - - data.ResourceTest(t, r, []acceptance.TestStep{ - { - Config: r.basic(data), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).ExistsInAzure(r), - ), - }, - data.ImportStep(), - { - Config: r.updateVolumes(data), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("volume.0.storage_quota_in_gb").HasValue("1200"), - check.That(data.ResourceName).Key("volume.1.export_policy_rule.0.allowed_clients").HasValue("10.0.0.0/8"), - check.That(data.ResourceName).Key("volume.2.tags.CreatedOnDate").HasValue("2022-07-27T12:00:00Z"), - check.That(data.ResourceName).Key("volume.4.storage_quota_in_gb").HasValue("1200"), - check.That(data.ResourceName).Key("volume.4.export_policy_rule.0.allowed_clients").HasValue("192.168.0.0/24"), - check.That(data.ResourceName).Key("volume.4.tags.CreatedOnDate").HasValue("2022-07-28T11:00:00Z"), - ), - }, - data.ImportStep(), - }) -} - -func TestAccNetAppVolumeGroupOracle_crossRegionReplication(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test_secondary") - r := NetAppVolumeGroupOracleResource{} - - data.ResourceTest(t, r, []acceptance.TestStep{ - { - Config: r.crossRegionReplication(data), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).ExistsInAzure(r), - ), - }, - data.ImportStep(), - }) -} +// func TestAccNetAppVolumeGroupOracle_backupVolumeSpecsNfsv3(t *testing.T) { +// data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") +// r := NetAppVolumeGroupOracleResource{} + +// data.ResourceTest(t, r, []acceptance.TestStep{ +// { +// Config: r.backupVolumeSpecsNfsv3(data), +// Check: acceptance.ComposeTestCheckFunc( +// check.That(data.ResourceName).ExistsInAzure(r), +// ), +// }, +// data.ImportStep(), +// }) +// } + +// func TestAccNetAppVolumeGroupOracle_snapshotPolicy(t *testing.T) { +// data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") +// r := NetAppVolumeGroupOracleResource{} + +// data.ResourceTest(t, r, []acceptance.TestStep{ +// { +// Config: r.avgSnapshotPolicy(data), +// Check: acceptance.ComposeTestCheckFunc( +// check.That(data.ResourceName).ExistsInAzure(r), +// ), +// }, +// data.ImportStep(), +// }) +// } + +// func TestAccNetAppVolumeGroupOracle_snapshotPolicyUpdate(t *testing.T) { +// data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") +// r := NetAppVolumeGroupOracleResource{} + +// data.ResourceTest(t, r, []acceptance.TestStep{ +// { +// Config: r.basic(data), +// Check: acceptance.ComposeTestCheckFunc( +// check.That(data.ResourceName).ExistsInAzure(r), +// ), +// }, +// data.ImportStep(), +// { +// Config: r.updateAvgSnapshotPolicy(data), +// Check: acceptance.ComposeTestCheckFunc( +// check.That(data.ResourceName).ExistsInAzure(r), +// ), +// }, +// data.ImportStep(), +// }) +// } + +// func TestAccNetAppVolumeGroupOracle_volumeUpdates(t *testing.T) { +// data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") +// r := NetAppVolumeGroupOracleResource{} + +// data.ResourceTest(t, r, []acceptance.TestStep{ +// { +// Config: r.basic(data), +// Check: acceptance.ComposeTestCheckFunc( +// check.That(data.ResourceName).ExistsInAzure(r), +// ), +// }, +// data.ImportStep(), +// { +// Config: r.updateVolumes(data), +// Check: acceptance.ComposeTestCheckFunc( +// check.That(data.ResourceName).ExistsInAzure(r), +// check.That(data.ResourceName).Key("volume.0.storage_quota_in_gb").HasValue("1200"), +// check.That(data.ResourceName).Key("volume.1.export_policy_rule.0.allowed_clients").HasValue("10.0.0.0/8"), +// check.That(data.ResourceName).Key("volume.2.tags.CreatedOnDate").HasValue("2022-07-27T12:00:00Z"), +// check.That(data.ResourceName).Key("volume.4.storage_quota_in_gb").HasValue("1200"), +// check.That(data.ResourceName).Key("volume.4.export_policy_rule.0.allowed_clients").HasValue("192.168.0.0/24"), +// check.That(data.ResourceName).Key("volume.4.tags.CreatedOnDate").HasValue("2022-07-28T11:00:00Z"), +// ), +// }, +// data.ImportStep(), +// }) +// } + +// func TestAccNetAppVolumeGroupOracle_crossRegionReplication(t *testing.T) { +// data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test_secondary") +// r := NetAppVolumeGroupOracleResource{} + +// data.ResourceTest(t, r, []acceptance.TestStep{ +// { +// Config: r.crossRegionReplication(data), +// Check: acceptance.ComposeTestCheckFunc( +// check.That(data.ResourceName).ExistsInAzure(r), +// ), +// }, +// data.ImportStep(), +// }) +// } func (t NetAppVolumeGroupOracleResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { id, err := volumegroups.ParseVolumeGroupID(state.ID) @@ -147,26 +162,26 @@ func (t NetAppVolumeGroupOracleResource) Exists(ctx context.Context, clients *cl } func (NetAppVolumeGroupOracleResource) basic(data acceptance.TestData) string { - template := NetAppVolumeGroupOracleResource{}.templatePPG(data) + template := NetAppVolumeGroupOracleResource{}.templateAvailabilityZone(data) return fmt.Sprintf(` %[1]s resource "azurerm_netapp_volume_group_oracle" "test" { - name = "acctest-NetAppVolumeGroup-%[2]d" + name = "acctest-NetAppVolumeGroupOracle-%[2]d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name account_name = azurerm_netapp_account.test.name - group_description = "Test volume group" + group_description = "Test volume group for Oracle" application_identifier = "TST" volume { - name = "acctest-NetAppVolume-1-%[2]d" - volume_path = "my-unique-file-path-1-%[2]d" + name = "acctest-NetAppVolume-Ora1-%[2]d" + volume_path = "my-unique-file-ora-path-1-%[2]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "data" + zone = "1" + volume_spec_name = "ora-data1" storage_quota_in_gb = 1024 throughput_in_mibps = 24 protocols = ["NFSv4.1"] @@ -182,21 +197,16 @@ resource "azurerm_netapp_volume_group_oracle" "test" { unix_read_write = true root_access_enabled = false } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } volume { - name = "acctest-NetAppVolume-2-%[2]d" - volume_path = "my-unique-file-path-2-%[2]d" + name = "acctest-NetAppVolume-Ora2-%[2]d" + volume_path = "my-unique-file-ora-path-2-%[2]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "log" + zone = "1" + volume_spec_name = "ora-data2" storage_quota_in_gb = 1024 throughput_in_mibps = 24 protocols = ["NFSv4.1"] @@ -214,19 +224,18 @@ resource "azurerm_netapp_volume_group_oracle" "test" { } tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" + "foo" = "BAR", } } volume { - name = "acctest-NetAppVolume-3-%[2]d" - volume_path = "my-unique-file-path-3-%[2]d" + name = "acctest-NetAppVolume-Ora3-%[2]d" + volume_path = "my-unique-file-ora-path-3-%[2]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "shared" + zone = "1" + volume_spec_name = "ora-data3" storage_quota_in_gb = 1024 throughput_in_mibps = 24 protocols = ["NFSv4.1"] @@ -242,20 +251,16 @@ resource "azurerm_netapp_volume_group_oracle" "test" { unix_read_write = true root_access_enabled = false } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } volume { - name = "acctest-NetAppVolume-4-%[2]d" - volume_path = "my-unique-file-path-4-%[2]d" + name = "acctest-NetAppVolume-Ora4-%[2]d" + volume_path = "my-unique-file-ora-path-4-%[2]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id - volume_spec_name = "data-backup" + zone = "1" + volume_spec_name = "ora-data4" storage_quota_in_gb = 1024 throughput_in_mibps = 24 protocols = ["NFSv4.1"] @@ -271,20 +276,16 @@ resource "azurerm_netapp_volume_group_oracle" "test" { unix_read_write = true root_access_enabled = false } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } volume { - name = "acctest-NetAppVolume-5-%[2]d" - volume_path = "my-unique-file-path-5-%[2]d" + name = "acctest-NetAppVolume-Ora5-%[2]d" + volume_path = "my-unique-file-ora-path-5-%[2]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id - volume_spec_name = "log-backup" + zone = "1" + volume_spec_name = "ora-data5" storage_quota_in_gb = 1024 throughput_in_mibps = 24 protocols = ["NFSv4.1"] @@ -300,47 +301,21 @@ resource "azurerm_netapp_volume_group_oracle" "test" { unix_read_write = true root_access_enabled = false } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } - depends_on = [ - azurerm_linux_virtual_machine.test, - azurerm_proximity_placement_group.test - ] -} -`, template, data.RandomInteger) -} - -func (NetAppVolumeGroupOracleResource) backupVolumeSpecsNfsv3(data acceptance.TestData) string { - template := NetAppVolumeGroupOracleResource{}.templatePPG(data) - return fmt.Sprintf(` -%[1]s - -resource "azurerm_netapp_volume_group_oracle" "test" { - name = "acctest-NetAppVolumeGroup-%[2]d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - account_name = azurerm_netapp_account.test.name - group_description = "Test volume group" - application_identifier = "TST" - volume { - name = "acctest-NetAppVolume-1-%[2]d" - volume_path = "my-unique-file-path-1-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "data" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false + name = "acctest-NetAppVolume-Ora6-%[2]d" + volume_path = "my-unique-file-ora-path-6-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-data6" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false export_policy_rule { rule_index = 1 @@ -351,26 +326,21 @@ resource "azurerm_netapp_volume_group_oracle" "test" { unix_read_write = true root_access_enabled = false } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } volume { - name = "acctest-NetAppVolume-2-%[2]d" - volume_path = "my-unique-file-path-2-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "log" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false + name = "acctest-NetAppVolume-Ora7-%[2]d" + volume_path = "my-unique-file-ora-path-7-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-data7" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false export_policy_rule { rule_index = 1 @@ -381,26 +351,21 @@ resource "azurerm_netapp_volume_group_oracle" "test" { unix_read_write = true root_access_enabled = false } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } volume { - name = "acctest-NetAppVolume-3-%[2]d" - volume_path = "my-unique-file-path-3-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "shared" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false + name = "acctest-NetAppVolume-Ora8-%[2]d" + volume_path = "my-unique-file-ora-path-8-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-data8" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false export_policy_rule { rule_index = 1 @@ -411,1231 +376,1931 @@ resource "azurerm_netapp_volume_group_oracle" "test" { unix_read_write = true root_access_enabled = false } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } volume { - name = "acctest-NetAppVolume-4-%[2]d" - volume_path = "my-unique-file-path-4-%[2]d" + name = "acctest-NetAppVolume-OraLog-%[2]d" + volume_path = "my-unique-file-oralog-path-%[2]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id - volume_spec_name = "data-backup" + zone = "1" + volume_spec_name = "ora-log" storage_quota_in_gb = 1024 throughput_in_mibps = 24 - protocols = ["NFSv3"] + protocols = ["NFSv4.1"] security_style = "unix" snapshot_directory_visible = false export_policy_rule { rule_index = 1 allowed_clients = "0.0.0.0/0" - nfsv3_enabled = true - nfsv41_enabled = false + nfsv3_enabled = false + nfsv41_enabled = true unix_read_only = false unix_read_write = true root_access_enabled = false } + } - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" + volume { + name = "acctest-NetAppVolume-OraLogMirror-%[2]d" + volume_path = "my-unique-file-oralogmirror-path-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-log-mirror" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false } } volume { - name = "acctest-NetAppVolume-5-%[2]d" - volume_path = "my-unique-file-path-5-%[2]d" + name = "acctest-NetAppVolume-OraBinary-%[2]d" + volume_path = "my-unique-file-orabinary-path-%[2]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id - volume_spec_name = "log-backup" + zone = "1" + volume_spec_name = "ora-binary" storage_quota_in_gb = 1024 throughput_in_mibps = 24 - protocols = ["NFSv3"] + protocols = ["NFSv4.1"] security_style = "unix" snapshot_directory_visible = false export_policy_rule { rule_index = 1 allowed_clients = "0.0.0.0/0" - nfsv3_enabled = true - nfsv41_enabled = false + nfsv3_enabled = false + nfsv41_enabled = true unix_read_only = false unix_read_write = true root_access_enabled = false } + } - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" + volume { + name = "acctest-NetAppVolume-OraBackup-%[2]d" + volume_path = "my-unique-file-orabackup-path-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-backup" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false } } - - depends_on = [ - azurerm_linux_virtual_machine.test, - azurerm_proximity_placement_group.test - ] } `, template, data.RandomInteger) } -func (NetAppVolumeGroupOracleResource) avgSnapshotPolicy(data acceptance.TestData) string { - template := NetAppVolumeGroupOracleResource{}.templatePPG(data) +func (NetAppVolumeGroupOracleResource) nfsv3(data acceptance.TestData) string { + template := NetAppVolumeGroupOracleResource{}.templateAvailabilityZone(data) return fmt.Sprintf(` %[1]s -resource "azurerm_netapp_snapshot_policy" "test" { - name = "acctest-NetAppSnapshotPolicy-%[2]d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - account_name = azurerm_netapp_account.test.name - enabled = true - - monthly_schedule { - snapshots_to_keep = 1 - days_of_month = [15, 30] - hour = 23 - minute = 30 - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } -} - resource "azurerm_netapp_volume_group_oracle" "test" { - name = "acctest-NetAppVolumeGroup-%[2]d" + name = "acctest-NetAppVolumeGroupOracle-%[2]d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name account_name = azurerm_netapp_account.test.name - group_description = "Test volume group" + group_description = "Test volume group for Oracle" application_identifier = "TST" volume { - name = "acctest-NetAppVolume-1-%[2]d" - volume_path = "my-unique-file-path-1-%[2]d" + name = "acctest-NetAppVolume-Ora1-%[2]d" + volume_path = "my-unique-file-ora-path-1-%[2]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "data" + zone = "1" + volume_spec_name = "ora-data1" storage_quota_in_gb = 1024 throughput_in_mibps = 24 - protocols = ["NFSv4.1"] + protocols = ["NFSv3"] security_style = "unix" snapshot_directory_visible = false export_policy_rule { rule_index = 1 allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true + nfsv3_enabled = true + nfsv41_enabled = false unix_read_only = false unix_read_write = true root_access_enabled = false } - - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } volume { - name = "acctest-NetAppVolume-2-%[2]d" - volume_path = "my-unique-file-path-2-%[2]d" + name = "acctest-NetAppVolume-Ora2-%[2]d" + volume_path = "my-unique-file-ora-path-2-%[2]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "log" + zone = "1" + volume_spec_name = "ora-data2" storage_quota_in_gb = 1024 throughput_in_mibps = 24 - protocols = ["NFSv4.1"] + protocols = ["NFSv3"] security_style = "unix" snapshot_directory_visible = false export_policy_rule { rule_index = 1 allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true + nfsv3_enabled = true + nfsv41_enabled = false unix_read_only = false unix_read_write = true root_access_enabled = false } - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" + "foo" = "BAR", } } volume { - name = "acctest-NetAppVolume-3-%[2]d" - volume_path = "my-unique-file-path-3-%[2]d" + name = "acctest-NetAppVolume-Ora3-%[2]d" + volume_path = "my-unique-file-ora-path-3-%[2]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "shared" + zone = "1" + volume_spec_name = "ora-data3" storage_quota_in_gb = 1024 throughput_in_mibps = 24 - protocols = ["NFSv4.1"] + protocols = ["NFSv3"] security_style = "unix" snapshot_directory_visible = false export_policy_rule { rule_index = 1 allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true + nfsv3_enabled = true + nfsv41_enabled = false unix_read_only = false unix_read_write = true root_access_enabled = false } - - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } volume { - name = "acctest-NetAppVolume-4-%[2]d" - volume_path = "my-unique-file-path-4-%[2]d" + name = "acctest-NetAppVolume-Ora4-%[2]d" + volume_path = "my-unique-file-ora-path-4-%[2]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id - volume_spec_name = "data-backup" + zone = "1" + volume_spec_name = "ora-data4" storage_quota_in_gb = 1024 throughput_in_mibps = 24 - protocols = ["NFSv4.1"] + protocols = ["NFSv3"] security_style = "unix" snapshot_directory_visible = false export_policy_rule { rule_index = 1 allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true + nfsv3_enabled = true + nfsv41_enabled = false unix_read_only = false unix_read_write = true root_access_enabled = false } - - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } volume { - name = "acctest-NetAppVolume-5-%[2]d" - volume_path = "my-unique-file-path-5-%[2]d" + name = "acctest-NetAppVolume-Ora5-%[2]d" + volume_path = "my-unique-file-ora-path-5-%[2]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id - volume_spec_name = "log-backup" + zone = "1" + volume_spec_name = "ora-data5" storage_quota_in_gb = 1024 throughput_in_mibps = 24 - protocols = ["NFSv4.1"] + protocols = ["NFSv3"] security_style = "unix" snapshot_directory_visible = false export_policy_rule { rule_index = 1 allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true + nfsv3_enabled = true + nfsv41_enabled = false unix_read_only = false unix_read_write = true root_access_enabled = false } - - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - depends_on = [ - azurerm_linux_virtual_machine.test, - azurerm_proximity_placement_group.test - ] -} -`, template, data.RandomInteger) -} - -func (NetAppVolumeGroupOracleResource) updateAvgSnapshotPolicy(data acceptance.TestData) string { - template := NetAppVolumeGroupOracleResource{}.templatePPG(data) - return fmt.Sprintf(` -%[1]s - -resource "azurerm_netapp_snapshot_policy" "test" { - name = "acctest-NetAppSnapshotPolicy-New-%[2]d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - account_name = azurerm_netapp_account.test.name - enabled = true - - monthly_schedule { - snapshots_to_keep = 3 - days_of_month = [10, 25] - hour = 23 - minute = 30 - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } -} - -resource "azurerm_netapp_volume_group_oracle" "test" { - name = "acctest-NetAppVolumeGroup-%[2]d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - account_name = azurerm_netapp_account.test.name - group_description = "Test volume group" - application_identifier = "TST" - - volume { - name = "acctest-NetAppVolume-1-%[2]d" - volume_path = "my-unique-file-path-1-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "data" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-2-%[2]d" - volume_path = "my-unique-file-path-2-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "log" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-3-%[2]d" - volume_path = "my-unique-file-path-3-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "shared" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-4-%[2]d" - volume_path = "my-unique-file-path-4-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - volume_spec_name = "data-backup" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-5-%[2]d" - volume_path = "my-unique-file-path-5-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - volume_spec_name = "log-backup" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - depends_on = [ - azurerm_linux_virtual_machine.test, - azurerm_proximity_placement_group.test - ] -} -`, template, data.RandomInteger) -} - -func (NetAppVolumeGroupOracleResource) updateVolumes(data acceptance.TestData) string { - template := NetAppVolumeGroupOracleResource{}.templatePPG(data) - return fmt.Sprintf(` -%[1]s - -resource "azurerm_netapp_volume_group_oracle" "test" { - name = "acctest-NetAppVolumeGroup-%[2]d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - account_name = azurerm_netapp_account.test.name - group_description = "Test volume group" - application_identifier = "TST" - - volume { - name = "acctest-NetAppVolume-1-%[2]d" - volume_path = "my-unique-file-path-1-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "data" - storage_quota_in_gb = 1200 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-2-%[2]d" - volume_path = "my-unique-file-path-2-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "log" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "10.0.0.0/8" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-3-%[2]d" - volume_path = "my-unique-file-path-3-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "shared" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-27T12:00:00Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-4-%[2]d" - volume_path = "my-unique-file-path-4-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - volume_spec_name = "data-backup" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-5-%[2]d" - volume_path = "my-unique-file-path-5-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - volume_spec_name = "log-backup" - storage_quota_in_gb = 1200 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "192.168.0.0/24" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-28T11:00:00Z", - "SkipASMAzSecPack" = "true" - } - } - - depends_on = [ - azurerm_linux_virtual_machine.test, - azurerm_proximity_placement_group.test - ] -} -`, template, data.RandomInteger) -} - -func (NetAppVolumeGroupOracleResource) crossRegionReplication(data acceptance.TestData) string { - template := NetAppVolumeGroupOracleResource{}.templateForAvgCrossRegionReplication(data) - return fmt.Sprintf(` -%[1]s - -resource "azurerm_netapp_volume_group_oracle" "test_primary" { - name = "acctest-NetAppVolumeGroup-Primary-%[2]d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - account_name = azurerm_netapp_account.test.name - group_description = "Test volume group" - application_identifier = "TST" - - volume { - name = "acctest-NetAppVolume-1-Primary-%[2]d" - volume_path = "my-unique-file-path-1-Primary-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "data" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-2-Primary-%[2]d" - volume_path = "my-unique-file-path-2-Primary-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "log" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-3-Primary-%[2]d" - volume_path = "my-unique-file-path-3-Primary-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "shared" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } volume { - name = "acctest-NetAppVolume-4-Primary-%[2]d" - volume_path = "my-unique-file-path-4-Primary-%[2]d" + name = "acctest-NetAppVolume-Ora6-%[2]d" + volume_path = "my-unique-file-ora-path-6-%[2]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id - volume_spec_name = "data-backup" + zone = "1" + volume_spec_name = "ora-data6" storage_quota_in_gb = 1024 throughput_in_mibps = 24 - protocols = ["NFSv4.1"] + protocols = ["NFSv3"] security_style = "unix" snapshot_directory_visible = false export_policy_rule { rule_index = 1 allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true + nfsv3_enabled = true + nfsv41_enabled = false unix_read_only = false unix_read_write = true root_access_enabled = false } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } volume { - name = "acctest-NetAppVolume-5-Primary-%[2]d" - volume_path = "my-unique-file-path-5-Primary-%[2]d" + name = "acctest-NetAppVolume-Ora7-%[2]d" + volume_path = "my-unique-file-ora-path-7-%[2]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id - volume_spec_name = "log-backup" + zone = "1" + volume_spec_name = "ora-data7" storage_quota_in_gb = 1024 throughput_in_mibps = 24 - protocols = ["NFSv4.1"] + protocols = ["NFSv3"] security_style = "unix" snapshot_directory_visible = false export_policy_rule { rule_index = 1 allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true + nfsv3_enabled = true + nfsv41_enabled = false unix_read_only = false unix_read_write = true root_access_enabled = false } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } - depends_on = [ - azurerm_linux_virtual_machine.test, - azurerm_proximity_placement_group.test - ] -} - -resource "azurerm_netapp_volume_group_oracle" "test_secondary" { - name = "acctest-NetAppVolumeGroup-Secondary-%[2]d" - location = "%[3]s" - resource_group_name = azurerm_resource_group.test.name - account_name = azurerm_netapp_account.test_secondary.name - group_description = "Test volume group" - application_identifier = "TST" - volume { - name = "acctest-NetAppVolume-1-Secondary-%[2]d" - volume_path = "my-unique-file-path-1-Secondary-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test_secondary.id - subnet_id = azurerm_subnet.test_secondary.id - proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id - volume_spec_name = "data" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false + name = "acctest-NetAppVolume-Ora8-%[2]d" + volume_path = "my-unique-file-ora-path-8-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-data8" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv3"] + security_style = "unix" + snapshot_directory_visible = false export_policy_rule { rule_index = 1 allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true + nfsv3_enabled = true + nfsv41_enabled = false unix_read_only = false unix_read_write = true root_access_enabled = false } - - data_protection_replication { - endpoint_type = "dst" - remote_volume_location = azurerm_netapp_volume_group_oracle.test_primary.location - remote_volume_resource_id = azurerm_netapp_volume_group_oracle.test_primary.volume[0].id - replication_frequency = "10minutes" - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } volume { - name = "acctest-NetAppVolume-2-Secondary-%[2]d" - volume_path = "my-unique-file-path-2-Secondary-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test_secondary.id - subnet_id = azurerm_subnet.test_secondary.id - proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id - volume_spec_name = "log" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false + name = "acctest-NetAppVolume-OraLog-%[2]d" + volume_path = "my-unique-file-oralog-path-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv3"] + security_style = "unix" + snapshot_directory_visible = false export_policy_rule { rule_index = 1 allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true + nfsv3_enabled = true + nfsv41_enabled = false unix_read_only = false unix_read_write = true root_access_enabled = false } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } volume { - name = "acctest-NetAppVolume-3-Secondary-%[2]d" - volume_path = "my-unique-file-path-3-Secondary-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test_secondary.id - subnet_id = azurerm_subnet.test_secondary.id - proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id - volume_spec_name = "shared" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false + name = "acctest-NetAppVolume-OraLogMirror-%[2]d" + volume_path = "my-unique-file-oralogmirror-path-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-log-mirror" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv3"] + security_style = "unix" + snapshot_directory_visible = false export_policy_rule { rule_index = 1 allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true + nfsv3_enabled = true + nfsv41_enabled = false unix_read_only = false unix_read_write = true root_access_enabled = false } - - data_protection_replication { - endpoint_type = "dst" - remote_volume_location = azurerm_netapp_volume_group_oracle.test_primary.location - remote_volume_resource_id = azurerm_netapp_volume_group_oracle.test_primary.volume[2].id - replication_frequency = "10minutes" - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } volume { - name = "acctest-NetAppVolume-4-Secondary-%[2]d" - volume_path = "my-unique-file-path-4-Secondary-%[2]d" + name = "acctest-NetAppVolume-OraBinary-%[2]d" + volume_path = "my-unique-file-orabinary-path-%[2]d" service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test_secondary.id - subnet_id = azurerm_subnet.test_secondary.id - volume_spec_name = "data-backup" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-binary" storage_quota_in_gb = 1024 throughput_in_mibps = 24 - protocols = ["NFSv4.1"] + protocols = ["NFSv3"] security_style = "unix" snapshot_directory_visible = false export_policy_rule { rule_index = 1 allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true + nfsv3_enabled = true + nfsv41_enabled = false unix_read_only = false unix_read_write = true root_access_enabled = false } - - data_protection_replication { - endpoint_type = "dst" - remote_volume_location = azurerm_netapp_volume_group_oracle.test_primary.location - remote_volume_resource_id = azurerm_netapp_volume_group_oracle.test_primary.volume[3].id - replication_frequency = "10minutes" - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } volume { - name = "acctest-NetAppVolume-5-Secondary-%[2]d" - volume_path = "my-unique-file-path-5-Secondary-%[2]d" + name = "acctest-NetAppVolume-OraBackup-%[2]d" + volume_path = "my-unique-file-orabackup-path-%[2]d" service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test_secondary.id - subnet_id = azurerm_subnet.test_secondary.id - volume_spec_name = "log-backup" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-backup" storage_quota_in_gb = 1024 throughput_in_mibps = 24 - protocols = ["NFSv4.1"] + protocols = ["NFSv3"] security_style = "unix" snapshot_directory_visible = false export_policy_rule { rule_index = 1 allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true + nfsv3_enabled = true + nfsv41_enabled = false unix_read_only = false unix_read_write = true root_access_enabled = false } - - data_protection_replication { - endpoint_type = "dst" - remote_volume_location = azurerm_netapp_volume_group_oracle.test_primary.location - remote_volume_resource_id = azurerm_netapp_volume_group_oracle.test_primary.volume[4].id - replication_frequency = "10minutes" - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - depends_on = [ - azurerm_linux_virtual_machine.test_secondary, - azurerm_proximity_placement_group.test_secondary, - - ] -} - - -`, template, data.RandomInteger, "westus") -} - -func (r NetAppVolumeGroupOracleResource) templateForAvgCrossRegionReplication(data acceptance.TestData) string { - template := NetAppVolumeGroupOracleResource{}.templatePPG(data) - return fmt.Sprintf(` -%[1]s - -resource "azurerm_network_security_group" "test_secondary" { - name = "acctest-NSG-Secondary-%[2]d" - location = "%[3]s" - resource_group_name = azurerm_resource_group.test.name - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } -} - -resource "azurerm_virtual_network" "test_secondary" { - name = "acctest-VirtualNetwork-Secondary-%[2]d" - location = "%[3]s" - resource_group_name = azurerm_resource_group.test.name - address_space = ["10.6.0.0/16"] - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } -} - -resource "azurerm_subnet" "test_secondary" { - name = "acctest-DelegatedSubnet-%[2]d" - resource_group_name = azurerm_resource_group.test.name - virtual_network_name = azurerm_virtual_network.test_secondary.name - address_prefixes = ["10.6.2.0/24"] - - delegation { - name = "testdelegation" - - service_delegation { - name = "Microsoft.Netapp/volumes" - actions = ["Microsoft.Network/networkinterfaces/*", "Microsoft.Network/virtualNetworks/subnets/join/action"] - } - } -} - -resource "azurerm_subnet" "test1_secondary" { - name = "acctest-HostsSubnet-%[2]d" - resource_group_name = azurerm_resource_group.test.name - virtual_network_name = azurerm_virtual_network.test_secondary.name - address_prefixes = ["10.6.1.0/24"] -} - -resource "azurerm_subnet_network_security_group_association" "test_secondary" { - subnet_id = azurerm_subnet.test1_secondary.id - network_security_group_id = azurerm_network_security_group.test_secondary.id -} - -resource "azurerm_proximity_placement_group" "test_secondary" { - name = "acctest-PPG-Secondary-%[2]d" - location = "%[3]s" - resource_group_name = azurerm_resource_group.test.name - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } -} - -resource "azurerm_availability_set" "test_secondary" { - name = "acctest-avset-Secondary-%[2]d" - location = "%[3]s" - resource_group_name = azurerm_resource_group.test.name - - proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } -} - -resource "azurerm_network_interface" "test_secondary" { - name = "acctest-nic-Secondary-%[2]d" - resource_group_name = azurerm_resource_group.test.name - location = "%[3]s" - - ip_configuration { - name = "internal" - subnet_id = azurerm_subnet.test1_secondary.id - private_ip_address_allocation = "Dynamic" - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } -} - -resource "azurerm_linux_virtual_machine" "test_secondary" { - name = "acctest-vm-secondary-%[2]d" - resource_group_name = azurerm_resource_group.test.name - location = "%[3]s" - size = "Standard_M8ms" - admin_username = local.admin_username - admin_password = local.admin_password - disable_password_authentication = false - proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id - availability_set_id = azurerm_availability_set.test_secondary.id - network_interface_ids = [ - azurerm_network_interface.test_secondary.id - ] - - source_image_reference { - publisher = "Canonical" - offer = "0001-com-ubuntu-server-jammy" - sku = "22_04-lts" - version = "latest" - } - - os_disk { - storage_account_type = "Standard_LRS" - caching = "ReadWrite" - } - - tags = { - "platformsettings.host_environment.service.platform_optedin_for_rootcerts" = "true", - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true", - "Owner" = "pmarques" - } -} - -resource "azurerm_netapp_account" "test_secondary" { - name = "acctest-NetAppAccount-Secondary-%[2]d" - location = "%[3]s" - resource_group_name = azurerm_resource_group.test.name - - depends_on = [ - azurerm_subnet.test_secondary, - azurerm_subnet.test1_secondary - ] - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } -} - -resource "azurerm_netapp_pool" "test_secondary" { - name = "acctest-NetAppPool-Secondary-%[2]d" - location = "%[3]s" - resource_group_name = azurerm_resource_group.test.name - account_name = azurerm_netapp_account.test_secondary.name - service_level = "Standard" - size_in_tb = 8 - qos_type = "Manual" - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" } } -`, template, data.RandomInteger, "westus") +`, template, data.RandomInteger) } -func (NetAppVolumeGroupOracleResource) templatePPG(data acceptance.TestData) string { +// func (NetAppVolumeGroupOracleResource) backupVolumeSpecsNfsv3(data acceptance.TestData) string { +// template := NetAppVolumeGroupOracleResource{}.templatePPG(data) +// return fmt.Sprintf(` +// %[1]s + +// resource "azurerm_netapp_volume_group_oracle" "test" { +// name = "acctest-NetAppVolumeGroup-%[2]d" +// location = azurerm_resource_group.test.location +// resource_group_name = azurerm_resource_group.test.name +// account_name = azurerm_netapp_account.test.name +// group_description = "Test volume group" +// application_identifier = "TST" + +// volume { +// name = "acctest-NetAppVolume-Ora1-%[2]d" +// volume_path = "my-unique-file-ora-path-1-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "data" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora2-%[2]d" +// volume_path = "my-unique-file-ora-path-2-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "log" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora3-%[2]d" +// volume_path = "my-unique-file-ora-path-3-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "shared" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora4-%[2]d" +// volume_path = "my-unique-file-ora-path-4-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "data-backup" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv3"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = true +// nfsv41_enabled = false +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora5-%[2]d" +// volume_path = "my-unique-file-ora-path-5-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "log-backup" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv3"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = true +// nfsv41_enabled = false +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// depends_on = [ +// azurerm_linux_virtual_machine.test, +// azurerm_proximity_placement_group.test +// ] +// } +// `, template, data.RandomInteger) +// } + +// func (NetAppVolumeGroupOracleResource) avgSnapshotPolicy(data acceptance.TestData) string { +// template := NetAppVolumeGroupOracleResource{}.templatePPG(data) +// return fmt.Sprintf(` +// %[1]s + +// resource "azurerm_netapp_snapshot_policy" "test" { +// name = "acctest-NetAppSnapshotPolicy-%[2]d" +// location = azurerm_resource_group.test.location +// resource_group_name = azurerm_resource_group.test.name +// account_name = azurerm_netapp_account.test.name +// enabled = true + +// monthly_schedule { +// snapshots_to_keep = 1 +// days_of_month = [15, 30] +// hour = 23 +// minute = 30 +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// resource "azurerm_netapp_volume_group_oracle" "test" { +// name = "acctest-NetAppVolumeGroup-%[2]d" +// location = azurerm_resource_group.test.location +// resource_group_name = azurerm_resource_group.test.name +// account_name = azurerm_netapp_account.test.name +// group_description = "Test volume group" +// application_identifier = "TST" + +// volume { +// name = "acctest-NetAppVolume-Ora1-%[2]d" +// volume_path = "my-unique-file-ora-path-1-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "data" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// data_protection_snapshot_policy { +// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora2-%[2]d" +// volume_path = "my-unique-file-ora-path-2-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "log" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// data_protection_snapshot_policy { +// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora3-%[2]d" +// volume_path = "my-unique-file-ora-path-3-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "shared" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// data_protection_snapshot_policy { +// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora4-%[2]d" +// volume_path = "my-unique-file-ora-path-4-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "data-backup" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// data_protection_snapshot_policy { +// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora5-%[2]d" +// volume_path = "my-unique-file-ora-path-5-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "log-backup" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// data_protection_snapshot_policy { +// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// depends_on = [ +// azurerm_linux_virtual_machine.test, +// azurerm_proximity_placement_group.test +// ] +// } +// `, template, data.RandomInteger) +// } + +// func (NetAppVolumeGroupOracleResource) updateAvgSnapshotPolicy(data acceptance.TestData) string { +// template := NetAppVolumeGroupOracleResource{}.templatePPG(data) +// return fmt.Sprintf(` +// %[1]s + +// resource "azurerm_netapp_snapshot_policy" "test" { +// name = "acctest-NetAppSnapshotPolicy-New-%[2]d" +// location = azurerm_resource_group.test.location +// resource_group_name = azurerm_resource_group.test.name +// account_name = azurerm_netapp_account.test.name +// enabled = true + +// monthly_schedule { +// snapshots_to_keep = 3 +// days_of_month = [10, 25] +// hour = 23 +// minute = 30 +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// resource "azurerm_netapp_volume_group_oracle" "test" { +// name = "acctest-NetAppVolumeGroup-%[2]d" +// location = azurerm_resource_group.test.location +// resource_group_name = azurerm_resource_group.test.name +// account_name = azurerm_netapp_account.test.name +// group_description = "Test volume group" +// application_identifier = "TST" + +// volume { +// name = "acctest-NetAppVolume-Ora1-%[2]d" +// volume_path = "my-unique-file-ora-path-1-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "data" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// data_protection_snapshot_policy { +// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora2-%[2]d" +// volume_path = "my-unique-file-ora-path-2-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "log" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// data_protection_snapshot_policy { +// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora3-%[2]d" +// volume_path = "my-unique-file-ora-path-3-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "shared" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// data_protection_snapshot_policy { +// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora4-%[2]d" +// volume_path = "my-unique-file-ora-path-4-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "data-backup" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// data_protection_snapshot_policy { +// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora5-%[2]d" +// volume_path = "my-unique-file-ora-path-5-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "log-backup" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// data_protection_snapshot_policy { +// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// depends_on = [ +// azurerm_linux_virtual_machine.test, +// azurerm_proximity_placement_group.test +// ] +// } +// `, template, data.RandomInteger) +// } + +// func (NetAppVolumeGroupOracleResource) updateVolumes(data acceptance.TestData) string { +// template := NetAppVolumeGroupOracleResource{}.templatePPG(data) +// return fmt.Sprintf(` +// %[1]s + +// resource "azurerm_netapp_volume_group_oracle" "test" { +// name = "acctest-NetAppVolumeGroup-%[2]d" +// location = azurerm_resource_group.test.location +// resource_group_name = azurerm_resource_group.test.name +// account_name = azurerm_netapp_account.test.name +// group_description = "Test volume group" +// application_identifier = "TST" + +// volume { +// name = "acctest-NetAppVolume-Ora1-%[2]d" +// volume_path = "my-unique-file-ora-path-1-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "data" +// storage_quota_in_gb = 1200 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora2-%[2]d" +// volume_path = "my-unique-file-ora-path-2-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "log" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "10.0.0.0/8" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora3-%[2]d" +// volume_path = "my-unique-file-ora-path-3-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "shared" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// tags = { +// "CreatedOnDate" = "2022-07-27T12:00:00Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora4-%[2]d" +// volume_path = "my-unique-file-ora-path-4-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "data-backup" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora5-%[2]d" +// volume_path = "my-unique-file-ora-path-5-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "log-backup" +// storage_quota_in_gb = 1200 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "192.168.0.0/24" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// tags = { +// "CreatedOnDate" = "2022-07-28T11:00:00Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// depends_on = [ +// azurerm_linux_virtual_machine.test, +// azurerm_proximity_placement_group.test +// ] +// } +// `, template, data.RandomInteger) +// } + +// func (NetAppVolumeGroupOracleResource) crossRegionReplication(data acceptance.TestData) string { +// template := NetAppVolumeGroupOracleResource{}.templateForAvgCrossRegionReplication(data) +// return fmt.Sprintf(` +// %[1]s + +// resource "azurerm_netapp_volume_group_oracle" "test_primary" { +// name = "acctest-NetAppVolumeGroup-Primary-%[2]d" +// location = azurerm_resource_group.test.location +// resource_group_name = azurerm_resource_group.test.name +// account_name = azurerm_netapp_account.test.name +// group_description = "Test volume group" +// application_identifier = "TST" + +// volume { +// name = "acctest-NetAppVolume-Ora1-Primary-%[2]d" +// volume_path = "my-unique-file-ora-path-1-Primary-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "data" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora2-Primary-%[2]d" +// volume_path = "my-unique-file-ora-path-2-Primary-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "log" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora3-Primary-%[2]d" +// volume_path = "my-unique-file-ora-path-3-Primary-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "shared" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora4-Primary-%[2]d" +// volume_path = "my-unique-file-ora-path-4-Primary-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "data-backup" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora5-Primary-%[2]d" +// volume_path = "my-unique-file-ora-path-5-Primary-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "log-backup" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// depends_on = [ +// azurerm_linux_virtual_machine.test, +// azurerm_proximity_placement_group.test +// ] +// } + +// resource "azurerm_netapp_volume_group_oracle" "test_secondary" { +// name = "acctest-NetAppVolumeGroup-Secondary-%[2]d" +// location = "%[3]s" +// resource_group_name = azurerm_resource_group.test.name +// account_name = azurerm_netapp_account.test_secondary.name +// group_description = "Test volume group" +// application_identifier = "TST" + +// volume { +// name = "acctest-NetAppVolume-Ora1-Secondary-%[2]d" +// volume_path = "my-unique-file-ora-path-1-Secondary-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test_secondary.id +// subnet_id = azurerm_subnet.test_secondary.id +// proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id +// volume_spec_name = "data" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// data_protection_replication { +// endpoint_type = "dst" +// remote_volume_location = azurerm_netapp_volume_group_oracle.test_primary.location +// remote_volume_resource_id = azurerm_netapp_volume_group_oracle.test_primary.volume[0].id +// replication_frequency = "10minutes" +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora2-Secondary-%[2]d" +// volume_path = "my-unique-file-ora-path-2-Secondary-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test_secondary.id +// subnet_id = azurerm_subnet.test_secondary.id +// proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id +// volume_spec_name = "log" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora3-Secondary-%[2]d" +// volume_path = "my-unique-file-ora-path-3-Secondary-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test_secondary.id +// subnet_id = azurerm_subnet.test_secondary.id +// proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id +// volume_spec_name = "shared" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// data_protection_replication { +// endpoint_type = "dst" +// remote_volume_location = azurerm_netapp_volume_group_oracle.test_primary.location +// remote_volume_resource_id = azurerm_netapp_volume_group_oracle.test_primary.volume[2].id +// replication_frequency = "10minutes" +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora4-Secondary-%[2]d" +// volume_path = "my-unique-file-ora-path-4-Secondary-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test_secondary.id +// subnet_id = azurerm_subnet.test_secondary.id +// volume_spec_name = "data-backup" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// data_protection_replication { +// endpoint_type = "dst" +// remote_volume_location = azurerm_netapp_volume_group_oracle.test_primary.location +// remote_volume_resource_id = azurerm_netapp_volume_group_oracle.test_primary.volume[3].id +// replication_frequency = "10minutes" +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// volume { +// name = "acctest-NetAppVolume-Ora5-Secondary-%[2]d" +// volume_path = "my-unique-file-ora-path-5-Secondary-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test_secondary.id +// subnet_id = azurerm_subnet.test_secondary.id +// volume_spec_name = "log-backup" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } + +// data_protection_replication { +// endpoint_type = "dst" +// remote_volume_location = azurerm_netapp_volume_group_oracle.test_primary.location +// remote_volume_resource_id = azurerm_netapp_volume_group_oracle.test_primary.volume[4].id +// replication_frequency = "10minutes" +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// depends_on = [ +// azurerm_linux_virtual_machine.test_secondary, +// azurerm_proximity_placement_group.test_secondary, + +// ] +// } + +// `, template, data.RandomInteger, "westus") +// } + +// func (r NetAppVolumeGroupOracleResource) templateForAvgCrossRegionReplication(data acceptance.TestData) string { +// template := NetAppVolumeGroupOracleResource{}.templatePPG(data) +// return fmt.Sprintf(` +// %[1]s + +// resource "azurerm_network_security_group" "test_secondary" { +// name = "acctest-NSG-Secondary-%[2]d" +// location = "%[3]s" +// resource_group_name = azurerm_resource_group.test.name + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// resource "azurerm_virtual_network" "test_secondary" { +// name = "acctest-VirtualNetwork-Secondary-%[2]d" +// location = "%[3]s" +// resource_group_name = azurerm_resource_group.test.name +// address_space = ["10.6.0.0/16"] + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// resource "azurerm_subnet" "test_secondary" { +// name = "acctest-DelegatedSubnet-%[2]d" +// resource_group_name = azurerm_resource_group.test.name +// virtual_network_name = azurerm_virtual_network.test_secondary.name +// address_prefixes = ["10.6.2.0/24"] + +// delegation { +// name = "testdelegation" + +// service_delegation { +// name = "Microsoft.Netapp/volumes" +// actions = ["Microsoft.Network/networkinterfaces/*", "Microsoft.Network/virtualNetworks/subnets/join/action"] +// } +// } +// } + +// resource "azurerm_subnet" "test1_secondary" { +// name = "acctest-HostsSubnet-%[2]d" +// resource_group_name = azurerm_resource_group.test.name +// virtual_network_name = azurerm_virtual_network.test_secondary.name +// address_prefixes = ["10.6.1.0/24"] +// } + +// resource "azurerm_subnet_network_security_group_association" "test_secondary" { +// subnet_id = azurerm_subnet.test1_secondary.id +// network_security_group_id = azurerm_network_security_group.test_secondary.id +// } + +// resource "azurerm_proximity_placement_group" "test_secondary" { +// name = "acctest-PPG-Secondary-%[2]d" +// location = "%[3]s" +// resource_group_name = azurerm_resource_group.test.name + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// resource "azurerm_availability_set" "test_secondary" { +// name = "acctest-avset-Secondary-%[2]d" +// location = "%[3]s" +// resource_group_name = azurerm_resource_group.test.name + +// proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// resource "azurerm_network_interface" "test_secondary" { +// name = "acctest-nic-Secondary-%[2]d" +// resource_group_name = azurerm_resource_group.test.name +// location = "%[3]s" + +// ip_configuration { +// name = "internal" +// subnet_id = azurerm_subnet.test1_secondary.id +// private_ip_address_allocation = "Dynamic" +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// resource "azurerm_linux_virtual_machine" "test_secondary" { +// name = "acctest-vm-secondary-%[2]d" +// resource_group_name = azurerm_resource_group.test.name +// location = "%[3]s" +// size = "Standard_M8ms" +// admin_username = local.admin_username +// admin_password = local.admin_password +// disable_password_authentication = false +// proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id +// availability_set_id = azurerm_availability_set.test_secondary.id +// network_interface_ids = [ +// azurerm_network_interface.test_secondary.id +// ] + +// source_image_reference { +// publisher = "Canonical" +// offer = "0001-com-ubuntu-server-jammy" +// sku = "22_04-lts" +// version = "latest" +// } + +// os_disk { +// storage_account_type = "Standard_LRS" +// caching = "ReadWrite" +// } + +// tags = { +// "platformsettings.host_environment.service.platform_optedin_for_rootcerts" = "true", +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true", +// "Owner" = "pmarques" +// } +// } + +// resource "azurerm_netapp_account" "test_secondary" { +// name = "acctest-NetAppAccount-Secondary-%[2]d" +// location = "%[3]s" +// resource_group_name = azurerm_resource_group.test.name + +// depends_on = [ +// azurerm_subnet.test_secondary, +// azurerm_subnet.test1_secondary +// ] + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// resource "azurerm_netapp_pool" "test_secondary" { +// name = "acctest-NetAppPool-Secondary-%[2]d" +// location = "%[3]s" +// resource_group_name = azurerm_resource_group.test.name +// account_name = azurerm_netapp_account.test_secondary.name +// service_level = "Standard" +// size_in_tb = 8 +// qos_type = "Manual" + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } +// `, template, data.RandomInteger, "westus") +// } + +// func (NetAppVolumeGroupSapHanaResource) templatePPG(data acceptance.TestData) string { +// return fmt.Sprintf(` +// provider "azurerm" { +// alias = "all2" +// features { +// resource_group { +// prevent_deletion_if_contains_resources = false +// } +// netapp { +// prevent_volume_destruction = false +// delete_backups_on_backup_vault_destroy = true +// } +// } +// } + +// locals { +// admin_username = "testadmin%[1]d" +// admin_password = "Password1234!%[1]d" +// } + +// resource "azurerm_resource_group" "test" { +// name = "acctestRG-netapp-%[1]d" +// location = "%[2]s" + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true", +// "SkipNRMSNSG" = "true" +// } +// } + +// resource "azurerm_network_security_group" "test" { +// name = "acctest-NSG-%[1]d" +// location = azurerm_resource_group.test.location +// resource_group_name = azurerm_resource_group.test.name + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// resource "azurerm_virtual_network" "test" { +// name = "acctest-VirtualNetwork-%[1]d" +// location = azurerm_resource_group.test.location +// resource_group_name = azurerm_resource_group.test.name +// address_space = ["10.6.0.0/16"] + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// resource "azurerm_subnet" "test" { +// name = "acctest-DelegatedSubnet-%[1]d" +// resource_group_name = azurerm_resource_group.test.name +// virtual_network_name = azurerm_virtual_network.test.name +// address_prefixes = ["10.6.2.0/24"] + +// delegation { +// name = "testdelegation" + +// service_delegation { +// name = "Microsoft.Netapp/volumes" +// actions = ["Microsoft.Network/networkinterfaces/*", "Microsoft.Network/virtualNetworks/subnets/join/action"] +// } +// } +// } + +// resource "azurerm_subnet" "test1" { +// name = "acctest-HostsSubnet-%[1]d" +// resource_group_name = azurerm_resource_group.test.name +// virtual_network_name = azurerm_virtual_network.test.name +// address_prefixes = ["10.6.1.0/24"] +// } + +// resource "azurerm_subnet_network_security_group_association" "public" { +// subnet_id = azurerm_subnet.test.id +// network_security_group_id = azurerm_network_security_group.test.id +// } + +// resource "azurerm_proximity_placement_group" "test" { +// name = "acctest-PPG-%[1]d" +// location = azurerm_resource_group.test.location +// resource_group_name = azurerm_resource_group.test.name + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// resource "azurerm_availability_set" "test" { +// name = "acctest-avset-%[1]d" +// location = azurerm_resource_group.test.location +// resource_group_name = azurerm_resource_group.test.name + +// proximity_placement_group_id = azurerm_proximity_placement_group.test.id + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// resource "azurerm_network_interface" "test" { +// name = "acctest-nic-%[1]d" +// resource_group_name = azurerm_resource_group.test.name +// location = azurerm_resource_group.test.location + +// ip_configuration { +// name = "internal" +// subnet_id = azurerm_subnet.test1.id +// private_ip_address_allocation = "Dynamic" +// } + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// resource "azurerm_linux_virtual_machine" "test" { +// name = "acctest-vm-%[1]d" +// resource_group_name = azurerm_resource_group.test.name +// location = azurerm_resource_group.test.location +// size = "Standard_M8ms" +// admin_username = local.admin_username +// admin_password = local.admin_password +// disable_password_authentication = false +// proximity_placement_group_id = azurerm_proximity_placement_group.test.id +// availability_set_id = azurerm_availability_set.test.id +// network_interface_ids = [ +// azurerm_network_interface.test.id +// ] + +// source_image_reference { +// publisher = "Canonical" +// offer = "0001-com-ubuntu-server-jammy" +// sku = "22_04-lts" +// version = "latest" +// } + +// os_disk { +// storage_account_type = "Standard_LRS" +// caching = "ReadWrite" +// } + +// tags = { +// "platformsettings.host_environment.service.platform_optedin_for_rootcerts" = "true", +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true", +// "Owner" = "pmarques" +// } +// } + +// resource "azurerm_netapp_account" "test" { +// name = "acctest-NetAppAccount-%[1]d" +// location = azurerm_resource_group.test.location +// resource_group_name = azurerm_resource_group.test.name + +// depends_on = [ +// azurerm_subnet.test, +// azurerm_subnet.test1 +// ] + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } + +// resource "azurerm_netapp_pool" "test" { +// name = "acctest-NetAppPool-%[1]d" +// location = azurerm_resource_group.test.location +// resource_group_name = azurerm_resource_group.test.name +// account_name = azurerm_netapp_account.test.name +// service_level = "Standard" +// size_in_tb = 8 +// qos_type = "Manual" + +// tags = { +// "CreatedOnDate" = "2022-07-08T23:50:21Z", +// "SkipASMAzSecPack" = "true" +// } +// } +// `, data.RandomInteger, "eastus") +// } + +func (NetAppVolumeGroupOracleResource) templateAvailabilityZone(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { - alias = "all2" features { resource_group { prevent_deletion_if_contains_resources = false } netapp { prevent_volume_destruction = false - delete_backups_on_backup_vault_destroy = true } } } -locals { - admin_username = "testadmin%[1]d" - admin_password = "Password1234!%[1]d" -} - resource "azurerm_resource_group" "test" { name = "acctestRG-netapp-%[1]d" location = "%[2]s" - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true", - "SkipNRMSNSG" = "true" - } -} - -resource "azurerm_network_security_group" "test" { - name = "acctest-NSG-%[1]d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" + tags = { + "SkipNRMSNSG" = "true" } } @@ -1644,11 +2309,6 @@ resource "azurerm_virtual_network" "test" { location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name address_space = ["10.6.0.0/16"] - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } resource "azurerm_subnet" "test" { @@ -1667,107 +2327,14 @@ resource "azurerm_subnet" "test" { } } -resource "azurerm_subnet" "test1" { - name = "acctest-HostsSubnet-%[1]d" - resource_group_name = azurerm_resource_group.test.name - virtual_network_name = azurerm_virtual_network.test.name - address_prefixes = ["10.6.1.0/24"] -} - -resource "azurerm_subnet_network_security_group_association" "public" { - subnet_id = azurerm_subnet.test.id - network_security_group_id = azurerm_network_security_group.test.id -} - -resource "azurerm_proximity_placement_group" "test" { - name = "acctest-PPG-%[1]d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } -} - -resource "azurerm_availability_set" "test" { - name = "acctest-avset-%[1]d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } -} - -resource "azurerm_network_interface" "test" { - name = "acctest-nic-%[1]d" - resource_group_name = azurerm_resource_group.test.name - location = azurerm_resource_group.test.location - - ip_configuration { - name = "internal" - subnet_id = azurerm_subnet.test1.id - private_ip_address_allocation = "Dynamic" - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } -} - -resource "azurerm_linux_virtual_machine" "test" { - name = "acctest-vm-%[1]d" - resource_group_name = azurerm_resource_group.test.name - location = azurerm_resource_group.test.location - size = "Standard_M8ms" - admin_username = local.admin_username - admin_password = local.admin_password - disable_password_authentication = false - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - availability_set_id = azurerm_availability_set.test.id - network_interface_ids = [ - azurerm_network_interface.test.id - ] - - source_image_reference { - publisher = "Canonical" - offer = "0001-com-ubuntu-server-jammy" - sku = "22_04-lts" - version = "latest" - } - - os_disk { - storage_account_type = "Standard_LRS" - caching = "ReadWrite" - } - - tags = { - "platformsettings.host_environment.service.platform_optedin_for_rootcerts" = "true", - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true", - "Owner" = "pmarques" - } -} - resource "azurerm_netapp_account" "test" { name = "acctest-NetAppAccount-%[1]d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name depends_on = [ - azurerm_subnet.test, - azurerm_subnet.test1 + azurerm_subnet.test ] - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } resource "azurerm_netapp_pool" "test" { @@ -1776,13 +2343,8 @@ resource "azurerm_netapp_pool" "test" { resource_group_name = azurerm_resource_group.test.name account_name = azurerm_netapp_account.test.name service_level = "Standard" - size_in_tb = 8 + size_in_tb = 18 qos_type = "Manual" - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } } `, data.RandomInteger, "eastus") } diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource.go index c8c5e76f1883..e2ed8c5465c9 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource.go @@ -473,7 +473,7 @@ func (r NetAppVolumeGroupSapHanaResource) Update() sdk.ResourceFunc { rule.Nfsv3 = utils.Bool(v["nfsv3_enabled"].(bool)) rule.Nfsv41 = utils.Bool(v["nfsv41_enabled"].(bool)) - errors = append(errors, netAppValidate.ValidateNetAppVolumeGroupExportPolicyRuleSAPHanna(rule, volumeProtocol)...) + errors = append(errors, netAppValidate.ValidateNetAppVolumeGroupExportPolicyRule(rule, volumeProtocol)...) } } diff --git a/internal/services/netapp/validate/volume_group_oracle_volumes_export_policy_validation_test.go b/internal/services/netapp/validate/volume_group_oracle_volumes_export_policy_validation_test.go index efdb816460ea..a6637693a219 100644 --- a/internal/services/netapp/validate/volume_group_oracle_volumes_export_policy_validation_test.go +++ b/internal/services/netapp/validate/volume_group_oracle_volumes_export_policy_validation_test.go @@ -94,7 +94,7 @@ func TestValidateNetAppVolumeGroupExportPolicyRuleOracle(t *testing.T) { for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { - errors := ValidateNetAppVolumeGroupExportPolicyRuleOracle(tc.Rule, tc.Protocol) + errors := ValidateNetAppVolumeGroupExportPolicyRule(tc.Rule, tc.Protocol) if len(errors) != tc.Errors { t.Fatalf("expected ValidateNetAppVolumeGroupOracleVolumes to return %d error(s) not %d", tc.Errors, len(errors)) diff --git a/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go b/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go index cd3b033c0cba..b4e1ebb78bb7 100644 --- a/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go +++ b/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go @@ -61,8 +61,9 @@ func PossibleValuesForProtocolTypeVolumeGroupOracle() []string { func ValidateNetAppVolumeGroupOracleVolumes(volumeList *[]volumegroups.VolumeGroupVolumeProperties) []error { errors := make([]error, 0) + expectedZone := "" volumeSpecRepeatCount := make(map[string]int) - applicationType := string(volumegroups.ApplicationTypeSAPNegativeHANA) + applicationType := string(volumegroups.ApplicationTypeORACLE) // Validating minimum volume count if len(*volumeList) < len(RequiredVolumesForOracle()) { @@ -97,7 +98,7 @@ func ValidateNetAppVolumeGroupOracleVolumes(volumeList *[]volumegroups.VolumeGro } } - // Validate that protocol is valid for SAP Hana + // Validate that protocol is valid for Oracle if !findStringInSlice(PossibleValuesForProtocolTypeVolumeGroupOracle(), protocolType) { errors = append(errors, fmt.Errorf("'protocol %v is invalid for Oracle'", protocolType)) } @@ -113,7 +114,7 @@ func ValidateNetAppVolumeGroupOracleVolumes(volumeList *[]volumegroups.VolumeGro // Validating export policies if volume.Properties.ExportPolicy != nil { for _, rule := range pointer.From(volume.Properties.ExportPolicy.Rules) { - errors = append(errors, ValidateNetAppVolumeGroupExportPolicyRuleOracle(rule, protocolType)...) + errors = append(errors, ValidateNetAppVolumeGroupExportPolicyRule(rule, protocolType)...) } } @@ -132,6 +133,11 @@ func ValidateNetAppVolumeGroupOracleVolumes(volumeList *[]volumegroups.VolumeGro errors = append(errors, fmt.Errorf("'snapshot policy cannot be enabled on a data protection volume for %v on volume %v'", applicationType, pointer.From(volume.Name))) } + // Validating that zone and proximity placement group are not specified together + if (pointer.From(volume.Zones) != nil || len(pointer.From(volume.Zones)) > 0) && pointer.From(volume.Properties.ProximityPlacementGroup) != "" { + errors = append(errors, fmt.Errorf("'zone and proximity_placement_group_id cannot be specified together on volume %v'", pointer.From(volume.Name))) + } + // TODO: // Validating that data-backup and log-backup don't have PPG defined // if (strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleDataBackup)) || // strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleLogBackup))) && @@ -147,6 +153,18 @@ func ValidateNetAppVolumeGroupOracleVolumes(volumeList *[]volumegroups.VolumeGro // errors = append(errors, fmt.Errorf("'%v volume spec type must have PPG defined for %v on volume %v'", pointer.From(volume.Properties.VolumeSpecName), applicationType, pointer.From(volume.Name))) // } + // Getting the first zone for validations, all volumes must be in the same zone + if expectedZone == "" { + if volume.Zones != nil && len(pointer.From(volume.Zones)) > 0 { + expectedZone = pointer.From(volume.Zones)[0] + } + } + + // Validating that all volumes are in the same zone + if volume.Zones != nil && len(pointer.From(volume.Zones)) > 0 && pointer.From(volume.Zones)[0] != expectedZone { + errors = append(errors, fmt.Errorf("'zone must be the same on all volumes of this volume group, volume %v zone is %v'", pointer.From(volume.Name), pointer.From(volume.Zones)[0])) + } + // Adding volume spec name to hashmap for post volume loop check volumeSpecRepeatCount[pointer.From(volume.Properties.VolumeSpecName)] += 1 } diff --git a/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go b/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go index bf903e4bfee5..a95e720e71b6 100644 --- a/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go +++ b/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go @@ -436,6 +436,48 @@ func TestValidateNetAppVolumeGroupOracleVolumes(t *testing.T) { }, Errors: 0, }, + { + Name: "ValidatePPGAndAvailabilityZoneNotSetAtSameTime", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + }, + Zones: pointer.To([]string{"1"}), + }, + { // log + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + }, + Zones: pointer.To([]string{"1"}), + }, + }, + Errors: 2, + }, { Name: "ValidateMinimumVolumes", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ @@ -476,6 +518,86 @@ func TestValidateNetAppVolumeGroupOracleVolumes(t *testing.T) { }, Errors: 0, }, + { + Name: "ValidateVolumesSameZone", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + }, + Zones: pointer.To([]string{"1"}), + }, + { // log + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + }, + Zones: pointer.To([]string{"1"}), + }, + }, + Errors: 0, + }, + { + Name: "ValidateVolumesNotSameZoneErrors", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + }, + Zones: pointer.To([]string{"1"}), + }, + { // log + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + }, + Zones: pointer.To([]string{"2"}), + }, + }, + Errors: 1, + }, { Name: "ValidateRequiredVolumeSpecs", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ @@ -684,78 +806,6 @@ func TestValidateNetAppVolumeGroupOracleVolumes(t *testing.T) { // }, // Errors: 3, // }, - // TODO: - // { - // Name: "ValidateNoPPGBackupVolumes", - // VolumesData: []volumegroups.VolumeGroupVolumeProperties{ - // { // data - // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData))), - // Properties: volumegroups.VolumeProperties{ - // ProtocolTypes: pointer.To([]string{"NFSv4.1"}), - // ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), - // SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData)), - // }, - // }, - // { // log - // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), - // Properties: volumegroups.VolumeProperties{ - // ProtocolTypes: pointer.To([]string{"NFSv4.1"}), - // ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), - // SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), - // }, - // }, - // { // data-backup - // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleDataBackup))), - // Properties: volumegroups.VolumeProperties{ - // ProtocolTypes: pointer.To([]string{"NFSv4.1"}), - // ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), - // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleDataBackup)), - // }, - // }, - // { // log-backup - // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLogBackup))), - // Properties: volumegroups.VolumeProperties{ - // ProtocolTypes: pointer.To([]string{"NFSv4.1"}), - // ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), - // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLogBackup)), - // }, - // }, - // }, - // Errors: 2, - // }, - // TODO: - //{ - // Name: "ValidateRequiredPpgForNonBackupVolumes", - // VolumesData: []volumegroups.VolumeGroupVolumeProperties{ - // { // data - // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData))), - // Properties: volumegroups.VolumeProperties{ - // ProtocolTypes: pointer.To([]string{"NFSv4.1"}), - // SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData)), - // }, - // }, - // { // log - // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), - // Properties: volumegroups.VolumeProperties{ - // ProtocolTypes: pointer.To([]string{"NFSv4.1"}), - // SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), - // }, - // }, - // { // shared - // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleShared))), - // Properties: volumegroups.VolumeProperties{ - // ProtocolTypes: pointer.To([]string{"NFSv4.1"}), - // SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleShared)), - // }, - // }, - // }, - // Errors: 3, - // }, { Name: "ValidateVolumeSpecCantRepeat", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ @@ -818,38 +868,6 @@ func TestValidateNetAppVolumeGroupOracleVolumes(t *testing.T) { }, Errors: 1, }, - { - Name: "ValidateSnapshotPolicyNotEnabledOnEndpointDstVolume", - VolumesData: []volumegroups.VolumeGroupVolumeProperties{ - { // data1 - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), - Properties: volumegroups.VolumeProperties{ - ProtocolTypes: pointer.To([]string{"NFSv4.1"}), - ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), - SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), - DataProtection: &volumegroups.VolumePropertiesDataProtection{ - Replication: &volumegroups.ReplicationObject{ - EndpointType: pointer.To(volumegroups.EndpointTypeDst), - }, - Snapshot: &volumegroups.VolumeSnapshotProperties{ - SnapshotPolicyId: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.NetApp/netAppAccounts/account1/capacityPools/pool1/volumes/volume1/snapshotPolicies/snapshotPolicy1"), - }, - }, - }, - }, - { // log - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), - Properties: volumegroups.VolumeProperties{ - ProtocolTypes: pointer.To([]string{"NFSv4.1"}), - ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), - SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), - }, - }, - }, - Errors: 1, - }, } for _, tc := range cases { diff --git a/internal/services/netapp/validate/volume_group_sap_hana_volumes_export_policy_validation.go b/internal/services/netapp/validate/volume_group_sap_hana_volumes_export_policy_validation.go deleted file mode 100644 index 1adfea70124e..000000000000 --- a/internal/services/netapp/validate/volume_group_sap_hana_volumes_export_policy_validation.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package validate - -import ( - "fmt" - "strings" - - "github.com/hashicorp/go-azure-helpers/lang/pointer" - "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/volumegroups" -) - -func ValidateNetAppVolumeGroupExportPolicyRuleSAPHanna(rule volumegroups.ExportPolicyRule, protocolType string) []error { - errors := make([]error, 0) - - // Validating that nfsv3 and nfsv4.1 are not enabled in the same rule - if pointer.From(rule.Nfsv3) && pointer.From(rule.Nfsv41) { - errors = append(errors, fmt.Errorf("'nfsv3 and nfsv4.1 cannot be enabled at the same time'")) - } - - // Validating that nfsv3 and nfsv4.1 are not disabled in the same rule - if !pointer.From(rule.Nfsv3) && !pointer.From(rule.Nfsv41) { - errors = append(errors, fmt.Errorf("'nfsv3 and nfsv4.1 cannot be enabled at the same time'")) - } - - // Validating that nfsv4.1 export policy is not set on nfsv3 volume - if pointer.From(rule.Nfsv41) && strings.EqualFold(protocolType, string(ProtocolTypeNfsV3)) { - errors = append(errors, fmt.Errorf("'nfsv4.1 export policy cannot be enabled on nfsv3 volume'")) - } - - // Validating that nfsv3 export policy is not set on nfsv4.1 volume - if pointer.From(rule.Nfsv3) && strings.EqualFold(protocolType, string(ProtocolTypeNfsV41)) { - errors = append(errors, fmt.Errorf("'nfsv3 export policy cannot be enabled on nfsv4.1 volume'")) - } - - return errors -} diff --git a/internal/services/netapp/validate/volume_group_sap_hana_volumes_export_policy_validation_test.go b/internal/services/netapp/validate/volume_group_sap_hana_volumes_export_policy_validation_test.go index c2416e3d8aca..895e914f39c9 100644 --- a/internal/services/netapp/validate/volume_group_sap_hana_volumes_export_policy_validation_test.go +++ b/internal/services/netapp/validate/volume_group_sap_hana_volumes_export_policy_validation_test.go @@ -94,7 +94,7 @@ func TestValidateNetAppVolumeGroupExportPolicyRuleSAPHanna(t *testing.T) { for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { - errors := ValidateNetAppVolumeGroupExportPolicyRuleSAPHanna(tc.Rule, tc.Protocol) + errors := ValidateNetAppVolumeGroupExportPolicyRule(tc.Rule, tc.Protocol) if len(errors) != tc.Errors { t.Fatalf("expected ValidateNetAppVolumeGroupSAPHanaVolumes to return %d error(s) not %d", tc.Errors, len(errors)) diff --git a/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation.go b/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation.go index 1716968cd013..327f6d5973bb 100644 --- a/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation.go +++ b/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation.go @@ -99,7 +99,7 @@ func ValidateNetAppVolumeGroupSAPHanaVolumes(volumeList *[]volumegroups.VolumeGr // Validating export policies if volume.Properties.ExportPolicy != nil { for _, rule := range pointer.From(volume.Properties.ExportPolicy.Rules) { - errors = append(errors, ValidateNetAppVolumeGroupExportPolicyRuleSAPHanna(rule, protocolType)...) + errors = append(errors, ValidateNetAppVolumeGroupExportPolicyRule(rule, protocolType)...) } } diff --git a/internal/services/netapp/validate/volume_group_oracle_volumes_export_policy_validation.go b/internal/services/netapp/validate/volume_group_volumes_export_policy_validation.go similarity index 91% rename from internal/services/netapp/validate/volume_group_oracle_volumes_export_policy_validation.go rename to internal/services/netapp/validate/volume_group_volumes_export_policy_validation.go index d7e13ede32a3..d8058b079279 100644 --- a/internal/services/netapp/validate/volume_group_oracle_volumes_export_policy_validation.go +++ b/internal/services/netapp/validate/volume_group_volumes_export_policy_validation.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/volumegroups" ) -func ValidateNetAppVolumeGroupExportPolicyRuleOracle(rule volumegroups.ExportPolicyRule, protocolType string) []error { +func ValidateNetAppVolumeGroupExportPolicyRule(rule volumegroups.ExportPolicyRule, protocolType string) []error { errors := make([]error, 0) // Validating that nfsv3 and nfsv4.1 are not enabled in the same rule From fb14fe3f89eb5b352ed79898370bf148bac8bf6e Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 27 Nov 2024 20:00:05 +0000 Subject: [PATCH 03/39] fixing panic on data protection replication removal for Oracle --- internal/services/netapp/models/models.go | 35 ++++- .../netapp_volume_group_oracle_resource.go | 4 +- ...etapp_volume_group_oracle_resource_test.go | 2 + .../services/netapp/netapp_volume_helper.go | 125 ++++++++++++++++++ 4 files changed, 157 insertions(+), 9 deletions(-) diff --git a/internal/services/netapp/models/models.go b/internal/services/netapp/models/models.go index 8641aa2624ab..320db19758cd 100644 --- a/internal/services/netapp/models/models.go +++ b/internal/services/netapp/models/models.go @@ -63,14 +63,35 @@ type NetAppVolumeGroupSapHanaDataSourceModel struct { Volumes []NetAppVolumeGroupVolume `tfschema:"volume"` } +type NetAppVolumeGroupOracleVolume struct { + Id string `tfschema:"id"` + Name string `tfschema:"name"` + VolumePath string `tfschema:"volume_path"` + ServiceLevel string `tfschema:"service_level"` + SubnetId string `tfschema:"subnet_id"` + Protocols []string `tfschema:"protocols"` + SecurityStyle string `tfschema:"security_style"` + StorageQuotaInGB int64 `tfschema:"storage_quota_in_gb"` + ThroughputInMibps float64 `tfschema:"throughput_in_mibps"` + Tags map[string]string `tfschema:"tags"` + SnapshotDirectoryVisible bool `tfschema:"snapshot_directory_visible"` + CapacityPoolId string `tfschema:"capacity_pool_id"` + ProximityPlacementGroupId string `tfschema:"proximity_placement_group_id"` + VolumeSpecName string `tfschema:"volume_spec_name"` + ExportPolicy []ExportPolicyRule `tfschema:"export_policy_rule"` + MountIpAddresses []string `tfschema:"mount_ip_addresses"` + DataProtectionSnapshotPolicy []DataProtectionSnapshotPolicy `tfschema:"data_protection_snapshot_policy"` + Zone string `tfschema:"zone"` +} + type NetAppVolumeGroupOracleModel struct { - Name string `tfschema:"name"` - ResourceGroupName string `tfschema:"resource_group_name"` - Location string `tfschema:"location"` - AccountName string `tfschema:"account_name"` - GroupDescription string `tfschema:"group_description"` - ApplicationIdentifier string `tfschema:"application_identifier"` - Volumes []NetAppVolumeGroupVolume `tfschema:"volume"` + Name string `tfschema:"name"` + ResourceGroupName string `tfschema:"resource_group_name"` + Location string `tfschema:"location"` + AccountName string `tfschema:"account_name"` + GroupDescription string `tfschema:"group_description"` + ApplicationIdentifier string `tfschema:"application_identifier"` + Volumes []NetAppVolumeGroupOracleVolume `tfschema:"volume"` } type NetAppVolumeGroupOracleDataSourceModel struct { diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource.go b/internal/services/netapp/netapp_volume_group_oracle_resource.go index 7fa85024ef1d..205329a529ab 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource.go @@ -288,7 +288,7 @@ func (r NetAppVolumeGroupOracleResource) Create() sdk.ResourceFunc { return metadata.ResourceRequiresImport(r.ResourceType(), id) } - volumeList, err := expandNetAppVolumeGroupVolumes(model.Volumes) + volumeList, err := expandNetAppVolumeGroupOracleVolumes(model.Volumes) if err != nil { return err } @@ -465,7 +465,7 @@ func (r NetAppVolumeGroupOracleResource) Read() sdk.ResourceFunc { model.GroupDescription = pointer.From(props.GroupMetaData.GroupDescription) model.ApplicationIdentifier = pointer.From(props.GroupMetaData.ApplicationIdentifier) - volumes, err := flattenNetAppVolumeGroupVolumes(ctx, props.Volumes, metadata) + volumes, err := flattenNetAppVolumeGroupOracleVolumes(ctx, props.Volumes, metadata) if err != nil { return fmt.Errorf("setting `volume`: %+v", err) } diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index 4ac05de8c9b4..38fa4efde490 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -35,6 +35,8 @@ func TestAccNetAppVolumeGroupOracle_basic(t *testing.T) { } func TestAccNetAppVolumeGroupOracle_nfsv3(t *testing.T) { + // Adjust test configurations to exclude data_protection_replication + // Use the new NetAppVolumeGroupOracleVolume model in test data data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") r := NetAppVolumeGroupOracleResource{} diff --git a/internal/services/netapp/netapp_volume_helper.go b/internal/services/netapp/netapp_volume_helper.go index 3deca81ae113..1a9498bf921f 100644 --- a/internal/services/netapp/netapp_volume_helper.go +++ b/internal/services/netapp/netapp_volume_helper.go @@ -157,6 +157,61 @@ func expandNetAppVolumeGroupVolumes(input []netAppModels.NetAppVolumeGroupVolume return &results, nil } +func expandNetAppVolumeGroupOracleVolumes(input []netAppModels.NetAppVolumeGroupOracleVolume) (*[]volumegroups.VolumeGroupVolumeProperties, error) { + if len(input) == 0 { + return &[]volumegroups.VolumeGroupVolumeProperties{}, fmt.Errorf("received empty NetAppVolumeGroupVolume slice") + } + + results := make([]volumegroups.VolumeGroupVolumeProperties, 0) + + for _, item := range input { + name := item.Name + volumePath := item.VolumePath + serviceLevel := volumegroups.ServiceLevel(item.ServiceLevel) + subnetID := item.SubnetId + capacityPoolID := item.CapacityPoolId + protocols := item.Protocols + snapshotDirectoryVisible := item.SnapshotDirectoryVisible + securityStyle := volumegroups.SecurityStyle(item.SecurityStyle) + storageQuotaInGB := item.StorageQuotaInGB * 1073741824 + exportPolicyRule := expandNetAppVolumeGroupVolumeExportPolicyRule(item.ExportPolicy) + dataProtectionSnapshotPolicy := expandNetAppVolumeGroupDataProtectionSnapshotPolicy(item.DataProtectionSnapshotPolicy) + + volumeProperties := &volumegroups.VolumeGroupVolumeProperties{ + Name: utils.String(name), + Properties: volumegroups.VolumeProperties{ + CapacityPoolResourceId: utils.String(capacityPoolID), + CreationToken: volumePath, + ServiceLevel: &serviceLevel, + SubnetId: subnetID, + ProtocolTypes: &protocols, + SecurityStyle: &securityStyle, + UsageThreshold: storageQuotaInGB, + ExportPolicy: exportPolicyRule, + SnapshotDirectoryVisible: utils.Bool(snapshotDirectoryVisible), + ThroughputMibps: utils.Float(item.ThroughputInMibps), + VolumeSpecName: utils.String(item.VolumeSpecName), + DataProtection: &volumegroups.VolumePropertiesDataProtection{ + Snapshot: dataProtectionSnapshotPolicy.Snapshot, + }, + }, + Tags: &item.Tags, + } + + if v := item.ProximityPlacementGroupId; v != "" { + volumeProperties.Properties.ProximityPlacementGroup = pointer.To(pointer.From(pointer.To(v))) + } + + if v := item.Zone; v != "" { + volumeProperties.Zones = pointer.To([]string{v}) + } + + results = append(results, *volumeProperties) + } + + return &results, nil +} + func expandNetAppVolumeGroupVolumeExportPolicyRulePatch(input []interface{}) *volumes.VolumePatchPropertiesExportPolicy { if len(input) == 0 { return &volumes.VolumePatchPropertiesExportPolicy{} @@ -403,6 +458,76 @@ func flattenNetAppVolumeGroupVolumes(ctx context.Context, input *[]volumegroups. return results, nil } +func flattenNetAppVolumeGroupOracleVolumes(ctx context.Context, input *[]volumegroups.VolumeGroupVolumeProperties, metadata sdk.ResourceMetaData) ([]netAppModels.NetAppVolumeGroupOracleVolume, error) { + results := make([]netAppModels.NetAppVolumeGroupOracleVolume, 0) + + if input == nil || len(pointer.From(input)) == 0 { + return results, fmt.Errorf("received empty volumegroups.VolumeGroupVolumeProperties slice") + } + + for _, item := range *input { + volumeGroupVolume := netAppModels.NetAppVolumeGroupOracleVolume{} + + props := item.Properties + volumeGroupVolume.Name = getUserDefinedVolumeName(item.Name) + volumeGroupVolume.VolumePath = props.CreationToken + volumeGroupVolume.ServiceLevel = string(pointer.From(props.ServiceLevel)) + volumeGroupVolume.SubnetId = props.SubnetId + volumeGroupVolume.CapacityPoolId = pointer.From(props.CapacityPoolResourceId) + volumeGroupVolume.Protocols = pointer.From(props.ProtocolTypes) + volumeGroupVolume.SecurityStyle = string(pointer.From(props.SecurityStyle)) + volumeGroupVolume.SnapshotDirectoryVisible = pointer.From(props.SnapshotDirectoryVisible) + volumeGroupVolume.ThroughputInMibps = pointer.From(props.ThroughputMibps) + volumeGroupVolume.Tags = pointer.From(item.Tags) + + if props.ProximityPlacementGroup != nil { + volumeGroupVolume.ProximityPlacementGroupId = pointer.From(props.ProximityPlacementGroup) + } + + if item.Zones != nil && len(pointer.From(item.Zones)) > 0 { + volumeGroupVolume.Zone = (pointer.From(item.Zones))[0] + } + + volumeGroupVolume.VolumeSpecName = pointer.From(props.VolumeSpecName) + + if props.UsageThreshold > 0 { + usageThreshold := props.UsageThreshold / 1073741824 + volumeGroupVolume.StorageQuotaInGB = usageThreshold + } + + if props.ExportPolicy != nil && props.ExportPolicy.Rules != nil && len(pointer.From(props.ExportPolicy.Rules)) > 0 { + volumeGroupVolume.ExportPolicy = flattenNetAppVolumeGroupVolumesExportPolicies(props.ExportPolicy.Rules) + } + + if props.MountTargets != nil && len(pointer.From(props.MountTargets)) > 0 { + volumeGroupVolume.MountIpAddresses = flattenNetAppVolumeGroupVolumesMountIpAddresses(props.MountTargets) + } + + // Getting volume resource directly from standalone volume + // since VolumeGroup Volumes don't return DataProtection information + volumeClient := metadata.Client.NetApp.VolumeClient + id, err := volumes.ParseVolumeID(pointer.From(item.Id)) + if err != nil { + return []netAppModels.NetAppVolumeGroupOracleVolume{}, err + } + + standaloneVol, err := volumeClient.Get(ctx, pointer.From(id)) + if err != nil { + return []netAppModels.NetAppVolumeGroupOracleVolume{}, fmt.Errorf("retrieving %s: %v", id, err) + } + + if standaloneVol.Model.Properties.DataProtection != nil && standaloneVol.Model.Properties.DataProtection.Snapshot != nil { + volumeGroupVolume.DataProtectionSnapshotPolicy = flattenNetAppVolumeGroupVolumesDPSnapshotPolicy(standaloneVol.Model.Properties.DataProtection.Snapshot) + } + + volumeGroupVolume.Id = pointer.From(standaloneVol.Model.Id) + + results = append(results, volumeGroupVolume) + } + + return results, nil +} + func flattenNetAppVolumeGroupVolumesExportPolicies(input *[]volumegroups.ExportPolicyRule) []netAppModels.ExportPolicyRule { results := make([]netAppModels.ExportPolicyRule, 0) From f8fc32d6a232c1ecfc7e83f29da5b6f4ff34ad02 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 27 Nov 2024 21:11:12 +0000 Subject: [PATCH 04/39] Dedicating functions to SAPHana plus naming convention fixes for golang and SAPHana --- internal/services/netapp/models/models.go | 48 +++---- .../netapp_volume_group_oracle_data_source.go | 2 +- ...etapp_volume_group_oracle_resource_test.go | 2 +- ...etapp_volume_group_sap_hana_data_source.go | 22 +-- ..._volume_group_sap_hana_data_source_test.go | 10 +- .../netapp_volume_group_sap_hana_resource.go | 40 +++--- ...app_volume_group_sap_hana_resource_test.go | 58 ++++---- .../services/netapp/netapp_volume_helper.go | 16 +-- internal/services/netapp/registration.go | 4 +- ...a_volumes_export_policy_validation_test.go | 2 +- ...olume_group_sap_hana_volumes_validation.go | 50 +++---- ..._group_sap_hana_volumes_validation_test.go | 132 +++++++++--------- 12 files changed, 193 insertions(+), 193 deletions(-) diff --git a/internal/services/netapp/models/models.go b/internal/services/netapp/models/models.go index 320db19758cd..b33b5ed88368 100644 --- a/internal/services/netapp/models/models.go +++ b/internal/services/netapp/models/models.go @@ -21,7 +21,7 @@ type NetAppAccountEncryptionDataSourceModel struct { EncryptionKey string `tfschema:"encryption_key"` } -type NetAppVolumeGroupVolume struct { +type NetAppVolumeGroupSAPHanaVolume struct { Id string `tfschema:"id"` Name string `tfschema:"name"` VolumePath string `tfschema:"volume_path"` @@ -43,24 +43,24 @@ type NetAppVolumeGroupVolume struct { Zone string `tfschema:"zone"` } -type NetAppVolumeGroupSapHanaModel struct { - Name string `tfschema:"name"` - ResourceGroupName string `tfschema:"resource_group_name"` - Location string `tfschema:"location"` - AccountName string `tfschema:"account_name"` - GroupDescription string `tfschema:"group_description"` - ApplicationIdentifier string `tfschema:"application_identifier"` - Volumes []NetAppVolumeGroupVolume `tfschema:"volume"` +type NetAppVolumeGroupSAPHanaModel struct { + Name string `tfschema:"name"` + ResourceGroupName string `tfschema:"resource_group_name"` + Location string `tfschema:"location"` + AccountName string `tfschema:"account_name"` + GroupDescription string `tfschema:"group_description"` + ApplicationIdentifier string `tfschema:"application_identifier"` + Volumes []NetAppVolumeGroupSAPHanaVolume `tfschema:"volume"` } -type NetAppVolumeGroupSapHanaDataSourceModel struct { - Name string `tfschema:"name"` - ResourceGroupName string `tfschema:"resource_group_name"` - Location string `tfschema:"location"` - AccountName string `tfschema:"account_name"` - GroupDescription string `tfschema:"group_description"` - ApplicationIdentifier string `tfschema:"application_identifier"` - Volumes []NetAppVolumeGroupVolume `tfschema:"volume"` +type NetAppVolumeGroupSAPHanaDataSourceModel struct { + Name string `tfschema:"name"` + ResourceGroupName string `tfschema:"resource_group_name"` + Location string `tfschema:"location"` + AccountName string `tfschema:"account_name"` + GroupDescription string `tfschema:"group_description"` + ApplicationIdentifier string `tfschema:"application_identifier"` + Volumes []NetAppVolumeGroupSAPHanaVolume `tfschema:"volume"` } type NetAppVolumeGroupOracleVolume struct { @@ -95,13 +95,13 @@ type NetAppVolumeGroupOracleModel struct { } type NetAppVolumeGroupOracleDataSourceModel struct { - Name string `tfschema:"name"` - ResourceGroupName string `tfschema:"resource_group_name"` - Location string `tfschema:"location"` - AccountName string `tfschema:"account_name"` - GroupDescription string `tfschema:"group_description"` - ApplicationIdentifier string `tfschema:"application_identifier"` - Volumes []NetAppVolumeGroupVolume `tfschema:"volume"` + Name string `tfschema:"name"` + ResourceGroupName string `tfschema:"resource_group_name"` + Location string `tfschema:"location"` + AccountName string `tfschema:"account_name"` + GroupDescription string `tfschema:"group_description"` + ApplicationIdentifier string `tfschema:"application_identifier"` + Volumes []NetAppVolumeGroupOracleVolume `tfschema:"volume"` } type ExportPolicyRule struct { diff --git a/internal/services/netapp/netapp_volume_group_oracle_data_source.go b/internal/services/netapp/netapp_volume_group_oracle_data_source.go index 09855344953f..1756f67f8092 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_data_source.go +++ b/internal/services/netapp/netapp_volume_group_oracle_data_source.go @@ -264,7 +264,7 @@ func (r NetAppVolumeGroupOracleDataSource) Read() sdk.ResourceFunc { state.GroupDescription = pointer.From(groupMetaData.GroupDescription) } - volumes, err := flattenNetAppVolumeGroupVolumes(ctx, props.Volumes, metadata) + volumes, err := flattenNetAppVolumeGroupOracleVolumes(ctx, props.Volumes, metadata) if err != nil { return fmt.Errorf("setting `volume`: %+v", err) } diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index 38fa4efde490..0a43e93e460b 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -2094,7 +2094,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { // `, template, data.RandomInteger, "westus") // } -// func (NetAppVolumeGroupSapHanaResource) templatePPG(data acceptance.TestData) string { +// func (NetAppVolumeGroupSAPHanaResource) templatePPG(data acceptance.TestData) string { // return fmt.Sprintf(` // provider "azurerm" { // alias = "all2" diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_data_source.go b/internal/services/netapp/netapp_volume_group_sap_hana_data_source.go index 7aedf41ca471..e510af8c7d14 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_data_source.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_data_source.go @@ -18,23 +18,23 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" ) -var _ sdk.DataSource = NetAppVolumeGroupSapHanaDataSource{} +var _ sdk.DataSource = NetAppVolumeGroupSAPHanaDataSource{} -type NetAppVolumeGroupSapHanaDataSource struct{} +type NetAppVolumeGroupSAPHanaDataSource struct{} -func (r NetAppVolumeGroupSapHanaDataSource) ResourceType() string { +func (r NetAppVolumeGroupSAPHanaDataSource) ResourceType() string { return "azurerm_netapp_volume_group_sap_hana" } -func (r NetAppVolumeGroupSapHanaDataSource) ModelObject() interface{} { - return &netAppModels.NetAppVolumeGroupSapHanaDataSourceModel{} +func (r NetAppVolumeGroupSAPHanaDataSource) ModelObject() interface{} { + return &netAppModels.NetAppVolumeGroupSAPHanaDataSourceModel{} } -func (r NetAppVolumeGroupSapHanaDataSource) IDValidationFunc() pluginsdk.SchemaValidateFunc { +func (r NetAppVolumeGroupSAPHanaDataSource) IDValidationFunc() pluginsdk.SchemaValidateFunc { return volumegroups.ValidateVolumeGroupID } -func (r NetAppVolumeGroupSapHanaDataSource) Arguments() map[string]*pluginsdk.Schema { +func (r NetAppVolumeGroupSAPHanaDataSource) Arguments() map[string]*pluginsdk.Schema { return map[string]*pluginsdk.Schema{ "name": { Type: pluginsdk.TypeString, @@ -50,7 +50,7 @@ func (r NetAppVolumeGroupSapHanaDataSource) Arguments() map[string]*pluginsdk.Sc } } -func (r NetAppVolumeGroupSapHanaDataSource) Attributes() map[string]*pluginsdk.Schema { +func (r NetAppVolumeGroupSAPHanaDataSource) Attributes() map[string]*pluginsdk.Schema { return map[string]*pluginsdk.Schema{ "location": commonschema.LocationComputed(), @@ -233,13 +233,13 @@ func (r NetAppVolumeGroupSapHanaDataSource) Attributes() map[string]*pluginsdk.S } } -func (r NetAppVolumeGroupSapHanaDataSource) Read() sdk.ResourceFunc { +func (r NetAppVolumeGroupSAPHanaDataSource) Read() sdk.ResourceFunc { return sdk.ResourceFunc{ Timeout: 5 * time.Minute, Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { client := metadata.Client.NetApp.VolumeGroupClient - var state netAppModels.NetAppVolumeGroupSapHanaDataSourceModel + var state netAppModels.NetAppVolumeGroupSAPHanaDataSourceModel if err := metadata.Decode(&state); err != nil { return fmt.Errorf("decoding: %+v", err) } @@ -262,7 +262,7 @@ func (r NetAppVolumeGroupSapHanaDataSource) Read() sdk.ResourceFunc { state.GroupDescription = pointer.From(groupMetaData.GroupDescription) } - volumes, err := flattenNetAppVolumeGroupVolumes(ctx, props.Volumes, metadata) + volumes, err := flattenNetAppVolumeGroupSAPHanaVolumes(ctx, props.Volumes, metadata) if err != nil { return fmt.Errorf("setting `volume`: %+v", err) } diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_data_source_test.go b/internal/services/netapp/netapp_volume_group_sap_hana_data_source_test.go index 84014a2ad8e7..576ff656d34c 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_data_source_test.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_data_source_test.go @@ -11,11 +11,11 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" ) -type NetAppVolumeGroupSapHanaDataSource struct{} +type NetAppVolumeGroupSAPHanaDataSource struct{} -func TestAccNetAppVolumeGroupSapHanaDataSource_basic(t *testing.T) { +func TestAccNetAppVolumeGroupSAPHanaDataSource_basic(t *testing.T) { data := acceptance.BuildTestData(t, "data.azurerm_netapp_volume_group_sap_hana", "test") - d := NetAppVolumeGroupSapHanaDataSource{} + d := NetAppVolumeGroupSAPHanaDataSource{} data.DataSourceTest(t, []acceptance.TestStep{ { @@ -29,7 +29,7 @@ func TestAccNetAppVolumeGroupSapHanaDataSource_basic(t *testing.T) { }) } -func (d NetAppVolumeGroupSapHanaDataSource) basic(data acceptance.TestData) string { +func (d NetAppVolumeGroupSAPHanaDataSource) basic(data acceptance.TestData) string { return fmt.Sprintf(` %s @@ -38,5 +38,5 @@ data "azurerm_netapp_volume_group_sap_hana" "test" { resource_group_name = azurerm_netapp_volume_group_sap_hana.test.resource_group_name account_name = azurerm_netapp_volume_group_sap_hana.test.account_name } -`, NetAppVolumeGroupSapHanaResource{}.basic(data)) +`, NetAppVolumeGroupSAPHanaResource{}.basic(data)) } diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource.go index e2ed8c5465c9..9a106cba48b5 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource.go @@ -28,23 +28,23 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/utils" ) -type NetAppVolumeGroupSapHanaResource struct{} +type NetAppVolumeGroupSAPHanaResource struct{} -var _ sdk.Resource = NetAppVolumeGroupSapHanaResource{} +var _ sdk.Resource = NetAppVolumeGroupSAPHanaResource{} -func (r NetAppVolumeGroupSapHanaResource) ModelObject() interface{} { - return &netAppModels.NetAppVolumeGroupSapHanaModel{} +func (r NetAppVolumeGroupSAPHanaResource) ModelObject() interface{} { + return &netAppModels.NetAppVolumeGroupSAPHanaModel{} } -func (r NetAppVolumeGroupSapHanaResource) ResourceType() string { +func (r NetAppVolumeGroupSAPHanaResource) ResourceType() string { return "azurerm_netapp_volume_group_sap_hana" } -func (r NetAppVolumeGroupSapHanaResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { +func (r NetAppVolumeGroupSAPHanaResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { return volumegroups.ValidateVolumeGroupID } -func (r NetAppVolumeGroupSapHanaResource) Arguments() map[string]*pluginsdk.Schema { +func (r NetAppVolumeGroupSAPHanaResource) Arguments() map[string]*pluginsdk.Schema { return map[string]*pluginsdk.Schema{ "name": { Type: pluginsdk.TypeString, @@ -115,7 +115,7 @@ func (r NetAppVolumeGroupSapHanaResource) Arguments() map[string]*pluginsdk.Sche Type: pluginsdk.TypeString, Required: true, ForceNew: true, - ValidateFunc: validation.StringInSlice(netAppValidate.PossibleValuesForVolumeSpecNameSapHana(), false), + ValidateFunc: validation.StringInSlice(netAppValidate.PossibleValuesForVolumeSpecNameSAPHana(), false), }, "volume_path": { @@ -151,7 +151,7 @@ func (r NetAppVolumeGroupSapHanaResource) Arguments() map[string]*pluginsdk.Sche MaxItems: 1, Elem: &pluginsdk.Schema{ Type: pluginsdk.TypeString, - ValidateFunc: validation.StringInSlice(netAppValidate.PossibleValuesForProtocolTypeVolumeGroupSapHana(), false), + ValidateFunc: validation.StringInSlice(netAppValidate.PossibleValuesForProtocolTypeVolumeGroupSAPHana(), false), }, }, @@ -291,11 +291,11 @@ func (r NetAppVolumeGroupSapHanaResource) Arguments() map[string]*pluginsdk.Sche } } -func (r NetAppVolumeGroupSapHanaResource) Attributes() map[string]*pluginsdk.Schema { +func (r NetAppVolumeGroupSAPHanaResource) Attributes() map[string]*pluginsdk.Schema { return map[string]*pluginsdk.Schema{} } -func (r NetAppVolumeGroupSapHanaResource) Create() sdk.ResourceFunc { +func (r NetAppVolumeGroupSAPHanaResource) Create() sdk.ResourceFunc { return sdk.ResourceFunc{ Timeout: 90 * time.Minute, Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { @@ -304,7 +304,7 @@ func (r NetAppVolumeGroupSapHanaResource) Create() sdk.ResourceFunc { subscriptionId := metadata.Client.Account.SubscriptionId - var model netAppModels.NetAppVolumeGroupSapHanaModel + var model netAppModels.NetAppVolumeGroupSAPHanaModel if err := metadata.Decode(&model); err != nil { return fmt.Errorf("decoding: %+v", err) } @@ -321,7 +321,7 @@ func (r NetAppVolumeGroupSapHanaResource) Create() sdk.ResourceFunc { return metadata.ResourceRequiresImport(r.ResourceType(), id) } - volumeList, err := expandNetAppVolumeGroupVolumes(model.Volumes) + volumeList, err := expandNetAppVolumeGroupSAPHanaVolumes(model.Volumes) if err != nil { return err } @@ -411,7 +411,7 @@ func (r NetAppVolumeGroupSapHanaResource) Create() sdk.ResourceFunc { } } -func (r NetAppVolumeGroupSapHanaResource) Update() sdk.ResourceFunc { +func (r NetAppVolumeGroupSAPHanaResource) Update() sdk.ResourceFunc { return sdk.ResourceFunc{ Timeout: 120 * time.Minute, Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { @@ -423,7 +423,7 @@ func (r NetAppVolumeGroupSapHanaResource) Update() sdk.ResourceFunc { } metadata.Logger.Infof("Decoding state for %s", id) - var state netAppModels.NetAppVolumeGroupSapHanaModel + var state netAppModels.NetAppVolumeGroupSAPHanaModel if err := metadata.Decode(&state); err != nil { return fmt.Errorf("decoding: %+v", err) } @@ -524,7 +524,7 @@ func (r NetAppVolumeGroupSapHanaResource) Update() sdk.ResourceFunc { } } -func (r NetAppVolumeGroupSapHanaResource) Read() sdk.ResourceFunc { +func (r NetAppVolumeGroupSAPHanaResource) Read() sdk.ResourceFunc { return sdk.ResourceFunc{ Timeout: 5 * time.Minute, Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { @@ -536,7 +536,7 @@ func (r NetAppVolumeGroupSapHanaResource) Read() sdk.ResourceFunc { } metadata.Logger.Infof("Decoding state for %s", id) - var state netAppModels.NetAppVolumeGroupSapHanaModel + var state netAppModels.NetAppVolumeGroupSAPHanaModel if err := metadata.Decode(&state); err != nil { return fmt.Errorf("decoding: %+v", err) } @@ -549,7 +549,7 @@ func (r NetAppVolumeGroupSapHanaResource) Read() sdk.ResourceFunc { return fmt.Errorf("retrieving %s: %v", id, err) } - model := netAppModels.NetAppVolumeGroupSapHanaModel{ + model := netAppModels.NetAppVolumeGroupSAPHanaModel{ Name: id.VolumeGroupName, AccountName: id.NetAppAccountName, Location: location.NormalizeNilable(existing.Model.Location), @@ -560,7 +560,7 @@ func (r NetAppVolumeGroupSapHanaResource) Read() sdk.ResourceFunc { model.GroupDescription = pointer.From(props.GroupMetaData.GroupDescription) model.ApplicationIdentifier = pointer.From(props.GroupMetaData.ApplicationIdentifier) - volumes, err := flattenNetAppVolumeGroupVolumes(ctx, props.Volumes, metadata) + volumes, err := flattenNetAppVolumeGroupSAPHanaVolumes(ctx, props.Volumes, metadata) if err != nil { return fmt.Errorf("setting `volume`: %+v", err) } @@ -575,7 +575,7 @@ func (r NetAppVolumeGroupSapHanaResource) Read() sdk.ResourceFunc { } } -func (r NetAppVolumeGroupSapHanaResource) Delete() sdk.ResourceFunc { +func (r NetAppVolumeGroupSAPHanaResource) Delete() sdk.ResourceFunc { return sdk.ResourceFunc{ Timeout: 120 * time.Minute, Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go index ed24ff62567b..6bb27c95d740 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go @@ -17,11 +17,11 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/utils" ) -type NetAppVolumeGroupSapHanaResource struct{} +type NetAppVolumeGroupSAPHanaResource struct{} -func TestAccNetAppVolumeGroupSapHana_basic(t *testing.T) { +func TestAccNetAppVolumeGroupSAPHana_basic(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_sap_hana", "test") - r := NetAppVolumeGroupSapHanaResource{} + r := NetAppVolumeGroupSAPHanaResource{} data.ResourceTest(t, r, []acceptance.TestStep{ { @@ -34,9 +34,9 @@ func TestAccNetAppVolumeGroupSapHana_basic(t *testing.T) { }) } -func TestAccNetAppVolumeGroupSapHana_backupVolumeSpecsNfsv3(t *testing.T) { +func TestAccNetAppVolumeGroupSAPHana_backupVolumeSpecsNfsv3(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_sap_hana", "test") - r := NetAppVolumeGroupSapHanaResource{} + r := NetAppVolumeGroupSAPHanaResource{} data.ResourceTest(t, r, []acceptance.TestStep{ { @@ -49,9 +49,9 @@ func TestAccNetAppVolumeGroupSapHana_backupVolumeSpecsNfsv3(t *testing.T) { }) } -func TestAccNetAppVolumeGroupSapHana_snapshotPolicy(t *testing.T) { +func TestAccNetAppVolumeGroupSAPHana_snapshotPolicy(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_sap_hana", "test") - r := NetAppVolumeGroupSapHanaResource{} + r := NetAppVolumeGroupSAPHanaResource{} data.ResourceTest(t, r, []acceptance.TestStep{ { @@ -64,9 +64,9 @@ func TestAccNetAppVolumeGroupSapHana_snapshotPolicy(t *testing.T) { }) } -func TestAccNetAppVolumeGroupSapHana_snapshotPolicyUpdate(t *testing.T) { +func TestAccNetAppVolumeGroupSAPHana_snapshotPolicyUpdate(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_sap_hana", "test") - r := NetAppVolumeGroupSapHanaResource{} + r := NetAppVolumeGroupSAPHanaResource{} data.ResourceTest(t, r, []acceptance.TestStep{ { @@ -86,9 +86,9 @@ func TestAccNetAppVolumeGroupSapHana_snapshotPolicyUpdate(t *testing.T) { }) } -func TestAccNetAppVolumeGroupSapHana_volumeUpdates(t *testing.T) { +func TestAccNetAppVolumeGroupSAPHana_volumeUpdates(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_sap_hana", "test") - r := NetAppVolumeGroupSapHanaResource{} + r := NetAppVolumeGroupSAPHanaResource{} data.ResourceTest(t, r, []acceptance.TestStep{ { @@ -114,9 +114,9 @@ func TestAccNetAppVolumeGroupSapHana_volumeUpdates(t *testing.T) { }) } -func TestAccNetAppVolumeGroupSapHana_crossRegionReplication(t *testing.T) { +func TestAccNetAppVolumeGroupSAPHana_crossRegionReplication(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_sap_hana", "test_secondary") - r := NetAppVolumeGroupSapHanaResource{} + r := NetAppVolumeGroupSAPHanaResource{} data.ResourceTest(t, r, []acceptance.TestStep{ { @@ -129,7 +129,7 @@ func TestAccNetAppVolumeGroupSapHana_crossRegionReplication(t *testing.T) { }) } -func (t NetAppVolumeGroupSapHanaResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { +func (t NetAppVolumeGroupSAPHanaResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { id, err := volumegroups.ParseVolumeGroupID(state.ID) if err != nil { return nil, err @@ -146,8 +146,8 @@ func (t NetAppVolumeGroupSapHanaResource) Exists(ctx context.Context, clients *c return utils.Bool(true), nil } -func (NetAppVolumeGroupSapHanaResource) basic(data acceptance.TestData) string { - template := NetAppVolumeGroupSapHanaResource{}.templatePPG(data) +func (NetAppVolumeGroupSAPHanaResource) basic(data acceptance.TestData) string { + template := NetAppVolumeGroupSAPHanaResource{}.templatePPG(data) return fmt.Sprintf(` %[1]s @@ -315,8 +315,8 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { `, template, data.RandomInteger) } -func (NetAppVolumeGroupSapHanaResource) backupVolumeSpecsNfsv3(data acceptance.TestData) string { - template := NetAppVolumeGroupSapHanaResource{}.templatePPG(data) +func (NetAppVolumeGroupSAPHanaResource) backupVolumeSpecsNfsv3(data acceptance.TestData) string { + template := NetAppVolumeGroupSAPHanaResource{}.templatePPG(data) return fmt.Sprintf(` %[1]s @@ -484,8 +484,8 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { `, template, data.RandomInteger) } -func (NetAppVolumeGroupSapHanaResource) avgSnapshotPolicy(data acceptance.TestData) string { - template := NetAppVolumeGroupSapHanaResource{}.templatePPG(data) +func (NetAppVolumeGroupSAPHanaResource) avgSnapshotPolicy(data acceptance.TestData) string { + template := NetAppVolumeGroupSAPHanaResource{}.templatePPG(data) return fmt.Sprintf(` %[1]s @@ -693,8 +693,8 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { `, template, data.RandomInteger) } -func (NetAppVolumeGroupSapHanaResource) updateAvgSnapshotPolicy(data acceptance.TestData) string { - template := NetAppVolumeGroupSapHanaResource{}.templatePPG(data) +func (NetAppVolumeGroupSAPHanaResource) updateAvgSnapshotPolicy(data acceptance.TestData) string { + template := NetAppVolumeGroupSAPHanaResource{}.templatePPG(data) return fmt.Sprintf(` %[1]s @@ -902,8 +902,8 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { `, template, data.RandomInteger) } -func (NetAppVolumeGroupSapHanaResource) updateVolumes(data acceptance.TestData) string { - template := NetAppVolumeGroupSapHanaResource{}.templatePPG(data) +func (NetAppVolumeGroupSAPHanaResource) updateVolumes(data acceptance.TestData) string { + template := NetAppVolumeGroupSAPHanaResource{}.templatePPG(data) return fmt.Sprintf(` %[1]s @@ -1071,8 +1071,8 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { `, template, data.RandomInteger) } -func (NetAppVolumeGroupSapHanaResource) crossRegionReplication(data acceptance.TestData) string { - template := NetAppVolumeGroupSapHanaResource{}.templateForAvgCrossRegionReplication(data) +func (NetAppVolumeGroupSAPHanaResource) crossRegionReplication(data acceptance.TestData) string { + template := NetAppVolumeGroupSAPHanaResource{}.templateForAvgCrossRegionReplication(data) return fmt.Sprintf(` %[1]s @@ -1433,8 +1433,8 @@ resource "azurerm_netapp_volume_group_sap_hana" "test_secondary" { `, template, data.RandomInteger, "westus") } -func (r NetAppVolumeGroupSapHanaResource) templateForAvgCrossRegionReplication(data acceptance.TestData) string { - template := NetAppVolumeGroupSapHanaResource{}.templatePPG(data) +func (r NetAppVolumeGroupSAPHanaResource) templateForAvgCrossRegionReplication(data acceptance.TestData) string { + template := NetAppVolumeGroupSAPHanaResource{}.templatePPG(data) return fmt.Sprintf(` %[1]s @@ -1597,7 +1597,7 @@ resource "azurerm_netapp_pool" "test_secondary" { `, template, data.RandomInteger, "westus") } -func (NetAppVolumeGroupSapHanaResource) templatePPG(data acceptance.TestData) string { +func (NetAppVolumeGroupSAPHanaResource) templatePPG(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { alias = "all2" diff --git a/internal/services/netapp/netapp_volume_helper.go b/internal/services/netapp/netapp_volume_helper.go index 1a9498bf921f..f438df37add0 100644 --- a/internal/services/netapp/netapp_volume_helper.go +++ b/internal/services/netapp/netapp_volume_helper.go @@ -100,9 +100,9 @@ func expandNetAppVolumeGroupDataProtectionSnapshotPolicy(input []netAppModels.Da } } -func expandNetAppVolumeGroupVolumes(input []netAppModels.NetAppVolumeGroupVolume) (*[]volumegroups.VolumeGroupVolumeProperties, error) { +func expandNetAppVolumeGroupSAPHanaVolumes(input []netAppModels.NetAppVolumeGroupSAPHanaVolume) (*[]volumegroups.VolumeGroupVolumeProperties, error) { if len(input) == 0 { - return &[]volumegroups.VolumeGroupVolumeProperties{}, fmt.Errorf("received empty NetAppVolumeGroupVolume slice") + return &[]volumegroups.VolumeGroupVolumeProperties{}, fmt.Errorf("received empty NetAppVolumeGroupSAPHanaVolume slice") } results := make([]volumegroups.VolumeGroupVolumeProperties, 0) @@ -159,7 +159,7 @@ func expandNetAppVolumeGroupVolumes(input []netAppModels.NetAppVolumeGroupVolume func expandNetAppVolumeGroupOracleVolumes(input []netAppModels.NetAppVolumeGroupOracleVolume) (*[]volumegroups.VolumeGroupVolumeProperties, error) { if len(input) == 0 { - return &[]volumegroups.VolumeGroupVolumeProperties{}, fmt.Errorf("received empty NetAppVolumeGroupVolume slice") + return &[]volumegroups.VolumeGroupVolumeProperties{}, fmt.Errorf("received empty NetAppVolumeGroupSAPHanaVolume slice") } results := make([]volumegroups.VolumeGroupVolumeProperties, 0) @@ -384,15 +384,15 @@ func expandNetAppVolumeDataProtectionBackupPolicyPatch(input []interface{}) *vol } } -func flattenNetAppVolumeGroupVolumes(ctx context.Context, input *[]volumegroups.VolumeGroupVolumeProperties, metadata sdk.ResourceMetaData) ([]netAppModels.NetAppVolumeGroupVolume, error) { - results := make([]netAppModels.NetAppVolumeGroupVolume, 0) +func flattenNetAppVolumeGroupSAPHanaVolumes(ctx context.Context, input *[]volumegroups.VolumeGroupVolumeProperties, metadata sdk.ResourceMetaData) ([]netAppModels.NetAppVolumeGroupSAPHanaVolume, error) { + results := make([]netAppModels.NetAppVolumeGroupSAPHanaVolume, 0) if input == nil || len(pointer.From(input)) == 0 { return results, fmt.Errorf("received empty volumegroups.VolumeGroupVolumeProperties slice") } for _, item := range *input { - volumeGroupVolume := netAppModels.NetAppVolumeGroupVolume{} + volumeGroupVolume := netAppModels.NetAppVolumeGroupSAPHanaVolume{} props := item.Properties volumeGroupVolume.Name = getUserDefinedVolumeName(item.Name) @@ -434,12 +434,12 @@ func flattenNetAppVolumeGroupVolumes(ctx context.Context, input *[]volumegroups. volumeClient := metadata.Client.NetApp.VolumeClient id, err := volumes.ParseVolumeID(pointer.From(item.Id)) if err != nil { - return []netAppModels.NetAppVolumeGroupVolume{}, err + return []netAppModels.NetAppVolumeGroupSAPHanaVolume{}, err } standaloneVol, err := volumeClient.Get(ctx, pointer.From(id)) if err != nil { - return []netAppModels.NetAppVolumeGroupVolume{}, fmt.Errorf("retrieving %s: %v", id, err) + return []netAppModels.NetAppVolumeGroupSAPHanaVolume{}, fmt.Errorf("retrieving %s: %v", id, err) } if standaloneVol.Model.Properties.DataProtection != nil && standaloneVol.Model.Properties.DataProtection.Replication != nil { diff --git a/internal/services/netapp/registration.go b/internal/services/netapp/registration.go index 6c2801cd75ec..2bc1f82c5858 100644 --- a/internal/services/netapp/registration.go +++ b/internal/services/netapp/registration.go @@ -52,7 +52,7 @@ func (r Registration) SupportedResources() map[string]*pluginsdk.Resource { // DataSources returns the typed DataSources supported by this service func (r Registration) DataSources() []sdk.DataSource { return []sdk.DataSource{ - NetAppVolumeGroupSapHanaDataSource{}, + NetAppVolumeGroupSAPHanaDataSource{}, NetAppVolumeQuotaRuleDataSource{}, NetAppAccountEncryptionDataSource{}, NetAppBackupVaultDataSource{}, @@ -64,7 +64,7 @@ func (r Registration) DataSources() []sdk.DataSource { // Resources returns the typed Resources supported by this service func (r Registration) Resources() []sdk.Resource { return []sdk.Resource{ - NetAppVolumeGroupSapHanaResource{}, + NetAppVolumeGroupSAPHanaResource{}, NetAppVolumeQuotaRuleResource{}, NetAppAccountEncryptionResource{}, NetAppBackupVaultResource{}, diff --git a/internal/services/netapp/validate/volume_group_sap_hana_volumes_export_policy_validation_test.go b/internal/services/netapp/validate/volume_group_sap_hana_volumes_export_policy_validation_test.go index 895e914f39c9..4c7437b37a70 100644 --- a/internal/services/netapp/validate/volume_group_sap_hana_volumes_export_policy_validation_test.go +++ b/internal/services/netapp/validate/volume_group_sap_hana_volumes_export_policy_validation_test.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/utils" ) -func TestValidateNetAppVolumeGroupExportPolicyRuleSAPHanna(t *testing.T) { +func TestValidateNetAppVolumeGroupExportPolicyRuleSAPHana(t *testing.T) { cases := []struct { Name string Protocol string diff --git a/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation.go b/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation.go index 327f6d5973bb..f04c73279ade 100644 --- a/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation.go +++ b/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation.go @@ -11,34 +11,34 @@ import ( "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/volumegroups" ) -type VolumeSpecNameSapHana string +type VolumeSpecNameSAPHana string const ( - VolumeSpecNameSapHanaData VolumeSpecNameSapHana = "data" - VolumeSpecNameSapHanaLog VolumeSpecNameSapHana = "log" - VolumeSpecNameSapHanaShared VolumeSpecNameSapHana = "shared" - VolumeSpecNameSapHanaDataBackup VolumeSpecNameSapHana = "data-backup" - VolumeSpecNameSapHanaLogBackup VolumeSpecNameSapHana = "log-backup" + VolumeSpecNameSAPHanaData VolumeSpecNameSAPHana = "data" + VolumeSpecNameSAPHanaLog VolumeSpecNameSAPHana = "log" + VolumeSpecNameSAPHanaShared VolumeSpecNameSAPHana = "shared" + VolumeSpecNameSAPHanaDataBackup VolumeSpecNameSAPHana = "data-backup" + VolumeSpecNameSAPHanaLogBackup VolumeSpecNameSAPHana = "log-backup" ) -func PossibleValuesForVolumeSpecNameSapHana() []string { +func PossibleValuesForVolumeSpecNameSAPHana() []string { return []string{ - string(VolumeSpecNameSapHanaData), - string(VolumeSpecNameSapHanaLog), - string(VolumeSpecNameSapHanaShared), - string(VolumeSpecNameSapHanaDataBackup), - string(VolumeSpecNameSapHanaLogBackup), + string(VolumeSpecNameSAPHanaData), + string(VolumeSpecNameSAPHanaLog), + string(VolumeSpecNameSAPHanaShared), + string(VolumeSpecNameSAPHanaDataBackup), + string(VolumeSpecNameSAPHanaLogBackup), } } func RequiredVolumesForSAPHANA() []string { return []string{ - string(VolumeSpecNameSapHanaData), - string(VolumeSpecNameSapHanaLog), + string(VolumeSpecNameSAPHanaData), + string(VolumeSpecNameSAPHanaLog), } } -func PossibleValuesForProtocolTypeVolumeGroupSapHana() []string { +func PossibleValuesForProtocolTypeVolumeGroupSAPHana() []string { return []string{ string(ProtocolTypeNfsV41), string(ProtocolTypeNfsV3), @@ -84,15 +84,15 @@ func ValidateNetAppVolumeGroupSAPHanaVolumes(volumeList *[]volumegroups.VolumeGr } // Validate that protocol is valid for SAP Hana - if !findStringInSlice(PossibleValuesForProtocolTypeVolumeGroupSapHana(), protocolType) { + if !findStringInSlice(PossibleValuesForProtocolTypeVolumeGroupSAPHana(), protocolType) { errors = append(errors, fmt.Errorf("'protocol %v is invalid for SAP Hana'", protocolType)) } // Can't be nfsv3 on data, log and share volumes if strings.EqualFold(protocolType, string(ProtocolTypeNfsV3)) && - (strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSapHanaData)) || - strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSapHanaShared)) || - strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSapHanaLog))) { + (strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSAPHanaData)) || + strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSAPHanaShared)) || + strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSAPHanaLog))) { errors = append(errors, fmt.Errorf("'nfsv3 on data, log and shared volumes for %v is not supported on volume %v'", applicationType, pointer.From(volume.Name))) } @@ -104,7 +104,7 @@ func ValidateNetAppVolumeGroupSAPHanaVolumes(volumeList *[]volumegroups.VolumeGr } // Checking CRR rule that log cannot be DataProtection type - if strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSapHanaLog)) && + if strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSAPHanaLog)) && volume.Properties.DataProtection != nil && volume.Properties.DataProtection.Replication != nil && strings.EqualFold(string(pointer.From(volume.Properties.DataProtection.Replication.EndpointType)), string(volumegroups.EndpointTypeDst)) { @@ -119,16 +119,16 @@ func ValidateNetAppVolumeGroupSAPHanaVolumes(volumeList *[]volumegroups.VolumeGr } // Validating that data-backup and log-backup don't have PPG defined - if (strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSapHanaDataBackup)) || - strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSapHanaLogBackup))) && + if (strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSAPHanaDataBackup)) || + strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSAPHanaLogBackup))) && pointer.From(volume.Properties.ProximityPlacementGroup) != "" { errors = append(errors, fmt.Errorf("'%v volume spec type cannot have PPG defined for %v on volume %v'", pointer.From(volume.Properties.VolumeSpecName), applicationType, pointer.From(volume.Name))) } // Validating that data, log and shared have PPG defined. - if (strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSapHanaData)) || - strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSapHanaLog)) || - strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSapHanaShared))) && + if (strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSAPHanaData)) || + strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSAPHanaLog)) || + strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameSAPHanaShared))) && pointer.From(volume.Properties.ProximityPlacementGroup) == "" { errors = append(errors, fmt.Errorf("'%v volume spec type must have PPG defined for %v on volume %v'", pointer.From(volume.Properties.VolumeSpecName), applicationType, pointer.From(volume.Name))) } diff --git a/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation_test.go b/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation_test.go index a01d28537ac9..6cf9c0793f7e 100644 --- a/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation_test.go +++ b/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation_test.go @@ -22,7 +22,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { Name: "ValidateCorrectSettingsAllVolumes", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ { // data - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaData))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaData))), Properties: volumegroups.VolumeProperties{ ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ Rules: &[]volumegroups.ExportPolicyRule{ @@ -35,11 +35,11 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaData)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaData)), }, }, { // log - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaLog))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaLog))), Properties: volumegroups.VolumeProperties{ ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ Rules: &[]volumegroups.ExportPolicyRule{ @@ -52,11 +52,11 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaLog)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaLog)), }, }, { // shared - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaShared))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaShared))), Properties: volumegroups.VolumeProperties{ ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ Rules: &[]volumegroups.ExportPolicyRule{ @@ -69,11 +69,11 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaShared)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaShared)), }, }, { // data-backup - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaDataBackup))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaDataBackup))), Properties: volumegroups.VolumeProperties{ ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ Rules: &[]volumegroups.ExportPolicyRule{ @@ -85,11 +85,11 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { }, ProtocolTypes: pointer.To([]string{"NFSv4.1"}), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaDataBackup)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaDataBackup)), }, }, { // log-backup - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaLogBackup))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaLogBackup))), Properties: volumegroups.VolumeProperties{ ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ Rules: &[]volumegroups.ExportPolicyRule{ @@ -101,7 +101,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { }, ProtocolTypes: pointer.To([]string{"NFSv4.1"}), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaLogBackup)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaLogBackup)), }, }, }, @@ -111,7 +111,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { Name: "ValidateMinimumVolumes", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ { // data - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaData))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaData))), Properties: volumegroups.VolumeProperties{ ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ Rules: &[]volumegroups.ExportPolicyRule{ @@ -124,11 +124,11 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaData)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaData)), }, }, { // log - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaLog))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaLog))), Properties: volumegroups.VolumeProperties{ ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ Rules: &[]volumegroups.ExportPolicyRule{ @@ -141,7 +141,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaLog)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaLog)), }, }, }, @@ -151,7 +151,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { Name: "ValidateRequiredVolumeSpecs", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ { // shared - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaShared))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaShared))), Properties: volumegroups.VolumeProperties{ ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ Rules: &[]volumegroups.ExportPolicyRule{ @@ -164,11 +164,11 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaShared)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaShared)), }, }, { // data-backup - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaDataBackup))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaDataBackup))), Properties: volumegroups.VolumeProperties{ ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ Rules: &[]volumegroups.ExportPolicyRule{ @@ -180,11 +180,11 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { }, ProtocolTypes: pointer.To([]string{"NFSv4.1"}), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaDataBackup)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaDataBackup)), }, }, { // log-backup - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaLogBackup))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaLogBackup))), Properties: volumegroups.VolumeProperties{ ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ Rules: &[]volumegroups.ExportPolicyRule{ @@ -196,7 +196,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { }, ProtocolTypes: pointer.To([]string{"NFSv4.1"}), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaLogBackup)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaLogBackup)), }, }, }, @@ -206,7 +206,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { Name: "ValidateLessThanMinimumVolumes", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ { // data - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaData))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaData))), Properties: volumegroups.VolumeProperties{ ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ Rules: &[]volumegroups.ExportPolicyRule{ @@ -219,7 +219,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaData)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaData)), }, }, }, @@ -229,7 +229,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { Name: "ValidateMultiProtocolFails", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ { // data - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaData))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaData))), Properties: volumegroups.VolumeProperties{ ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ Rules: &[]volumegroups.ExportPolicyRule{ @@ -242,7 +242,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { ProtocolTypes: pointer.To([]string{"NFSv4.1", "NFSv3"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaData)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaData)), }, }, }, @@ -252,7 +252,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { Name: "ValidateNoProtocolFails", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ { // data - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaData))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaData))), Properties: volumegroups.VolumeProperties{ ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ Rules: &[]volumegroups.ExportPolicyRule{ @@ -265,7 +265,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { ProtocolTypes: pointer.To([]string{}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaData)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaData)), }, }, }, @@ -275,7 +275,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { Name: "ValidateInvalidProtocolList", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ { // data - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaData))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaData))), Properties: volumegroups.VolumeProperties{ ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ Rules: &[]volumegroups.ExportPolicyRule{ @@ -288,7 +288,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { ProtocolTypes: pointer.To([]string{"NFSv4.1", "InvalidProtocol"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaData)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaData)), }, }, }, @@ -298,7 +298,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { Name: "ValidateInvalidProtocol", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ { // data - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaData))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaData))), Properties: volumegroups.VolumeProperties{ ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ Rules: &[]volumegroups.ExportPolicyRule{ @@ -311,7 +311,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { ProtocolTypes: pointer.To([]string{"InvalidProtocol"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaData)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaData)), }, }, }, @@ -321,7 +321,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { Name: "ValidateCIFSInvalidProtocolForSAPHana", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ { // data - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaData))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaData))), Properties: volumegroups.VolumeProperties{ ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ Rules: &[]volumegroups.ExportPolicyRule{ @@ -334,7 +334,7 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { ProtocolTypes: pointer.To([]string{"CIFS"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaData)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaData)), }, }, }, @@ -344,27 +344,27 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { Name: "ValidateNoNfsVersionThreeOnDataLogAndSharedVolumes", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ { // data - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaData))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaData))), Properties: volumegroups.VolumeProperties{ ProtocolTypes: pointer.To([]string{"NFSv3"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaData)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaData)), }, }, { // log - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaLog))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaLog))), Properties: volumegroups.VolumeProperties{ ProtocolTypes: pointer.To([]string{"NFSv3"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaLog)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaLog)), }, }, { // shared - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaShared))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaShared))), Properties: volumegroups.VolumeProperties{ ProtocolTypes: pointer.To([]string{"NFSv3"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaShared)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaShared)), }, }, }, @@ -374,37 +374,37 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { Name: "ValidateNoPPGBackupVolumes", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ { // data - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaData))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaData))), Properties: volumegroups.VolumeProperties{ ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaData)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaData)), }, }, { // log - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaLog))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaLog))), Properties: volumegroups.VolumeProperties{ ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaLog)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaLog)), }, }, { // data-backup - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaDataBackup))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaDataBackup))), Properties: volumegroups.VolumeProperties{ ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaDataBackup)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaDataBackup)), }, }, { // log-backup - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaLogBackup))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaLogBackup))), Properties: volumegroups.VolumeProperties{ ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaLogBackup)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaLogBackup)), }, }, }, @@ -414,27 +414,27 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { Name: "ValidateRequiredPpgForNonBackupVolumes", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ { // data - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaData))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaData))), Properties: volumegroups.VolumeProperties{ ProtocolTypes: pointer.To([]string{"NFSv4.1"}), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaData)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaData)), }, }, { // log - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaLog))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaLog))), Properties: volumegroups.VolumeProperties{ ProtocolTypes: pointer.To([]string{"NFSv4.1"}), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaLog)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaLog)), }, }, { // shared - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaShared))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaShared))), Properties: volumegroups.VolumeProperties{ ProtocolTypes: pointer.To([]string{"NFSv4.1"}), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaShared)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaShared)), }, }, }, @@ -444,30 +444,30 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { Name: "ValidateVolumeSpecCantRepeat", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ { // data - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaData))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaData))), Properties: volumegroups.VolumeProperties{ ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaData)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaData)), }, }, { // log - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaLog))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaLog))), Properties: volumegroups.VolumeProperties{ ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaLog)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaLog)), }, }, { // shared - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaShared))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaShared))), Properties: volumegroups.VolumeProperties{ ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaData)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaData)), }, }, }, @@ -477,21 +477,21 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { Name: "ValidateEndpointDstNotEnabledOnLogVolume", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ { // data - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaData))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaData))), Properties: volumegroups.VolumeProperties{ ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaData)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaData)), }, }, { // log - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaLog))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaLog))), Properties: volumegroups.VolumeProperties{ ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaLog)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaLog)), DataProtection: &volumegroups.VolumePropertiesDataProtection{ Replication: &volumegroups.ReplicationObject{ EndpointType: pointer.To(volumegroups.EndpointTypeDst), @@ -506,12 +506,12 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { Name: "ValidateSnapshotPolicyNotEnabledOnEndpointDstVolume", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ { // data - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaData))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaData))), Properties: volumegroups.VolumeProperties{ ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaData)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaData)), DataProtection: &volumegroups.VolumePropertiesDataProtection{ Replication: &volumegroups.ReplicationObject{ EndpointType: pointer.To(volumegroups.EndpointTypeDst), @@ -523,12 +523,12 @@ func TestValidateNetAppVolumeGroupSAPHanaVolumes(t *testing.T) { }, }, { // log - Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSapHanaLog))), + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameSAPHanaLog))), Properties: volumegroups.VolumeProperties{ ProtocolTypes: pointer.To([]string{"NFSv4.1"}), ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), - VolumeSpecName: pointer.To(string(VolumeSpecNameSapHanaLog)), + VolumeSpecName: pointer.To(string(VolumeSpecNameSAPHanaLog)), }, }, }, From 7997c44c942b13fd6fa65a6f77b6c9a5c3f34b4a Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 3 Dec 2024 00:23:40 +0000 Subject: [PATCH 05/39] WIP: AVG for Oracle --- internal/services/netapp/README.md | 38 +- internal/services/netapp/models/models.go | 1 - ...pp_volume_group_oracle_data_source_test.go | 2 +- .../netapp_volume_group_oracle_resource.go | 25 +- ...etapp_volume_group_oracle_resource_test.go | 1653 +++-------------- .../netapp_volume_group_sap_hana_resource.go | 26 +- ...app_volume_group_sap_hana_resource_test.go | 44 +- .../services/netapp/netapp_volume_helper.go | 44 +- .../netapp_volume_quota_rule_resource.go | 89 +- .../services/netapp/netapp_volume_resource.go | 28 +- 10 files changed, 558 insertions(+), 1392 deletions(-) diff --git a/internal/services/netapp/README.md b/internal/services/netapp/README.md index afdb8f6741bb..3fd33ec5da18 100644 --- a/internal/services/netapp/README.md +++ b/internal/services/netapp/README.md @@ -9,7 +9,7 @@ This document gives insights into who is maintaining this service and includes d ## Acceptance Tests -- There is lack of SMB-related acceptance tests because it requires Active Directory Domain Controller infrastructure which is not easily automatable. SMB-related tests can only be tested if the infrastructure is setup beforehand which is not that trivial. We should not require SMB tests unless it comes with Domain Controller setup automation. Without automation, the SMB acceptance tests will fail and cause disruptions in CI/bulk testing. +- There is lack of SMB-related acceptance tests because it requires Active Directory Domain Controller infrastructure which is not easy to automate properly. SMB-related tests can only be tested if the infrastructure is setup beforehand which is not that trivial. We should not require SMB tests unless it comes with Domain Controller setup automation. Without automation, the SMB acceptance tests will fail and cause disruptions in CI/bulk testing. - New tests failing should not be accepted. @@ -26,6 +26,42 @@ if err := waitForVolumeCreateOrUpdate(ctx, client, id); err != nil { This is because some operations return from regular SDK polling as completed but due to several factors it is still in progress (e.g. ARM caching, software and hardware layer sync delays, etc.). These wait functions are necessary and should not be removed. +- Do not approve Pull Requests that relies on ThenPoll() methods, e.g. `DeleteThenPoll()`, and please do not ask contributors to use these methods, due to some unknown [issues](https://github.com/hashicorp/pandora/issues/4571) with Pandora, those for Azure NetApp Files are not reliable, causing errors from time to time (and depending on the operation, very frequently) like this: + +```text +pmarques [ ~/go/src/github.com/hashicorp/terraform-provider-azurerm ]$ make acctests SERVICE='netapp' TESTARGS=' -parallel 5 -run=TestAccNetAppVolumeGroupSAPHana_crossRegionReplication -count=1' TESTTIMEOUT='1200m' +==> Checking that code complies with gofmt requirements... +==> Checking that Custom Timeouts are used... +egrep: warning: egrep is obsolescent; using grep -E +egrep: warning: egrep is obsolescent; using grep -E +==> Checking that acceptance test packages are used... +TF_ACC=1 go test -v ./internal/services/netapp -parallel 5 -run=TestAccNetAppVolumeGroupSAPHana_crossRegionReplication -count=1 -timeout 1200m -ldflags="-X=github.com/hashicorp/terraform-provider-azurerm/version.ProviderVersion=acc" +=== RUN TestAccNetAppVolumeGroupSAPHana_crossRegionReplication +=== PAUSE TestAccNetAppVolumeGroupSAPHana_crossRegionReplication +=== CONT TestAccNetAppVolumeGroupSAPHana_crossRegionReplication + testcase.go:173: Error running post-test destroy, there may be dangling resources: exit status 1 + + Error: deleting `volume`: deleting replicate Volume (Subscription: "66bc9830-19b6-4987-94d2-0e487be7aa47" + Resource Group Name: "acctestRG-netapp-241202215210177839" + Net App Account Name: "acctest-NetAppAccount-Secondary-241202215210177839" + Capacity Pool Name: "acctest-NetAppPool-Secondary-241202215210177839" + Volume Name: "acctest-NetAppVolume-1-Secondary-241202215210177839"): polling after VolumesDeleteReplication: `result.Status` was nil/empty - `op.Status` was "DeleteReplication" / `op.Properties.ProvisioningState` was "" + + deleting `volume`: deleting replicate Volume (Subscription: + "66bc9830-19b6-4987-94d2-0e487be7aa47" + Resource Group Name: "acctestRG-netapp-241202215210177839" + Net App Account Name: "acctest-NetAppAccount-Secondary-241202215210177839" + Capacity Pool Name: "acctest-NetAppPool-Secondary-241202215210177839" + Volume Name: "acctest-NetAppVolume-1-Secondary-241202215210177839"): polling + after VolumesDeleteReplication: `result.Status` was nil/empty - `op.Status` + was "DeleteReplication" / `op.Properties.ProvisioningState` was "" +--- FAIL: TestAccNetAppVolumeGroupSAPHana_crossRegionReplication (1375.67s) +FAIL +FAIL github.com/hashicorp/terraform-provider-azurerm/internal/services/netapp 1375.697s +FAIL +make: *** [GNUmakefile:103: acctests] Error 1 +``` + ## Data loss prevention protection - Due to possibility of a volume to be deleted due to configuration changes on config file or changes made outside of Terraform, we have decided to not allow deletion of volumes by default. This is to prevent data loss. If you want to delete a volume, you need to set the feature block configuration `prevent_deletion_if_contains_resources` argument to `true`. diff --git a/internal/services/netapp/models/models.go b/internal/services/netapp/models/models.go index b33b5ed88368..6c68e44a8df8 100644 --- a/internal/services/netapp/models/models.go +++ b/internal/services/netapp/models/models.go @@ -40,7 +40,6 @@ type NetAppVolumeGroupSAPHanaVolume struct { MountIpAddresses []string `tfschema:"mount_ip_addresses"` DataProtectionReplication []DataProtectionReplication `tfschema:"data_protection_replication"` DataProtectionSnapshotPolicy []DataProtectionSnapshotPolicy `tfschema:"data_protection_snapshot_policy"` - Zone string `tfschema:"zone"` } type NetAppVolumeGroupSAPHanaModel struct { diff --git a/internal/services/netapp/netapp_volume_group_oracle_data_source_test.go b/internal/services/netapp/netapp_volume_group_oracle_data_source_test.go index a0afa4c59575..092cf3c15165 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_data_source_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_data_source_test.go @@ -23,7 +23,7 @@ func TestAccNetAppVolumeGroupOracleDataSource_basic(t *testing.T) { Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).Key("name").Exists(), check.That(data.ResourceName).Key("resource_group_name").Exists(), - check.That(data.ResourceName).Key("volume.1.volume_spec_name").HasValue("log"), + check.That(data.ResourceName).Key("volume.1.volume_spec_name").HasValue("ora-data2"), ), }, }) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource.go b/internal/services/netapp/netapp_volume_group_oracle_resource.go index 205329a529ab..25a443754292 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource.go @@ -310,14 +310,15 @@ func (r NetAppVolumeGroupOracleResource) Create() sdk.ResourceFunc { }, } - err = client.CreateThenPoll(ctx, id, parameters) - if err != nil { + // Can't use CreateThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = client.Create(ctx, id, parameters); err != nil { return fmt.Errorf("creating %s: %+v", id, err) } // Waiting for volume group be completely provisioned if err := waitForVolumeGroupCreateOrUpdate(ctx, client, id); err != nil { - return err + return fmt.Errorf("waiting creation %s: %+v", id, err) } metadata.SetID(id) @@ -417,9 +418,16 @@ func (r NetAppVolumeGroupOracleResource) Update() sdk.ResourceFunc { update.Tags = tags.Expand(tagsRaw) } - if err = volumeClient.UpdateThenPoll(ctx, volumeId, update); err != nil { + // Can't use UpdateThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = volumeClient.Update(ctx, volumeId, update); err != nil { return fmt.Errorf("updating %s: %+v", volumeId, err) } + + // Waiting for volume to fully complete an update + if err := waitForVolumeCreateOrUpdate(ctx, volumeClient, volumeId); err != nil { + return fmt.Errorf("waiting update %s: %+v", volumeId, err) + } } } } @@ -511,10 +519,17 @@ func (r NetAppVolumeGroupOracleResource) Delete() sdk.ResourceFunc { } // Removing Volume Group - if err = client.DeleteThenPoll(ctx, pointer.From(id)); err != nil { + // Can't use DeleteThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = client.Delete(ctx, pointer.From(id)); err != nil { return fmt.Errorf("deleting %s: %+v", pointer.From(id), err) } + // Waiting for volume group be completely deleted + if err := waitForVolumeGroupDelete(ctx, client, pointer.From(id)); err != nil { + return fmt.Errorf("waiting delete %s: %+v", pointer.From(id), err) + } + return nil }, } diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index 0a43e93e460b..43834a5492c4 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -51,100 +51,66 @@ func TestAccNetAppVolumeGroupOracle_nfsv3(t *testing.T) { }) } -// func TestAccNetAppVolumeGroupOracle_backupVolumeSpecsNfsv3(t *testing.T) { -// data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") -// r := NetAppVolumeGroupOracleResource{} - -// data.ResourceTest(t, r, []acceptance.TestStep{ -// { -// Config: r.backupVolumeSpecsNfsv3(data), -// Check: acceptance.ComposeTestCheckFunc( -// check.That(data.ResourceName).ExistsInAzure(r), -// ), -// }, -// data.ImportStep(), -// }) -// } +func TestAccNetAppVolumeGroupOracle_snapshotPolicy(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") + r := NetAppVolumeGroupOracleResource{} -// func TestAccNetAppVolumeGroupOracle_snapshotPolicy(t *testing.T) { -// data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") -// r := NetAppVolumeGroupOracleResource{} - -// data.ResourceTest(t, r, []acceptance.TestStep{ -// { -// Config: r.avgSnapshotPolicy(data), -// Check: acceptance.ComposeTestCheckFunc( -// check.That(data.ResourceName).ExistsInAzure(r), -// ), -// }, -// data.ImportStep(), -// }) -// } + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.avgSnapshotPolicy(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} -// func TestAccNetAppVolumeGroupOracle_snapshotPolicyUpdate(t *testing.T) { -// data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") -// r := NetAppVolumeGroupOracleResource{} - -// data.ResourceTest(t, r, []acceptance.TestStep{ -// { -// Config: r.basic(data), -// Check: acceptance.ComposeTestCheckFunc( -// check.That(data.ResourceName).ExistsInAzure(r), -// ), -// }, -// data.ImportStep(), -// { -// Config: r.updateAvgSnapshotPolicy(data), -// Check: acceptance.ComposeTestCheckFunc( -// check.That(data.ResourceName).ExistsInAzure(r), -// ), -// }, -// data.ImportStep(), -// }) -// } +func TestAccNetAppVolumeGroupOracle_snapshotPolicyUpdate(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") + r := NetAppVolumeGroupOracleResource{} -// func TestAccNetAppVolumeGroupOracle_volumeUpdates(t *testing.T) { -// data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") -// r := NetAppVolumeGroupOracleResource{} - -// data.ResourceTest(t, r, []acceptance.TestStep{ -// { -// Config: r.basic(data), -// Check: acceptance.ComposeTestCheckFunc( -// check.That(data.ResourceName).ExistsInAzure(r), -// ), -// }, -// data.ImportStep(), -// { -// Config: r.updateVolumes(data), -// Check: acceptance.ComposeTestCheckFunc( -// check.That(data.ResourceName).ExistsInAzure(r), -// check.That(data.ResourceName).Key("volume.0.storage_quota_in_gb").HasValue("1200"), -// check.That(data.ResourceName).Key("volume.1.export_policy_rule.0.allowed_clients").HasValue("10.0.0.0/8"), -// check.That(data.ResourceName).Key("volume.2.tags.CreatedOnDate").HasValue("2022-07-27T12:00:00Z"), -// check.That(data.ResourceName).Key("volume.4.storage_quota_in_gb").HasValue("1200"), -// check.That(data.ResourceName).Key("volume.4.export_policy_rule.0.allowed_clients").HasValue("192.168.0.0/24"), -// check.That(data.ResourceName).Key("volume.4.tags.CreatedOnDate").HasValue("2022-07-28T11:00:00Z"), -// ), -// }, -// data.ImportStep(), -// }) -// } + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.updateAvgSnapshotPolicy(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} -// func TestAccNetAppVolumeGroupOracle_crossRegionReplication(t *testing.T) { -// data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test_secondary") -// r := NetAppVolumeGroupOracleResource{} - -// data.ResourceTest(t, r, []acceptance.TestStep{ -// { -// Config: r.crossRegionReplication(data), -// Check: acceptance.ComposeTestCheckFunc( -// check.That(data.ResourceName).ExistsInAzure(r), -// ), -// }, -// data.ImportStep(), -// }) -// } +func TestAccNetAppVolumeGroupOracle_volumeUpdates(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") + r := NetAppVolumeGroupOracleResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.updateVolumes(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("volume.0.storage_quota_in_gb").HasValue("1200"), + check.That(data.ResourceName).Key("volume.1.export_policy_rule.0.allowed_clients").HasValue("10.0.0.0/8"), + ), + }, + data.ImportStep(), + }) +} func (t NetAppVolumeGroupOracleResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { id, err := volumegroups.ParseVolumeGroupID(state.ID) @@ -803,1296 +769,289 @@ resource "azurerm_netapp_volume_group_oracle" "test" { `, template, data.RandomInteger) } -// func (NetAppVolumeGroupOracleResource) backupVolumeSpecsNfsv3(data acceptance.TestData) string { -// template := NetAppVolumeGroupOracleResource{}.templatePPG(data) -// return fmt.Sprintf(` -// %[1]s - -// resource "azurerm_netapp_volume_group_oracle" "test" { -// name = "acctest-NetAppVolumeGroup-%[2]d" -// location = azurerm_resource_group.test.location -// resource_group_name = azurerm_resource_group.test.name -// account_name = azurerm_netapp_account.test.name -// group_description = "Test volume group" -// application_identifier = "TST" - -// volume { -// name = "acctest-NetAppVolume-Ora1-%[2]d" -// volume_path = "my-unique-file-ora-path-1-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "data" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } +func (NetAppVolumeGroupOracleResource) avgSnapshotPolicy(data acceptance.TestData) string { + template := NetAppVolumeGroupOracleResource{}.templateAvailabilityZone(data) + return fmt.Sprintf(` +%[1]s -// volume { -// name = "acctest-NetAppVolume-Ora2-%[2]d" -// volume_path = "my-unique-file-ora-path-2-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "log" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } +resource "azurerm_netapp_snapshot_policy" "test" { + name = "acctest-NetAppSnapshotPolicy-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + enabled = true -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } + monthly_schedule { + snapshots_to_keep = 1 + days_of_month = [15, 30] + hour = 23 + minute = 30 + } -// volume { -// name = "acctest-NetAppVolume-Ora3-%[2]d" -// volume_path = "my-unique-file-ora-path-3-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "shared" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } +resource "azurerm_netapp_volume_group_oracle" "test" { + name = "acctest-NetAppVolumeGroup-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + group_description = "Test volume group" + application_identifier = "TST" -// volume { -// name = "acctest-NetAppVolume-Ora4-%[2]d" -// volume_path = "my-unique-file-ora-path-4-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "data-backup" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv3"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = true -// nfsv41_enabled = false -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } + volume { + name = "acctest-NetAppVolume-Ora1-%[2]d" + volume_path = "my-unique-file-ora-path-1-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-data" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } -// volume { -// name = "acctest-NetAppVolume-Ora5-%[2]d" -// volume_path = "my-unique-file-ora-path-5-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "log-backup" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv3"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = true -// nfsv41_enabled = false -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } + data_protection_snapshot_policy { + snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id + } -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } -// depends_on = [ -// azurerm_linux_virtual_machine.test, -// azurerm_proximity_placement_group.test -// ] -// } -// `, template, data.RandomInteger) -// } + volume { + name = "acctest-NetAppVolume-OraLog-%[2]d" + volume_path = "my-unique-file-ora-path-2-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false -// func (NetAppVolumeGroupOracleResource) avgSnapshotPolicy(data acceptance.TestData) string { -// template := NetAppVolumeGroupOracleResource{}.templatePPG(data) -// return fmt.Sprintf(` -// %[1]s + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } -// resource "azurerm_netapp_snapshot_policy" "test" { -// name = "acctest-NetAppSnapshotPolicy-%[2]d" -// location = azurerm_resource_group.test.location -// resource_group_name = azurerm_resource_group.test.name -// account_name = azurerm_netapp_account.test.name -// enabled = true + data_protection_snapshot_policy { + snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id + } -// monthly_schedule { -// snapshots_to_keep = 1 -// days_of_month = [15, 30] -// hour = 23 -// minute = 30 -// } + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } +} +`, template, data.RandomInteger) +} -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } +func (NetAppVolumeGroupOracleResource) updateAvgSnapshotPolicy(data acceptance.TestData) string { + template := NetAppVolumeGroupOracleResource{}.templateAvailabilityZone(data) + return fmt.Sprintf(` +%[1]s -// resource "azurerm_netapp_volume_group_oracle" "test" { -// name = "acctest-NetAppVolumeGroup-%[2]d" -// location = azurerm_resource_group.test.location -// resource_group_name = azurerm_resource_group.test.name -// account_name = azurerm_netapp_account.test.name -// group_description = "Test volume group" -// application_identifier = "TST" - -// volume { -// name = "acctest-NetAppVolume-Ora1-%[2]d" -// volume_path = "my-unique-file-ora-path-1-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "data" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } +resource "azurerm_netapp_snapshot_policy" "test" { + name = "acctest-NetAppSnapshotPolicy-New-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + enabled = true -// data_protection_snapshot_policy { -// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id -// } + monthly_schedule { + snapshots_to_keep = 3 + days_of_month = [10, 25] + hour = 23 + minute = 30 + } -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} -// volume { -// name = "acctest-NetAppVolume-Ora2-%[2]d" -// volume_path = "my-unique-file-ora-path-2-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "log" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } +resource "azurerm_netapp_volume_group_oracle" "test" { + name = "acctest-NetAppVolumeGroup-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + group_description = "Test volume group" + application_identifier = "TST" -// data_protection_snapshot_policy { -// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id -// } + volume { + name = "acctest-NetAppVolume-Ora1-%[2]d" + volume_path = "my-unique-file-ora-path-1-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "2" + volume_spec_name = "ora-data" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } -// volume { -// name = "acctest-NetAppVolume-Ora3-%[2]d" -// volume_path = "my-unique-file-ora-path-3-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "shared" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } + data_protection_snapshot_policy { + snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id + } -// data_protection_snapshot_policy { -// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id -// } + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } + volume { + name = "acctest-NetAppVolume-OraLog-%[2]d" + volume_path = "my-unique-file-ora-path-2-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "2" + volume_spec_name = "ora-log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false -// volume { -// name = "acctest-NetAppVolume-Ora4-%[2]d" -// volume_path = "my-unique-file-ora-path-4-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "data-backup" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } -// data_protection_snapshot_policy { -// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id -// } + data_protection_snapshot_policy { + snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id + } -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } +} +`, template, data.RandomInteger) +} -// volume { -// name = "acctest-NetAppVolume-Ora5-%[2]d" -// volume_path = "my-unique-file-ora-path-5-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "log-backup" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } +func (NetAppVolumeGroupOracleResource) updateVolumes(data acceptance.TestData) string { + template := NetAppVolumeGroupOracleResource{}.templateAvailabilityZone(data) + return fmt.Sprintf(` +%[1]s -// data_protection_snapshot_policy { -// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id -// } +resource "azurerm_netapp_volume_group_oracle" "test" { + name = "acctest-NetAppVolumeGroup-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + group_description = "Test volume group" + application_identifier = "TST" -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } + volume { + name = "acctest-NetAppVolume-Ora1-%[2]d" + volume_path = "my-unique-file-ora-path-1-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-data" + storage_quota_in_gb = 1200 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false -// depends_on = [ -// azurerm_linux_virtual_machine.test, -// azurerm_proximity_placement_group.test -// ] -// } -// `, template, data.RandomInteger) -// } - -// func (NetAppVolumeGroupOracleResource) updateAvgSnapshotPolicy(data acceptance.TestData) string { -// template := NetAppVolumeGroupOracleResource{}.templatePPG(data) -// return fmt.Sprintf(` -// %[1]s - -// resource "azurerm_netapp_snapshot_policy" "test" { -// name = "acctest-NetAppSnapshotPolicy-New-%[2]d" -// location = azurerm_resource_group.test.location -// resource_group_name = azurerm_resource_group.test.name -// account_name = azurerm_netapp_account.test.name -// enabled = true - -// monthly_schedule { -// snapshots_to_keep = 3 -// days_of_month = [10, 25] -// hour = 23 -// minute = 30 -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// resource "azurerm_netapp_volume_group_oracle" "test" { -// name = "acctest-NetAppVolumeGroup-%[2]d" -// location = azurerm_resource_group.test.location -// resource_group_name = azurerm_resource_group.test.name -// account_name = azurerm_netapp_account.test.name -// group_description = "Test volume group" -// application_identifier = "TST" - -// volume { -// name = "acctest-NetAppVolume-Ora1-%[2]d" -// volume_path = "my-unique-file-ora-path-1-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "data" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// data_protection_snapshot_policy { -// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora2-%[2]d" -// volume_path = "my-unique-file-ora-path-2-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "log" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// data_protection_snapshot_policy { -// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora3-%[2]d" -// volume_path = "my-unique-file-ora-path-3-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "shared" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// data_protection_snapshot_policy { -// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora4-%[2]d" -// volume_path = "my-unique-file-ora-path-4-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "data-backup" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// data_protection_snapshot_policy { -// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora5-%[2]d" -// volume_path = "my-unique-file-ora-path-5-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "log-backup" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// data_protection_snapshot_policy { -// snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// depends_on = [ -// azurerm_linux_virtual_machine.test, -// azurerm_proximity_placement_group.test -// ] -// } -// `, template, data.RandomInteger) -// } - -// func (NetAppVolumeGroupOracleResource) updateVolumes(data acceptance.TestData) string { -// template := NetAppVolumeGroupOracleResource{}.templatePPG(data) -// return fmt.Sprintf(` -// %[1]s - -// resource "azurerm_netapp_volume_group_oracle" "test" { -// name = "acctest-NetAppVolumeGroup-%[2]d" -// location = azurerm_resource_group.test.location -// resource_group_name = azurerm_resource_group.test.name -// account_name = azurerm_netapp_account.test.name -// group_description = "Test volume group" -// application_identifier = "TST" - -// volume { -// name = "acctest-NetAppVolume-Ora1-%[2]d" -// volume_path = "my-unique-file-ora-path-1-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "data" -// storage_quota_in_gb = 1200 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora2-%[2]d" -// volume_path = "my-unique-file-ora-path-2-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "log" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "10.0.0.0/8" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora3-%[2]d" -// volume_path = "my-unique-file-ora-path-3-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "shared" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// tags = { -// "CreatedOnDate" = "2022-07-27T12:00:00Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora4-%[2]d" -// volume_path = "my-unique-file-ora-path-4-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "data-backup" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora5-%[2]d" -// volume_path = "my-unique-file-ora-path-5-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "log-backup" -// storage_quota_in_gb = 1200 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "192.168.0.0/24" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// tags = { -// "CreatedOnDate" = "2022-07-28T11:00:00Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// depends_on = [ -// azurerm_linux_virtual_machine.test, -// azurerm_proximity_placement_group.test -// ] -// } -// `, template, data.RandomInteger) -// } - -// func (NetAppVolumeGroupOracleResource) crossRegionReplication(data acceptance.TestData) string { -// template := NetAppVolumeGroupOracleResource{}.templateForAvgCrossRegionReplication(data) -// return fmt.Sprintf(` -// %[1]s - -// resource "azurerm_netapp_volume_group_oracle" "test_primary" { -// name = "acctest-NetAppVolumeGroup-Primary-%[2]d" -// location = azurerm_resource_group.test.location -// resource_group_name = azurerm_resource_group.test.name -// account_name = azurerm_netapp_account.test.name -// group_description = "Test volume group" -// application_identifier = "TST" - -// volume { -// name = "acctest-NetAppVolume-Ora1-Primary-%[2]d" -// volume_path = "my-unique-file-ora-path-1-Primary-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "data" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora2-Primary-%[2]d" -// volume_path = "my-unique-file-ora-path-2-Primary-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "log" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora3-Primary-%[2]d" -// volume_path = "my-unique-file-ora-path-3-Primary-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "shared" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora4-Primary-%[2]d" -// volume_path = "my-unique-file-ora-path-4-Primary-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "data-backup" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora5-Primary-%[2]d" -// volume_path = "my-unique-file-ora-path-5-Primary-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "log-backup" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// depends_on = [ -// azurerm_linux_virtual_machine.test, -// azurerm_proximity_placement_group.test -// ] -// } - -// resource "azurerm_netapp_volume_group_oracle" "test_secondary" { -// name = "acctest-NetAppVolumeGroup-Secondary-%[2]d" -// location = "%[3]s" -// resource_group_name = azurerm_resource_group.test.name -// account_name = azurerm_netapp_account.test_secondary.name -// group_description = "Test volume group" -// application_identifier = "TST" - -// volume { -// name = "acctest-NetAppVolume-Ora1-Secondary-%[2]d" -// volume_path = "my-unique-file-ora-path-1-Secondary-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test_secondary.id -// subnet_id = azurerm_subnet.test_secondary.id -// proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id -// volume_spec_name = "data" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// data_protection_replication { -// endpoint_type = "dst" -// remote_volume_location = azurerm_netapp_volume_group_oracle.test_primary.location -// remote_volume_resource_id = azurerm_netapp_volume_group_oracle.test_primary.volume[0].id -// replication_frequency = "10minutes" -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora2-Secondary-%[2]d" -// volume_path = "my-unique-file-ora-path-2-Secondary-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test_secondary.id -// subnet_id = azurerm_subnet.test_secondary.id -// proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id -// volume_spec_name = "log" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora3-Secondary-%[2]d" -// volume_path = "my-unique-file-ora-path-3-Secondary-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test_secondary.id -// subnet_id = azurerm_subnet.test_secondary.id -// proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id -// volume_spec_name = "shared" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// data_protection_replication { -// endpoint_type = "dst" -// remote_volume_location = azurerm_netapp_volume_group_oracle.test_primary.location -// remote_volume_resource_id = azurerm_netapp_volume_group_oracle.test_primary.volume[2].id -// replication_frequency = "10minutes" -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora4-Secondary-%[2]d" -// volume_path = "my-unique-file-ora-path-4-Secondary-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test_secondary.id -// subnet_id = azurerm_subnet.test_secondary.id -// volume_spec_name = "data-backup" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// data_protection_replication { -// endpoint_type = "dst" -// remote_volume_location = azurerm_netapp_volume_group_oracle.test_primary.location -// remote_volume_resource_id = azurerm_netapp_volume_group_oracle.test_primary.volume[3].id -// replication_frequency = "10minutes" -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora5-Secondary-%[2]d" -// volume_path = "my-unique-file-ora-path-5-Secondary-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test_secondary.id -// subnet_id = azurerm_subnet.test_secondary.id -// volume_spec_name = "log-backup" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// data_protection_replication { -// endpoint_type = "dst" -// remote_volume_location = azurerm_netapp_volume_group_oracle.test_primary.location -// remote_volume_resource_id = azurerm_netapp_volume_group_oracle.test_primary.volume[4].id -// replication_frequency = "10minutes" -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// depends_on = [ -// azurerm_linux_virtual_machine.test_secondary, -// azurerm_proximity_placement_group.test_secondary, - -// ] -// } - -// `, template, data.RandomInteger, "westus") -// } - -// func (r NetAppVolumeGroupOracleResource) templateForAvgCrossRegionReplication(data acceptance.TestData) string { -// template := NetAppVolumeGroupOracleResource{}.templatePPG(data) -// return fmt.Sprintf(` -// %[1]s - -// resource "azurerm_network_security_group" "test_secondary" { -// name = "acctest-NSG-Secondary-%[2]d" -// location = "%[3]s" -// resource_group_name = azurerm_resource_group.test.name - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// resource "azurerm_virtual_network" "test_secondary" { -// name = "acctest-VirtualNetwork-Secondary-%[2]d" -// location = "%[3]s" -// resource_group_name = azurerm_resource_group.test.name -// address_space = ["10.6.0.0/16"] - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// resource "azurerm_subnet" "test_secondary" { -// name = "acctest-DelegatedSubnet-%[2]d" -// resource_group_name = azurerm_resource_group.test.name -// virtual_network_name = azurerm_virtual_network.test_secondary.name -// address_prefixes = ["10.6.2.0/24"] - -// delegation { -// name = "testdelegation" - -// service_delegation { -// name = "Microsoft.Netapp/volumes" -// actions = ["Microsoft.Network/networkinterfaces/*", "Microsoft.Network/virtualNetworks/subnets/join/action"] -// } -// } -// } - -// resource "azurerm_subnet" "test1_secondary" { -// name = "acctest-HostsSubnet-%[2]d" -// resource_group_name = azurerm_resource_group.test.name -// virtual_network_name = azurerm_virtual_network.test_secondary.name -// address_prefixes = ["10.6.1.0/24"] -// } - -// resource "azurerm_subnet_network_security_group_association" "test_secondary" { -// subnet_id = azurerm_subnet.test1_secondary.id -// network_security_group_id = azurerm_network_security_group.test_secondary.id -// } - -// resource "azurerm_proximity_placement_group" "test_secondary" { -// name = "acctest-PPG-Secondary-%[2]d" -// location = "%[3]s" -// resource_group_name = azurerm_resource_group.test.name - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// resource "azurerm_availability_set" "test_secondary" { -// name = "acctest-avset-Secondary-%[2]d" -// location = "%[3]s" -// resource_group_name = azurerm_resource_group.test.name - -// proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// resource "azurerm_network_interface" "test_secondary" { -// name = "acctest-nic-Secondary-%[2]d" -// resource_group_name = azurerm_resource_group.test.name -// location = "%[3]s" - -// ip_configuration { -// name = "internal" -// subnet_id = azurerm_subnet.test1_secondary.id -// private_ip_address_allocation = "Dynamic" -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// resource "azurerm_linux_virtual_machine" "test_secondary" { -// name = "acctest-vm-secondary-%[2]d" -// resource_group_name = azurerm_resource_group.test.name -// location = "%[3]s" -// size = "Standard_M8ms" -// admin_username = local.admin_username -// admin_password = local.admin_password -// disable_password_authentication = false -// proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id -// availability_set_id = azurerm_availability_set.test_secondary.id -// network_interface_ids = [ -// azurerm_network_interface.test_secondary.id -// ] - -// source_image_reference { -// publisher = "Canonical" -// offer = "0001-com-ubuntu-server-jammy" -// sku = "22_04-lts" -// version = "latest" -// } - -// os_disk { -// storage_account_type = "Standard_LRS" -// caching = "ReadWrite" -// } - -// tags = { -// "platformsettings.host_environment.service.platform_optedin_for_rootcerts" = "true", -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true", -// "Owner" = "pmarques" -// } -// } - -// resource "azurerm_netapp_account" "test_secondary" { -// name = "acctest-NetAppAccount-Secondary-%[2]d" -// location = "%[3]s" -// resource_group_name = azurerm_resource_group.test.name + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } -// depends_on = [ -// azurerm_subnet.test_secondary, -// azurerm_subnet.test1_secondary -// ] + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } + volume { + name = "acctest-NetAppVolume-OraLog-%[2]d" + volume_path = "my-unique-file-ora-path-2-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false -// resource "azurerm_netapp_pool" "test_secondary" { -// name = "acctest-NetAppPool-Secondary-%[2]d" -// location = "%[3]s" -// resource_group_name = azurerm_resource_group.test.name -// account_name = azurerm_netapp_account.test_secondary.name -// service_level = "Standard" -// size_in_tb = 8 -// qos_type = "Manual" + export_policy_rule { + rule_index = 1 + allowed_clients = "10.0.0.0/8" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } -// `, template, data.RandomInteger, "westus") -// } + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } +} +`, template, data.RandomInteger) +} // func (NetAppVolumeGroupSAPHanaResource) templatePPG(data acceptance.TestData) string { // return fmt.Sprintf(` diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource.go index 9a106cba48b5..9bbed8c2c039 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource.go @@ -354,14 +354,15 @@ func (r NetAppVolumeGroupSAPHanaResource) Create() sdk.ResourceFunc { }, } - err = client.CreateThenPoll(ctx, id, parameters) - if err != nil { + // Can't use CreateThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = client.Create(ctx, id, parameters); err != nil { return fmt.Errorf("creating %s: %+v", id, err) } // Waiting for volume group be completely provisioned if err := waitForVolumeGroupCreateOrUpdate(ctx, client, id); err != nil { - return err + return fmt.Errorf("waiting create %s: %+v", id, err) } // CRR - Authorizing secondaries from primary volumes @@ -389,7 +390,9 @@ func (r NetAppVolumeGroupSAPHanaResource) Create() sdk.ResourceFunc { } // Authorizing - if err = replicationClient.VolumesAuthorizeReplicationThenPoll(ctx, pointer.From(primaryId), volumesreplication.AuthorizeRequest{ + // Can't use CreateThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = replicationClient.VolumesAuthorizeReplication(ctx, pointer.From(primaryId), volumesreplication.AuthorizeRequest{ RemoteVolumeResourceId: utils.String(secondaryId.ID()), }, ); err != nil { @@ -512,9 +515,16 @@ func (r NetAppVolumeGroupSAPHanaResource) Update() sdk.ResourceFunc { update.Tags = tags.Expand(tagsRaw) } - if err = volumeClient.UpdateThenPoll(ctx, volumeId, update); err != nil { + // Can't use UpdateThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = volumeClient.Update(ctx, volumeId, update); err != nil { return fmt.Errorf("updating %s: %+v", volumeId, err) } + + // Waiting for volume be completely updated + if err := waitForVolumeCreateOrUpdate(ctx, volumeClient, volumeId); err != nil { + return fmt.Errorf("waiting update %s: %+v", volumeId, err) + } } } } @@ -605,8 +615,10 @@ func (r NetAppVolumeGroupSAPHanaResource) Delete() sdk.ResourceFunc { } } - // Removing Volume Group - if err = client.DeleteThenPoll(ctx, pointer.From(id)); err != nil { + // Deleting Volume Group + // Can't use DeleteThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = client.Delete(ctx, pointer.From(id)); err != nil { return fmt.Errorf("deleting %s: %+v", pointer.From(id), err) } diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go index 6bb27c95d740..80b857535fc6 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go @@ -1429,8 +1429,7 @@ resource "azurerm_netapp_volume_group_sap_hana" "test_secondary" { ] } - -`, template, data.RandomInteger, "westus") +`, template, data.RandomInteger, "westus3") } func (r NetAppVolumeGroupSAPHanaResource) templateForAvgCrossRegionReplication(data acceptance.TestData) string { @@ -1438,6 +1437,12 @@ func (r NetAppVolumeGroupSAPHanaResource) templateForAvgCrossRegionReplication(d return fmt.Sprintf(` %[1]s +resource "azurerm_user_assigned_identity" "test_secondary" { + name = "user-assigned-identity-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name +} + resource "azurerm_network_security_group" "test_secondary" { name = "acctest-NSG-Secondary-%[2]d" location = "%[3]s" @@ -1534,7 +1539,7 @@ resource "azurerm_linux_virtual_machine" "test_secondary" { name = "acctest-vm-secondary-%[2]d" resource_group_name = azurerm_resource_group.test.name location = "%[3]s" - size = "Standard_M8ms" + size = "Standard_D2s_v4" admin_username = local.admin_username admin_password = local.admin_password disable_password_authentication = false @@ -1551,12 +1556,22 @@ resource "azurerm_linux_virtual_machine" "test_secondary" { version = "latest" } + patch_assessment_mode = "AutomaticByPlatform" + os_disk { storage_account_type = "Standard_LRS" caching = "ReadWrite" } + identity { + type = "SystemAssigned, UserAssigned" + identity_ids = [ + azurerm_user_assigned_identity.test_secondary.id + ] + } + tags = { + "AzSecPackAutoConfigReady" = "true", "platformsettings.host_environment.service.platform_optedin_for_rootcerts" = "true", "CreatedOnDate" = "2022-07-08T23:50:21Z", "SkipASMAzSecPack" = "true", @@ -1594,13 +1609,12 @@ resource "azurerm_netapp_pool" "test_secondary" { "SkipASMAzSecPack" = "true" } } -`, template, data.RandomInteger, "westus") +`, template, data.RandomInteger, "westus3") } func (NetAppVolumeGroupSAPHanaResource) templatePPG(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { - alias = "all2" features { resource_group { prevent_deletion_if_contains_resources = false @@ -1628,6 +1642,12 @@ resource "azurerm_resource_group" "test" { } } +resource "azurerm_user_assigned_identity" "test" { + name = "user-assigned-identity-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name +} + resource "azurerm_network_security_group" "test" { name = "acctest-NSG-%[1]d" location = azurerm_resource_group.test.location @@ -1724,7 +1744,7 @@ resource "azurerm_linux_virtual_machine" "test" { name = "acctest-vm-%[1]d" resource_group_name = azurerm_resource_group.test.name location = azurerm_resource_group.test.location - size = "Standard_M8ms" + size = "Standard_D2s_v4" admin_username = local.admin_username admin_password = local.admin_password disable_password_authentication = false @@ -1741,12 +1761,22 @@ resource "azurerm_linux_virtual_machine" "test" { version = "latest" } + patch_assessment_mode = "AutomaticByPlatform" + os_disk { storage_account_type = "Standard_LRS" caching = "ReadWrite" } + identity { + type = "SystemAssigned, UserAssigned" + identity_ids = [ + azurerm_user_assigned_identity.test.id + ] + } + tags = { + "AzSecPackAutoConfigReady" = "true", "platformsettings.host_environment.service.platform_optedin_for_rootcerts" = "true", "CreatedOnDate" = "2022-07-08T23:50:21Z", "SkipASMAzSecPack" = "true", @@ -1784,5 +1814,5 @@ resource "azurerm_netapp_pool" "test" { "SkipASMAzSecPack" = "true" } } -`, data.RandomInteger, "eastus") +`, data.RandomInteger, "westus2") } diff --git a/internal/services/netapp/netapp_volume_helper.go b/internal/services/netapp/netapp_volume_helper.go index f438df37add0..4a99005d714d 100644 --- a/internal/services/netapp/netapp_volume_helper.go +++ b/internal/services/netapp/netapp_volume_helper.go @@ -147,10 +147,6 @@ func expandNetAppVolumeGroupSAPHanaVolumes(input []netAppModels.NetAppVolumeGrou volumeProperties.Properties.ProximityPlacementGroup = pointer.To(pointer.From(pointer.To(v))) } - if v := item.Zone; v != "" { - volumeProperties.Zones = pointer.To([]string{v}) - } - results = append(results, *volumeProperties) } @@ -410,10 +406,6 @@ func flattenNetAppVolumeGroupSAPHanaVolumes(ctx context.Context, input *[]volume volumeGroupVolume.ProximityPlacementGroupId = pointer.From(props.ProximityPlacementGroup) } - if item.Zones != nil && len(pointer.From(item.Zones)) > 0 { - volumeGroupVolume.Zone = (pointer.From(item.Zones))[0] - } - volumeGroupVolume.VolumeSpecName = pointer.From(props.VolumeSpecName) if props.UsageThreshold > 0 { @@ -659,7 +651,9 @@ func deleteVolume(ctx context.Context, metadata sdk.ResourceMetaData, volumeId s } // Breaking replication - if err = replicationClient.VolumesBreakReplicationThenPoll(ctx, pointer.From(replicaVolumeId), volumesreplication.BreakReplicationRequest{ + // Can't use VolumesBreakReplicationThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = replicationClient.VolumesBreakReplication(ctx, pointer.From(replicaVolumeId), volumesreplication.BreakReplicationRequest{ ForceBreakReplication: utils.Bool(true), }); err != nil { return fmt.Errorf("breaking replication for %s: %+v", pointer.From(replicaVolumeId), err) @@ -673,7 +667,9 @@ func deleteVolume(ctx context.Context, metadata sdk.ResourceMetaData, volumeId s } // Deleting replication and waiting for it to fully complete the operation - if err = replicationClient.VolumesDeleteReplicationThenPoll(ctx, pointer.From(replicaVolumeId)); err != nil { + // Can't use VolumesDeleteReplicationThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = replicationClient.VolumesDeleteReplication(ctx, pointer.From(replicaVolumeId)); err != nil { return fmt.Errorf("deleting replicate %s: %+v", pointer.From(replicaVolumeId), err) } @@ -683,14 +679,16 @@ func deleteVolume(ctx context.Context, metadata sdk.ResourceMetaData, volumeId s } // Deleting volume and waiting for it to fully complete the operation - if err = client.DeleteThenPoll(ctx, pointer.From(id), volumes.DeleteOperationOptions{ + // Can't use DeleteVolumeThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = client.Delete(ctx, pointer.From(id), volumes.DeleteOperationOptions{ ForceDelete: utils.Bool(true), }); err != nil { return fmt.Errorf("deleting %s: %+v", pointer.From(id), err) } if err = waitForVolumeDeletion(ctx, client, pointer.From(id)); err != nil { - return fmt.Errorf("waiting for deletion of %s: %+v", pointer.From(id), err) + return fmt.Errorf("waiting delete %s: %+v", pointer.From(id), err) } return nil @@ -740,6 +738,28 @@ func waitForVolumeGroupCreateOrUpdate(ctx context.Context, client *volumegroups. return nil } +func waitForVolumeGroupDelete(ctx context.Context, client *volumegroups.VolumeGroupsClient, id volumegroups.VolumeGroupId) error { + deadline, ok := ctx.Deadline() + if !ok { + return fmt.Errorf("internal-error: context had no deadline") + } + stateConf := &pluginsdk.StateChangeConf{ + ContinuousTargetOccurence: 5, + Delay: 10 * time.Second, + MinTimeout: 10 * time.Second, + Pending: []string{"200", "202"}, + Target: []string{"204", "404"}, + Refresh: netappVolumeGroupStateRefreshFunc(ctx, client, id), + Timeout: time.Until(deadline), + } + + if _, err := stateConf.WaitForStateContext(ctx); err != nil { + return fmt.Errorf("waiting for %s to be deleted: %+v", id, err) + } + + return nil +} + func waitForReplAuthorization(ctx context.Context, client *volumesreplication.VolumesReplicationClient, id volumesreplication.VolumeId) error { deadline, ok := ctx.Deadline() if !ok { diff --git a/internal/services/netapp/netapp_volume_quota_rule_resource.go b/internal/services/netapp/netapp_volume_quota_rule_resource.go index 5dc39c9e63af..30e0cdceb08a 100644 --- a/internal/services/netapp/netapp_volume_quota_rule_resource.go +++ b/internal/services/netapp/netapp_volume_quota_rule_resource.go @@ -128,11 +128,17 @@ func (r NetAppVolumeQuotaRuleResource) Create() sdk.ResourceFunc { }, } - err = client.CreateThenPoll(ctx, id, parameters) - if err != nil { + // Can't use CreateThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = client.Create(ctx, id, parameters); err != nil { return fmt.Errorf("creating %s: %+v", id, err) } + // Waiting for quota rule to be created + if err := waitForQuotaRuleCreateOrUpdate(ctx, client, id); err != nil { + return fmt.Errorf("waiting create %s: %+v", id, err) + } + metadata.SetID(id) return nil @@ -166,9 +172,16 @@ func (r NetAppVolumeQuotaRuleResource) Update() sdk.ResourceFunc { update.Properties.QuotaSizeInKiBs = utils.Int64(state.QuotaSizeInKiB) - if err := client.UpdateThenPoll(ctx, pointer.From(id), update); err != nil { + // Can't use UpdateThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err := client.Update(ctx, pointer.From(id), update); err != nil { return fmt.Errorf("updating %s: %+v", id, err) } + + // Waiting for quota rule to be updated + if err := waitForQuotaRuleCreateOrUpdate(ctx, client, pointer.From(id)); err != nil { + return fmt.Errorf("waiting update %s: %+v", id, err) + } } return nil @@ -238,11 +251,79 @@ func (r NetAppVolumeQuotaRuleResource) Delete() sdk.ResourceFunc { return fmt.Errorf("retrieving %s: %v", id, err) } - if err = client.DeleteThenPoll(ctx, pointer.From(id)); err != nil { + // Can't use UpdateThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = client.Delete(ctx, pointer.From(id)); err != nil { return fmt.Errorf("deleting %s: %+v", pointer.From(id), err) } + // Waiting for quota rule to be deleted + if err := waitForQuotaRuleDelete(ctx, client, pointer.From(id)); err != nil { + return fmt.Errorf("waiting delete %s: %+v", id, err) + } + return nil }, } } + +func waitForQuotaRuleCreateOrUpdate(ctx context.Context, client *volumequotarules.VolumeQuotaRulesClient, id volumequotarules.VolumeQuotaRuleId) error { + deadline, ok := ctx.Deadline() + if !ok { + return fmt.Errorf("internal-error: context had no deadline") + } + stateConf := &pluginsdk.StateChangeConf{ + ContinuousTargetOccurence: 5, + Delay: 10 * time.Second, + MinTimeout: 10 * time.Second, + Pending: []string{"204", "404"}, + Target: []string{"200", "202"}, + Refresh: netAppVolumeQuotaRuleStateRefreshFunc(ctx, client, id), + Timeout: time.Until(deadline), + } + + if _, err := stateConf.WaitForStateContext(ctx); err != nil { + return fmt.Errorf("waiting for %s to finish creating/updating: %+v", id, err) + } + + return nil +} + +func netAppVolumeQuotaRuleStateRefreshFunc(ctx context.Context, client *volumequotarules.VolumeQuotaRulesClient, id volumequotarules.VolumeQuotaRuleId) pluginsdk.StateRefreshFunc { + return func() (interface{}, string, error) { + res, err := client.Get(ctx, id) + if err != nil { + if !response.WasNotFound(res.HttpResponse) { + return nil, "", fmt.Errorf("retrieving %s: %s", id, err) + } + } + + statusCode := "dropped connection" + if res.HttpResponse != nil { + statusCode = fmt.Sprintf("%d", res.HttpResponse.StatusCode) + } + return res, statusCode, nil + } +} + +func waitForQuotaRuleDelete(ctx context.Context, client *volumequotarules.VolumeQuotaRulesClient, id volumequotarules.VolumeQuotaRuleId) error { + deadline, ok := ctx.Deadline() + if !ok { + return fmt.Errorf("internal-error: context had no deadline") + } + stateConf := &pluginsdk.StateChangeConf{ + ContinuousTargetOccurence: 5, + Delay: 10 * time.Second, + MinTimeout: 10 * time.Second, + Pending: []string{"200", "202"}, + Target: []string{"204", "404"}, + Refresh: netAppVolumeQuotaRuleStateRefreshFunc(ctx, client, id), + Timeout: time.Until(deadline), + } + + if _, err := stateConf.WaitForStateContext(ctx); err != nil { + return fmt.Errorf("waiting for %s to finish deleting: %+v", id, err) + } + + return nil +} diff --git a/internal/services/netapp/netapp_volume_resource.go b/internal/services/netapp/netapp_volume_resource.go index 84a45eb5a9b1..c0f6b3e962eb 100644 --- a/internal/services/netapp/netapp_volume_resource.go +++ b/internal/services/netapp/netapp_volume_resource.go @@ -609,7 +609,9 @@ func resourceNetAppVolumeCreate(d *pluginsdk.ResourceData, meta interface{}) err parameters.Properties.KeyVaultPrivateEndpointResourceId = pointer.To(keyVaultPrivateEndpointID.(string)) } - if err := client.CreateOrUpdateThenPoll(ctx, id, parameters); err != nil { + // Can't use CreateOrUpdateThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err := client.CreateOrUpdate(ctx, id, parameters); err != nil { return fmt.Errorf("creating %s: %+v", id, err) } @@ -626,7 +628,9 @@ func resourceNetAppVolumeCreate(d *pluginsdk.ResourceData, meta interface{}) err return err } - if err = replicationClient.VolumesAuthorizeReplicationThenPoll(ctx, *replVolID, volumesreplication.AuthorizeRequest{ + // Can't use VolumesAuthorizeReplicationThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = replicationClient.VolumesAuthorizeReplication(ctx, *replVolID, volumesreplication.AuthorizeRequest{ RemoteVolumeResourceId: utils.String(id.ID()), }, ); err != nil { @@ -741,7 +745,9 @@ func resourceNetAppVolumeUpdate(d *pluginsdk.ResourceData, meta interface{}) err update.Tags = tags.Expand(tagsRaw) } - if err = client.UpdateThenPoll(ctx, *id, update); err != nil { + // Can't use UpdateThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = client.Update(ctx, *id, update); err != nil { return fmt.Errorf("updating %s: %+v", id, err) } @@ -894,7 +900,9 @@ func resourceNetAppVolumeDelete(d *pluginsdk.ResourceData, meta interface{}) err } // Breaking replication - if err = replicationClient.VolumesBreakReplicationThenPoll(ctx, *replicaVolumeId, volumesreplication.BreakReplicationRequest{ + // Can't use VolumesBreakReplicationThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = replicationClient.VolumesBreakReplication(ctx, *replicaVolumeId, volumesreplication.BreakReplicationRequest{ ForceBreakReplication: utils.Bool(true), }); err != nil { return fmt.Errorf("breaking replication for %s: %+v", *replicaVolumeId, err) @@ -940,7 +948,9 @@ func resourceNetAppVolumeDelete(d *pluginsdk.ResourceData, meta interface{}) err }, } - if err = client.UpdateThenPoll(ctx, *id, disableBackupPolicy); err != nil { + // Can't use UpdateThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = client.Update(ctx, *id, disableBackupPolicy); err != nil { return fmt.Errorf("updating %s: %+v", id, err) } @@ -965,7 +975,9 @@ func resourceNetAppVolumeDelete(d *pluginsdk.ResourceData, meta interface{}) err }, } - if err = client.UpdateThenPoll(ctx, *id, backupPolicyIdRemoval); err != nil { + // Can't use UpdateThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = client.Update(ctx, *id, backupPolicyIdRemoval); err != nil { return fmt.Errorf("updating %s: %+v", id, err) } @@ -978,7 +990,9 @@ func resourceNetAppVolumeDelete(d *pluginsdk.ResourceData, meta interface{}) err } // Deleting volume and waiting for it fo fully complete the operation - if err = client.DeleteThenPoll(ctx, *id, volumes.DeleteOperationOptions{ + // Can't use DeleteThenPoll because from time to time the LRO SDK fails, + // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 + if _, err = client.Delete(ctx, *id, volumes.DeleteOperationOptions{ ForceDelete: utils.Bool(true), }); err != nil { return fmt.Errorf("deleting %s: %+v", *id, err) From 5d21308e04e68e6b3390d7f4a7594b6b85b18263 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 3 Dec 2024 16:02:57 +0000 Subject: [PATCH 06/39] Reverting UpdateThenPull changes --- .../netapp/netapp_volume_group_oracle_resource.go | 4 +--- .../netapp/netapp_volume_group_sap_hana_resource.go | 4 +--- .../netapp/netapp_volume_quota_rule_resource.go | 6 ++---- internal/services/netapp/netapp_volume_resource.go | 12 +++--------- 4 files changed, 7 insertions(+), 19 deletions(-) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource.go b/internal/services/netapp/netapp_volume_group_oracle_resource.go index 25a443754292..214942e59fd9 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource.go @@ -418,9 +418,7 @@ func (r NetAppVolumeGroupOracleResource) Update() sdk.ResourceFunc { update.Tags = tags.Expand(tagsRaw) } - // Can't use UpdateThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err = volumeClient.Update(ctx, volumeId, update); err != nil { + if err = volumeClient.UpdateThenPoll(ctx, volumeId, update); err != nil { return fmt.Errorf("updating %s: %+v", volumeId, err) } diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource.go index 9bbed8c2c039..7902f0f2c5f8 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource.go @@ -515,9 +515,7 @@ func (r NetAppVolumeGroupSAPHanaResource) Update() sdk.ResourceFunc { update.Tags = tags.Expand(tagsRaw) } - // Can't use UpdateThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err = volumeClient.Update(ctx, volumeId, update); err != nil { + if err = volumeClient.UpdateThenPoll(ctx, volumeId, update); err != nil { return fmt.Errorf("updating %s: %+v", volumeId, err) } diff --git a/internal/services/netapp/netapp_volume_quota_rule_resource.go b/internal/services/netapp/netapp_volume_quota_rule_resource.go index 30e0cdceb08a..78fbadf1a07f 100644 --- a/internal/services/netapp/netapp_volume_quota_rule_resource.go +++ b/internal/services/netapp/netapp_volume_quota_rule_resource.go @@ -172,9 +172,7 @@ func (r NetAppVolumeQuotaRuleResource) Update() sdk.ResourceFunc { update.Properties.QuotaSizeInKiBs = utils.Int64(state.QuotaSizeInKiB) - // Can't use UpdateThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err := client.Update(ctx, pointer.From(id), update); err != nil { + if err := client.UpdateThenPoll(ctx, pointer.From(id), update); err != nil { return fmt.Errorf("updating %s: %+v", id, err) } @@ -251,7 +249,7 @@ func (r NetAppVolumeQuotaRuleResource) Delete() sdk.ResourceFunc { return fmt.Errorf("retrieving %s: %v", id, err) } - // Can't use UpdateThenPoll because from time to time the LRO SDK fails, + // Can't use DeleteThenPoll because from time to time the LRO SDK fails, // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 if _, err = client.Delete(ctx, pointer.From(id)); err != nil { return fmt.Errorf("deleting %s: %+v", pointer.From(id), err) diff --git a/internal/services/netapp/netapp_volume_resource.go b/internal/services/netapp/netapp_volume_resource.go index c0f6b3e962eb..c6b476a3ff58 100644 --- a/internal/services/netapp/netapp_volume_resource.go +++ b/internal/services/netapp/netapp_volume_resource.go @@ -745,9 +745,7 @@ func resourceNetAppVolumeUpdate(d *pluginsdk.ResourceData, meta interface{}) err update.Tags = tags.Expand(tagsRaw) } - // Can't use UpdateThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err = client.Update(ctx, *id, update); err != nil { + if err = client.UpdateThenPoll(ctx, *id, update); err != nil { return fmt.Errorf("updating %s: %+v", id, err) } @@ -948,9 +946,7 @@ func resourceNetAppVolumeDelete(d *pluginsdk.ResourceData, meta interface{}) err }, } - // Can't use UpdateThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err = client.Update(ctx, *id, disableBackupPolicy); err != nil { + if err = client.UpdateThenPoll(ctx, *id, disableBackupPolicy); err != nil { return fmt.Errorf("updating %s: %+v", id, err) } @@ -975,9 +971,7 @@ func resourceNetAppVolumeDelete(d *pluginsdk.ResourceData, meta interface{}) err }, } - // Can't use UpdateThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err = client.Update(ctx, *id, backupPolicyIdRemoval); err != nil { + if err = client.UpdateThenPoll(ctx, *id, backupPolicyIdRemoval); err != nil { return fmt.Errorf("updating %s: %+v", id, err) } From efe1b6f8977e0513b1a766d8fc84076a0eec38f9 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 3 Dec 2024 16:03:11 +0000 Subject: [PATCH 07/39] updating readme --- internal/services/netapp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/services/netapp/README.md b/internal/services/netapp/README.md index 3fd33ec5da18..0aa25560c3e1 100644 --- a/internal/services/netapp/README.md +++ b/internal/services/netapp/README.md @@ -26,7 +26,7 @@ if err := waitForVolumeCreateOrUpdate(ctx, client, id); err != nil { This is because some operations return from regular SDK polling as completed but due to several factors it is still in progress (e.g. ARM caching, software and hardware layer sync delays, etc.). These wait functions are necessary and should not be removed. -- Do not approve Pull Requests that relies on ThenPoll() methods, e.g. `DeleteThenPoll()`, and please do not ask contributors to use these methods, due to some unknown [issues](https://github.com/hashicorp/pandora/issues/4571) with Pandora, those for Azure NetApp Files are not reliable, causing errors from time to time (and depending on the operation, very frequently) like this: +- Do not approve Pull Requests that relies on `ThenPoll()` methods, e.g. `DeleteThenPoll()`, we should not use those for volume related operations due to some unknown [issues](https://github.com/hashicorp/pandora/issues/4571) with Pandora, those for Azure NetApp Files are not reliable, causing errors from time to time (and depending on the operation, very frequently) like this: ```text pmarques [ ~/go/src/github.com/hashicorp/terraform-provider-azurerm ]$ make acctests SERVICE='netapp' TESTARGS=' -parallel 5 -run=TestAccNetAppVolumeGroupSAPHana_crossRegionReplication -count=1' TESTTIMEOUT='1200m' From fa4aea8710cd51c8d7270a44cd3b5147265e098d Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 3 Dec 2024 20:14:21 +0000 Subject: [PATCH 08/39] rolling back a few ThenPoll changes --- ...netapp_account_encryption_resource_test.go | 5 + .../netapp_volume_group_oracle_resource.go | 9 +- ...etapp_volume_group_oracle_resource_test.go | 6 +- .../netapp_volume_group_sap_hana_resource.go | 12 +-- ...app_volume_group_sap_hana_resource_test.go | 6 +- .../services/netapp/netapp_volume_helper.go | 8 +- .../netapp_volume_quota_rule_resource.go | 8 +- .../services/netapp/netapp_volume_resource.go | 12 +-- .../netapp/netapp_volume_resource_test.go | 91 +------------------ 9 files changed, 26 insertions(+), 131 deletions(-) diff --git a/internal/services/netapp/netapp_account_encryption_resource_test.go b/internal/services/netapp/netapp_account_encryption_resource_test.go index 0fa754abc395..25340d0d760b 100644 --- a/internal/services/netapp/netapp_account_encryption_resource_test.go +++ b/internal/services/netapp/netapp_account_encryption_resource_test.go @@ -520,6 +520,11 @@ provider "azurerm" { purge_soft_delete_on_destroy = false purge_soft_deleted_keys_on_destroy = false } + + netapp { + prevent_volume_destruction = false + delete_backups_on_backup_vault_destroy = true + } } } diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource.go b/internal/services/netapp/netapp_volume_group_oracle_resource.go index 214942e59fd9..9bb7bcb623a0 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource.go @@ -310,9 +310,7 @@ func (r NetAppVolumeGroupOracleResource) Create() sdk.ResourceFunc { }, } - // Can't use CreateThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err = client.Create(ctx, id, parameters); err != nil { + if err = client.CreateThenPoll(ctx, id, parameters); err != nil { return fmt.Errorf("creating %s: %+v", id, err) } @@ -516,10 +514,7 @@ func (r NetAppVolumeGroupOracleResource) Delete() sdk.ResourceFunc { } } - // Removing Volume Group - // Can't use DeleteThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err = client.Delete(ctx, pointer.From(id)); err != nil { + if err = client.DeleteThenPoll(ctx, pointer.From(id)); err != nil { return fmt.Errorf("deleting %s: %+v", pointer.From(id), err) } diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index 43834a5492c4..b744dcae5118 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -809,7 +809,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id zone = "1" - volume_spec_name = "ora-data" + volume_spec_name = "ora-data1" storage_quota_in_gb = 1024 throughput_in_mibps = 24 protocols = ["NFSv4.1"] @@ -913,7 +913,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id zone = "2" - volume_spec_name = "ora-data" + volume_spec_name = "ora-data1" storage_quota_in_gb = 1024 throughput_in_mibps = 24 protocols = ["NFSv4.1"] @@ -997,7 +997,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id zone = "1" - volume_spec_name = "ora-data" + volume_spec_name = "ora-data1" storage_quota_in_gb = 1200 throughput_in_mibps = 24 protocols = ["NFSv4.1"] diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource.go index 7902f0f2c5f8..831fd360eaf9 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource.go @@ -354,9 +354,7 @@ func (r NetAppVolumeGroupSAPHanaResource) Create() sdk.ResourceFunc { }, } - // Can't use CreateThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err = client.Create(ctx, id, parameters); err != nil { + if err = client.CreateThenPoll(ctx, id, parameters); err != nil { return fmt.Errorf("creating %s: %+v", id, err) } @@ -390,9 +388,7 @@ func (r NetAppVolumeGroupSAPHanaResource) Create() sdk.ResourceFunc { } // Authorizing - // Can't use CreateThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err = replicationClient.VolumesAuthorizeReplication(ctx, pointer.From(primaryId), volumesreplication.AuthorizeRequest{ + if err = replicationClient.VolumesAuthorizeReplicationThenPoll(ctx, pointer.From(primaryId), volumesreplication.AuthorizeRequest{ RemoteVolumeResourceId: utils.String(secondaryId.ID()), }, ); err != nil { @@ -614,9 +610,7 @@ func (r NetAppVolumeGroupSAPHanaResource) Delete() sdk.ResourceFunc { } // Deleting Volume Group - // Can't use DeleteThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err = client.Delete(ctx, pointer.From(id)); err != nil { + if err = client.DeleteThenPoll(ctx, pointer.From(id)); err != nil { return fmt.Errorf("deleting %s: %+v", pointer.From(id), err) } diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go index 80b857535fc6..4942d5279ef0 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go @@ -1429,7 +1429,7 @@ resource "azurerm_netapp_volume_group_sap_hana" "test_secondary" { ] } -`, template, data.RandomInteger, "westus3") +`, template, data.RandomInteger, "canadaeast") } func (r NetAppVolumeGroupSAPHanaResource) templateForAvgCrossRegionReplication(data acceptance.TestData) string { @@ -1609,7 +1609,7 @@ resource "azurerm_netapp_pool" "test_secondary" { "SkipASMAzSecPack" = "true" } } -`, template, data.RandomInteger, "westus3") +`, template, data.RandomInteger, "canadaeast") } func (NetAppVolumeGroupSAPHanaResource) templatePPG(data acceptance.TestData) string { @@ -1814,5 +1814,5 @@ resource "azurerm_netapp_pool" "test" { "SkipASMAzSecPack" = "true" } } -`, data.RandomInteger, "westus2") +`, data.RandomInteger, "canadacentral") } diff --git a/internal/services/netapp/netapp_volume_helper.go b/internal/services/netapp/netapp_volume_helper.go index 4a99005d714d..5d51317464bd 100644 --- a/internal/services/netapp/netapp_volume_helper.go +++ b/internal/services/netapp/netapp_volume_helper.go @@ -651,9 +651,7 @@ func deleteVolume(ctx context.Context, metadata sdk.ResourceMetaData, volumeId s } // Breaking replication - // Can't use VolumesBreakReplicationThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err = replicationClient.VolumesBreakReplication(ctx, pointer.From(replicaVolumeId), volumesreplication.BreakReplicationRequest{ + if err = replicationClient.VolumesBreakReplicationThenPoll(ctx, pointer.From(replicaVolumeId), volumesreplication.BreakReplicationRequest{ ForceBreakReplication: utils.Bool(true), }); err != nil { return fmt.Errorf("breaking replication for %s: %+v", pointer.From(replicaVolumeId), err) @@ -679,9 +677,7 @@ func deleteVolume(ctx context.Context, metadata sdk.ResourceMetaData, volumeId s } // Deleting volume and waiting for it to fully complete the operation - // Can't use DeleteVolumeThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err = client.Delete(ctx, pointer.From(id), volumes.DeleteOperationOptions{ + if err = client.DeleteThenPoll(ctx, pointer.From(id), volumes.DeleteOperationOptions{ ForceDelete: utils.Bool(true), }); err != nil { return fmt.Errorf("deleting %s: %+v", pointer.From(id), err) diff --git a/internal/services/netapp/netapp_volume_quota_rule_resource.go b/internal/services/netapp/netapp_volume_quota_rule_resource.go index 78fbadf1a07f..5cbeb3017a33 100644 --- a/internal/services/netapp/netapp_volume_quota_rule_resource.go +++ b/internal/services/netapp/netapp_volume_quota_rule_resource.go @@ -128,9 +128,7 @@ func (r NetAppVolumeQuotaRuleResource) Create() sdk.ResourceFunc { }, } - // Can't use CreateThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err = client.Create(ctx, id, parameters); err != nil { + if err = client.CreateThenPoll(ctx, id, parameters); err != nil { return fmt.Errorf("creating %s: %+v", id, err) } @@ -249,9 +247,7 @@ func (r NetAppVolumeQuotaRuleResource) Delete() sdk.ResourceFunc { return fmt.Errorf("retrieving %s: %v", id, err) } - // Can't use DeleteThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err = client.Delete(ctx, pointer.From(id)); err != nil { + if err = client.DeleteThenPoll(ctx, pointer.From(id)); err != nil { return fmt.Errorf("deleting %s: %+v", pointer.From(id), err) } diff --git a/internal/services/netapp/netapp_volume_resource.go b/internal/services/netapp/netapp_volume_resource.go index c6b476a3ff58..cd8a623c7ec3 100644 --- a/internal/services/netapp/netapp_volume_resource.go +++ b/internal/services/netapp/netapp_volume_resource.go @@ -609,9 +609,7 @@ func resourceNetAppVolumeCreate(d *pluginsdk.ResourceData, meta interface{}) err parameters.Properties.KeyVaultPrivateEndpointResourceId = pointer.To(keyVaultPrivateEndpointID.(string)) } - // Can't use CreateOrUpdateThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err := client.CreateOrUpdate(ctx, id, parameters); err != nil { + if err := client.CreateOrUpdateThenPoll(ctx, id, parameters); err != nil { return fmt.Errorf("creating %s: %+v", id, err) } @@ -628,9 +626,7 @@ func resourceNetAppVolumeCreate(d *pluginsdk.ResourceData, meta interface{}) err return err } - // Can't use VolumesAuthorizeReplicationThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err = replicationClient.VolumesAuthorizeReplication(ctx, *replVolID, volumesreplication.AuthorizeRequest{ + if err = replicationClient.VolumesAuthorizeReplicationThenPoll(ctx, *replVolID, volumesreplication.AuthorizeRequest{ RemoteVolumeResourceId: utils.String(id.ID()), }, ); err != nil { @@ -984,9 +980,7 @@ func resourceNetAppVolumeDelete(d *pluginsdk.ResourceData, meta interface{}) err } // Deleting volume and waiting for it fo fully complete the operation - // Can't use DeleteThenPoll because from time to time the LRO SDK fails, - // please see Pandora's issue: https://github.com/hashicorp/pandora/issues/4571 - if _, err = client.Delete(ctx, *id, volumes.DeleteOperationOptions{ + if err = client.DeleteThenPoll(ctx, *id, volumes.DeleteOperationOptions{ ForceDelete: utils.Bool(true), }); err != nil { return fmt.Errorf("deleting %s: %+v", *id, err) diff --git a/internal/services/netapp/netapp_volume_resource_test.go b/internal/services/netapp/netapp_volume_resource_test.go index 01b05f92dd38..9cb8e2a3975d 100644 --- a/internal/services/netapp/netapp_volume_resource_test.go +++ b/internal/services/netapp/netapp_volume_resource_test.go @@ -271,40 +271,6 @@ func TestAccNetAppVolume_update(t *testing.T) { }) } -func TestAccNetAppVolume_updateSubnet(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_netapp_volume", "test") - r := NetAppVolumeResource{} - resourceGroupName := fmt.Sprintf("acctestRG-netapp-%d", data.RandomInteger) - oldVNetName := fmt.Sprintf("acctest-VirtualNetwork-%d", data.RandomInteger) - oldSubnetName := fmt.Sprintf("acctest-Subnet-%d", data.RandomInteger) - newVNetName := fmt.Sprintf("acctest-updated-VirtualNetwork-%d", data.RandomInteger) - newSubnetName := fmt.Sprintf("acctest-updated-Subnet-%d", data.RandomInteger) - uriTemplate := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/virtualNetworks/%s/subnets/%s" - - subscriptionID := os.Getenv("ARM_SUBSCRIPTION_ID") - oldSubnetId := fmt.Sprintf(uriTemplate, subscriptionID, resourceGroupName, oldVNetName, oldSubnetName) - newSubnetId := fmt.Sprintf(uriTemplate, subscriptionID, resourceGroupName, newVNetName, newSubnetName) - - data.ResourceTest(t, r, []acceptance.TestStep{ - { - Config: r.basic(data), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("subnet_id").HasValue(oldSubnetId), - ), - }, - data.ImportStep(), - { - Config: r.updateSubnet(data), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("subnet_id").HasValue(newSubnetId), - ), - }, - data.ImportStep(), - }) -} - func TestAccNetAppVolume_updateExportPolicyRule(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_netapp_volume", "test") r := NetAppVolumeResource{} @@ -1146,59 +1112,6 @@ resource "azurerm_netapp_volume" "test" { `, r.templatePoolQosManual(data), data.RandomInteger, data.RandomInteger) } -func (r NetAppVolumeResource) updateSubnet(data acceptance.TestData) string { - return fmt.Sprintf(` -%s - -resource "azurerm_virtual_network" "updated" { - name = "acctest-updated-VirtualNetwork-%d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - address_space = ["10.1.0.0/16"] - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } -} - -resource "azurerm_subnet" "updated" { - name = "acctest-updated-Subnet-%d" - resource_group_name = azurerm_resource_group.test.name - virtual_network_name = azurerm_virtual_network.updated.name - address_prefixes = ["10.1.3.0/24"] - - delegation { - name = "testdelegation2" - - service_delegation { - name = "Microsoft.Netapp/volumes" - actions = ["Microsoft.Network/networkinterfaces/*", "Microsoft.Network/virtualNetworks/subnets/join/action"] - } - } -} - -resource "azurerm_netapp_volume" "test" { - name = "acctest-updated-NetAppVolume-%d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - account_name = azurerm_netapp_account.test.name - pool_name = azurerm_netapp_pool.test.name - volume_path = "my-updated-unique-file-path-%d" - service_level = "Standard" - subnet_id = azurerm_subnet.updated.id - protocols = ["NFSv3"] - storage_quota_in_gb = 100 - throughput_in_mibps = 1.562 - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } -} -`, r.template(data), data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger) -} - func (r NetAppVolumeResource) updateExportPolicyRule(data acceptance.TestData) string { return fmt.Sprintf(` %s @@ -1491,12 +1404,14 @@ resource "azurerm_subnet" "test-non-delegated" { func (NetAppVolumeResource) templateProviderFeatureFlags() string { return ` provider "azurerm" { + alias = "volumeTests" features { resource_group { prevent_deletion_if_contains_resources = false } + netapp { - prevent_volume_destruction = false + prevent_volume_destruction = false delete_backups_on_backup_vault_destroy = true } } From 9a0d61015797de1a4a54f2ee24f0de5cf47e55ba Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 3 Dec 2024 20:17:28 +0000 Subject: [PATCH 09/39] Removing alias --- internal/services/netapp/netapp_volume_resource_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/services/netapp/netapp_volume_resource_test.go b/internal/services/netapp/netapp_volume_resource_test.go index 9cb8e2a3975d..3b4b5939639e 100644 --- a/internal/services/netapp/netapp_volume_resource_test.go +++ b/internal/services/netapp/netapp_volume_resource_test.go @@ -1404,14 +1404,13 @@ resource "azurerm_subnet" "test-non-delegated" { func (NetAppVolumeResource) templateProviderFeatureFlags() string { return ` provider "azurerm" { - alias = "volumeTests" features { resource_group { prevent_deletion_if_contains_resources = false } netapp { - prevent_volume_destruction = false + prevent_volume_destruction = false delete_backups_on_backup_vault_destroy = true } } From 019d6d516718f67822a157e84115d0a5bbc772d2 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 3 Dec 2024 20:24:36 +0000 Subject: [PATCH 10/39] fixing double provider definition --- .../netapp/netapp_volume_resource_test.go | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/internal/services/netapp/netapp_volume_resource_test.go b/internal/services/netapp/netapp_volume_resource_test.go index 3b4b5939639e..11d911d12f9c 100644 --- a/internal/services/netapp/netapp_volume_resource_test.go +++ b/internal/services/netapp/netapp_volume_resource_test.go @@ -1362,10 +1362,8 @@ resource "azurerm_netapp_pool" "test" { func (r NetAppVolumeResource) networkTemplate(data acceptance.TestData) string { return fmt.Sprintf(` -%[1]s - -resource "azurerm_virtual_network" "test" { - name = "acctest-VirtualNetwork-%[2]d" + resource "azurerm_virtual_network" "test" { + name = "acctest-VirtualNetwork-%[1]d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name address_space = ["10.6.0.0/16"] @@ -1377,7 +1375,7 @@ resource "azurerm_virtual_network" "test" { } resource "azurerm_subnet" "test-delegated" { - name = "acctest-Delegated-Subnet-%[2]d" + name = "acctest-Delegated-Subnet-%[1]d" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test.name address_prefixes = ["10.6.1.0/24"] @@ -1393,12 +1391,12 @@ resource "azurerm_subnet" "test-delegated" { } resource "azurerm_subnet" "test-non-delegated" { - name = "acctest-Non-Delegated-Subnet-%[2]d" + name = "acctest-Non-Delegated-Subnet-%[1]d" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test.name address_prefixes = ["10.6.0.0/24"] } -`, r.templateProviderFeatureFlags(), data.RandomInteger) +`, data.RandomInteger) } func (NetAppVolumeResource) templateProviderFeatureFlags() string { @@ -1409,8 +1407,13 @@ provider "azurerm" { prevent_deletion_if_contains_resources = false } - netapp { - prevent_volume_destruction = false + key_vault { + purge_soft_delete_on_destroy = false + purge_soft_deleted_keys_on_destroy = false + } + + netapp { + prevent_volume_destruction = false delete_backups_on_backup_vault_destroy = true } } From 1bc8b695bb54aec2b8d06990912e4fd9bf7870ca Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 3 Dec 2024 23:18:42 +0000 Subject: [PATCH 11/39] scaling back oracle volume tests --- ...etapp_volume_group_oracle_resource_test.go | 742 ++++++------------ 1 file changed, 244 insertions(+), 498 deletions(-) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index b744dcae5118..a6934402fb2c 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -167,184 +167,184 @@ resource "azurerm_netapp_volume_group_oracle" "test" { } } - volume { - name = "acctest-NetAppVolume-Ora2-%[2]d" - volume_path = "my-unique-file-ora-path-2-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data2" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "foo" = "BAR", - } - } - - volume { - name = "acctest-NetAppVolume-Ora3-%[2]d" - volume_path = "my-unique-file-ora-path-3-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data3" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } - - volume { - name = "acctest-NetAppVolume-Ora4-%[2]d" - volume_path = "my-unique-file-ora-path-4-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data4" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } - - volume { - name = "acctest-NetAppVolume-Ora5-%[2]d" - volume_path = "my-unique-file-ora-path-5-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data5" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false +// volume { +// name = "acctest-NetAppVolume-Ora2-%[2]d" +// volume_path = "my-unique-file-ora-path-2-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "ora-data2" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } +// tags = { +// "foo" = "BAR", +// } +// } - volume { - name = "acctest-NetAppVolume-Ora6-%[2]d" - volume_path = "my-unique-file-ora-path-6-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data6" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false +// volume { +// name = "acctest-NetAppVolume-Ora3-%[2]d" +// volume_path = "my-unique-file-ora-path-3-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "ora-data3" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } +// } - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } +// volume { +// name = "acctest-NetAppVolume-Ora4-%[2]d" +// volume_path = "my-unique-file-ora-path-4-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "ora-data4" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } +// } - volume { - name = "acctest-NetAppVolume-Ora7-%[2]d" - volume_path = "my-unique-file-ora-path-7-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data7" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false +// volume { +// name = "acctest-NetAppVolume-Ora5-%[2]d" +// volume_path = "my-unique-file-ora-path-5-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "ora-data5" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } +// } - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } +// volume { +// name = "acctest-NetAppVolume-Ora6-%[2]d" +// volume_path = "my-unique-file-ora-path-6-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "ora-data6" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } +// } - volume { - name = "acctest-NetAppVolume-Ora8-%[2]d" - volume_path = "my-unique-file-ora-path-8-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data8" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false +// volume { +// name = "acctest-NetAppVolume-Ora7-%[2]d" +// volume_path = "my-unique-file-ora-path-7-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "ora-data7" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } +// } - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } +// volume { +// name = "acctest-NetAppVolume-Ora8-%[2]d" +// volume_path = "my-unique-file-ora-path-8-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "ora-data8" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } +// } volume { name = "acctest-NetAppVolume-OraLog-%[2]d" @@ -371,80 +371,80 @@ resource "azurerm_netapp_volume_group_oracle" "test" { } } - volume { - name = "acctest-NetAppVolume-OraLogMirror-%[2]d" - volume_path = "my-unique-file-oralogmirror-path-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-log-mirror" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } - - volume { - name = "acctest-NetAppVolume-OraBinary-%[2]d" - volume_path = "my-unique-file-orabinary-path-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-binary" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } +// volume { +// name = "acctest-NetAppVolume-OraLogMirror-%[2]d" +// volume_path = "my-unique-file-oralogmirror-path-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "ora-log-mirror" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } +// } - volume { - name = "acctest-NetAppVolume-OraBackup-%[2]d" - volume_path = "my-unique-file-orabackup-path-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-backup" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false +// volume { +// name = "acctest-NetAppVolume-OraBinary-%[2]d" +// volume_path = "my-unique-file-orabinary-path-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "ora-binary" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } +// } - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } +// volume { +// name = "acctest-NetAppVolume-OraBackup-%[2]d" +// volume_path = "my-unique-file-orabackup-path-%[2]d" +// service_level = "Standard" +// capacity_pool_id = azurerm_netapp_pool.test.id +// subnet_id = azurerm_subnet.test.id +// zone = "1" +// volume_spec_name = "ora-backup" +// storage_quota_in_gb = 1024 +// throughput_in_mibps = 24 +// protocols = ["NFSv4.1"] +// security_style = "unix" +// snapshot_directory_visible = false + +// export_policy_rule { +// rule_index = 1 +// allowed_clients = "0.0.0.0/0" +// nfsv3_enabled = false +// nfsv41_enabled = true +// unix_read_only = false +// unix_read_write = true +// root_access_enabled = false +// } +// } } `, template, data.RandomInteger) } @@ -487,185 +487,6 @@ resource "azurerm_netapp_volume_group_oracle" "test" { } } - volume { - name = "acctest-NetAppVolume-Ora2-%[2]d" - volume_path = "my-unique-file-ora-path-2-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data2" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv3"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = true - nfsv41_enabled = false - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "foo" = "BAR", - } - } - - volume { - name = "acctest-NetAppVolume-Ora3-%[2]d" - volume_path = "my-unique-file-ora-path-3-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data3" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv3"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = true - nfsv41_enabled = false - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } - - volume { - name = "acctest-NetAppVolume-Ora4-%[2]d" - volume_path = "my-unique-file-ora-path-4-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data4" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv3"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = true - nfsv41_enabled = false - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } - - volume { - name = "acctest-NetAppVolume-Ora5-%[2]d" - volume_path = "my-unique-file-ora-path-5-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data5" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv3"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = true - nfsv41_enabled = false - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } - - volume { - name = "acctest-NetAppVolume-Ora6-%[2]d" - volume_path = "my-unique-file-ora-path-6-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data6" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv3"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = true - nfsv41_enabled = false - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } - - volume { - name = "acctest-NetAppVolume-Ora7-%[2]d" - volume_path = "my-unique-file-ora-path-7-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data7" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv3"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = true - nfsv41_enabled = false - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } - - volume { - name = "acctest-NetAppVolume-Ora8-%[2]d" - volume_path = "my-unique-file-ora-path-8-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data8" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv3"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = true - nfsv41_enabled = false - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } - volume { name = "acctest-NetAppVolume-OraLog-%[2]d" volume_path = "my-unique-file-oralog-path-%[2]d" @@ -690,81 +511,6 @@ resource "azurerm_netapp_volume_group_oracle" "test" { root_access_enabled = false } } - - volume { - name = "acctest-NetAppVolume-OraLogMirror-%[2]d" - volume_path = "my-unique-file-oralogmirror-path-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-log-mirror" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv3"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = true - nfsv41_enabled = false - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } - - volume { - name = "acctest-NetAppVolume-OraBinary-%[2]d" - volume_path = "my-unique-file-orabinary-path-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-binary" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv3"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = true - nfsv41_enabled = false - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } - - volume { - name = "acctest-NetAppVolume-OraBackup-%[2]d" - volume_path = "my-unique-file-orabackup-path-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-backup" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv3"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = true - nfsv41_enabled = false - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - } } `, template, data.RandomInteger) } @@ -1307,5 +1053,5 @@ resource "azurerm_netapp_pool" "test" { size_in_tb = 18 qos_type = "Manual" } -`, data.RandomInteger, "eastus") +`, data.RandomInteger, "canadaeast") } From 2b17d57037325472e53d26128b84f5fe81819c29 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 3 Dec 2024 23:43:04 +0000 Subject: [PATCH 12/39] Changing region for AZ supported one --- .../services/netapp/netapp_volume_group_oracle_resource_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index a6934402fb2c..b515bedda9b6 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -1053,5 +1053,5 @@ resource "azurerm_netapp_pool" "test" { size_in_tb = 18 qos_type = "Manual" } -`, data.RandomInteger, "canadaeast") +`, data.RandomInteger, "canadacentral") } From ba12d83b32ddfea445b2e52587903ea1d765991c Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 4 Dec 2024 20:16:46 +0000 Subject: [PATCH 13/39] fixing a few issues with testing --- .../netapp/netapp_volume_group_oracle_data_source_test.go | 2 +- .../services/netapp/netapp_volume_group_oracle_resource.go | 1 + .../netapp/netapp_volume_group_oracle_resource_test.go | 2 +- .../netapp/netapp_volume_group_sap_hana_resource_test.go | 6 ++++++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/internal/services/netapp/netapp_volume_group_oracle_data_source_test.go b/internal/services/netapp/netapp_volume_group_oracle_data_source_test.go index 092cf3c15165..7fa7609a439c 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_data_source_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_data_source_test.go @@ -23,7 +23,7 @@ func TestAccNetAppVolumeGroupOracleDataSource_basic(t *testing.T) { Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).Key("name").Exists(), check.That(data.ResourceName).Key("resource_group_name").Exists(), - check.That(data.ResourceName).Key("volume.1.volume_spec_name").HasValue("ora-data2"), + check.That(data.ResourceName).Key("volume.1.volume_spec_name").HasValue("ora-log"), ), }, }) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource.go b/internal/services/netapp/netapp_volume_group_oracle_resource.go index 9bb7bcb623a0..69d77d920234 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource.go @@ -348,6 +348,7 @@ func (r NetAppVolumeGroupOracleResource) Update() sdk.ResourceFunc { if metadata.ResourceData.HasChange("volume") { // Iterating over each volume and performing individual patch for i := 0; i < metadata.ResourceData.Get("volume.#").(int); i++ { + // Checking if individual volume has a change volumeItem := fmt.Sprintf("volume.%v", i) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index b515bedda9b6..854c48590e88 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -72,7 +72,7 @@ func TestAccNetAppVolumeGroupOracle_snapshotPolicyUpdate(t *testing.T) { data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.basic(data), + Config: r.avgSnapshotPolicy(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go index 4942d5279ef0..3cc20f3b294e 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go @@ -1510,6 +1510,9 @@ resource "azurerm_availability_set" "test_secondary" { location = "%[3]s" resource_group_name = azurerm_resource_group.test.name + platform_update_domain_count = 2 + platform_fault_domain_count = 2 + proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id tags = { @@ -1715,6 +1718,9 @@ resource "azurerm_availability_set" "test" { location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name + platform_update_domain_count = 2 + platform_fault_domain_count = 2 + proximity_placement_group_id = azurerm_proximity_placement_group.test.id tags = { From df4784fd34c2534c759ed6bc0560f2a6f92d13ce Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 4 Dec 2024 20:58:25 +0000 Subject: [PATCH 14/39] scaling down SAP Hana tests to avoid regional capacity issues --- ...app_volume_group_sap_hana_resource_test.go | 662 +----------------- 1 file changed, 27 insertions(+), 635 deletions(-) diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go index 3cc20f3b294e..42d48e91b257 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go @@ -104,10 +104,6 @@ func TestAccNetAppVolumeGroupSAPHana_volumeUpdates(t *testing.T) { check.That(data.ResourceName).ExistsInAzure(r), check.That(data.ResourceName).Key("volume.0.storage_quota_in_gb").HasValue("1200"), check.That(data.ResourceName).Key("volume.1.export_policy_rule.0.allowed_clients").HasValue("10.0.0.0/8"), - check.That(data.ResourceName).Key("volume.2.tags.CreatedOnDate").HasValue("2022-07-27T12:00:00Z"), - check.That(data.ResourceName).Key("volume.4.storage_quota_in_gb").HasValue("1200"), - check.That(data.ResourceName).Key("volume.4.export_policy_rule.0.allowed_clients").HasValue("192.168.0.0/24"), - check.That(data.ResourceName).Key("volume.4.tags.CreatedOnDate").HasValue("2022-07-28T11:00:00Z"), ), }, data.ImportStep(), @@ -218,95 +214,7 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { "SkipASMAzSecPack" = "true" } } - - volume { - name = "acctest-NetAppVolume-3-%[2]d" - volume_path = "my-unique-file-path-3-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "shared" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-4-%[2]d" - volume_path = "my-unique-file-path-4-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - volume_spec_name = "data-backup" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-5-%[2]d" - volume_path = "my-unique-file-path-5-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - volume_spec_name = "log-backup" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - + depends_on = [ azurerm_linux_virtual_machine.test, azurerm_proximity_placement_group.test @@ -388,36 +296,6 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { } } - volume { - name = "acctest-NetAppVolume-3-%[2]d" - volume_path = "my-unique-file-path-3-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "shared" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - volume { name = "acctest-NetAppVolume-4-%[2]d" volume_path = "my-unique-file-path-4-%[2]d" @@ -584,107 +462,7 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { "SkipASMAzSecPack" = "true" } } - - volume { - name = "acctest-NetAppVolume-3-%[2]d" - volume_path = "my-unique-file-path-3-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "shared" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-4-%[2]d" - volume_path = "my-unique-file-path-4-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - volume_spec_name = "data-backup" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-5-%[2]d" - volume_path = "my-unique-file-path-5-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - volume_spec_name = "log-backup" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - + depends_on = [ azurerm_linux_virtual_machine.test, azurerm_proximity_placement_group.test @@ -794,136 +572,36 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { } } + depends_on = [ + azurerm_linux_virtual_machine.test, + azurerm_proximity_placement_group.test + ] +} +`, template, data.RandomInteger) +} + +func (NetAppVolumeGroupSAPHanaResource) updateVolumes(data acceptance.TestData) string { + template := NetAppVolumeGroupSAPHanaResource{}.templatePPG(data) + return fmt.Sprintf(` +%[1]s + +resource "azurerm_netapp_volume_group_sap_hana" "test" { + name = "acctest-NetAppVolumeGroup-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + group_description = "Test volume group" + application_identifier = "TST" + volume { - name = "acctest-NetAppVolume-3-%[2]d" - volume_path = "my-unique-file-path-3-%[2]d" + name = "acctest-NetAppVolume-1-%[2]d" + volume_path = "my-unique-file-path-1-%[2]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "shared" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-4-%[2]d" - volume_path = "my-unique-file-path-4-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - volume_spec_name = "data-backup" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-5-%[2]d" - volume_path = "my-unique-file-path-5-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - volume_spec_name = "log-backup" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - depends_on = [ - azurerm_linux_virtual_machine.test, - azurerm_proximity_placement_group.test - ] -} -`, template, data.RandomInteger) -} - -func (NetAppVolumeGroupSAPHanaResource) updateVolumes(data acceptance.TestData) string { - template := NetAppVolumeGroupSAPHanaResource{}.templatePPG(data) - return fmt.Sprintf(` -%[1]s - -resource "azurerm_netapp_volume_group_sap_hana" "test" { - name = "acctest-NetAppVolumeGroup-%[2]d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - account_name = azurerm_netapp_account.test.name - group_description = "Test volume group" - application_identifier = "TST" - - volume { - name = "acctest-NetAppVolume-1-%[2]d" - volume_path = "my-unique-file-path-1-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "data" - storage_quota_in_gb = 1200 + volume_spec_name = "data" + storage_quota_in_gb = 1200 throughput_in_mibps = 24 protocols = ["NFSv4.1"] security_style = "unix" @@ -975,94 +653,6 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { } } - volume { - name = "acctest-NetAppVolume-3-%[2]d" - volume_path = "my-unique-file-path-3-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "shared" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-27T12:00:00Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-4-%[2]d" - volume_path = "my-unique-file-path-4-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - volume_spec_name = "data-backup" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-5-%[2]d" - volume_path = "my-unique-file-path-5-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - volume_spec_name = "log-backup" - storage_quota_in_gb = 1200 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "192.168.0.0/24" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-28T11:00:00Z", - "SkipASMAzSecPack" = "true" - } - } - depends_on = [ azurerm_linux_virtual_machine.test, azurerm_proximity_placement_group.test @@ -1144,94 +734,6 @@ resource "azurerm_netapp_volume_group_sap_hana" "test_primary" { } } - volume { - name = "acctest-NetAppVolume-3-Primary-%[2]d" - volume_path = "my-unique-file-path-3-Primary-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - proximity_placement_group_id = azurerm_proximity_placement_group.test.id - volume_spec_name = "shared" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-4-Primary-%[2]d" - volume_path = "my-unique-file-path-4-Primary-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - volume_spec_name = "data-backup" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-5-Primary-%[2]d" - volume_path = "my-unique-file-path-5-Primary-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - volume_spec_name = "log-backup" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - depends_on = [ azurerm_linux_virtual_machine.test, azurerm_proximity_placement_group.test @@ -1313,119 +815,9 @@ resource "azurerm_netapp_volume_group_sap_hana" "test_secondary" { } } - volume { - name = "acctest-NetAppVolume-3-Secondary-%[2]d" - volume_path = "my-unique-file-path-3-Secondary-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test_secondary.id - subnet_id = azurerm_subnet.test_secondary.id - proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id - volume_spec_name = "shared" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - data_protection_replication { - endpoint_type = "dst" - remote_volume_location = azurerm_netapp_volume_group_sap_hana.test_primary.location - remote_volume_resource_id = azurerm_netapp_volume_group_sap_hana.test_primary.volume[2].id - replication_frequency = "10minutes" - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-4-Secondary-%[2]d" - volume_path = "my-unique-file-path-4-Secondary-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test_secondary.id - subnet_id = azurerm_subnet.test_secondary.id - volume_spec_name = "data-backup" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - data_protection_replication { - endpoint_type = "dst" - remote_volume_location = azurerm_netapp_volume_group_sap_hana.test_primary.location - remote_volume_resource_id = azurerm_netapp_volume_group_sap_hana.test_primary.volume[3].id - replication_frequency = "10minutes" - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - - volume { - name = "acctest-NetAppVolume-5-Secondary-%[2]d" - volume_path = "my-unique-file-path-5-Secondary-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test_secondary.id - subnet_id = azurerm_subnet.test_secondary.id - volume_spec_name = "log-backup" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false - - export_policy_rule { - rule_index = 1 - allowed_clients = "0.0.0.0/0" - nfsv3_enabled = false - nfsv41_enabled = true - unix_read_only = false - unix_read_write = true - root_access_enabled = false - } - - data_protection_replication { - endpoint_type = "dst" - remote_volume_location = azurerm_netapp_volume_group_sap_hana.test_primary.location - remote_volume_resource_id = azurerm_netapp_volume_group_sap_hana.test_primary.volume[4].id - replication_frequency = "10minutes" - } - - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true" - } - } - depends_on = [ azurerm_linux_virtual_machine.test_secondary, azurerm_proximity_placement_group.test_secondary, - ] } From 4923c31c121549f9b66cd5d387068742af34f5dc Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 4 Dec 2024 23:15:37 +0000 Subject: [PATCH 15/39] Changing region for CRR and SAP Hana --- .../netapp/netapp_volume_group_sap_hana_resource_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go index 42d48e91b257..f976270957c7 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go @@ -821,7 +821,7 @@ resource "azurerm_netapp_volume_group_sap_hana" "test_secondary" { ] } -`, template, data.RandomInteger, "canadaeast") +`, template, data.RandomInteger, "westus2") } func (r NetAppVolumeGroupSAPHanaResource) templateForAvgCrossRegionReplication(data acceptance.TestData) string { @@ -1004,7 +1004,7 @@ resource "azurerm_netapp_pool" "test_secondary" { "SkipASMAzSecPack" = "true" } } -`, template, data.RandomInteger, "canadaeast") +`, template, data.RandomInteger, "westus2") } func (NetAppVolumeGroupSAPHanaResource) templatePPG(data acceptance.TestData) string { @@ -1212,5 +1212,5 @@ resource "azurerm_netapp_pool" "test" { "SkipASMAzSecPack" = "true" } } -`, data.RandomInteger, "canadacentral") +`, data.RandomInteger, "westus3") } From 413cf22980d341193660e226ffdd0d153101c900 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 18 Dec 2024 00:29:09 +0000 Subject: [PATCH 16/39] PPG testing and CMK implementation --- internal/services/netapp/models/models.go | 2 + ...pp_volume_group_oracle_data_source_test.go | 2 +- .../netapp_volume_group_oracle_resource.go | 18 +- ...etapp_volume_group_oracle_resource_test.go | 1015 +++++++++-------- .../services/netapp/netapp_volume_helper.go | 18 +- .../volume_group_oracle_volumes_validation.go | 42 +- ...me_group_oracle_volumes_validation_test.go | 505 +++++++- 7 files changed, 1088 insertions(+), 514 deletions(-) diff --git a/internal/services/netapp/models/models.go b/internal/services/netapp/models/models.go index 6c68e44a8df8..7350bd8dfcee 100644 --- a/internal/services/netapp/models/models.go +++ b/internal/services/netapp/models/models.go @@ -81,6 +81,8 @@ type NetAppVolumeGroupOracleVolume struct { MountIpAddresses []string `tfschema:"mount_ip_addresses"` DataProtectionSnapshotPolicy []DataProtectionSnapshotPolicy `tfschema:"data_protection_snapshot_policy"` Zone string `tfschema:"zone"` + EncryptionKeySource string `tfschema:"encryption_key_source"` + KeyVaultPrivateEndpointId string `tfschema:"key_vault_private_endpoint_id"` } type NetAppVolumeGroupOracleModel struct { diff --git a/internal/services/netapp/netapp_volume_group_oracle_data_source_test.go b/internal/services/netapp/netapp_volume_group_oracle_data_source_test.go index 7fa7609a439c..f44f5a714da1 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_data_source_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_data_source_test.go @@ -38,5 +38,5 @@ data "azurerm_netapp_volume_group_oracle" "test" { resource_group_name = azurerm_netapp_volume_group_oracle.test.resource_group_name account_name = azurerm_netapp_volume_group_oracle.test.account_name } -`, NetAppVolumeGroupOracleResource{}.basic(data)) +`, NetAppVolumeGroupOracleResource{}.basicAvailabilityZone(data)) } diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource.go b/internal/services/netapp/netapp_volume_group_oracle_resource.go index 69d77d920234..251d7b4f8541 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource.go @@ -252,6 +252,22 @@ func (r NetAppVolumeGroupOracleResource) Arguments() map[string]*pluginsdk.Schem }, }, }, + + "encryption_key_source": { + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + ValidateFunc: validation.StringInSlice(volumes.PossibleValuesForEncryptionKeySource(), false), + }, + + "key_vault_private_endpoint_id": { + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + ValidateFunc: azure.ValidateResourceID, + }, }, }, }, @@ -267,8 +283,6 @@ func (r NetAppVolumeGroupOracleResource) Create() sdk.ResourceFunc { Timeout: 90 * time.Minute, Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { client := metadata.Client.NetApp.VolumeGroupClient - //replicationClient := metadata.Client.NetApp.VolumeReplicationClient - subscriptionId := metadata.Client.Account.SubscriptionId var model netAppModels.NetAppVolumeGroupOracleModel diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index 854c48590e88..30942f30078a 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -6,6 +6,7 @@ package netapp_test import ( "context" "fmt" + "os" "testing" "github.com/hashicorp/go-azure-helpers/lang/response" @@ -19,13 +20,28 @@ import ( type NetAppVolumeGroupOracleResource struct{} -func TestAccNetAppVolumeGroupOracle_basic(t *testing.T) { +func TestAccNetAppVolumeGroupOracle_basicAvailabilityZone(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") r := NetAppVolumeGroupOracleResource{} data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.basic(data), + Config: r.basicAvailabilityZone(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccNetAppVolumeGroupOracle_basicProximityPlacementGroup(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") + r := NetAppVolumeGroupOracleResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basicProximityPlacementGroup(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), @@ -94,7 +110,7 @@ func TestAccNetAppVolumeGroupOracle_volumeUpdates(t *testing.T) { data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.basic(data), + Config: r.basicAvailabilityZone(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), @@ -112,6 +128,23 @@ func TestAccNetAppVolumeGroupOracle_volumeUpdates(t *testing.T) { }) } +func TestAccNetAppVolumeGroupOracle_volCustomerManagedKeyEncryption(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_netapp_volume_group_oracle", "test") + r := NetAppVolumeGroupOracleResource{} + + tenantID := os.Getenv("ARM_TENANT_ID") + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.volEncryptionCmkOracle(data, tenantID), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + func (t NetAppVolumeGroupOracleResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { id, err := volumegroups.ParseVolumeGroupID(state.ID) if err != nil { @@ -129,8 +162,8 @@ func (t NetAppVolumeGroupOracleResource) Exists(ctx context.Context, clients *cl return utils.Bool(true), nil } -func (NetAppVolumeGroupOracleResource) basic(data acceptance.TestData) string { - template := NetAppVolumeGroupOracleResource{}.templateAvailabilityZone(data) +func (NetAppVolumeGroupOracleResource) basicAvailabilityZone(data acceptance.TestData) string { + template := NetAppVolumeGroupOracleResource{}.templateAvailabilityZoneOracle(data) return fmt.Sprintf(` %[1]s @@ -167,185 +200,6 @@ resource "azurerm_netapp_volume_group_oracle" "test" { } } -// volume { -// name = "acctest-NetAppVolume-Ora2-%[2]d" -// volume_path = "my-unique-file-ora-path-2-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "ora-data2" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } - -// tags = { -// "foo" = "BAR", -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora3-%[2]d" -// volume_path = "my-unique-file-ora-path-3-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "ora-data3" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora4-%[2]d" -// volume_path = "my-unique-file-ora-path-4-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "ora-data4" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora5-%[2]d" -// volume_path = "my-unique-file-ora-path-5-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "ora-data5" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora6-%[2]d" -// volume_path = "my-unique-file-ora-path-6-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "ora-data6" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora7-%[2]d" -// volume_path = "my-unique-file-ora-path-7-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "ora-data7" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } -// } - -// volume { -// name = "acctest-NetAppVolume-Ora8-%[2]d" -// volume_path = "my-unique-file-ora-path-8-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "ora-data8" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } -// } - volume { name = "acctest-NetAppVolume-OraLog-%[2]d" volume_path = "my-unique-file-oralog-path-%[2]d" @@ -370,87 +224,83 @@ resource "azurerm_netapp_volume_group_oracle" "test" { root_access_enabled = false } } +} +`, template, data.RandomInteger) +} + +func (NetAppVolumeGroupOracleResource) basicProximityPlacementGroup(data acceptance.TestData) string { + template := NetAppVolumeGroupOracleResource{}.templatePpgOracle(data) + return fmt.Sprintf(` +%[1]s + +resource "azurerm_netapp_volume_group_oracle" "test" { + name = "acctest-NetAppVolumeGroupOracle-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + group_description = "Test volume group for Oracle" + application_identifier = "TST" + + volume { + name = "acctest-NetAppVolume-Ora1-%[2]d" + volume_path = "my-unique-file-ora-path-1-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "ora-data1" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + } + + volume { + name = "acctest-NetAppVolume-OraLog-%[2]d" + volume_path = "my-unique-file-oralog-path-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "ora-log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + } -// volume { -// name = "acctest-NetAppVolume-OraLogMirror-%[2]d" -// volume_path = "my-unique-file-oralogmirror-path-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "ora-log-mirror" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } -// } - -// volume { -// name = "acctest-NetAppVolume-OraBinary-%[2]d" -// volume_path = "my-unique-file-orabinary-path-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "ora-binary" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } -// } - -// volume { -// name = "acctest-NetAppVolume-OraBackup-%[2]d" -// volume_path = "my-unique-file-orabackup-path-%[2]d" -// service_level = "Standard" -// capacity_pool_id = azurerm_netapp_pool.test.id -// subnet_id = azurerm_subnet.test.id -// zone = "1" -// volume_spec_name = "ora-backup" -// storage_quota_in_gb = 1024 -// throughput_in_mibps = 24 -// protocols = ["NFSv4.1"] -// security_style = "unix" -// snapshot_directory_visible = false - -// export_policy_rule { -// rule_index = 1 -// allowed_clients = "0.0.0.0/0" -// nfsv3_enabled = false -// nfsv41_enabled = true -// unix_read_only = false -// unix_read_write = true -// root_access_enabled = false -// } -// } + depends_on = [ + azurerm_linux_virtual_machine.test, + azurerm_proximity_placement_group.test + ] } `, template, data.RandomInteger) } func (NetAppVolumeGroupOracleResource) nfsv3(data acceptance.TestData) string { - template := NetAppVolumeGroupOracleResource{}.templateAvailabilityZone(data) + template := NetAppVolumeGroupOracleResource{}.templateAvailabilityZoneOracle(data) return fmt.Sprintf(` %[1]s @@ -516,7 +366,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { } func (NetAppVolumeGroupOracleResource) avgSnapshotPolicy(data acceptance.TestData) string { - template := NetAppVolumeGroupOracleResource{}.templateAvailabilityZone(data) + template := NetAppVolumeGroupOracleResource{}.templateAvailabilityZoneOracle(data) return fmt.Sprintf(` %[1]s @@ -620,7 +470,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { } func (NetAppVolumeGroupOracleResource) updateAvgSnapshotPolicy(data acceptance.TestData) string { - template := NetAppVolumeGroupOracleResource{}.templateAvailabilityZone(data) + template := NetAppVolumeGroupOracleResource{}.templateAvailabilityZoneOracle(data) return fmt.Sprintf(` %[1]s @@ -724,7 +574,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { } func (NetAppVolumeGroupOracleResource) updateVolumes(data acceptance.TestData) string { - template := NetAppVolumeGroupOracleResource{}.templateAvailabilityZone(data) + template := NetAppVolumeGroupOracleResource{}.templateAvailabilityZoneOracle(data) return fmt.Sprintf(` %[1]s @@ -799,197 +649,450 @@ resource "azurerm_netapp_volume_group_oracle" "test" { `, template, data.RandomInteger) } -// func (NetAppVolumeGroupSAPHanaResource) templatePPG(data acceptance.TestData) string { -// return fmt.Sprintf(` -// provider "azurerm" { -// alias = "all2" -// features { -// resource_group { -// prevent_deletion_if_contains_resources = false -// } -// netapp { -// prevent_volume_destruction = false -// delete_backups_on_backup_vault_destroy = true -// } -// } -// } - -// locals { -// admin_username = "testadmin%[1]d" -// admin_password = "Password1234!%[1]d" -// } - -// resource "azurerm_resource_group" "test" { -// name = "acctestRG-netapp-%[1]d" -// location = "%[2]s" - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true", -// "SkipNRMSNSG" = "true" -// } -// } - -// resource "azurerm_network_security_group" "test" { -// name = "acctest-NSG-%[1]d" -// location = azurerm_resource_group.test.location -// resource_group_name = azurerm_resource_group.test.name - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// resource "azurerm_virtual_network" "test" { -// name = "acctest-VirtualNetwork-%[1]d" -// location = azurerm_resource_group.test.location -// resource_group_name = azurerm_resource_group.test.name -// address_space = ["10.6.0.0/16"] - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// resource "azurerm_subnet" "test" { -// name = "acctest-DelegatedSubnet-%[1]d" -// resource_group_name = azurerm_resource_group.test.name -// virtual_network_name = azurerm_virtual_network.test.name -// address_prefixes = ["10.6.2.0/24"] - -// delegation { -// name = "testdelegation" - -// service_delegation { -// name = "Microsoft.Netapp/volumes" -// actions = ["Microsoft.Network/networkinterfaces/*", "Microsoft.Network/virtualNetworks/subnets/join/action"] -// } -// } -// } - -// resource "azurerm_subnet" "test1" { -// name = "acctest-HostsSubnet-%[1]d" -// resource_group_name = azurerm_resource_group.test.name -// virtual_network_name = azurerm_virtual_network.test.name -// address_prefixes = ["10.6.1.0/24"] -// } - -// resource "azurerm_subnet_network_security_group_association" "public" { -// subnet_id = azurerm_subnet.test.id -// network_security_group_id = azurerm_network_security_group.test.id -// } - -// resource "azurerm_proximity_placement_group" "test" { -// name = "acctest-PPG-%[1]d" -// location = azurerm_resource_group.test.location -// resource_group_name = azurerm_resource_group.test.name - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// resource "azurerm_availability_set" "test" { -// name = "acctest-avset-%[1]d" -// location = azurerm_resource_group.test.location -// resource_group_name = azurerm_resource_group.test.name - -// proximity_placement_group_id = azurerm_proximity_placement_group.test.id - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// resource "azurerm_network_interface" "test" { -// name = "acctest-nic-%[1]d" -// resource_group_name = azurerm_resource_group.test.name -// location = azurerm_resource_group.test.location - -// ip_configuration { -// name = "internal" -// subnet_id = azurerm_subnet.test1.id -// private_ip_address_allocation = "Dynamic" -// } - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// resource "azurerm_linux_virtual_machine" "test" { -// name = "acctest-vm-%[1]d" -// resource_group_name = azurerm_resource_group.test.name -// location = azurerm_resource_group.test.location -// size = "Standard_M8ms" -// admin_username = local.admin_username -// admin_password = local.admin_password -// disable_password_authentication = false -// proximity_placement_group_id = azurerm_proximity_placement_group.test.id -// availability_set_id = azurerm_availability_set.test.id -// network_interface_ids = [ -// azurerm_network_interface.test.id -// ] - -// source_image_reference { -// publisher = "Canonical" -// offer = "0001-com-ubuntu-server-jammy" -// sku = "22_04-lts" -// version = "latest" -// } - -// os_disk { -// storage_account_type = "Standard_LRS" -// caching = "ReadWrite" -// } - -// tags = { -// "platformsettings.host_environment.service.platform_optedin_for_rootcerts" = "true", -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true", -// "Owner" = "pmarques" -// } -// } - -// resource "azurerm_netapp_account" "test" { -// name = "acctest-NetAppAccount-%[1]d" -// location = azurerm_resource_group.test.location -// resource_group_name = azurerm_resource_group.test.name - -// depends_on = [ -// azurerm_subnet.test, -// azurerm_subnet.test1 -// ] - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } - -// resource "azurerm_netapp_pool" "test" { -// name = "acctest-NetAppPool-%[1]d" -// location = azurerm_resource_group.test.location -// resource_group_name = azurerm_resource_group.test.name -// account_name = azurerm_netapp_account.test.name -// service_level = "Standard" -// size_in_tb = 8 -// qos_type = "Manual" - -// tags = { -// "CreatedOnDate" = "2022-07-08T23:50:21Z", -// "SkipASMAzSecPack" = "true" -// } -// } -// `, data.RandomInteger, "eastus") -// } - -func (NetAppVolumeGroupOracleResource) templateAvailabilityZone(data acceptance.TestData) string { +func (NetAppVolumeGroupOracleResource) volEncryptionCmkOracle(data acceptance.TestData, tenantID string) string { + return fmt.Sprintf(` +provider "azurerm" { + features { + resource_group { + prevent_deletion_if_contains_resources = false + } + netapp { + prevent_volume_destruction = false + } + } +} + +data "azurerm_client_config" "current" { +} + +resource "azurerm_key_vault" "test" { + name = "anfakv%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + enabled_for_disk_encryption = true + enabled_for_deployment = true + enabled_for_template_deployment = true + purge_protection_enabled = true + tenant_id = "%[2]s" + + sku_name = "standard" +} + +resource "azurerm_key_vault_access_policy" "test-currentuser" { + key_vault_id = azurerm_key_vault.test.id + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = data.azurerm_client_config.current.object_id + + key_permissions = [ + "Get", + "Create", + "Delete", + "WrapKey", + "UnwrapKey", + "GetRotationPolicy", + "SetRotationPolicy", + ] +} + +resource "azurerm_key_vault_key" "test" { + name = "anfenckey%[1]d" + key_vault_id = azurerm_key_vault.test.id + key_type = "RSA" + key_size = 2048 + + key_opts = [ + "decrypt", + "encrypt", + "sign", + "unwrapKey", + "verify", + "wrapKey", + ] + + depends_on = [ + azurerm_key_vault_access_policy.test-currentuser + ] +} + +resource "azurerm_netapp_account" "test" { + name = "acctest-NetAppAccount-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + identity { + type = "SystemAssigned" + } +} + +resource "azurerm_key_vault_access_policy" "test-systemassigned" { + key_vault_id = azurerm_key_vault.test.id + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = azurerm_netapp_account.test.identity.0.principal_id + + key_permissions = [ + "Get", + "Encrypt", + "Decrypt" + ] +} + +resource "azurerm_netapp_account_encryption" "test" { + netapp_account_id = azurerm_netapp_account.test.id + + system_assigned_identity_principal_id = azurerm_netapp_account.test.identity.0.principal_id + + encryption_key = azurerm_key_vault_key.test.versionless_id + + depends_on = [ + azurerm_key_vault_access_policy.test-systemassigned + ] +} + +resource "azurerm_virtual_network" "test" { + name = "acctest-VirtualNetwork-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + address_space = ["10.6.0.0/16"] + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_subnet" "test-delegated" { + name = "acctest-Delegated-Subnet-%[1]d" + resource_group_name = azurerm_resource_group.test.name + virtual_network_name = azurerm_virtual_network.test.name + address_prefixes = ["10.6.1.0/24"] + + delegation { + name = "testdelegation" + + service_delegation { + name = "Microsoft.Netapp/volumes" + actions = ["Microsoft.Network/networkinterfaces/*", "Microsoft.Network/virtualNetworks/subnets/join/action"] + } + } +} + +resource "azurerm_subnet" "test-non-delegated" { + name = "acctest-Non-Delegated-Subnet-%[1]d" + resource_group_name = azurerm_resource_group.test.name + virtual_network_name = azurerm_virtual_network.test.name + address_prefixes = ["10.6.0.0/24"] +} + +resource "azurerm_private_endpoint" "test" { + name = "acctest-pe-akv-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + subnet_id = azurerm_subnet.test-non-delegated.id + + private_service_connection { + name = "acctest-pe-sc-akv-%[1]d" + private_connection_resource_id = azurerm_key_vault.test.id + is_manual_connection = false + subresource_names = ["Vault"] + } + + tags = { + CreatedOnDate = "2023-10-03T19:58:43.6509795Z" + } +} + +resource "azurerm_netapp_pool" "test" { + name = "acctest-NetAppPool-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + service_level = "Standard" + size_in_tb = 4 + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + + depends_on = [ + azurerm_netapp_account_encryption.test + ] +} + +resource "azurerm_netapp_volume_group_oracle" "test" { + name = "acctest-NetAppVolumeGroupOracle-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + group_description = "Test volume group for Oracle" + application_identifier = "TST" + + volume { + name = "acctest-NetAppVolume-Ora1-%[1]d" + volume_path = "my-unique-file-ora-path-1-%[1]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-data1" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + encryption_key_source = "Microsoft.KeyVault" + key_vault_private_endpoint_id = azurerm_private_endpoint.test.id + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + } + + volume { + name = "acctest-NetAppVolume-OraLog-%[1]d" + volume_path = "my-unique-file-oralog-path-%[1]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + encryption_key_source = "Microsoft.KeyVault" + key_vault_private_endpoint_id = azurerm_private_endpoint.test.id + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + } +} +`, data.RandomInteger, tenantID) +} + +func (NetAppVolumeGroupOracleResource) templatePpgOracle(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features { + resource_group { + prevent_deletion_if_contains_resources = false + } + netapp { + prevent_volume_destruction = false + delete_backups_on_backup_vault_destroy = true + } + } +} + +locals { + admin_username = "testadmin%[1]d" + admin_password = "Password1234!%[1]d" +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-netapp-%[1]d" + location = "%[2]s" + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true", + "SkipNRMSNSG" = "true" + } +} + +resource "azurerm_user_assigned_identity" "test" { + name = "user-assigned-identity-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name +} + +resource "azurerm_network_security_group" "test" { + name = "acctest-NSG-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_virtual_network" "test" { + name = "acctest-VirtualNetwork-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + address_space = ["10.0.0.0/16"] + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_subnet" "test" { + name = "acctest-DelegatedSubnet-%[1]d" + resource_group_name = azurerm_resource_group.test.name + virtual_network_name = azurerm_virtual_network.test.name + address_prefixes = ["10.0.2.0/24"] + + delegation { + name = "testdelegation" + + service_delegation { + name = "Microsoft.Netapp/volumes" + actions = ["Microsoft.Network/networkinterfaces/*", "Microsoft.Network/virtualNetworks/subnets/join/action"] + } + } +} + +resource "azurerm_subnet" "test1" { + name = "acctest-HostsSubnet-%[1]d" + resource_group_name = azurerm_resource_group.test.name + virtual_network_name = azurerm_virtual_network.test.name + address_prefixes = ["10.0.1.0/24"] +} + +resource "azurerm_subnet_network_security_group_association" "public" { + subnet_id = azurerm_subnet.test.id + network_security_group_id = azurerm_network_security_group.test.id +} + +resource "azurerm_proximity_placement_group" "test" { + name = "acctest-PPG-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_availability_set" "test" { + name = "acctest-avset-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + platform_update_domain_count = 2 + platform_fault_domain_count = 2 + + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_network_interface" "test" { + name = "acctest-nic-%[1]d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + + ip_configuration { + name = "internal" + subnet_id = azurerm_subnet.test1.id + private_ip_address_allocation = "Dynamic" + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_linux_virtual_machine" "test" { + name = "acctest-vm-%[1]d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + size = "Standard_D2s_v4" + admin_username = local.admin_username + admin_password = local.admin_password + disable_password_authentication = false + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + availability_set_id = azurerm_availability_set.test.id + network_interface_ids = [ + azurerm_network_interface.test.id + ] + + source_image_reference { + publisher = "Canonical" + offer = "0001-com-ubuntu-server-jammy" + sku = "22_04-lts" + version = "latest" + } + + patch_assessment_mode = "AutomaticByPlatform" + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + identity { + type = "SystemAssigned, UserAssigned" + identity_ids = [ + azurerm_user_assigned_identity.test.id + ] + } + + tags = { + "AzSecPackAutoConfigReady" = "true", + "platformsettings.host_environment.service.platform_optedin_for_rootcerts" = "true", + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true", + "Owner" = "pmarques" + } +} + +resource "azurerm_netapp_account" "test" { + name = "acctest-NetAppAccount-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + depends_on = [ + azurerm_subnet.test, + azurerm_subnet.test1 + ] + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_netapp_pool" "test" { + name = "acctest-NetAppPool-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + service_level = "Standard" + size_in_tb = 8 + qos_type = "Manual" + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} +`, data.RandomInteger, "westus3") +} + +func (NetAppVolumeGroupOracleResource) templateAvailabilityZoneOracle(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { features { @@ -1015,14 +1118,14 @@ resource "azurerm_virtual_network" "test" { name = "acctest-VirtualNetwork-%[1]d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name - address_space = ["10.6.0.0/16"] + address_space = ["10.0.0.0/16"] } resource "azurerm_subnet" "test" { name = "acctest-DelegatedSubnet-%[1]d" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test.name - address_prefixes = ["10.6.2.0/24"] + address_prefixes = ["10.0.2.0/24"] delegation { name = "testdelegation" @@ -1053,5 +1156,5 @@ resource "azurerm_netapp_pool" "test" { size_in_tb = 18 qos_type = "Manual" } -`, data.RandomInteger, "canadacentral") +`, data.RandomInteger, "westus3") } diff --git a/internal/services/netapp/netapp_volume_helper.go b/internal/services/netapp/netapp_volume_helper.go index 5d51317464bd..467a63a3e9b5 100644 --- a/internal/services/netapp/netapp_volume_helper.go +++ b/internal/services/netapp/netapp_volume_helper.go @@ -195,13 +195,21 @@ func expandNetAppVolumeGroupOracleVolumes(input []netAppModels.NetAppVolumeGroup } if v := item.ProximityPlacementGroupId; v != "" { - volumeProperties.Properties.ProximityPlacementGroup = pointer.To(pointer.From(pointer.To(v))) + volumeProperties.Properties.ProximityPlacementGroup = pointer.To(v) } if v := item.Zone; v != "" { volumeProperties.Zones = pointer.To([]string{v}) } + if v := item.EncryptionKeySource; v != "" { + volumeProperties.Properties.EncryptionKeySource = pointer.To(volumegroups.EncryptionKeySource(v)) + } + + if v := item.KeyVaultPrivateEndpointId; v != "" { + volumeProperties.Properties.KeyVaultPrivateEndpointResourceId = pointer.To(v) + } + results = append(results, *volumeProperties) } @@ -480,6 +488,14 @@ func flattenNetAppVolumeGroupOracleVolumes(ctx context.Context, input *[]volumeg volumeGroupVolume.Zone = (pointer.From(item.Zones))[0] } + if props.EncryptionKeySource != nil { + volumeGroupVolume.EncryptionKeySource = pointer.From((*string)(props.EncryptionKeySource)) + } + + if props.KeyVaultPrivateEndpointResourceId != nil { + volumeGroupVolume.KeyVaultPrivateEndpointId = pointer.From(props.KeyVaultPrivateEndpointResourceId) + } + volumeGroupVolume.VolumeSpecName = pointer.From(props.VolumeSpecName) if props.UsageThreshold > 0 { diff --git a/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go b/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go index b4e1ebb78bb7..442dece455c1 100644 --- a/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go +++ b/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go @@ -62,6 +62,7 @@ func PossibleValuesForProtocolTypeVolumeGroupOracle() []string { func ValidateNetAppVolumeGroupOracleVolumes(volumeList *[]volumegroups.VolumeGroupVolumeProperties) []error { errors := make([]error, 0) expectedZone := "" + expectedPpgId := "" volumeSpecRepeatCount := make(map[string]int) applicationType := string(volumegroups.ApplicationTypeORACLE) @@ -103,14 +104,6 @@ func ValidateNetAppVolumeGroupOracleVolumes(volumeList *[]volumegroups.VolumeGro errors = append(errors, fmt.Errorf("'protocol %v is invalid for Oracle'", protocolType)) } - // TODO: // Can't be nfsv3 on data, log and share volumes - // if strings.EqualFold(protocolType, string(ProtocolTypeNfsV3)) && - // (strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleData)) || - // strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleShared)) || - // strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleLog))) { - // errors = append(errors, fmt.Errorf("'nfsv3 on data, log and shared volumes for %v is not supported on volume %v'", applicationType, pointer.From(volume.Name))) - // } - // Validating export policies if volume.Properties.ExportPolicy != nil { for _, rule := range pointer.From(volume.Properties.ExportPolicy.Rules) { @@ -138,21 +131,6 @@ func ValidateNetAppVolumeGroupOracleVolumes(volumeList *[]volumegroups.VolumeGro errors = append(errors, fmt.Errorf("'zone and proximity_placement_group_id cannot be specified together on volume %v'", pointer.From(volume.Name))) } - // TODO: // Validating that data-backup and log-backup don't have PPG defined - // if (strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleDataBackup)) || - // strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleLogBackup))) && - // pointer.From(volume.Properties.ProximityPlacementGroup) != "" { - // errors = append(errors, fmt.Errorf("'%v volume spec type cannot have PPG defined for %v on volume %v'", pointer.From(volume.Properties.VolumeSpecName), applicationType, pointer.From(volume.Name))) - // } - - // TODO: // Validating that data, log and shared have PPG defined. - // if (strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleData)) || - // strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleLog)) || - // strings.EqualFold(pointer.From(volume.Properties.VolumeSpecName), string(VolumeSpecNameOracleShared))) && - // pointer.From(volume.Properties.ProximityPlacementGroup) == "" { - // errors = append(errors, fmt.Errorf("'%v volume spec type must have PPG defined for %v on volume %v'", pointer.From(volume.Properties.VolumeSpecName), applicationType, pointer.From(volume.Name))) - // } - // Getting the first zone for validations, all volumes must be in the same zone if expectedZone == "" { if volume.Zones != nil && len(pointer.From(volume.Zones)) > 0 { @@ -165,6 +143,24 @@ func ValidateNetAppVolumeGroupOracleVolumes(volumeList *[]volumegroups.VolumeGro errors = append(errors, fmt.Errorf("'zone must be the same on all volumes of this volume group, volume %v zone is %v'", pointer.From(volume.Name), pointer.From(volume.Zones)[0])) } + // Getting the first PPG for validations, all volumes must be in the same PPG + if expectedPpgId == "" { + if volume.Properties.ProximityPlacementGroup != nil { + expectedPpgId = pointer.From(volume.Properties.ProximityPlacementGroup) + } + } + + // Validating that all volumes are in the same PPG + if volume.Properties.ProximityPlacementGroup != nil && pointer.From(volume.Properties.ProximityPlacementGroup) != expectedPpgId { + errors = append(errors, fmt.Errorf("'proximity_placement_group_id must be the same on all volumes of this volume group, volume %v ppg id is %v'", pointer.From(volume.Name), pointer.From(volume.Properties.ProximityPlacementGroup))) + } + + // Validating that encryption_key_source and key_vault_private_endpoint_id are only specified together + if (pointer.From(volume.Properties.EncryptionKeySource) != "" && pointer.From(volume.Properties.KeyVaultPrivateEndpointResourceId) == "") || + (pointer.From(volume.Properties.EncryptionKeySource) == "" && pointer.From(volume.Properties.KeyVaultPrivateEndpointResourceId) != "") { + errors = append(errors, fmt.Errorf("'encryption_key_source and key_vault_private_endpoint_id must be specified together on volume %v'", pointer.From(volume.Name))) + } + // Adding volume spec name to hashmap for post volume loop check volumeSpecRepeatCount[pointer.From(volume.Properties.VolumeSpecName)] += 1 } diff --git a/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go b/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go index a95e720e71b6..9b8bb7a692ec 100644 --- a/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go +++ b/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go @@ -436,6 +436,426 @@ func TestValidateNetAppVolumeGroupOracleVolumes(t *testing.T) { }, Errors: 0, }, + { + Name: "ValidateCorrectSettingsAllVolumesProximityPlacementGroup", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + }, + }, + { // data2 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData2))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData2)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + }, + }, + { // data3 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData3))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData3)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + }, + }, + { // data4 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData4))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData4)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + }, + }, + { // data5 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData5))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData5)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + }, + }, + { // data6 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData6))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData6)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + }, + }, + { // data7 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData7))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData7)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + }, + }, + { // data8 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData8))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData8)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + }, + }, + { // log + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + }, + }, + { // binary + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleBinary))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleBinary)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + }, + }, + { // mirror + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleMirror))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleMirror)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + }, + }, + { // backup + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleBackup))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleBackup)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + }, + }, + }, + Errors: 0, + }, + { + Name: "ValidateCorrectSettingsAllVolumesProximityPlacementGroupFailsWhenDifferent", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + }, + }, + { // data2 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData2))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData2)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg2"), + }, + }, + { // data3 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData3))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData3)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg3"), + }, + }, + { // data4 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData4))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData4)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg4"), + }, + }, + { // data5 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData5))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData5)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg5"), + }, + }, + { // data6 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData6))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData6)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg6"), + }, + }, + { // data7 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData7))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData7)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg7"), + }, + }, + { // data8 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData8))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData8)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg8"), + }, + }, + { // log + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg9"), + }, + }, + { // binary + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleBinary))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleBinary)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg10"), + }, + }, + { // mirror + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleMirror))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleMirror)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg11"), + }, + }, + { // backup + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleBackup))), + Properties: volumegroups.VolumeProperties{ + ExportPolicy: &volumegroups.VolumePropertiesExportPolicy{ + Rules: &[]volumegroups.ExportPolicyRule{ + { + Nfsv3: pointer.To(false), + Nfsv41: utils.Bool(true), + }, + }, + }, + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleBackup)), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg12"), + }, + }, + }, + Errors: 11, + }, { Name: "ValidatePPGAndAvailabilityZoneNotSetAtSameTime", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ @@ -775,37 +1195,6 @@ func TestValidateNetAppVolumeGroupOracleVolumes(t *testing.T) { }, Errors: 3, }, - // TODO: - // { - // Name: "ValidateNoNfsVersionThreeOnDataLogAndSharedVolumes", - // VolumesData: []volumegroups.VolumeGroupVolumeProperties{ - // { // data - // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData))), - // Properties: volumegroups.VolumeProperties{ - // ProtocolTypes: pointer.To([]string{"NFSv3"}), - // ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), - // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData)), - // }, - // }, - // { // log - // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), - // Properties: volumegroups.VolumeProperties{ - // ProtocolTypes: pointer.To([]string{"NFSv3"}), - // ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), - // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), - // }, - // }, - // { // shared - // Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleShared))), - // Properties: volumegroups.VolumeProperties{ - // ProtocolTypes: pointer.To([]string{"NFSv3"}), - // ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), - // VolumeSpecName: pointer.To(string(VolumeSpecNameOracleShared)), - // }, - // }, - // }, - // Errors: 3, - // }, { Name: "ValidateVolumeSpecCantRepeat", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ @@ -868,6 +1257,60 @@ func TestValidateNetAppVolumeGroupOracleVolumes(t *testing.T) { }, Errors: 1, }, + { + Name: "ValidateCustomerManagedKeyOptionsAreSetTogether", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + EncryptionKeySource: pointer.To(volumegroups.EncryptionKeySourceMicrosoftPointKeyVault), + KeyVaultPrivateEndpointResourceId: pointer.To("/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/myResourceGroup/providers/Microsoft.Network/privateEndpoints/myKeyvaultPE"), + }, + }, + { // log + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + EncryptionKeySource: pointer.To(volumegroups.EncryptionKeySourceMicrosoftPointKeyVault), + KeyVaultPrivateEndpointResourceId: pointer.To("/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/myResourceGroup/providers/Microsoft.Network/privateEndpoints/myKeyvaultPE"), + }, + }, + }, + Errors: 0, + }, + { + Name: "ValidateCustomerManagedKeyOptionsNotSetTogetherFails", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + EncryptionKeySource: pointer.To(volumegroups.EncryptionKeySourceMicrosoftPointKeyVault), + }, + }, + { // log + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + KeyVaultPrivateEndpointResourceId: pointer.To("/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/myResourceGroup/providers/Microsoft.Network/privateEndpoints/myKeyvaultPE"), + }, + }, + }, + Errors: 2, + }, } for _, tc := range cases { From 404e0415f52bb2c086f69ba41e9b2c11c9184f96 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 18 Dec 2024 00:30:52 +0000 Subject: [PATCH 17/39] adding cmk support on data source --- .../netapp/netapp_volume_group_oracle_data_source.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/internal/services/netapp/netapp_volume_group_oracle_data_source.go b/internal/services/netapp/netapp_volume_group_oracle_data_source.go index 1756f67f8092..1096c832e289 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_data_source.go +++ b/internal/services/netapp/netapp_volume_group_oracle_data_source.go @@ -229,6 +229,16 @@ func (r NetAppVolumeGroupOracleDataSource) Attributes() map[string]*pluginsdk.Sc }, }, }, + + "encryption_key_source": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "key_vault_private_endpoint_id": { + Type: pluginsdk.TypeString, + Computed: true, + }, }, }, }, From 0422ff9de2d2420c135965c4f40b97a80cdd77a1 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 19 Dec 2024 01:35:23 +0000 Subject: [PATCH 18/39] CMK implementation --- internal/services/netapp/models/models.go | 1 + .../netapp_volume_group_oracle_data_source.go | 5 ++ .../netapp_volume_group_oracle_resource.go | 6 ++ ...etapp_volume_group_oracle_resource_test.go | 28 +++++--- .../services/netapp/netapp_volume_helper.go | 3 + .../volume_group_oracle_volumes_validation.go | 43 ++++++++++-- ...me_group_oracle_volumes_validation_test.go | 66 ++++++++++++++++++- 7 files changed, 138 insertions(+), 14 deletions(-) diff --git a/internal/services/netapp/models/models.go b/internal/services/netapp/models/models.go index 7350bd8dfcee..62feef05599c 100644 --- a/internal/services/netapp/models/models.go +++ b/internal/services/netapp/models/models.go @@ -83,6 +83,7 @@ type NetAppVolumeGroupOracleVolume struct { Zone string `tfschema:"zone"` EncryptionKeySource string `tfschema:"encryption_key_source"` KeyVaultPrivateEndpointId string `tfschema:"key_vault_private_endpoint_id"` + NetworkFeatures string `tfschema:"network_features"` } type NetAppVolumeGroupOracleModel struct { diff --git a/internal/services/netapp/netapp_volume_group_oracle_data_source.go b/internal/services/netapp/netapp_volume_group_oracle_data_source.go index 1096c832e289..7cf820ba2c1f 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_data_source.go +++ b/internal/services/netapp/netapp_volume_group_oracle_data_source.go @@ -239,6 +239,11 @@ func (r NetAppVolumeGroupOracleDataSource) Attributes() map[string]*pluginsdk.Sc Type: pluginsdk.TypeString, Computed: true, }, + + "network_features": { + Type: pluginsdk.TypeString, + Computed: true, + }, }, }, }, diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource.go b/internal/services/netapp/netapp_volume_group_oracle_resource.go index 251d7b4f8541..2c2f80c11033 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource.go @@ -268,6 +268,12 @@ func (r NetAppVolumeGroupOracleResource) Arguments() map[string]*pluginsdk.Schem Computed: true, ValidateFunc: azure.ValidateResourceID, }, + + "network_features": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice(volumegroups.PossibleValuesForNetworkFeatures(), false), + }, }, }, }, diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index 30942f30078a..d9a766e3ab13 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -665,6 +665,15 @@ provider "azurerm" { data "azurerm_client_config" "current" { } +resource "azurerm_resource_group" "test" { + name = "acctestRG-netapp-%[1]d" + location = "%[3]s" + + tags = { + "SkipNRMSNSG" = "true" + } +} + resource "azurerm_key_vault" "test" { name = "anfakv%[1]d" location = azurerm_resource_group.test.location @@ -808,6 +817,7 @@ resource "azurerm_netapp_pool" "test" { account_name = azurerm_netapp_account.test.name service_level = "Standard" size_in_tb = 4 + qos_type = "Manual" tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", @@ -832,7 +842,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { volume_path = "my-unique-file-ora-path-1-%[1]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id + subnet_id = azurerm_subnet.test-delegated.id zone = "1" volume_spec_name = "ora-data1" storage_quota_in_gb = 1024 @@ -842,6 +852,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { snapshot_directory_visible = false encryption_key_source = "Microsoft.KeyVault" key_vault_private_endpoint_id = azurerm_private_endpoint.test.id + network_features = "Standard" export_policy_rule { rule_index = 1 @@ -859,7 +870,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { volume_path = "my-unique-file-oralog-path-%[1]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id + subnet_id = azurerm_subnet.test-delegated.id zone = "1" volume_spec_name = "ora-log" storage_quota_in_gb = 1024 @@ -869,6 +880,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { snapshot_directory_visible = false encryption_key_source = "Microsoft.KeyVault" key_vault_private_endpoint_id = azurerm_private_endpoint.test.id + network_features = "Standard" export_policy_rule { rule_index = 1 @@ -881,7 +893,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { } } } -`, data.RandomInteger, tenantID) +`, data.RandomInteger, tenantID, "eastus") } func (NetAppVolumeGroupOracleResource) templatePpgOracle(data acceptance.TestData) string { @@ -907,10 +919,8 @@ resource "azurerm_resource_group" "test" { name = "acctestRG-netapp-%[1]d" location = "%[2]s" - tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z", - "SkipASMAzSecPack" = "true", - "SkipNRMSNSG" = "true" + tags = { + "SkipNRMSNSG" = "true" } } @@ -1081,7 +1091,7 @@ resource "azurerm_netapp_pool" "test" { resource_group_name = azurerm_resource_group.test.name account_name = azurerm_netapp_account.test.name service_level = "Standard" - size_in_tb = 8 + size_in_tb = 4 qos_type = "Manual" tags = { @@ -1153,7 +1163,7 @@ resource "azurerm_netapp_pool" "test" { resource_group_name = azurerm_resource_group.test.name account_name = azurerm_netapp_account.test.name service_level = "Standard" - size_in_tb = 18 + size_in_tb = 4 qos_type = "Manual" } `, data.RandomInteger, "westus3") diff --git a/internal/services/netapp/netapp_volume_helper.go b/internal/services/netapp/netapp_volume_helper.go index 467a63a3e9b5..de8152f90c77 100644 --- a/internal/services/netapp/netapp_volume_helper.go +++ b/internal/services/netapp/netapp_volume_helper.go @@ -172,6 +172,7 @@ func expandNetAppVolumeGroupOracleVolumes(input []netAppModels.NetAppVolumeGroup storageQuotaInGB := item.StorageQuotaInGB * 1073741824 exportPolicyRule := expandNetAppVolumeGroupVolumeExportPolicyRule(item.ExportPolicy) dataProtectionSnapshotPolicy := expandNetAppVolumeGroupDataProtectionSnapshotPolicy(item.DataProtectionSnapshotPolicy) + networkFeatures := item.NetworkFeatures volumeProperties := &volumegroups.VolumeGroupVolumeProperties{ Name: utils.String(name), @@ -187,6 +188,7 @@ func expandNetAppVolumeGroupOracleVolumes(input []netAppModels.NetAppVolumeGroup SnapshotDirectoryVisible: utils.Bool(snapshotDirectoryVisible), ThroughputMibps: utils.Float(item.ThroughputInMibps), VolumeSpecName: utils.String(item.VolumeSpecName), + NetworkFeatures: pointer.To(volumegroups.NetworkFeatures(networkFeatures)), DataProtection: &volumegroups.VolumePropertiesDataProtection{ Snapshot: dataProtectionSnapshotPolicy.Snapshot, }, @@ -479,6 +481,7 @@ func flattenNetAppVolumeGroupOracleVolumes(ctx context.Context, input *[]volumeg volumeGroupVolume.SnapshotDirectoryVisible = pointer.From(props.SnapshotDirectoryVisible) volumeGroupVolume.ThroughputInMibps = pointer.From(props.ThroughputMibps) volumeGroupVolume.Tags = pointer.From(item.Tags) + volumeGroupVolume.NetworkFeatures = string(pointer.From(props.NetworkFeatures)) if props.ProximityPlacementGroup != nil { volumeGroupVolume.ProximityPlacementGroupId = pointer.From(props.ProximityPlacementGroup) diff --git a/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go b/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go index 442dece455c1..15fd4c46392b 100644 --- a/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go +++ b/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go @@ -63,6 +63,8 @@ func ValidateNetAppVolumeGroupOracleVolumes(volumeList *[]volumegroups.VolumeGro errors := make([]error, 0) expectedZone := "" expectedPpgId := "" + expectedKeyVaultPrivateEndpointResourceId := "" + expectedEncryptionKeySource := "" volumeSpecRepeatCount := make(map[string]int) applicationType := string(volumegroups.ApplicationTypeORACLE) @@ -155,10 +157,43 @@ func ValidateNetAppVolumeGroupOracleVolumes(volumeList *[]volumegroups.VolumeGro errors = append(errors, fmt.Errorf("'proximity_placement_group_id must be the same on all volumes of this volume group, volume %v ppg id is %v'", pointer.From(volume.Name), pointer.From(volume.Properties.ProximityPlacementGroup))) } - // Validating that encryption_key_source and key_vault_private_endpoint_id are only specified together - if (pointer.From(volume.Properties.EncryptionKeySource) != "" && pointer.From(volume.Properties.KeyVaultPrivateEndpointResourceId) == "") || - (pointer.From(volume.Properties.EncryptionKeySource) == "" && pointer.From(volume.Properties.KeyVaultPrivateEndpointResourceId) != "") { - errors = append(errors, fmt.Errorf("'encryption_key_source and key_vault_private_endpoint_id must be specified together on volume %v'", pointer.From(volume.Name))) + // Validating that encryption_key_source when key source is AKV has key_vault_private_endpoint_id specified + if pointer.From(volume.Properties.EncryptionKeySource) == volumegroups.EncryptionKeySourceMicrosoftPointKeyVault && pointer.From(volume.Properties.KeyVaultPrivateEndpointResourceId) == "" { + errors = append(errors, fmt.Errorf("'encryption_key_source as microsoft.keyvault must have key_vault_private_endpoint_id specified on volume %v'", pointer.From(volume.Name))) + } + + // Validating that encryption_key_source is set when key_vault_private_endpoint_id is specified + if pointer.From(volume.Properties.KeyVaultPrivateEndpointResourceId) != "" && pointer.From(volume.Properties.EncryptionKeySource) == "" { + errors = append(errors, fmt.Errorf("'encryption_key_source must be set when key_vault_private_endpoint_id is specified on volume %v'", pointer.From(volume.Name))) + } + + // Getting the first KeyVaultPrivateEndpointResourceId for validations, all volumes must have the same KeyVaultPrivateEndpointResourceId + if expectedKeyVaultPrivateEndpointResourceId == "" { + if volume.Properties.KeyVaultPrivateEndpointResourceId != nil { + expectedKeyVaultPrivateEndpointResourceId = pointer.From(volume.Properties.KeyVaultPrivateEndpointResourceId) + } + } + + // Validating that all volumes have the same KeyVaultPrivateEndpointResourceId + if volume.Properties.KeyVaultPrivateEndpointResourceId != nil && pointer.From(volume.Properties.KeyVaultPrivateEndpointResourceId) != expectedKeyVaultPrivateEndpointResourceId { + errors = append(errors, fmt.Errorf("'key_vault_private_endpoint_id must be the same on all volumes of this volume group, volume %v key vault private endpoint id is %v'", pointer.From(volume.Name), pointer.From(volume.Properties.KeyVaultPrivateEndpointResourceId))) + } + + // Getting the first EncryptionKeySource for validations, all volumes must have the same EncryptionKeySource + if expectedEncryptionKeySource == "" { + if volume.Properties.EncryptionKeySource != nil { + expectedEncryptionKeySource = string(pointer.From(volume.Properties.EncryptionKeySource)) + } + } + + // Validating that all volumes have the same EncryptionKeySource + if volume.Properties.EncryptionKeySource != nil && pointer.From(volume.Properties.EncryptionKeySource) != volumegroups.EncryptionKeySource(expectedEncryptionKeySource) { + errors = append(errors, fmt.Errorf("'encryption_key_source must be the same on all volumes of this volume group, volume %v encryption key source is %v'", pointer.From(volume.Name), pointer.From(volume.Properties.EncryptionKeySource))) + } + + // Validate that volume networkFeature is set to standard when volume.Properties.EncryptionKeySource == "Microsoft.KeyVault" + if volume.Properties.EncryptionKeySource != nil && pointer.From(volume.Properties.EncryptionKeySource) == volumegroups.EncryptionKeySourceMicrosoftPointKeyVault && pointer.From(volume.Properties.NetworkFeatures) != volumegroups.NetworkFeaturesStandard { + errors = append(errors, fmt.Errorf("'network_feature must be set to standard when encryption_key_source is set to Microsoft.KeyVault on volume %v, current value is %v'", pointer.From(volume.Name), pointer.From(volume.Properties.NetworkFeatures))) } // Adding volume spec name to hashmap for post volume loop check diff --git a/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go b/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go index 9b8bb7a692ec..5752fa6827a4 100644 --- a/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go +++ b/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go @@ -1286,7 +1286,7 @@ func TestValidateNetAppVolumeGroupOracleVolumes(t *testing.T) { Errors: 0, }, { - Name: "ValidateCustomerManagedKeyOptionsNotSetTogetherFails", + Name: "ValidateCustomerManagedKeyOptionsNotSetTogetherFailsWhenKeyVault", VolumesData: []volumegroups.VolumeGroupVolumeProperties{ { // data1 Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), @@ -1311,6 +1311,70 @@ func TestValidateNetAppVolumeGroupOracleVolumes(t *testing.T) { }, Errors: 2, }, + { + Name: "ValidateCustomerManagedKeyNotSameAllVolumesFails", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + EncryptionKeySource: pointer.To(volumegroups.EncryptionKeySourceMicrosoftPointKeyVault), + KeyVaultPrivateEndpointResourceId: pointer.To("/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/myResourceGroup/providers/Microsoft.Network/privateEndpoints/myKeyvaultPE"), + }, + }, + { // data2 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData2))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData2)), + EncryptionKeySource: pointer.To(volumegroups.EncryptionKeySourceMicrosoftPointNetApp), + }, + }, + { // log + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + EncryptionKeySource: pointer.To(volumegroups.EncryptionKeySourceMicrosoftPointKeyVault), + KeyVaultPrivateEndpointResourceId: pointer.To("/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/myResourceGroup/providers/Microsoft.Network/privateEndpoints/myKeyvaultPE1"), + }, + }, + }, + Errors: 10, + }, + { + Name: "ValidatePlatformManagedKey", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + EncryptionKeySource: pointer.To(volumegroups.EncryptionKeySourceMicrosoftPointNetApp), + }, + }, + { // log + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + EncryptionKeySource: pointer.To(volumegroups.EncryptionKeySourceMicrosoftPointNetApp), + }, + }, + }, + Errors: 0, + }, } for _, tc := range cases { From a4e9f2ffa2bcc660d3bbb768fe074e231f87faf2 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 19 Dec 2024 22:45:52 +0000 Subject: [PATCH 19/39] Changes to make it work with MSFT test sub --- ...netapp_account_encryption_resource_test.go | 329 +++++++++--------- ...etapp_volume_group_oracle_resource_test.go | 98 +++--- 2 files changed, 222 insertions(+), 205 deletions(-) diff --git a/internal/services/netapp/netapp_account_encryption_resource_test.go b/internal/services/netapp/netapp_account_encryption_resource_test.go index 25340d0d760b..85b0dc08d86d 100644 --- a/internal/services/netapp/netapp_account_encryption_resource_test.go +++ b/internal/services/netapp/netapp_account_encryption_resource_test.go @@ -106,6 +106,20 @@ func (r NetAppAccountEncryptionResource) cmkSystemAssigned(data acceptance.TestD data "azurerm_client_config" "current" { } +resource "azurerm_netapp_account" "test" { + name = "acctest-NetAppAccount-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + identity { + type = "SystemAssigned" + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z" + } +} + resource "azurerm_key_vault" "test" { name = "anfakv%[2]d" location = azurerm_resource_group.test.location @@ -115,24 +129,43 @@ resource "azurerm_key_vault" "test" { enabled_for_template_deployment = true purge_protection_enabled = true tenant_id = "%[3]s" - sku_name = "standard" -} -resource "azurerm_key_vault_access_policy" "test-currentuser" { - key_vault_id = azurerm_key_vault.test.id - tenant_id = azurerm_netapp_account.test.identity.0.tenant_id - object_id = data.azurerm_client_config.current.object_id - - key_permissions = [ - "Get", - "Create", - "Delete", - "WrapKey", - "UnwrapKey", - "GetRotationPolicy", - "SetRotationPolicy", - ] + access_policy { + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = data.azurerm_client_config.current.object_id + + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] + key_permissions = [ + "Get", + "Create", + "Delete", + "WrapKey", + "UnwrapKey", + "GetRotationPolicy", + "SetRotationPolicy", + ] + } + + access_policy { + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = azurerm_netapp_account.test.identity.0.principal_id + + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] + key_permissions = [ + "Get", + "Encrypt", + "Decrypt" + ] + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z" + } } resource "azurerm_key_vault_key" "test" { @@ -149,44 +182,12 @@ resource "azurerm_key_vault_key" "test" { "verify", "wrapKey", ] - - depends_on = [ - azurerm_key_vault_access_policy.test-currentuser - ] -} - -resource "azurerm_netapp_account" "test" { - name = "acctest-NetAppAccount-%[2]d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - - identity { - type = "SystemAssigned" - } -} - -resource "azurerm_key_vault_access_policy" "test-systemassigned" { - key_vault_id = azurerm_key_vault.test.id - tenant_id = azurerm_netapp_account.test.identity.0.tenant_id - object_id = azurerm_netapp_account.test.identity.0.principal_id - - key_permissions = [ - "Get", - "Encrypt", - "Decrypt" - ] } resource "azurerm_netapp_account_encryption" "test" { netapp_account_id = azurerm_netapp_account.test.id - system_assigned_identity_principal_id = azurerm_netapp_account.test.identity.0.principal_id - encryption_key = azurerm_key_vault_key.test.versionless_id - - depends_on = [ - azurerm_key_vault_access_policy.test-systemassigned - ] } `, r.template(data), data.RandomInteger, tenantID) } @@ -199,6 +200,10 @@ resource "azurerm_user_assigned_identity" "test" { name = "user-assigned-identity-%[2]d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z" + } } data "azurerm_client_config" "current" { @@ -213,13 +218,15 @@ resource "azurerm_key_vault" "test" { enabled_for_template_deployment = true purge_protection_enabled = true tenant_id = "%[3]s" - sku_name = "standard" access_policy { tenant_id = "%[3]s" - object_id = data.azurerm_client_config.current.object_id + object_id = data.azurerm_client_config.current.object_id + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] key_permissions = [ "Get", "Create", @@ -235,12 +242,19 @@ resource "azurerm_key_vault" "test" { tenant_id = "%[3]s" object_id = azurerm_user_assigned_identity.test.principal_id + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] key_permissions = [ "Get", "Encrypt", "Decrypt" ] } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z" + } } resource "azurerm_key_vault_key" "test" { @@ -270,13 +284,16 @@ resource "azurerm_netapp_account" "test" { azurerm_user_assigned_identity.test.id ] } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } } resource "azurerm_netapp_account_encryption" "test" { netapp_account_id = azurerm_netapp_account.test.id - user_assigned_identity_id = azurerm_user_assigned_identity.test.id - encryption_key = azurerm_key_vault_key.test.versionless_id } `, r.template(data), data.RandomInteger, tenantID) @@ -289,6 +306,21 @@ func (r NetAppAccountEncryptionResource) keyUpdate1(data acceptance.TestData, te data "azurerm_client_config" "current" { } +resource "azurerm_netapp_account" "test" { + name = "acctest-NetAppAccount-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + identity { + type = "SystemAssigned" + } + + tags = { + "SkipNRMSNSG" = "true", + "CreatedOnDate" = "2022-07-08T23:50:21Z" + } +} + resource "azurerm_key_vault" "test" { name = "anfakv%[2]d" location = azurerm_resource_group.test.location @@ -298,24 +330,43 @@ resource "azurerm_key_vault" "test" { enabled_for_template_deployment = true purge_protection_enabled = true tenant_id = "%[3]s" - sku_name = "standard" -} -resource "azurerm_key_vault_access_policy" "test-currentuser" { - key_vault_id = azurerm_key_vault.test.id - tenant_id = azurerm_netapp_account.test.identity.0.tenant_id - object_id = data.azurerm_client_config.current.object_id - - key_permissions = [ - "Get", - "Create", - "Delete", - "WrapKey", - "UnwrapKey", - "GetRotationPolicy", - "SetRotationPolicy", - ] + access_policy { + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = data.azurerm_client_config.current.object_id + + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] + key_permissions = [ + "Get", + "Create", + "Delete", + "WrapKey", + "UnwrapKey", + "GetRotationPolicy", + "SetRotationPolicy", + ] + } + + access_policy { + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = azurerm_netapp_account.test.identity.0.principal_id + + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] + key_permissions = [ + "Get", + "Encrypt", + "Decrypt" + ] + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z" + } } resource "azurerm_key_vault_key" "test" { @@ -332,10 +383,6 @@ resource "azurerm_key_vault_key" "test" { "verify", "wrapKey", ] - - depends_on = [ - azurerm_key_vault_access_policy.test-currentuser - ] } resource "azurerm_key_vault_key" "test-new-key" { @@ -352,45 +399,12 @@ resource "azurerm_key_vault_key" "test-new-key" { "verify", "wrapKey", ] - - depends_on = [ - azurerm_key_vault_key.test, - azurerm_key_vault_access_policy.test-currentuser - ] -} - -resource "azurerm_netapp_account" "test" { - name = "acctest-NetAppAccount-%[2]d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - - identity { - type = "SystemAssigned" - } -} - -resource "azurerm_key_vault_access_policy" "test-systemassigned" { - key_vault_id = azurerm_key_vault.test.id - tenant_id = azurerm_netapp_account.test.identity.0.tenant_id - object_id = azurerm_netapp_account.test.identity.0.principal_id - - key_permissions = [ - "Get", - "Encrypt", - "Decrypt" - ] } resource "azurerm_netapp_account_encryption" "test" { netapp_account_id = azurerm_netapp_account.test.id - system_assigned_identity_principal_id = azurerm_netapp_account.test.identity.0.principal_id - encryption_key = azurerm_key_vault_key.test.versionless_id - - depends_on = [ - azurerm_key_vault_access_policy.test-systemassigned - ] } `, r.template(data), data.RandomInteger, tenantID) } @@ -402,6 +416,21 @@ func (r NetAppAccountEncryptionResource) keyUpdate2(data acceptance.TestData, te data "azurerm_client_config" "current" { } +resource "azurerm_netapp_account" "test" { + name = "acctest-NetAppAccount-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + identity { + type = "SystemAssigned" + } + + tags = { + "SkipNRMSNSG" = "true", + "CreatedOnDate" = "2022-07-08T23:50:21Z" + } +} + resource "azurerm_key_vault" "test" { name = "anfakv%[2]d" location = azurerm_resource_group.test.location @@ -411,24 +440,43 @@ resource "azurerm_key_vault" "test" { enabled_for_template_deployment = true purge_protection_enabled = true tenant_id = "%[3]s" + sku_name = "standard" - sku_name = "standard" -} + access_policy { + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = data.azurerm_client_config.current.object_id + + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] + key_permissions = [ + "Get", + "Create", + "Delete", + "WrapKey", + "UnwrapKey", + "GetRotationPolicy", + "SetRotationPolicy", + ] + } -resource "azurerm_key_vault_access_policy" "test-currentuser" { - key_vault_id = azurerm_key_vault.test.id - tenant_id = azurerm_netapp_account.test.identity.0.tenant_id - object_id = data.azurerm_client_config.current.object_id - - key_permissions = [ - "Get", - "Create", - "Delete", - "WrapKey", - "UnwrapKey", - "GetRotationPolicy", - "SetRotationPolicy", - ] + access_policy { + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = azurerm_netapp_account.test.identity.0.principal_id + + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] + key_permissions = [ + "Get", + "Encrypt", + "Decrypt" + ] + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z" + } } resource "azurerm_key_vault_key" "test" { @@ -445,10 +493,6 @@ resource "azurerm_key_vault_key" "test" { "verify", "wrapKey", ] - - depends_on = [ - azurerm_key_vault_access_policy.test-currentuser - ] } resource "azurerm_key_vault_key" "test-new-key" { @@ -467,43 +511,14 @@ resource "azurerm_key_vault_key" "test-new-key" { ] depends_on = [ - azurerm_key_vault_key.test, - azurerm_key_vault_access_policy.test-currentuser - ] -} - -resource "azurerm_netapp_account" "test" { - name = "acctest-NetAppAccount-%[2]d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - - identity { - type = "SystemAssigned" - } -} - -resource "azurerm_key_vault_access_policy" "test-systemassigned" { - key_vault_id = azurerm_key_vault.test.id - tenant_id = azurerm_netapp_account.test.identity.0.tenant_id - object_id = azurerm_netapp_account.test.identity.0.principal_id - - key_permissions = [ - "Get", - "Encrypt", - "Decrypt" + azurerm_key_vault_key.test ] } resource "azurerm_netapp_account_encryption" "test" { netapp_account_id = azurerm_netapp_account.test.id - system_assigned_identity_principal_id = azurerm_netapp_account.test.identity.0.principal_id - encryption_key = azurerm_key_vault_key.test-new-key.versionless_id - - depends_on = [ - azurerm_key_vault_access_policy.test-systemassigned - ] } `, r.template(data), data.RandomInteger, tenantID) } @@ -533,7 +548,9 @@ resource "azurerm_resource_group" "test" { location = "%[2]s" tags = { - "SkipNRMSNSG" = "true" + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true", + "SkipNRMSNSG" = "true" } } `, data.RandomInteger, data.Locations.Primary) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index d9a766e3ab13..7284db7963a4 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -670,7 +670,22 @@ resource "azurerm_resource_group" "test" { location = "%[3]s" tags = { - "SkipNRMSNSG" = "true" + "SkipNRMSNSG" = "true", + "CreatedOnDate" = "2022-07-08T23:50:21Z" + } +} + +resource "azurerm_netapp_account" "test" { + name = "acctest-NetAppAccount-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + identity { + type = "SystemAssigned" + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z" } } @@ -683,24 +698,37 @@ resource "azurerm_key_vault" "test" { enabled_for_template_deployment = true purge_protection_enabled = true tenant_id = "%[2]s" - sku_name = "standard" -} -resource "azurerm_key_vault_access_policy" "test-currentuser" { - key_vault_id = azurerm_key_vault.test.id - tenant_id = azurerm_netapp_account.test.identity.0.tenant_id - object_id = data.azurerm_client_config.current.object_id - - key_permissions = [ - "Get", - "Create", - "Delete", - "WrapKey", - "UnwrapKey", - "GetRotationPolicy", - "SetRotationPolicy", - ] + access_policy { + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = data.azurerm_client_config.current.object_id + + key_permissions = [ + "Get", + "Create", + "Delete", + "WrapKey", + "UnwrapKey", + "GetRotationPolicy", + "SetRotationPolicy", + ] + } + + access_policy { + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = azurerm_netapp_account.test.identity.0.principal_id + + key_permissions = [ + "Get", + "Encrypt", + "Decrypt" + ] + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z" + } } resource "azurerm_key_vault_key" "test" { @@ -717,44 +745,12 @@ resource "azurerm_key_vault_key" "test" { "verify", "wrapKey", ] - - depends_on = [ - azurerm_key_vault_access_policy.test-currentuser - ] -} - -resource "azurerm_netapp_account" "test" { - name = "acctest-NetAppAccount-%[1]d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - - identity { - type = "SystemAssigned" - } -} - -resource "azurerm_key_vault_access_policy" "test-systemassigned" { - key_vault_id = azurerm_key_vault.test.id - tenant_id = azurerm_netapp_account.test.identity.0.tenant_id - object_id = azurerm_netapp_account.test.identity.0.principal_id - - key_permissions = [ - "Get", - "Encrypt", - "Decrypt" - ] } resource "azurerm_netapp_account_encryption" "test" { netapp_account_id = azurerm_netapp_account.test.id - system_assigned_identity_principal_id = azurerm_netapp_account.test.identity.0.principal_id - encryption_key = azurerm_key_vault_key.test.versionless_id - - depends_on = [ - azurerm_key_vault_access_policy.test-systemassigned - ] } resource "azurerm_virtual_network" "test" { @@ -928,6 +924,10 @@ resource "azurerm_user_assigned_identity" "test" { name = "user-assigned-identity-%[1]d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z" + } } resource "azurerm_network_security_group" "test" { From 9135bc61e708b6bafc5331489cb7bac971524f7b Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 19 Dec 2024 22:56:56 +0000 Subject: [PATCH 20/39] Updating access policies --- .../netapp/netapp_volume_group_oracle_resource_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index 7284db7963a4..517013dc9117 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -704,6 +704,9 @@ resource "azurerm_key_vault" "test" { tenant_id = azurerm_netapp_account.test.identity.0.tenant_id object_id = data.azurerm_client_config.current.object_id + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] key_permissions = [ "Get", "Create", @@ -719,6 +722,9 @@ resource "azurerm_key_vault" "test" { tenant_id = azurerm_netapp_account.test.identity.0.tenant_id object_id = azurerm_netapp_account.test.identity.0.principal_id + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] key_permissions = [ "Get", "Encrypt", From 979be23cf0582de227e01993ef633e51d4c44435 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 20 Dec 2024 15:07:57 +0000 Subject: [PATCH 21/39] AVG test fixes --- ...etapp_volume_group_oracle_resource_test.go | 30 +++ ...app_volume_group_sap_hana_resource_test.go | 210 ++++++++++++++++++ 2 files changed, 240 insertions(+) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index 517013dc9117..562a496ecf28 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -198,6 +198,11 @@ resource "azurerm_netapp_volume_group_oracle" "test" { unix_read_write = true root_access_enabled = false } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } } volume { @@ -223,6 +228,11 @@ resource "azurerm_netapp_volume_group_oracle" "test" { unix_read_write = true root_access_enabled = false } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } } } `, template, data.RandomInteger) @@ -264,6 +274,11 @@ resource "azurerm_netapp_volume_group_oracle" "test" { unix_read_write = true root_access_enabled = false } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } } volume { @@ -289,6 +304,11 @@ resource "azurerm_netapp_volume_group_oracle" "test" { unix_read_write = true root_access_enabled = false } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } } depends_on = [ @@ -335,6 +355,11 @@ resource "azurerm_netapp_volume_group_oracle" "test" { unix_read_write = true root_access_enabled = false } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } } volume { @@ -360,6 +385,11 @@ resource "azurerm_netapp_volume_group_oracle" "test" { unix_read_write = true root_access_enabled = false } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } } } `, template, data.RandomInteger) diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go index f976270957c7..dba155f358bc 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go @@ -214,6 +214,36 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { "SkipASMAzSecPack" = "true" } } + + volume { + name = "acctest-NetAppVolume-3-%[2]d" + volume_path = "my-unique-file-path-3-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "shared" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } depends_on = [ azurerm_linux_virtual_machine.test, @@ -354,6 +384,36 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { } } + volume { + name = "acctest-NetAppVolume-6-%[2]d" + volume_path = "my-unique-file-path-6-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "shared" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + depends_on = [ azurerm_linux_virtual_machine.test, azurerm_proximity_placement_group.test @@ -462,6 +522,36 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { "SkipASMAzSecPack" = "true" } } + + volume { + name = "acctest-NetAppVolume-3-%[2]d" + volume_path = "my-unique-file-path-3-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "shared" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } depends_on = [ azurerm_linux_virtual_machine.test, @@ -572,6 +662,36 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { } } + volume { + name = "acctest-NetAppVolume-3-%[2]d" + volume_path = "my-unique-file-path-3-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "shared" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + depends_on = [ azurerm_linux_virtual_machine.test, azurerm_proximity_placement_group.test @@ -653,6 +773,36 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { } } + volume { + name = "acctest-NetAppVolume-3-%[2]d" + volume_path = "my-unique-file-path-3-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "shared" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + depends_on = [ azurerm_linux_virtual_machine.test, azurerm_proximity_placement_group.test @@ -734,6 +884,36 @@ resource "azurerm_netapp_volume_group_sap_hana" "test_primary" { } } + volume { + name = "acctest-NetAppVolume-3-Primary-%[2]d" + volume_path = "my-unique-file-path-3-Primary-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + proximity_placement_group_id = azurerm_proximity_placement_group.test.id + volume_spec_name = "shared" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + depends_on = [ azurerm_linux_virtual_machine.test, azurerm_proximity_placement_group.test @@ -815,6 +995,36 @@ resource "azurerm_netapp_volume_group_sap_hana" "test_secondary" { } } + volume { + name = "acctest-NetAppVolume-3-Secondary-%[2]d" + volume_path = "my-unique-file-path-3-Secondary-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test_secondary.id + subnet_id = azurerm_subnet.test_secondary.id + proximity_placement_group_id = azurerm_proximity_placement_group.test_secondary.id + volume_spec_name = "shared" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + } + depends_on = [ azurerm_linux_virtual_machine.test_secondary, azurerm_proximity_placement_group.test_secondary, From f2e7d1f55a77abfe13bec7fb28e1ea29bffe3f38 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 20 Dec 2024 15:18:45 +0000 Subject: [PATCH 22/39] Adding more validations, making Basic network feature the default --- .../netapp_volume_group_oracle_resource.go | 1 + ...me_group_oracle_volumes_validation_test.go | 67 ++++++++++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource.go b/internal/services/netapp/netapp_volume_group_oracle_resource.go index 2c2f80c11033..76b49e291f93 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource.go @@ -272,6 +272,7 @@ func (r NetAppVolumeGroupOracleResource) Arguments() map[string]*pluginsdk.Schem "network_features": { Type: pluginsdk.TypeString, Optional: true, + Default: "Basic", ValidateFunc: validation.StringInSlice(volumegroups.PossibleValuesForNetworkFeatures(), false), }, }, diff --git a/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go b/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go index 5752fa6827a4..572148839f68 100644 --- a/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go +++ b/internal/services/netapp/validate/volume_group_oracle_volumes_validation_test.go @@ -1269,6 +1269,7 @@ func TestValidateNetAppVolumeGroupOracleVolumes(t *testing.T) { VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), EncryptionKeySource: pointer.To(volumegroups.EncryptionKeySourceMicrosoftPointKeyVault), KeyVaultPrivateEndpointResourceId: pointer.To("/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/myResourceGroup/providers/Microsoft.Network/privateEndpoints/myKeyvaultPE"), + NetworkFeatures: pointer.To(volumegroups.NetworkFeaturesStandard), }, }, { // log @@ -1280,6 +1281,7 @@ func TestValidateNetAppVolumeGroupOracleVolumes(t *testing.T) { VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), EncryptionKeySource: pointer.To(volumegroups.EncryptionKeySourceMicrosoftPointKeyVault), KeyVaultPrivateEndpointResourceId: pointer.To("/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/myResourceGroup/providers/Microsoft.Network/privateEndpoints/myKeyvaultPE"), + NetworkFeatures: pointer.To(volumegroups.NetworkFeaturesStandard), }, }, }, @@ -1296,6 +1298,7 @@ func TestValidateNetAppVolumeGroupOracleVolumes(t *testing.T) { SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), EncryptionKeySource: pointer.To(volumegroups.EncryptionKeySourceMicrosoftPointKeyVault), + NetworkFeatures: pointer.To(volumegroups.NetworkFeaturesStandard), }, }, { // log @@ -1306,6 +1309,7 @@ func TestValidateNetAppVolumeGroupOracleVolumes(t *testing.T) { SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), KeyVaultPrivateEndpointResourceId: pointer.To("/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/myResourceGroup/providers/Microsoft.Network/privateEndpoints/myKeyvaultPE"), + NetworkFeatures: pointer.To(volumegroups.NetworkFeaturesStandard), }, }, }, @@ -1323,6 +1327,7 @@ func TestValidateNetAppVolumeGroupOracleVolumes(t *testing.T) { VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), EncryptionKeySource: pointer.To(volumegroups.EncryptionKeySourceMicrosoftPointKeyVault), KeyVaultPrivateEndpointResourceId: pointer.To("/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/myResourceGroup/providers/Microsoft.Network/privateEndpoints/myKeyvaultPE"), + NetworkFeatures: pointer.To(volumegroups.NetworkFeaturesStandard), }, }, { // data2 @@ -1344,10 +1349,11 @@ func TestValidateNetAppVolumeGroupOracleVolumes(t *testing.T) { VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), EncryptionKeySource: pointer.To(volumegroups.EncryptionKeySourceMicrosoftPointKeyVault), KeyVaultPrivateEndpointResourceId: pointer.To("/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/myResourceGroup/providers/Microsoft.Network/privateEndpoints/myKeyvaultPE1"), + NetworkFeatures: pointer.To(volumegroups.NetworkFeaturesStandard), }, }, }, - Errors: 10, + Errors: 2, }, { Name: "ValidatePlatformManagedKey", @@ -1375,6 +1381,65 @@ func TestValidateNetAppVolumeGroupOracleVolumes(t *testing.T) { }, Errors: 0, }, + { + Name: "ValidateCustomerManagedKeyFailsOnBasicNetworkFeatures", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + EncryptionKeySource: pointer.To(volumegroups.EncryptionKeySourceMicrosoftPointKeyVault), + KeyVaultPrivateEndpointResourceId: pointer.To("/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/myResourceGroup/providers/Microsoft.Network/privateEndpoints/myKeyvaultPE"), + NetworkFeatures: pointer.To(volumegroups.NetworkFeaturesBasic), + }, + }, + { // log + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + EncryptionKeySource: pointer.To(volumegroups.EncryptionKeySourceMicrosoftPointKeyVault), + KeyVaultPrivateEndpointResourceId: pointer.To("/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/myResourceGroup/providers/Microsoft.Network/privateEndpoints/myKeyvaultPE"), + }, + }, + }, + Errors: 2, + }, + { + Name: "ValidateCustomerManagedKeyPassOnStandardNetworkFeatures", + VolumesData: []volumegroups.VolumeGroupVolumeProperties{ + { // data1 + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleData1))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleData1)), + EncryptionKeySource: pointer.To(volumegroups.EncryptionKeySourceMicrosoftPointKeyVault), + KeyVaultPrivateEndpointResourceId: pointer.To("/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/myResourceGroup/providers/Microsoft.Network/privateEndpoints/myKeyvaultPE"), + NetworkFeatures: pointer.To(volumegroups.NetworkFeaturesStandard), + }, + }, + { // log + Name: pointer.To(fmt.Sprintf("volume-%v", string(VolumeSpecNameOracleLog))), + Properties: volumegroups.VolumeProperties{ + ProtocolTypes: pointer.To([]string{"NFSv4.1"}), + ProximityPlacementGroup: pointer.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1"), + SecurityStyle: pointer.To(volumegroups.SecurityStyleUnix), + VolumeSpecName: pointer.To(string(VolumeSpecNameOracleLog)), + EncryptionKeySource: pointer.To(volumegroups.EncryptionKeySourceMicrosoftPointKeyVault), + KeyVaultPrivateEndpointResourceId: pointer.To("/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/myResourceGroup/providers/Microsoft.Network/privateEndpoints/myKeyvaultPE"), + NetworkFeatures: pointer.To(volumegroups.NetworkFeaturesStandard), + }, + }, + }, + Errors: 0, + }, } for _, tc := range cases { From 5d61c293f153db3b93f7c4047c814156f201cf96 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 20 Dec 2024 16:46:06 +0000 Subject: [PATCH 23/39] Fixes to avoid allocation issues and fixing volume updates --- .../netapp/netapp_volume_group_oracle_resource_test.go | 10 +++++----- .../netapp_volume_group_sap_hana_resource_test.go | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index 562a496ecf28..d50688bf7ec6 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -538,7 +538,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id - zone = "2" + zone = "1" volume_spec_name = "ora-data1" storage_quota_in_gb = 1024 throughput_in_mibps = 24 @@ -572,7 +572,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id - zone = "2" + zone = "1" volume_spec_name = "ora-log" storage_quota_in_gb = 1024 throughput_in_mibps = 24 @@ -609,11 +609,11 @@ func (NetAppVolumeGroupOracleResource) updateVolumes(data acceptance.TestData) s %[1]s resource "azurerm_netapp_volume_group_oracle" "test" { - name = "acctest-NetAppVolumeGroup-%[2]d" + name = "acctest-NetAppVolumeGroupOracle-%[2]d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name account_name = azurerm_netapp_account.test.name - group_description = "Test volume group" + group_description = "Test volume group for Oracle" application_identifier = "TST" volume { @@ -648,7 +648,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { volume { name = "acctest-NetAppVolume-OraLog-%[2]d" - volume_path = "my-unique-file-ora-path-2-%[2]d" + volume_path = "my-unique-file-oralog-path-%[2]d" service_level = "Standard" capacity_pool_id = azurerm_netapp_pool.test.id subnet_id = azurerm_subnet.test.id diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go index dba155f358bc..3fbed0dc8018 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go @@ -1414,7 +1414,7 @@ resource "azurerm_netapp_pool" "test" { resource_group_name = azurerm_resource_group.test.name account_name = azurerm_netapp_account.test.name service_level = "Standard" - size_in_tb = 8 + size_in_tb = 6 qos_type = "Manual" tags = { From 08836a194896561f2d8ddc95649df30800fd4994 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 20 Dec 2024 17:04:49 +0000 Subject: [PATCH 24/39] removing hard-coded regions for AVG for Oracle, updating readme --- internal/services/netapp/README.md | 2 ++ .../netapp/netapp_volume_group_oracle_resource_test.go | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/services/netapp/README.md b/internal/services/netapp/README.md index 0aa25560c3e1..ecb1c2022c8b 100644 --- a/internal/services/netapp/README.md +++ b/internal/services/netapp/README.md @@ -13,6 +13,8 @@ This document gives insights into who is maintaining this service and includes d - New tests failing should not be accepted. +- For Azure NetApp Files, some features are highly dependent on specific regions, that's why for some acceptance tests, we will see regions defined there instead of for example `data.Locations.Primary` within the templates, this is expected and should not be changed. + ## Polling functions - Some Netapp resources requires an extra type of polling mechanism. For example: diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index d50688bf7ec6..514b91d0098b 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -1135,7 +1135,7 @@ resource "azurerm_netapp_pool" "test" { "SkipASMAzSecPack" = "true" } } -`, data.RandomInteger, "westus3") +`, data.RandomInteger, data.Locations.Primary) } func (NetAppVolumeGroupOracleResource) templateAvailabilityZoneOracle(data acceptance.TestData) string { @@ -1202,5 +1202,5 @@ resource "azurerm_netapp_pool" "test" { size_in_tb = 4 qos_type = "Manual" } -`, data.RandomInteger, "westus3") +`, data.RandomInteger, data.Locations.Primary) } From 5ec9c41e89b4650eb2762abe04d38bdf47899a23 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 20 Dec 2024 18:57:20 +0000 Subject: [PATCH 25/39] restoring HANA pool size --- .../netapp/netapp_volume_group_sap_hana_resource_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go index 3fbed0dc8018..dba155f358bc 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go @@ -1414,7 +1414,7 @@ resource "azurerm_netapp_pool" "test" { resource_group_name = azurerm_resource_group.test.name account_name = azurerm_netapp_account.test.name service_level = "Standard" - size_in_tb = 6 + size_in_tb = 8 qos_type = "Manual" tags = { From 7e5b0ea8a9690f482942a2d3407affdb23b64a17 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 20 Dec 2024 20:57:33 +0000 Subject: [PATCH 26/39] adding data protection back to shared volume --- .../netapp/netapp_volume_group_sap_hana_resource_test.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go index dba155f358bc..1a117f75f624 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go @@ -1019,6 +1019,13 @@ resource "azurerm_netapp_volume_group_sap_hana" "test_secondary" { root_access_enabled = false } + data_protection_replication { + endpoint_type = "dst" + remote_volume_location = azurerm_netapp_volume_group_sap_hana.test_primary.location + remote_volume_resource_id = azurerm_netapp_volume_group_sap_hana.test_primary.volume[2].id + replication_frequency = "10minutes" + } + tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", "SkipASMAzSecPack" = "true" From 723c402e79aa40c73b2ba4b6cd24c3234563489d Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 21 Dec 2024 00:04:55 +0000 Subject: [PATCH 27/39] removing snapshot policy before deleting volume if exists --- internal/services/netapp/netapp_volume_helper.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/internal/services/netapp/netapp_volume_helper.go b/internal/services/netapp/netapp_volume_helper.go index de8152f90c77..41ba3743359d 100644 --- a/internal/services/netapp/netapp_volume_helper.go +++ b/internal/services/netapp/netapp_volume_helper.go @@ -695,6 +695,19 @@ func deleteVolume(ctx context.Context, metadata sdk.ResourceMetaData, volumeId s } } + // Disassociating volume from snapshot policy if present + if existing.Model.Properties.DataProtection != nil && existing.Model.Properties.DataProtection.Snapshot != nil { + if err = client.UpdateThenPoll(ctx, pointer.From(id), volumes.VolumePatch{ + Properties: &volumes.VolumePatchProperties{ + DataProtection: &volumes.VolumePatchPropertiesDataProtection{ + Snapshot: &volumes.VolumeSnapshotProperties{}, + }, + }, + }); err != nil { + return fmt.Errorf("dissociating snapshot policy from %s: %+v", pointer.From(id), err) + } + } + // Deleting volume and waiting for it to fully complete the operation if err = client.DeleteThenPoll(ctx, pointer.From(id), volumes.DeleteOperationOptions{ ForceDelete: utils.Bool(true), From 179c9909d5b85efa849a9ac2fa3153ebb5276357 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 27 Dec 2024 00:32:04 +0000 Subject: [PATCH 28/39] WIP: working on snapshot policy deletion bug --- internal/services/netapp/README.md | 32 +++ .../netapp/netapp_snapshot_policy_resource.go | 221 +++++++++++++++++- .../netapp_volume_group_oracle_resource.go | 1 + ...etapp_volume_group_oracle_resource_test.go | 16 +- .../netapp_volume_group_sap_hana_resource.go | 1 + ...app_volume_group_sap_hana_resource_test.go | 14 +- .../services/netapp/netapp_volume_helper.go | 21 +- .../netapp/netapp_volume_resource_test.go | 64 +++++ 8 files changed, 345 insertions(+), 25 deletions(-) diff --git a/internal/services/netapp/README.md b/internal/services/netapp/README.md index ecb1c2022c8b..a3daaf3b1e18 100644 --- a/internal/services/netapp/README.md +++ b/internal/services/netapp/README.md @@ -89,3 +89,35 @@ features { } } ``` + +## Azure NetApp Files has features that requires disassociation, e.g. BackupPolicyId and SnapshotPolicyIds + +- For cases where a property must have its content removed, mostly Ids (BackupPolicyId or SnapshotPolicyIds), instead of using `nil`, use `pointer.To("")`, this will trigger ANF RP to update the resource and set the value to empty string, setting as `nil` won't trigger any action within ANF RP. + +E.g. + +```golang +// Removing SnapshotId +update := volumes.VolumePatch{ + Properties: &volumes.VolumePatchProperties{ + DataProtection: &volumes.VolumePatchPropertiesDataProtection{ + Snapshot: &volumes.VolumeSnapshotProperties{ + SnapshotPolicyId: pointer.To(""), + }, + }, + }, +} +``` + +```golang +// Removing BackupPolicyId +backupPolicyIdRemoval := volumes.VolumePatch{ + Properties: &volumes.VolumePatchProperties{ + DataProtection: &volumes.VolumePatchPropertiesDataProtection{ + Backup: &volumes.VolumeBackupProperties{ + BackupPolicyId: pointer.To(""), + }, + }, + }, +} +``` \ No newline at end of file diff --git a/internal/services/netapp/netapp_snapshot_policy_resource.go b/internal/services/netapp/netapp_snapshot_policy_resource.go index 2a0511a5c727..fb390eb12071 100644 --- a/internal/services/netapp/netapp_snapshot_policy_resource.go +++ b/internal/services/netapp/netapp_snapshot_policy_resource.go @@ -11,13 +11,17 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" "github.com/hashicorp/go-azure-helpers/resourcemanager/tags" + "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/capacitypools" "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/snapshotpolicy" + "github.com/hashicorp/go-azure-sdk/resource-manager/netapp/2024-03-01/volumes" "github.com/hashicorp/terraform-provider-azurerm/helpers/azure" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/locks" netAppValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/netapp/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" @@ -338,8 +342,100 @@ func resourceNetAppSnapshotPolicyRead(d *pluginsdk.ResourceData, meta interface{ return nil } +// func resourceNetAppSnapshotPolicyDelete(d *pluginsdk.ResourceData, meta interface{}) error { +// client := meta.(*clients.Client).NetApp.SnapshotPoliciesClient +// ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) +// defer cancel() + +// id, err := snapshotpolicy.ParseSnapshotPolicyID(d.Id()) +// if err != nil { +// return err +// } + +// // Deleting snapshot policy and waiting for it fo fully complete the operation +// if err = client.SnapshotPoliciesDeleteThenPoll(ctx, *id); err != nil { +// return fmt.Errorf("deleting %s: %+v", id, err) +// } + +// log.Printf("[DEBUG] Waiting for %s to be deleted", id) +// if err := waitForSnapshotPolicyDeletion(ctx, client, *id, d.Timeout(pluginsdk.TimeoutDelete)); err != nil { +// return err +// } + +// return nil +// } + +// func resourceNetAppSnapshotPolicyDelete(d *pluginsdk.ResourceData, meta interface{}) error { +// client := meta.(*clients.Client).NetApp.SnapshotPoliciesClient +// volumeClient := meta.(*clients.Client).NetApp.VolumeClient +// ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) +// defer cancel() + +// id, err := snapshotpolicy.ParseSnapshotPolicyID(d.Id()) +// if err != nil { +// return err +// } + +// // Try to delete the snapshot policy +// result, err := client.SnapshotPoliciesDelete(ctx, *id) + +// if err != nil { +// // Check if error is 409 with message about being used by volumes +// if result.HttpResponse != nil && result.HttpResponse.StatusCode == 409 && strings.Contains(err.Error(), "SnapshotPolicy is used") { +// // Get all volumes in the account that might be using this snapshot policy +// volumeIds, err := findVolumesUsingSnapshotPolicy(ctx, meta.(*clients.Client), *id) +// if err != nil { +// return fmt.Errorf("finding volumes using snapshot policy %s: %+v", *id, err) +// } + +// // Disassociate snapshot policy from each volume +// for _, volumeId := range volumeIds { +// volId, err := volumes.ParseVolumeID(volumeId) +// if err != nil { +// return fmt.Errorf("parsing volume ID %q: %+v", volumeId, err) +// } + +// // Update volume to remove snapshot policy +// update := volumes.VolumePatch{ +// Properties: &volumes.VolumePatchProperties{ +// DataProtection: &volumes.VolumePatchPropertiesDataProtection{ +// Snapshot: &volumes.VolumeSnapshotProperties{ +// SnapshotPolicyId: nil, +// }, +// }, +// }, +// } + +// if err = volumeClient.UpdateThenPoll(ctx, *volId, update); err != nil { +// return fmt.Errorf("removing snapshot policy from volume %s: %+v", *volId, err) +// } + +// // Wait for the update to complete +// if err := waitForVolumeCreateOrUpdate(ctx, volumeClient, *volId); err != nil { +// return fmt.Errorf("waiting for snapshot policy removal from volume %s: %+v", *volId, err) +// } +// } + +// // Try deleting the snapshot policy again using DeleteThenPoll +// if err = client.SnapshotPoliciesDeleteThenPoll(ctx, *id); err != nil { +// return fmt.Errorf("deleting %s after volume disassociation: %+v", *id, err) +// } +// } else { +// return fmt.Errorf("deleting %s: %+v", *id, err) +// } +// } + +// log.Printf("[DEBUG] Waiting for %s to be deleted", *id) +// if err := waitForSnapshotPolicyDeletion(ctx, client, *id, d.Timeout(pluginsdk.TimeoutDelete)); err != nil { +// return err +// } + +// return nil +// } + func resourceNetAppSnapshotPolicyDelete(d *pluginsdk.ResourceData, meta interface{}) error { client := meta.(*clients.Client).NetApp.SnapshotPoliciesClient + volumeClient := meta.(*clients.Client).NetApp.VolumeClient ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() @@ -348,19 +444,136 @@ func resourceNetAppSnapshotPolicyDelete(d *pluginsdk.ResourceData, meta interfac return err } - // Deleting snapshot policy and waiting for it fo fully complete the operation - if err = client.SnapshotPoliciesDeleteThenPoll(ctx, *id); err != nil { - return fmt.Errorf("deleting %s: %+v", id, err) + log.Printf("[INFO] Attempting to delete Snapshot Policy %s", *id) + // Try to delete the snapshot policy using DeleteThenPoll + err = client.SnapshotPoliciesDeleteThenPoll(ctx, *id) + if err != nil { + // Check if error is about snapshot policy being in use + if strings.Contains(err.Error(), "SnapshotPolicy is used") { + log.Printf("[INFO] Snapshot Policy %s is in use, finding volumes using this policy...", *id) + + // Get all volumes in the account that might be using this snapshot policy + volumeIds, err := findVolumesUsingSnapshotPolicy(ctx, meta.(*clients.Client), *id) + if err != nil { + return fmt.Errorf("finding volumes using snapshot policy %s: %+v", *id, err) + } + + log.Printf("[INFO] Found %d volumes using Snapshot Policy %s", len(volumeIds), *id) + + // Disassociate snapshot policy from each volume + for i, volumeId := range volumeIds { + log.Printf("[INFO] Processing volume %d of %d: %s", i+1, len(volumeIds), volumeId) + + volId, err := volumes.ParseVolumeID(volumeId) + if err != nil { + return fmt.Errorf("parsing volume ID %q: %+v", volumeId, err) + } + + log.Printf("[INFO] Removing snapshot policy from volume %s", *volId) + // Update volume to remove snapshot policy + update := volumes.VolumePatch{ + Properties: &volumes.VolumePatchProperties{ + DataProtection: &volumes.VolumePatchPropertiesDataProtection{ + Snapshot: &volumes.VolumeSnapshotProperties{ + SnapshotPolicyId: pointer.To(""), + }, + }, + }, + } + + locks.ByID(volumeId) + + if err = volumeClient.UpdateThenPoll(ctx, *volId, update); err != nil { + locks.UnlockByID(volumeId) + return fmt.Errorf("removing snapshot policy from volume %s: %+v", *volId, err) + } + + log.Printf("[INFO] Waiting for snapshot policy removal to complete for volume %s", *volId) + // Wait for the update to complete + if err := waitForVolumeCreateOrUpdate(ctx, volumeClient, *volId); err != nil { + locks.UnlockByID(volumeId) + return fmt.Errorf("waiting for snapshot policy removal from volume %s: %+v", *volId, err) + } + + locks.UnlockByID(volumeId) + } + + log.Printf("[INFO] All volumes processed, attempting to delete Snapshot Policy %s again", *id) + // Try deleting the snapshot policy again + if err = client.SnapshotPoliciesDeleteThenPoll(ctx, *id); err != nil { + return fmt.Errorf("deleting %s after volume disassociation: %+v", *id, err) + } + } else { + return fmt.Errorf("deleting %s: %+v", *id, err) + } } - log.Printf("[DEBUG] Waiting for %s to be deleted", id) + log.Printf("[INFO] Waiting for final confirmation of deletion for Snapshot Policy %s", *id) if err := waitForSnapshotPolicyDeletion(ctx, client, *id, d.Timeout(pluginsdk.TimeoutDelete)); err != nil { return err } + log.Printf("[INFO] Successfully deleted Snapshot Policy %s", *id) return nil } +func findVolumesUsingSnapshotPolicy(ctx context.Context, client *clients.Client, snapshotPolicyId snapshotpolicy.SnapshotPolicyId) ([]string, error) { + const logPrefix = "[findVolumesUsingSnapshotPolicy]" + log.Printf("[INFO] %s Starting search for volumes using snapshot policy %s", logPrefix, snapshotPolicyId.ID()) + + volumeIds := make([]string, 0) + + poolClient := client.NetApp.PoolClient + accountId := capacitypools.NewNetAppAccountID(snapshotPolicyId.SubscriptionId, snapshotPolicyId.ResourceGroupName, snapshotPolicyId.NetAppAccountName) + + log.Printf("[INFO] %s Listing capacity pools in account %s", logPrefix, snapshotPolicyId.NetAppAccountName) + poolsResult, err := poolClient.PoolsList(ctx, accountId) + if err != nil { + return nil, fmt.Errorf("listing capacity pools in account %s: %+v", snapshotPolicyId.NetAppAccountName, err) + } + + if model := poolsResult.Model; model != nil { + volumeClient := client.NetApp.VolumeClient + log.Printf("[INFO] %s Found %d pools to check", logPrefix, len(*model)) + + for i, pool := range *model { + if pool.Name == nil { + continue + } + + poolNameParts := strings.Split(pointer.From(pool.Name), "/") + poolName := poolNameParts[len(poolNameParts)-1] + + log.Printf("[INFO] %s Processing pool %d of %d: %s", logPrefix, i+1, len(*model), poolName) + + volumeId := volumes.NewCapacityPoolID(snapshotPolicyId.SubscriptionId, snapshotPolicyId.ResourceGroupName, snapshotPolicyId.NetAppAccountName, poolName) + volumesResult, err := volumeClient.List(ctx, volumeId) + if err != nil { + return nil, fmt.Errorf("listing volumes in pool %s: %+v", poolName, err) + } + + if volumesModel := volumesResult.Model; volumesModel != nil { + log.Printf("[INFO] %s Found %d volumes in pool %s", logPrefix, len(*volumesModel), poolName) + + for _, volume := range *volumesModel { + if volume.Id == nil || volume.Properties.DataProtection == nil || + volume.Properties.DataProtection.Snapshot == nil || volume.Properties.DataProtection.Snapshot.SnapshotPolicyId == nil { + continue + } + + if strings.EqualFold(*volume.Properties.DataProtection.Snapshot.SnapshotPolicyId, snapshotPolicyId.ID()) { + log.Printf("[INFO] %s Found volume using the snapshot policy: %s", logPrefix, *volume.Id) + volumeIds = append(volumeIds, *volume.Id) + } + } + } + } + } + + log.Printf("[INFO] %s Completed search, found %d volumes using the snapshot policy", logPrefix, len(volumeIds)) + return volumeIds, nil +} + func expandNetAppSnapshotPolicyHourlySchedule(input []interface{}) *snapshotpolicy.HourlySchedule { if len(input) == 0 || input[0] == nil { return &snapshotpolicy.HourlySchedule{} diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource.go b/internal/services/netapp/netapp_volume_group_oracle_resource.go index 76b49e291f93..5c38626fc069 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource.go @@ -241,6 +241,7 @@ func (r NetAppVolumeGroupOracleResource) Arguments() map[string]*pluginsdk.Schem "data_protection_snapshot_policy": { Type: pluginsdk.TypeList, Optional: true, + Computed: true, // Adding this because Terraform is not being able to build proper deletion graph, it is trying to delete the snapshot policy before the volume because this is in a deeper level within the schema MaxItems: 1, Elem: &pluginsdk.Resource{ Schema: map[string]*pluginsdk.Schema{ diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index 514b91d0098b..f999aa154805 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -495,6 +495,10 @@ resource "azurerm_netapp_volume_group_oracle" "test" { "SkipASMAzSecPack" = "true" } } + + depends_on = [ + azurerm_netapp_snapshot_policy.test + ] } `, template, data.RandomInteger) } @@ -556,10 +560,6 @@ resource "azurerm_netapp_volume_group_oracle" "test" { root_access_enabled = false } - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", "SkipASMAzSecPack" = "true" @@ -590,15 +590,15 @@ resource "azurerm_netapp_volume_group_oracle" "test" { root_access_enabled = false } - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", "SkipASMAzSecPack" = "true" } } + + depends_on = [ + azurerm_netapp_snapshot_policy.test + ] } `, template, data.RandomInteger) } diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource.go index 831fd360eaf9..cf383da1abe0 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource.go @@ -274,6 +274,7 @@ func (r NetAppVolumeGroupSAPHanaResource) Arguments() map[string]*pluginsdk.Sche "data_protection_snapshot_policy": { Type: pluginsdk.TypeList, Optional: true, + Computed: true, // Adding this because Terraform is not being able to build proper deletion graph, it is trying to delete the snapshot policy before the volume because this is in a deeper level within the schema MaxItems: 1, Elem: &pluginsdk.Resource{ Schema: map[string]*pluginsdk.Schema{ diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go index 1a117f75f624..583a8082695c 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go @@ -555,7 +555,8 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { depends_on = [ azurerm_linux_virtual_machine.test, - azurerm_proximity_placement_group.test + azurerm_proximity_placement_group.test, + azurerm_netapp_snapshot_policy.test ] } `, template, data.RandomInteger) @@ -618,10 +619,6 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { root_access_enabled = false } - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", "SkipASMAzSecPack" = "true" @@ -652,10 +649,6 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { root_access_enabled = false } - data_protection_snapshot_policy { - snapshot_policy_id = azurerm_netapp_snapshot_policy.test.id - } - tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", "SkipASMAzSecPack" = "true" @@ -694,7 +687,8 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { depends_on = [ azurerm_linux_virtual_machine.test, - azurerm_proximity_placement_group.test + azurerm_proximity_placement_group.test, + azurerm_netapp_snapshot_policy.test ] } `, template, data.RandomInteger) diff --git a/internal/services/netapp/netapp_volume_helper.go b/internal/services/netapp/netapp_volume_helper.go index 41ba3743359d..b9f43dff02d8 100644 --- a/internal/services/netapp/netapp_volume_helper.go +++ b/internal/services/netapp/netapp_volume_helper.go @@ -6,6 +6,7 @@ package netapp import ( "context" "fmt" + "log" "strconv" "strings" "time" @@ -322,7 +323,11 @@ func expandNetAppVolumeDataProtectionSnapshotPolicy(input []interface{}) *volume func expandNetAppVolumeDataProtectionSnapshotPolicyPatch(input []interface{}) *volumes.VolumePatchPropertiesDataProtection { if len(input) == 0 { - return &volumes.VolumePatchPropertiesDataProtection{} + return &volumes.VolumePatchPropertiesDataProtection{ + Snapshot: &volumes.VolumeSnapshotProperties{ + SnapshotPolicyId: pointer.To(""), + }, + } } snapshotObject := volumes.VolumeSnapshotProperties{} @@ -696,19 +701,29 @@ func deleteVolume(ctx context.Context, metadata sdk.ResourceMetaData, volumeId s } // Disassociating volume from snapshot policy if present - if existing.Model.Properties.DataProtection != nil && existing.Model.Properties.DataProtection.Snapshot != nil { + if existing.Model.Properties.DataProtection != nil && existing.Model.Properties.DataProtection.Snapshot != nil && existing.Model.Properties.DataProtection.Snapshot.SnapshotPolicyId != nil && existing.Model.Properties.DataProtection.Snapshot.SnapshotPolicyId != pointer.To("") { + log.Printf("[INFO] Disassociating volume from snapshot policy") if err = client.UpdateThenPoll(ctx, pointer.From(id), volumes.VolumePatch{ Properties: &volumes.VolumePatchProperties{ DataProtection: &volumes.VolumePatchPropertiesDataProtection{ - Snapshot: &volumes.VolumeSnapshotProperties{}, + Snapshot: &volumes.VolumeSnapshotProperties{ + SnapshotPolicyId: pointer.To(""), + }, }, }, }); err != nil { return fmt.Errorf("dissociating snapshot policy from %s: %+v", pointer.From(id), err) } + + // Wait for the volume update to complete + log.Printf("[INFO] Wait for the volume update to complete after unsetting snapshot policy") + if err := waitForVolumeCreateOrUpdate(ctx, client, volumes.VolumeId(pointer.From(id))); err != nil { + return fmt.Errorf("waiting for volume to reflect snapshotPolicyId unset from %q: %+v", pointer.From(id), err) + } } // Deleting volume and waiting for it to fully complete the operation + log.Printf("[INFO] Deleting volume %s", id.String()) if err = client.DeleteThenPoll(ctx, pointer.From(id), volumes.DeleteOperationOptions{ ForceDelete: utils.Bool(true), }); err != nil { diff --git a/internal/services/netapp/netapp_volume_resource_test.go b/internal/services/netapp/netapp_volume_resource_test.go index 11d911d12f9c..3b283dfde704 100644 --- a/internal/services/netapp/netapp_volume_resource_test.go +++ b/internal/services/netapp/netapp_volume_resource_test.go @@ -136,6 +136,28 @@ func TestAccNetAppVolume_snapshotPolicy(t *testing.T) { }) } +func TestAccNetAppVolume_snapshotPolicyUpdate(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_netapp_volume", "test") + r := NetAppVolumeResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.snapshotPolicy(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.snapshotPolicyUpdate(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + func TestAccNetAppVolume_crossRegionReplication(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_netapp_volume", "test_secondary") r := NetAppVolumeResource{} @@ -740,6 +762,48 @@ resource "azurerm_netapp_volume" "test" { `, template, data.RandomInteger) } +func (NetAppVolumeResource) snapshotPolicyUpdate(data acceptance.TestData) string { + template := NetAppVolumeResource{}.template(data) + return fmt.Sprintf(` +%[1]s + +resource "azurerm_netapp_snapshot_policy" "test" { + name = "acctest-NetAppSnapshotPolicy-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + enabled = true + + monthly_schedule { + snapshots_to_keep = 1 + days_of_month = [15, 30] + hour = 23 + minute = 30 + } +} + +resource "azurerm_netapp_volume" "test" { + name = "acctest-NetAppVolume-WithSnapshotPolicy-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_netapp_account.test.name + pool_name = azurerm_netapp_pool.test.name + volume_path = "my-unique-file-path-%[2]d" + service_level = "Standard" + subnet_id = azurerm_subnet.test.id + protocols = ["NFSv3"] + security_style = "unix" + storage_quota_in_gb = 100 + throughput_in_mibps = 1.562 + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} +`, template, data.RandomInteger) +} + func (NetAppVolumeResource) crossRegionReplication(data acceptance.TestData) string { template := NetAppVolumeResource{}.templateForCrossRegionReplication(data) return fmt.Sprintf(` From 00e0e3bf9f6a332e11743f156f76068e1eabca04 Mon Sep 17 00:00:00 2001 From: Paulo Costa Date: Fri, 27 Dec 2024 21:30:02 +0000 Subject: [PATCH 29/39] Adding docs and examples, minor fixes --- .../avg_oracle_availability_zone/README.md | 9 + .../avg_oracle_availability_zone/main.tf | 119 ++++++++ .../avg_oracle_availability_zone/variables.tf | 7 + .../avg_oracle_cmkSystemAssigned/README.md | 11 + .../avg_oracle_cmkSystemAssigned/main.tf | 240 +++++++++++++++++ .../avg_oracle_cmkSystemAssigned/variables.tf | 11 + .../README.md | 9 + .../main.tf | 254 +++++++++++++++++ .../variables.tf | 7 + .../avg_oracle_snapshot_policy/README.md | 9 + .../netapp/avg_oracle_snapshot_policy/main.tf | 138 ++++++++++ .../avg_oracle_snapshot_policy/variables.tf | 7 + ...netapp_account_encryption_resource_test.go | 144 +++++----- ...etapp_volume_group_oracle_resource_test.go | 255 +++++++++--------- ...app_volume_group_sap_hana_resource_test.go | 11 +- .../netapp/netapp_volume_resource_test.go | 2 +- .../netapp_volume_group_oracle.html.markdown | 139 ++++++++++ .../netapp_volume_group_oracle.html.markdown | 245 +++++++++++++++++ 18 files changed, 1411 insertions(+), 206 deletions(-) create mode 100644 examples/netapp/avg_oracle_availability_zone/README.md create mode 100644 examples/netapp/avg_oracle_availability_zone/main.tf create mode 100644 examples/netapp/avg_oracle_availability_zone/variables.tf create mode 100644 examples/netapp/avg_oracle_cmkSystemAssigned/README.md create mode 100644 examples/netapp/avg_oracle_cmkSystemAssigned/main.tf create mode 100644 examples/netapp/avg_oracle_cmkSystemAssigned/variables.tf create mode 100644 examples/netapp/avg_oracle_proximity_placement_group/README.md create mode 100644 examples/netapp/avg_oracle_proximity_placement_group/main.tf create mode 100644 examples/netapp/avg_oracle_proximity_placement_group/variables.tf create mode 100644 examples/netapp/avg_oracle_snapshot_policy/README.md create mode 100644 examples/netapp/avg_oracle_snapshot_policy/main.tf create mode 100644 examples/netapp/avg_oracle_snapshot_policy/variables.tf create mode 100644 website/docs/d/netapp_volume_group_oracle.html.markdown create mode 100644 website/docs/r/netapp_volume_group_oracle.html.markdown diff --git a/examples/netapp/avg_oracle_availability_zone/README.md b/examples/netapp/avg_oracle_availability_zone/README.md new file mode 100644 index 000000000000..ce5f683a558b --- /dev/null +++ b/examples/netapp/avg_oracle_availability_zone/README.md @@ -0,0 +1,9 @@ +## Example: NetApp Files Application Volume Group For Oracle with Availability Zone + +This example provisions an application volume group for Oracle resource using availability zone. + +### Variables + +* `prefix` - (Required) The prefix used for all resources in this example. + +* `location` - (Required) The Azure Region in which the resources in this example should be created. diff --git a/examples/netapp/avg_oracle_availability_zone/main.tf b/examples/netapp/avg_oracle_availability_zone/main.tf new file mode 100644 index 000000000000..7e53af375c9d --- /dev/null +++ b/examples/netapp/avg_oracle_availability_zone/main.tf @@ -0,0 +1,119 @@ +provider "azurerm" { + features { + netapp { + prevent_volume_destruction = true + } + } +} + +resource "azurerm_resource_group" "example" { + name = "${var.prefix}-resources" + location = var.location + + tags = { + "SkipNRMSNSG" = "true" + } +} + +resource "azurerm_virtual_network" "example" { + name = "${var.prefix}-vnet" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + address_space = ["10.47.0.0/16"] +} + +resource "azurerm_subnet" "example" { + name = "${var.prefix}-delegated-subnet" + resource_group_name = azurerm_resource_group.example.name + virtual_network_name = azurerm_virtual_network.example.name + address_prefixes = ["10.47.2.0/24"] + + delegation { + name = "exampledelegation" + + service_delegation { + name = "Microsoft.Netapp/volumes" + actions = ["Microsoft.Network/networkinterfaces/*", "Microsoft.Network/virtualNetworks/subnets/join/action"] + } + } +} + +resource "azurerm_netapp_account" "example" { + name = "${var.prefix}-netapp-account" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + + depends_on = [ + azurerm_subnet.example + ] +} + +resource "azurerm_netapp_pool" "example" { + name = "${var.prefix}-netapp-pool" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + account_name = azurerm_netapp_account.example.name + service_level = "Standard" + size_in_tb = 4 + qos_type = "Manual" +} + + +resource "azurerm_netapp_volume_group_oracle" "example" { + name = "${var.prefix}-NetAppVolumeGroupOracle" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + account_name = azurerm_netapp_account.example.name + group_description = "Example volume group for Oracle" + application_identifier = "TST" + + volume { + name = "${var.prefix}-volume-ora1" + volume_path = "${var.prefix}-my-unique-file-ora-path-1" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.example.id + subnet_id = azurerm_subnet.example.id + zone = "1" + volume_spec_name = "ora-data1" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + } + + volume { + name = "${var.prefix}-volume-oraLog" + volume_path = "${var.prefix}-my-unique-file-oralog-path" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.example.id + subnet_id = azurerm_subnet.example.id + zone = "1" + volume_spec_name = "ora-log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + } +} diff --git a/examples/netapp/avg_oracle_availability_zone/variables.tf b/examples/netapp/avg_oracle_availability_zone/variables.tf new file mode 100644 index 000000000000..31dcff302353 --- /dev/null +++ b/examples/netapp/avg_oracle_availability_zone/variables.tf @@ -0,0 +1,7 @@ +variable "location" { + description = "The Azure location where all resources in this example should be created." +} + +variable "prefix" { + description = "The prefix used for all resources used by this NetApp Volume" +} diff --git a/examples/netapp/avg_oracle_cmkSystemAssigned/README.md b/examples/netapp/avg_oracle_cmkSystemAssigned/README.md new file mode 100644 index 000000000000..f30f74ee7898 --- /dev/null +++ b/examples/netapp/avg_oracle_cmkSystemAssigned/README.md @@ -0,0 +1,11 @@ +## Example: NetApp Files Application Volume Group For Oracle with System Assigned Identity and Customer Managed Key + +This example provisions an application volume group for Oracle resource using System Assigned Identity and Customer Managed Key. + +### Variables + +* `prefix` - (Required) The prefix used for all resources in this example. + +* `location` - (Required) The Azure Region in which the resources in this example should be created. + +* `tenant_id` - (Required) The Tenant ID for key vault access policy. diff --git a/examples/netapp/avg_oracle_cmkSystemAssigned/main.tf b/examples/netapp/avg_oracle_cmkSystemAssigned/main.tf new file mode 100644 index 000000000000..1ba6f5af2d71 --- /dev/null +++ b/examples/netapp/avg_oracle_cmkSystemAssigned/main.tf @@ -0,0 +1,240 @@ +provider "azurerm" { + features { + netapp { + prevent_volume_destruction = true + } + } +} + +data "azurerm_client_config" "current" { +} + +resource "azurerm_resource_group" "example" { + name = "${var.prefix}-resources" + location = var.location + + tags = { + "SkipNRMSNSG" = "true" + } +} + +resource "azurerm_netapp_account" "example" { + name = "${var.prefix}-account" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + + identity { + type = "SystemAssigned" + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z" + } +} + +resource "azurerm_key_vault" "example" { + name = "${var.prefix}anfakv" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + enabled_for_disk_encryption = true + enabled_for_deployment = true + enabled_for_template_deployment = true + purge_protection_enabled = true + tenant_id = var.tenant_id + sku_name = "standard" + + access_policy { + tenant_id = azurerm_netapp_account.example.identity.0.tenant_id + object_id = data.azurerm_client_config.current.object_id + + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] + key_permissions = [ + "Get", + "Create", + "Delete", + "WrapKey", + "UnwrapKey", + "GetRotationPolicy", + "SetRotationPolicy", + ] + } + + access_policy { + tenant_id = azurerm_netapp_account.example.identity.0.tenant_id + object_id = azurerm_netapp_account.example.identity.0.principal_id + + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] + key_permissions = [ + "Get", + "Encrypt", + "Decrypt" + ] + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z" + } +} + +resource "azurerm_key_vault_key" "example" { + name = "${var.prefix}anfenckey" + key_vault_id = azurerm_key_vault.example.id + key_type = "RSA" + key_size = 2048 + + key_opts = [ + "decrypt", + "encrypt", + "sign", + "unwrapKey", + "verify", + "wrapKey", + ] +} + +resource "azurerm_netapp_account_encryption" "example" { + netapp_account_id = azurerm_netapp_account.example.id + system_assigned_identity_principal_id = azurerm_netapp_account.example.identity.0.principal_id + encryption_key = azurerm_key_vault_key.example.versionless_id +} + +resource "azurerm_virtual_network" "example" { + name = "${var.prefix}-virtual-network" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + address_space = ["10.6.0.0/16"] + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_subnet" "example-delegated" { + name = "${var.prefix}-delegated-subnet" + resource_group_name = azurerm_resource_group.example.name + virtual_network_name = azurerm_virtual_network.example.name + address_prefixes = ["10.6.1.0/24"] + + delegation { + name = "exampledelegation" + + service_delegation { + name = "Microsoft.Netapp/volumes" + actions = ["Microsoft.Network/networkinterfaces/*", "Microsoft.Network/virtualNetworks/subnets/join/action"] + } + } +} + +resource "azurerm_subnet" "example-non-delegated" { + name = "${var.prefix}-non-delegated-subnet" + resource_group_name = azurerm_resource_group.example.name + virtual_network_name = azurerm_virtual_network.example.name + address_prefixes = ["10.6.0.0/24"] +} + +resource "azurerm_private_endpoint" "example" { + name = "${var.prefix}-pe-akv" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + subnet_id = azurerm_subnet.example-non-delegated.id + + private_service_connection { + name = "${var.prefix}-pe-sc-akv" + private_connection_resource_id = azurerm_key_vault.example.id + is_manual_connection = false + subresource_names = ["Vault"] + } + + tags = { + CreatedOnDate = "2023-10-03T19:58:43.6509795Z" + } +} + +resource "azurerm_netapp_pool" "example" { + name = "${var.prefix}-capacity-pool" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + account_name = azurerm_netapp_account.example.name + service_level = "Standard" + size_in_tb = 4 + qos_type = "Manual" + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } + + depends_on = [ + azurerm_netapp_account_encryption.example + ] +} + +resource "azurerm_netapp_volume_group_oracle" "example" { + name = "${var.prefix}-volume-group-oracle" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + account_name = azurerm_netapp_account.example.name + group_description = "Example volume group for Oracle" + application_identifier = "TST" + + volume { + name = "${var.prefix}-volume-ora1" + volume_path = "${var.prefix}-my-unique-file-ora-path-1" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.example.id + subnet_id = azurerm_subnet.example-delegated.id + zone = "1" + volume_spec_name = "ora-data1" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + encryption_key_source = "Microsoft.KeyVault" + key_vault_private_endpoint_id = azurerm_private_endpoint.example.id + network_features = "Standard" + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + } + + volume { + name = "${var.prefix}-volume-oraLog" + volume_path = "${var.prefix}-my-unique-file-oralog-path" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.example.id + subnet_id = azurerm_subnet.example-delegated.id + zone = "1" + volume_spec_name = "ora-log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + encryption_key_source = "Microsoft.KeyVault" + key_vault_private_endpoint_id = azurerm_private_endpoint.example.id + network_features = "Standard" + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + } +} diff --git a/examples/netapp/avg_oracle_cmkSystemAssigned/variables.tf b/examples/netapp/avg_oracle_cmkSystemAssigned/variables.tf new file mode 100644 index 000000000000..f96daf16eeda --- /dev/null +++ b/examples/netapp/avg_oracle_cmkSystemAssigned/variables.tf @@ -0,0 +1,11 @@ +variable "location" { + description = "The Azure location where all resources in this example should be created." +} + +variable "prefix" { + description = "The prefix used for all resources used by this NetApp Volume" +} + +variable "tenant_id" { + description = "The Azure tenant ID used to create the user-assigned identity" +} diff --git a/examples/netapp/avg_oracle_proximity_placement_group/README.md b/examples/netapp/avg_oracle_proximity_placement_group/README.md new file mode 100644 index 000000000000..aaa8ce42bc9e --- /dev/null +++ b/examples/netapp/avg_oracle_proximity_placement_group/README.md @@ -0,0 +1,9 @@ +## Example: NetApp Files Application Volume Group For Oracle with Proximity Placement Group + +This example provisions an application volume group for Oracle resource using proximity placement group. + +### Variables + +* `prefix` - (Required) The prefix used for all resources in this example. + +* `location` - (Required) The Azure Region in which the resources in this example should be created. diff --git a/examples/netapp/avg_oracle_proximity_placement_group/main.tf b/examples/netapp/avg_oracle_proximity_placement_group/main.tf new file mode 100644 index 000000000000..f3e679767418 --- /dev/null +++ b/examples/netapp/avg_oracle_proximity_placement_group/main.tf @@ -0,0 +1,254 @@ +provider "azurerm" { + features { + netapp { + prevent_volume_destruction = true + } + } +} + +resource "random_string" "example" { + length = 12 + special = true +} + +locals { + admin_username = "exampleadmin" + admin_password = random_string.example.result +} + +resource "azurerm_resource_group" "example" { + name = "${var.prefix}-resources" + location = var.location + + tags = { + "SkipNRMSNSG" = "true" + } +} + +resource "azurerm_virtual_network" "example" { + name = "${var.prefix}-vnet" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + address_space = ["10.6.0.0/16"] +} + +resource "azurerm_subnet" "example" { + name = "${var.prefix}-delegated-subnet" + resource_group_name = azurerm_resource_group.example.name + virtual_network_name = azurerm_virtual_network.example.name + address_prefixes = ["10.6.2.0/24"] + + delegation { + name = "exampledelegation" + + service_delegation { + name = "Microsoft.Netapp/volumes" + actions = ["Microsoft.Network/networkinterfaces/*", "Microsoft.Network/virtualNetworks/subnets/join/action"] + } + } +} + +resource "azurerm_user_assigned_identity" "example" { + name = "${var.prefix}-user-assigned-identity" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z" + } +} + +resource "azurerm_network_security_group" "example" { + name = "${var.prefix}-nsg" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_subnet" "example1" { + name = "${var.prefix}-hosts-subnet" + resource_group_name = azurerm_resource_group.example.name + virtual_network_name = azurerm_virtual_network.example.name + address_prefixes = ["10.6.1.0/24"] +} + +resource "azurerm_subnet_network_security_group_association" "example" { + subnet_id = azurerm_subnet.example.id + network_security_group_id = azurerm_network_security_group.example.id +} + +resource "azurerm_proximity_placement_group" "example" { + name = "${var.prefix}-proximity-placement-group" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_availability_set" "example" { + name = "${var.prefix}-availability-set" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + + platform_update_domain_count = 2 + platform_fault_domain_count = 2 + + proximity_placement_group_id = azurerm_proximity_placement_group.example.id + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_network_interface" "example" { + name = "${var.prefix}-nic" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + + ip_configuration { + name = "internal" + subnet_id = azurerm_subnet.example1.id + private_ip_address_allocation = "Dynamic" + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_linux_virtual_machine" "example" { + name = "${var.prefix}-vm" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + size = "Standard_D2s_v4" + admin_username = local.admin_username + admin_password = local.admin_password + disable_password_authentication = false + proximity_placement_group_id = azurerm_proximity_placement_group.example.id + availability_set_id = azurerm_availability_set.example.id + network_interface_ids = [ + azurerm_network_interface.example.id + ] + + source_image_reference { + publisher = "Canonical" + offer = "0001-com-ubuntu-server-jammy" + sku = "22_04-lts" + version = "laexample" + } + + patch_assessment_mode = "AutomaticByPlatform" + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + identity { + type = "SystemAssigned, UserAssigned" + identity_ids = [ + azurerm_user_assigned_identity.example.id + ] + } + + tags = { + "AzSecPackAutoConfigReady" = "true", + "platformsettings.host_environment.service.platform_optedin_for_rootcerts" = "true", + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true", + "Owner" = "exampleuser" + } +} + +resource "azurerm_netapp_account" "example" { + name = "${var.prefix}-netapp-account" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + + depends_on = [ + azurerm_subnet.example + ] +} + +resource "azurerm_netapp_pool" "example" { + name = "${var.prefix}-netapp-pool" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + account_name = azurerm_netapp_account.example.name + service_level = "Standard" + size_in_tb = 4 + qos_type = "Manual" +} + +resource "azurerm_netapp_volume_group_oracle" "example" { + name = "${var.prefix}-NetAppVolumeGroupOracle" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + account_name = azurerm_netapp_account.example.name + group_description = "Example volume group for Oracle" + application_identifier = "TST" + + volume { + name = "${var.prefix}-NetAppVolume-Ora1" + volume_path = "${var.prefix}-my-unique-file-ora-path-1" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.example.id + subnet_id = azurerm_subnet.example.id + proximity_placement_group_id = azurerm_proximity_placement_group.example.id + volume_spec_name = "ora-data1" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + } + + volume { + name = "${var.prefix}-NetAppVolume-OraLog" + volume_path = "${var.prefix}-my-unique-file-oralog-path" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.example.id + subnet_id = azurerm_subnet.example.id + zone = "1" + volume_spec_name = "ora-log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + } + + depends_on = [ + azurerm_linux_virtual_machine.example, + azurerm_proximity_placement_group.example + ] +} diff --git a/examples/netapp/avg_oracle_proximity_placement_group/variables.tf b/examples/netapp/avg_oracle_proximity_placement_group/variables.tf new file mode 100644 index 000000000000..31dcff302353 --- /dev/null +++ b/examples/netapp/avg_oracle_proximity_placement_group/variables.tf @@ -0,0 +1,7 @@ +variable "location" { + description = "The Azure location where all resources in this example should be created." +} + +variable "prefix" { + description = "The prefix used for all resources used by this NetApp Volume" +} diff --git a/examples/netapp/avg_oracle_snapshot_policy/README.md b/examples/netapp/avg_oracle_snapshot_policy/README.md new file mode 100644 index 000000000000..900401bdca87 --- /dev/null +++ b/examples/netapp/avg_oracle_snapshot_policy/README.md @@ -0,0 +1,9 @@ +## Example: NetApp Files Application Volume Group For Oracle with Snapshot Policy + +This example provisions an application volume group for Oracle resource with snapshot policy. + +### Variables + +* `prefix` - (Required) The prefix used for all resources in this example. + +* `location` - (Required) The Azure Region in which the resources in this example should be created. diff --git a/examples/netapp/avg_oracle_snapshot_policy/main.tf b/examples/netapp/avg_oracle_snapshot_policy/main.tf new file mode 100644 index 000000000000..625dd47d6cfe --- /dev/null +++ b/examples/netapp/avg_oracle_snapshot_policy/main.tf @@ -0,0 +1,138 @@ +provider "azurerm" { + features { + netapp { + prevent_volume_destruction = true + } + } +} + +resource "azurerm_resource_group" "example" { + name = "${var.prefix}-resources" + location = var.location + + tags = { + "SkipNRMSNSG" = "true" + } +} + +resource "azurerm_virtual_network" "example" { + name = "${var.prefix}-vnet" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + address_space = ["10.6.0.0/16"] +} + +resource "azurerm_subnet" "example" { + name = "${var.prefix}-delegated-subnet" + resource_group_name = azurerm_resource_group.example.name + virtual_network_name = azurerm_virtual_network.example.name + address_prefixes = ["10.6.2.0/24"] + + delegation { + name = "exampledelegation" + + service_delegation { + name = "Microsoft.Netapp/volumes" + actions = ["Microsoft.Network/networkinterfaces/*", "Microsoft.Network/virtualNetworks/subnets/join/action"] + } + } +} + +resource "azurerm_netapp_account" "example" { + name = "${var.prefix}-netapp-account" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + + depends_on = [ + azurerm_subnet.example + ] +} + +resource "azurerm_netapp_pool" "example" { + name = "${var.prefix}-netapp-pool" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + account_name = azurerm_netapp_account.example.name + service_level = "Standard" + size_in_tb = 4 + qos_type = "Manual" +} + +resource "azurerm_netapp_snapshot_policy" "example" { + name = "${var.prefix}-snapshot-policy" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + account_name = azurerm_netapp_account.example.name + enabled = true + + monthly_schedule { + snapshots_to_keep = 1 + days_of_month = [15, 30] + hour = 23 + minute = 30 + } + + tags = { + "CreatedOnDate" = "2022-07-08T23:50:21Z", + "SkipASMAzSecPack" = "true" + } +} + +resource "azurerm_netapp_volume_group_oracle" "example" { + name = "${var.prefix}-volume-group-oracle" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + account_name = azurerm_netapp_account.example.name + group_description = "Example volume group for Oracle" + application_identifier = "TST" + + volume { + name = "${var.prefix}-volume-ora1" + volume_path = "${var.prefix}-my-unique-file-ora-path-1" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.example.id + subnet_id = azurerm_subnet.example.id + zone = "1" + volume_spec_name = "ora-data1" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + } + + volume { + name = "${var.prefix}-volume-oraLog" + volume_path = "${var.prefix}-my-unique-file-oralog-path" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.example.id + subnet_id = azurerm_subnet.example.id + zone = "1" + volume_spec_name = "ora-log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + } +} diff --git a/examples/netapp/avg_oracle_snapshot_policy/variables.tf b/examples/netapp/avg_oracle_snapshot_policy/variables.tf new file mode 100644 index 000000000000..31dcff302353 --- /dev/null +++ b/examples/netapp/avg_oracle_snapshot_policy/variables.tf @@ -0,0 +1,7 @@ +variable "location" { + description = "The Azure location where all resources in this example should be created." +} + +variable "prefix" { + description = "The prefix used for all resources used by this NetApp Volume" +} diff --git a/internal/services/netapp/netapp_account_encryption_resource_test.go b/internal/services/netapp/netapp_account_encryption_resource_test.go index 85b0dc08d86d..473d69b92d99 100644 --- a/internal/services/netapp/netapp_account_encryption_resource_test.go +++ b/internal/services/netapp/netapp_account_encryption_resource_test.go @@ -116,7 +116,7 @@ resource "azurerm_netapp_account" "test" { } tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z" + "CreatedOnDate" = "2022-07-08T23:50:21Z" } } @@ -129,15 +129,15 @@ resource "azurerm_key_vault" "test" { enabled_for_template_deployment = true purge_protection_enabled = true tenant_id = "%[3]s" - sku_name = "standard" + sku_name = "standard" access_policy { - tenant_id = azurerm_netapp_account.test.identity.0.tenant_id - object_id = data.azurerm_client_config.current.object_id + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = data.azurerm_client_config.current.object_id - certificate_permissions = [] - secret_permissions = [] - storage_permissions = [] + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] key_permissions = [ "Get", "Create", @@ -150,21 +150,21 @@ resource "azurerm_key_vault" "test" { } access_policy { - tenant_id = azurerm_netapp_account.test.identity.0.tenant_id - object_id = azurerm_netapp_account.test.identity.0.principal_id + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = azurerm_netapp_account.test.identity.0.principal_id - certificate_permissions = [] - secret_permissions = [] - storage_permissions = [] + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] key_permissions = [ "Get", "Encrypt", "Decrypt" ] } - + tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z" + "CreatedOnDate" = "2022-07-08T23:50:21Z" } } @@ -185,9 +185,9 @@ resource "azurerm_key_vault_key" "test" { } resource "azurerm_netapp_account_encryption" "test" { - netapp_account_id = azurerm_netapp_account.test.id + netapp_account_id = azurerm_netapp_account.test.id system_assigned_identity_principal_id = azurerm_netapp_account.test.identity.0.principal_id - encryption_key = azurerm_key_vault_key.test.versionless_id + encryption_key = azurerm_key_vault_key.test.versionless_id } `, r.template(data), data.RandomInteger, tenantID) } @@ -202,7 +202,7 @@ resource "azurerm_user_assigned_identity" "test" { resource_group_name = azurerm_resource_group.test.name tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z" + "CreatedOnDate" = "2022-07-08T23:50:21Z" } } @@ -218,15 +218,15 @@ resource "azurerm_key_vault" "test" { enabled_for_template_deployment = true purge_protection_enabled = true tenant_id = "%[3]s" - sku_name = "standard" + sku_name = "standard" access_policy { tenant_id = "%[3]s" - object_id = data.azurerm_client_config.current.object_id + object_id = data.azurerm_client_config.current.object_id - certificate_permissions = [] - secret_permissions = [] - storage_permissions = [] + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] key_permissions = [ "Get", "Create", @@ -242,9 +242,9 @@ resource "azurerm_key_vault" "test" { tenant_id = "%[3]s" object_id = azurerm_user_assigned_identity.test.principal_id - certificate_permissions = [] - secret_permissions = [] - storage_permissions = [] + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] key_permissions = [ "Get", "Encrypt", @@ -253,7 +253,7 @@ resource "azurerm_key_vault" "test" { } tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z" + "CreatedOnDate" = "2022-07-08T23:50:21Z" } } @@ -284,7 +284,7 @@ resource "azurerm_netapp_account" "test" { azurerm_user_assigned_identity.test.id ] } - + tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", "SkipASMAzSecPack" = "true" @@ -292,9 +292,9 @@ resource "azurerm_netapp_account" "test" { } resource "azurerm_netapp_account_encryption" "test" { - netapp_account_id = azurerm_netapp_account.test.id + netapp_account_id = azurerm_netapp_account.test.id user_assigned_identity_id = azurerm_user_assigned_identity.test.id - encryption_key = azurerm_key_vault_key.test.versionless_id + encryption_key = azurerm_key_vault_key.test.versionless_id } `, r.template(data), data.RandomInteger, tenantID) } @@ -315,8 +315,8 @@ resource "azurerm_netapp_account" "test" { type = "SystemAssigned" } - tags = { - "SkipNRMSNSG" = "true", + tags = { + "SkipNRMSNSG" = "true", "CreatedOnDate" = "2022-07-08T23:50:21Z" } } @@ -330,15 +330,15 @@ resource "azurerm_key_vault" "test" { enabled_for_template_deployment = true purge_protection_enabled = true tenant_id = "%[3]s" - sku_name = "standard" + sku_name = "standard" access_policy { - tenant_id = azurerm_netapp_account.test.identity.0.tenant_id - object_id = data.azurerm_client_config.current.object_id + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = data.azurerm_client_config.current.object_id - certificate_permissions = [] - secret_permissions = [] - storage_permissions = [] + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] key_permissions = [ "Get", "Create", @@ -351,12 +351,12 @@ resource "azurerm_key_vault" "test" { } access_policy { - tenant_id = azurerm_netapp_account.test.identity.0.tenant_id - object_id = azurerm_netapp_account.test.identity.0.principal_id + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = azurerm_netapp_account.test.identity.0.principal_id - certificate_permissions = [] - secret_permissions = [] - storage_permissions = [] + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] key_permissions = [ "Get", "Encrypt", @@ -402,9 +402,9 @@ resource "azurerm_key_vault_key" "test-new-key" { } resource "azurerm_netapp_account_encryption" "test" { - netapp_account_id = azurerm_netapp_account.test.id + netapp_account_id = azurerm_netapp_account.test.id system_assigned_identity_principal_id = azurerm_netapp_account.test.identity.0.principal_id - encryption_key = azurerm_key_vault_key.test.versionless_id + encryption_key = azurerm_key_vault_key.test.versionless_id } `, r.template(data), data.RandomInteger, tenantID) } @@ -425,8 +425,8 @@ resource "azurerm_netapp_account" "test" { type = "SystemAssigned" } - tags = { - "SkipNRMSNSG" = "true", + tags = { + "SkipNRMSNSG" = "true", "CreatedOnDate" = "2022-07-08T23:50:21Z" } } @@ -443,37 +443,37 @@ resource "azurerm_key_vault" "test" { sku_name = "standard" access_policy { - tenant_id = azurerm_netapp_account.test.identity.0.tenant_id - object_id = data.azurerm_client_config.current.object_id - - certificate_permissions = [] - secret_permissions = [] - storage_permissions = [] - key_permissions = [ - "Get", - "Create", - "Delete", - "WrapKey", - "UnwrapKey", - "GetRotationPolicy", - "SetRotationPolicy", + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = data.azurerm_client_config.current.object_id + + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] + key_permissions = [ + "Get", + "Create", + "Delete", + "WrapKey", + "UnwrapKey", + "GetRotationPolicy", + "SetRotationPolicy", ] } access_policy { - tenant_id = azurerm_netapp_account.test.identity.0.tenant_id - object_id = azurerm_netapp_account.test.identity.0.principal_id + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = azurerm_netapp_account.test.identity.0.principal_id - certificate_permissions = [] - secret_permissions = [] - storage_permissions = [] + certificate_permissions = [] + secret_permissions = [] + storage_permissions = [] key_permissions = [ "Get", "Encrypt", "Decrypt" ] } - + tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z" } @@ -516,9 +516,9 @@ resource "azurerm_key_vault_key" "test-new-key" { } resource "azurerm_netapp_account_encryption" "test" { - netapp_account_id = azurerm_netapp_account.test.id + netapp_account_id = azurerm_netapp_account.test.id system_assigned_identity_principal_id = azurerm_netapp_account.test.identity.0.principal_id - encryption_key = azurerm_key_vault_key.test-new-key.versionless_id + encryption_key = azurerm_key_vault_key.test-new-key.versionless_id } `, r.template(data), data.RandomInteger, tenantID) } @@ -536,10 +536,10 @@ provider "azurerm" { purge_soft_deleted_keys_on_destroy = false } - netapp { - prevent_volume_destruction = false + netapp { + prevent_volume_destruction = false delete_backups_on_backup_vault_destroy = true - } + } } } @@ -550,7 +550,7 @@ resource "azurerm_resource_group" "test" { tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", "SkipASMAzSecPack" = "true", - "SkipNRMSNSG" = "true" + "SkipNRMSNSG" = "true" } } `, data.RandomInteger, data.Locations.Primary) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index f999aa154805..b86ee6ead25f 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -176,18 +176,18 @@ resource "azurerm_netapp_volume_group_oracle" "test" { application_identifier = "TST" volume { - name = "acctest-NetAppVolume-Ora1-%[2]d" - volume_path = "my-unique-file-ora-path-1-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data1" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false + name = "acctest-NetAppVolume-Ora1-%[2]d" + volume_path = "my-unique-file-ora-path-1-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-data1" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false export_policy_rule { rule_index = 1 @@ -198,7 +198,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { unix_read_write = true root_access_enabled = false } - + tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", "SkipASMAzSecPack" = "true" @@ -228,7 +228,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { unix_read_write = true root_access_enabled = false } - + tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", "SkipASMAzSecPack" = "true" @@ -274,7 +274,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { unix_read_write = true root_access_enabled = false } - + tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", "SkipASMAzSecPack" = "true" @@ -333,18 +333,18 @@ resource "azurerm_netapp_volume_group_oracle" "test" { application_identifier = "TST" volume { - name = "acctest-NetAppVolume-Ora1-%[2]d" - volume_path = "my-unique-file-ora-path-1-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data1" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv3"] - security_style = "unix" - snapshot_directory_visible = false + name = "acctest-NetAppVolume-Ora1-%[2]d" + volume_path = "my-unique-file-ora-path-1-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-data1" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv3"] + security_style = "unix" + snapshot_directory_visible = false export_policy_rule { rule_index = 1 @@ -385,7 +385,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { unix_read_write = true root_access_enabled = false } - + tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", "SkipASMAzSecPack" = "true" @@ -429,18 +429,18 @@ resource "azurerm_netapp_volume_group_oracle" "test" { application_identifier = "TST" volume { - name = "acctest-NetAppVolume-Ora1-%[2]d" - volume_path = "my-unique-file-ora-path-1-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data1" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false + name = "acctest-NetAppVolume-Ora1-%[2]d" + volume_path = "my-unique-file-ora-path-1-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-data1" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false export_policy_rule { rule_index = 1 @@ -463,18 +463,18 @@ resource "azurerm_netapp_volume_group_oracle" "test" { } volume { - name = "acctest-NetAppVolume-OraLog-%[2]d" - volume_path = "my-unique-file-ora-path-2-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-log" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false + name = "acctest-NetAppVolume-OraLog-%[2]d" + volume_path = "my-unique-file-ora-path-2-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false export_policy_rule { rule_index = 1 @@ -537,18 +537,18 @@ resource "azurerm_netapp_volume_group_oracle" "test" { application_identifier = "TST" volume { - name = "acctest-NetAppVolume-Ora1-%[2]d" - volume_path = "my-unique-file-ora-path-1-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data1" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false + name = "acctest-NetAppVolume-Ora1-%[2]d" + volume_path = "my-unique-file-ora-path-1-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-data1" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false export_policy_rule { rule_index = 1 @@ -567,18 +567,18 @@ resource "azurerm_netapp_volume_group_oracle" "test" { } volume { - name = "acctest-NetAppVolume-OraLog-%[2]d" - volume_path = "my-unique-file-ora-path-2-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-log" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false + name = "acctest-NetAppVolume-OraLog-%[2]d" + volume_path = "my-unique-file-ora-path-2-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false export_policy_rule { rule_index = 1 @@ -617,18 +617,18 @@ resource "azurerm_netapp_volume_group_oracle" "test" { application_identifier = "TST" volume { - name = "acctest-NetAppVolume-Ora1-%[2]d" - volume_path = "my-unique-file-ora-path-1-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-data1" - storage_quota_in_gb = 1200 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false + name = "acctest-NetAppVolume-Ora1-%[2]d" + volume_path = "my-unique-file-ora-path-1-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-data1" + storage_quota_in_gb = 1200 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false export_policy_rule { rule_index = 1 @@ -647,18 +647,18 @@ resource "azurerm_netapp_volume_group_oracle" "test" { } volume { - name = "acctest-NetAppVolume-OraLog-%[2]d" - volume_path = "my-unique-file-oralog-path-%[2]d" - service_level = "Standard" - capacity_pool_id = azurerm_netapp_pool.test.id - subnet_id = azurerm_subnet.test.id - zone = "1" - volume_spec_name = "ora-log" - storage_quota_in_gb = 1024 - throughput_in_mibps = 24 - protocols = ["NFSv4.1"] - security_style = "unix" - snapshot_directory_visible = false + name = "acctest-NetAppVolume-OraLog-%[2]d" + volume_path = "my-unique-file-oralog-path-%[2]d" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.test.id + subnet_id = azurerm_subnet.test.id + zone = "1" + volume_spec_name = "ora-log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false export_policy_rule { rule_index = 1 @@ -687,7 +687,7 @@ provider "azurerm" { prevent_deletion_if_contains_resources = false } netapp { - prevent_volume_destruction = false + prevent_volume_destruction = false } } } @@ -699,8 +699,8 @@ resource "azurerm_resource_group" "test" { name = "acctestRG-netapp-%[1]d" location = "%[3]s" - tags = { - "SkipNRMSNSG" = "true", + tags = { + "SkipNRMSNSG" = "true", "CreatedOnDate" = "2022-07-08T23:50:21Z" } } @@ -728,33 +728,33 @@ resource "azurerm_key_vault" "test" { enabled_for_template_deployment = true purge_protection_enabled = true tenant_id = "%[2]s" - sku_name = "standard" + sku_name = "standard" access_policy { - tenant_id = azurerm_netapp_account.test.identity.0.tenant_id - object_id = data.azurerm_client_config.current.object_id + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = data.azurerm_client_config.current.object_id certificate_permissions = [] - secret_permissions = [] - storage_permissions = [] - key_permissions = [ - "Get", - "Create", - "Delete", - "WrapKey", - "UnwrapKey", - "GetRotationPolicy", - "SetRotationPolicy", + secret_permissions = [] + storage_permissions = [] + key_permissions = [ + "Get", + "Create", + "Delete", + "WrapKey", + "UnwrapKey", + "GetRotationPolicy", + "SetRotationPolicy", ] } access_policy { - tenant_id = azurerm_netapp_account.test.identity.0.tenant_id - object_id = azurerm_netapp_account.test.identity.0.principal_id + tenant_id = azurerm_netapp_account.test.identity.0.tenant_id + object_id = azurerm_netapp_account.test.identity.0.principal_id certificate_permissions = [] - secret_permissions = [] - storage_permissions = [] + secret_permissions = [] + storage_permissions = [] key_permissions = [ "Get", "Encrypt", @@ -784,9 +784,9 @@ resource "azurerm_key_vault_key" "test" { } resource "azurerm_netapp_account_encryption" "test" { - netapp_account_id = azurerm_netapp_account.test.id + netapp_account_id = azurerm_netapp_account.test.id system_assigned_identity_principal_id = azurerm_netapp_account.test.identity.0.principal_id - encryption_key = azurerm_key_vault_key.test.versionless_id + encryption_key = azurerm_key_vault_key.test.versionless_id } resource "azurerm_virtual_network" "test" { @@ -936,8 +936,7 @@ provider "azurerm" { prevent_deletion_if_contains_resources = false } netapp { - prevent_volume_destruction = false - delete_backups_on_backup_vault_destroy = true + prevent_volume_destruction = false } } } @@ -951,7 +950,7 @@ resource "azurerm_resource_group" "test" { name = "acctestRG-netapp-%[1]d" location = "%[2]s" - tags = { + tags = { "SkipNRMSNSG" = "true" } } @@ -962,7 +961,7 @@ resource "azurerm_user_assigned_identity" "test" { resource_group_name = azurerm_resource_group.test.name tags = { - "CreatedOnDate" = "2022-07-08T23:50:21Z" + "CreatedOnDate" = "2022-07-08T23:50:21Z" } } @@ -1146,7 +1145,7 @@ provider "azurerm" { prevent_deletion_if_contains_resources = false } netapp { - prevent_volume_destruction = false + prevent_volume_destruction = false } } } @@ -1155,7 +1154,7 @@ resource "azurerm_resource_group" "test" { name = "acctestRG-netapp-%[1]d" location = "%[2]s" - tags = { + tags = { "SkipNRMSNSG" = "true" } } diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go index 583a8082695c..7df6455e7f59 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go @@ -244,7 +244,7 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { "SkipASMAzSecPack" = "true" } } - + depends_on = [ azurerm_linux_virtual_machine.test, azurerm_proximity_placement_group.test @@ -552,11 +552,11 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { "SkipASMAzSecPack" = "true" } } - + depends_on = [ azurerm_linux_virtual_machine.test, azurerm_proximity_placement_group.test, - azurerm_netapp_snapshot_policy.test + azurerm_netapp_snapshot_policy.test ] } `, template, data.RandomInteger) @@ -688,7 +688,7 @@ resource "azurerm_netapp_volume_group_sap_hana" "test" { depends_on = [ azurerm_linux_virtual_machine.test, azurerm_proximity_placement_group.test, - azurerm_netapp_snapshot_policy.test + azurerm_netapp_snapshot_policy.test ] } `, template, data.RandomInteger) @@ -1013,7 +1013,7 @@ resource "azurerm_netapp_volume_group_sap_hana" "test_secondary" { root_access_enabled = false } - data_protection_replication { + data_protection_replication { endpoint_type = "dst" remote_volume_location = azurerm_netapp_volume_group_sap_hana.test_primary.location remote_volume_resource_id = azurerm_netapp_volume_group_sap_hana.test_primary.volume[2].id @@ -1032,6 +1032,7 @@ resource "azurerm_netapp_volume_group_sap_hana" "test_secondary" { ] } + `, template, data.RandomInteger, "westus2") } diff --git a/internal/services/netapp/netapp_volume_resource_test.go b/internal/services/netapp/netapp_volume_resource_test.go index 3b283dfde704..b71ef80213d6 100644 --- a/internal/services/netapp/netapp_volume_resource_test.go +++ b/internal/services/netapp/netapp_volume_resource_test.go @@ -1426,7 +1426,7 @@ resource "azurerm_netapp_pool" "test" { func (r NetAppVolumeResource) networkTemplate(data acceptance.TestData) string { return fmt.Sprintf(` - resource "azurerm_virtual_network" "test" { +resource "azurerm_virtual_network" "test" { name = "acctest-VirtualNetwork-%[1]d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name diff --git a/website/docs/d/netapp_volume_group_oracle.html.markdown b/website/docs/d/netapp_volume_group_oracle.html.markdown new file mode 100644 index 000000000000..50db9f03e26d --- /dev/null +++ b/website/docs/d/netapp_volume_group_oracle.html.markdown @@ -0,0 +1,139 @@ +--- +subcategory: "NetApp" +layout: "azurerm" +page_title: "Azure Resource Manager: Data Source: azurerm_netapp_volume_group_oracle" +description: |- + Gets information about an existing Application Volume Group for Oracle application. +--- + +# Data Source: azurerm_netapp_volume_group_oracle + +Use this data source to access information about an existing Application Volume Group for Oracle application. + +## Example Usage + +```hcl +data "azurerm_netapp_volume_group_oracle" "example" { + name = "existing application volume group name" + resource_group_name = "resource group name where the account and volume group belong to" + account_name = "existing account where the application volume group belong to" +} + +output "id" { + value = data.azurerm_netapp_volume_group_oracle.example.id +} +``` + +## Arguments Reference + +The following arguments are supported: + +* `account_name` - (Required) Name of the account where the application volume group belong to. + +* `name` - (Required) The name of this Application Volume Group for Oracle application. + +* `resource_group_name` - (Required) The name of the Resource Group where the Application Volume Group exists. + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the Application Volume Group. + +* `application_identifier` - The application identifier. + +* `group_description` - Volume group description. + +* `location` - The Azure Region where the Application Volume Group exists. + +* `volume` - A `volume` block as defined below. + +--- + +A `volume` block exports the following: + +* `capacity_pool_id` - The ID of the Capacity Pool. + +* `id` - Volume ID. + +* `name` - The name of this volume. + +* `proximity_placement_group_id` - The ID of the proximity placement group. + +* `security_style` - Volume security style. + +* `service_level` - The target performance of the file system. + +* `snapshot_directory_visible` - Is the .snapshot (NFS clients) path of a volume visible? + +* `storage_quota_in_gb` - The maximum Storage Quota allowed for a file system in Gigabytes. + +* `subnet_id` - The ID of the Subnet the NetApp Volume resides in. + +* `tags` - A mapping of tags assigned to the Application Volume Group. + +* `throughput_in_mibps` - Throughput of this volume in Mibps. + +* `volume_path` - A unique file path for the volume. + +* `volume_spec_name` - Volume spec name. + +* `data_protection_snapshot_policy` - A `data_protection_snapshot_policy` block as defined below. + +* `export_policy_rule` - A `export_policy_rule` block as defined below. + +* `mount_ip_addresses` - A `mount_ip_addresses` block as defined below. + +* `protocols` - A `protocols` block as defined below. + +* `network_features` - Network feature in use at the time of volume creation. + +* `encryption_key_source` - The encryption key source. + +* `key_vault_private_endpoint_id` - The Private Endpoint ID for Key Vault when using customer managed keys. + +--- + +A `data_protection_replication` block exports the following: + +* `endpoint_type` - The endpoint type. + +* `remote_volume_location` - Location of the primary volume. + +* `remote_volume_resource_id` - Resource ID of the primary volume. + +* `replication_frequency` - Replication frequency. + +--- + +A `data_protection_snapshot_policy` block exports the following: + +* `snapshot_policy_id` - Resource ID of the snapshot policy to apply to the volume. + +--- + +A `export_policy_rule` block exports the following: + +* `allowed_clients` - A list of allowed clients IPv4 addresses. + +* `nfsv3_enabled` - Is the NFSv3 protocol enabled? + +* `nfsv41_enabled` - Is the NFSv4.1 enabled? + +* `root_access_enabled` - Is root access permitted to this volume? + +* `rule_index` - The index number of the rule. + +* `unix_read_only` - Is the file system on unix read only?. + +* `unix_read_write` - Is the file system on unix read and write?. + +--- + + + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions: + +* `read` - (Defaults to 5 minutes) Used when retrieving the Application Volume Group. diff --git a/website/docs/r/netapp_volume_group_oracle.html.markdown b/website/docs/r/netapp_volume_group_oracle.html.markdown new file mode 100644 index 000000000000..48e31602c63a --- /dev/null +++ b/website/docs/r/netapp_volume_group_oracle.html.markdown @@ -0,0 +1,245 @@ +--- +subcategory: "NetApp" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_netapp_volume_group_oracle" +description: |- + Manages a Application Volume Group for Oracle application. +--- + +# azurerm_netapp_volume_group_oracle + +Manages a Application Volume Group for Oracle application. + +>Note: This feature is intended to be used for Oracle workloads only, with several requirements, please refer to [Understand Azure NetApp Files application volume group for Oracle](https://learn.microsoft.com/en-us/azure/azure-netapp-files/application-volume-oracle-introduction) document as the starting point to understand this feature before using it with Terraform. + +## Example Usage + +```hcl +provider "azurerm" { + features { + netapp { + prevent_volume_destruction = true + } + } +} + +resource "azurerm_resource_group" "example" { + name = "${var.prefix}-resources" + location = var.location + + tags = { + "SkipNRMSNSG" = "true" + } +} + +resource "azurerm_virtual_network" "example" { + name = "${var.prefix}-vnet" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + address_space = ["10.6.0.0/16"] +} + +resource "azurerm_subnet" "example" { + name = "${var.prefix}-delegated-subnet" + resource_group_name = azurerm_resource_group.example.name + virtual_network_name = azurerm_virtual_network.example.name + address_prefixes = ["10.6.2.0/24"] + + delegation { + name = "exampledelegation" + + service_delegation { + name = "Microsoft.Netapp/volumes" + actions = ["Microsoft.Network/networkinterfaces/*", "Microsoft.Network/virtualNetworks/subnets/join/action"] + } + } +} + +resource "azurerm_netapp_account" "example" { + name = "${var.prefix}-netapp-account" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + + depends_on = [ + azurerm_subnet.example + ] +} + +resource "azurerm_netapp_pool" "example" { + name = "${var.prefix}-netapp-pool" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + account_name = azurerm_netapp_account.example.name + service_level = "Standard" + size_in_tb = 4 + qos_type = "Manual" +} + + +resource "azurerm_netapp_volume_group_oracle" "example" { + name = "${var.prefix}-NetAppVolumeGroupOracle" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + account_name = azurerm_netapp_account.example.name + group_description = "Example volume group for Oracle" + application_identifier = "TST" + + volume { + name = "${var.prefix}-volume-ora1" + volume_path = "${var.prefix}-my-unique-file-ora-path-1" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.example.id + subnet_id = azurerm_subnet.example.id + zone = "1" + volume_spec_name = "ora-data1" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + } + + volume { + name = "${var.prefix}-volume-oraLog" + volume_path = "${var.prefix}-my-unique-file-oralog-path" + service_level = "Standard" + capacity_pool_id = azurerm_netapp_pool.example.id + subnet_id = azurerm_subnet.example.id + zone = "1" + volume_spec_name = "ora-log" + storage_quota_in_gb = 1024 + throughput_in_mibps = 24 + protocols = ["NFSv4.1"] + security_style = "unix" + snapshot_directory_visible = false + + export_policy_rule { + rule_index = 1 + allowed_clients = "0.0.0.0/0" + nfsv3_enabled = false + nfsv41_enabled = true + unix_read_only = false + unix_read_write = true + root_access_enabled = false + } + } +} +``` + +## Arguments Reference + +The following arguments are supported: + +* `account_name` - (Required) Name of the account where the application volume group belong to. Changing this forces a new Application Volume Group to be created and data will be lost. + +* `application_identifier` - (Required) The SAP System ID, maximum 3 characters, e.g. `OR1`. Changing this forces a new Application Volume Group to be created and data will be lost. + +* `group_description` - (Required) Volume group description. Changing this forces a new Application Volume Group to be created and data will be lost. + +* `location` - (Required) The Azure Region where the Application Volume Group should exist. Changing this forces a new Application Volume Group to be created and data will be lost. + +* `name` - (Required) The name which should be used for this Application Volume Group. Changing this forces a new Application Volume Group to be created and data will be lost. + +* `resource_group_name` - (Required) The name of the Resource Group where the Application Volume Group should exist. Changing this forces a new Application Volume Group to be created and data will be lost. + +* `volume` - (Required) One or more `volume` blocks as defined below. + +--- + +A `volume` block supports the following: + +* `capacity_pool_id` - (Required) The ID of the Capacity Pool. Changing this forces a new Application Volume Group to be created and data will be lost. + +* `name` - (Required) The name which should be used for this volume. Changing this forces a new Application Volume Group to be created and data will be lost. + +* `protocols` - (Required) The target volume protocol expressed as a list. Changing this forces a new Application Volume Group to be created and data will be lost. Supported values for Application Volume Group include `NFSv3` or `NFSv4.1`. + +* `proximity_placement_group_id` - (Optional) The ID of the proximity placement group (PPG). Changing this forces a new Application Volume Group to be created and data will be lost. For Oracle application, it is required to have PPG enabled so Azure NetApp Files can pin the volumes next to your compute resources, please check [Requirements and considerations for application volume group for Oracle](https://learn.microsoft.com/en-us/azure/azure-netapp-files/application-volume-group-oracle-considerations) for details and other requirements. Note that this cannot be used together with `zone`. + +* `zone` - (Optional) Specifies the Availability Zone in which the Volume should be located. Possible values are `1`, `2` and `3`, depending on the Azure region. Changing this forces a new resource to be created. This feature is currently in preview, for more information on how to enable it, please refer to [Manage availability zone volume placement for Azure NetApp Files](https://learn.microsoft.com/en-us/azure/azure-netapp-files/manage-availability-zone-volume-placement). Note that this cannot be used together with `proximity_placement_group_id`. + +* `security_style` - (Required) Volume security style. Possible values are `ntfs` and `unix`. Changing this forces a new Application Volume Group to be created and data will be lost. + +* `service_level` - (Required) Volume security style. Possible values are `Premium`, `Standard` and `Ultra`. Changing this forces a new Application Volume Group to be created and data will be lost. + +* `snapshot_directory_visible` - (Required) Specifies whether the .snapshot (NFS clients) path of a volume is visible. Changing this forces a new Application Volume Group to be created and data will be lost. + +* `storage_quota_in_gb` - (Required) The maximum Storage Quota allowed for a file system in Gigabytes. + +* `subnet_id` - (Required) The ID of the Subnet the NetApp Volume resides in, which must have the `Microsoft.NetApp/volumes` delegation. Changing this forces a new Application Volume Group to be created and data will be lost. + +* `throughput_in_mibps` - (Required) Throughput of this volume in Mibps. + +* `volume_path` - (Required) A unique file path for the volume. Changing this forces a new Application Volume Group to be created and data will be lost. + +* `volume_spec_name` - (Required) Volume specification name. Possible values are `ora-data1` through `ora-data8`, `ora-log`, `ora-log-mirror`, `ora-backup` and `ora-binary`. Changing this forces a new Application Volume Group to be created and data will be lost. + +* `tags` - (Optional) A mapping of tags which should be assigned to the Application Volume Group. + +* `network_features` - (Optional) Indicates which network feature to use, accepted values are `Basic` or `Standard`, it defaults to `Basic` if not defined. This is a feature in public preview and for more information about it and how to register, please refer to [Configure network features for an Azure NetApp Files volume](https://docs.microsoft.com/en-us/azure/azure-netapp-files/configure-network-features). This is required if enabling customer managed keys encryption scenario. + +* `encryption_key_source` - (Optional) The encryption key source, it can be `Microsoft.NetApp` for platform managed keys or `Microsoft.KeyVault` for customer-managed keys. This is required with `key_vault_private_endpoint_id`. Changing this forces a new resource to be created. + +* `key_vault_private_endpoint_id` - (Optional) The Private Endpoint ID for Key Vault, which is required when using customer-managed keys. This is required with `encryption_key_source`. Changing this forces a new resource to be created. + +* `export_policy_rule` - (Required) One or more `export_policy_rule` blocks as defined below. + +* `data_protection_snapshot_policy` - (Optional) A `data_protection_snapshot_policy` block as defined below. + +--- +A `data_protection_snapshot_policy` block supports the following: + +* `snapshot_policy_id` - (Required) Resource ID of the snapshot policy to apply to the volume. + +--- + +A `export_policy_rule` block supports the following: + +* `allowed_clients` - (Required) A comma-sperated list of allowed client IPv4 addresses. + +* `nfsv3_enabled` - (Required) Enables NFSv3. Please note that this cannot be enabled if volume has NFSv4.1 as its protocol. + +* `nfsv41_enabled` - (Required) Enables NFSv4.1. Please note that this cannot be enabled if volume has NFSv3 as its protocol. + +* `root_access_enabled` - (Optional) Is root access permitted to this volume? Defaults to `true`. + +* `rule_index` - (Required) The index number of the rule, must start at 1 and maximum 5. + +* `unix_read_only` - (Optional) Is the file system on unix read only? Defaults to `false. + +* `unix_read_write` - (Optional) Is the file system on unix read and write? Defaults to `true`. + +--- + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the Application Volume Group. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions: + +* `create` - (Defaults to 90 minutes) Used when creating the Application Volume Group. +* `read` - (Defaults to 5 minutes) Used when retrieving the Application Volume Group. +* `update` - (Defaults to 2 hours) Used when updating the Application Volume Group. +* `delete` - (Defaults to 2 hours) Used when deleting the Application Volume Group. + +## Import + +Application Volume Groups can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_netapp_volume_group_oracle.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mytest-rg/providers/Microsoft.NetApp/netAppAccounts/netapp-account-test/volumeGroups/netapp-volumegroup-test +``` From c3023ab74fe34c8c8b20513e614ea347f18f9e06 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 27 Dec 2024 22:44:48 +0000 Subject: [PATCH 30/39] updating network_features back to computed=true --- internal/services/netapp/README.md | 20 ++++++++++++++++++- .../netapp_volume_group_oracle_resource.go | 1 + .../services/netapp/netapp_volume_resource.go | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/internal/services/netapp/README.md b/internal/services/netapp/README.md index a3daaf3b1e18..85a2cce45839 100644 --- a/internal/services/netapp/README.md +++ b/internal/services/netapp/README.md @@ -120,4 +120,22 @@ backupPolicyIdRemoval := volumes.VolumePatch{ }, }, } -``` \ No newline at end of file +``` + +## `Computed` attribute of a few configuration items + +- Azure NetApp Files resources are complex enough on the backend and a few configuration items must remain in `computed = true` state and not changed under any circumstance, otherwise, if it is a `ForceNew = true` type of configuration, it may result in data loss. The best example of this is the configuration called `network_features`, this must be `computed = true` at all times, Azure NetApp Files team will soon make changes to networking that will make the property `network_features` be changed from `basic` to `standard` and to prevent data loss, this configuration should stay as is, with `computed = true` set. + +```golang +"network_features": { + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + Default: string(volumes.NetworkFeaturesBasic), + ValidateFunc: validation.StringInSlice([]string{ + string(volumes.NetworkFeaturesBasic), + string(volumes.NetworkFeaturesStandard), + }, false), +}, +``` + diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource.go b/internal/services/netapp/netapp_volume_group_oracle_resource.go index 5c38626fc069..c0b3ec5cc0d8 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource.go @@ -274,6 +274,7 @@ func (r NetAppVolumeGroupOracleResource) Arguments() map[string]*pluginsdk.Schem Type: pluginsdk.TypeString, Optional: true, Default: "Basic", + Computed: true, ValidateFunc: validation.StringInSlice(volumegroups.PossibleValuesForNetworkFeatures(), false), }, }, diff --git a/internal/services/netapp/netapp_volume_resource.go b/internal/services/netapp/netapp_volume_resource.go index cd8a623c7ec3..ee1620b03bf5 100644 --- a/internal/services/netapp/netapp_volume_resource.go +++ b/internal/services/netapp/netapp_volume_resource.go @@ -111,6 +111,7 @@ func resourceNetAppVolume() *pluginsdk.Resource { "network_features": { Type: pluginsdk.TypeString, Optional: true, + Computed: true, Default: string(volumes.NetworkFeaturesBasic), ValidateFunc: validation.StringInSlice([]string{ string(volumes.NetworkFeaturesBasic), From b78282181861e36688caf08161ce9d646d39f654 Mon Sep 17 00:00:00 2001 From: Paulo Costa Date: Fri, 27 Dec 2024 23:57:12 +0000 Subject: [PATCH 31/39] Removing comments and extra logs --- .../netapp/netapp_snapshot_policy_resource.go | 121 +----------------- 1 file changed, 3 insertions(+), 118 deletions(-) diff --git a/internal/services/netapp/netapp_snapshot_policy_resource.go b/internal/services/netapp/netapp_snapshot_policy_resource.go index fb390eb12071..400e8b149bda 100644 --- a/internal/services/netapp/netapp_snapshot_policy_resource.go +++ b/internal/services/netapp/netapp_snapshot_policy_resource.go @@ -342,97 +342,6 @@ func resourceNetAppSnapshotPolicyRead(d *pluginsdk.ResourceData, meta interface{ return nil } -// func resourceNetAppSnapshotPolicyDelete(d *pluginsdk.ResourceData, meta interface{}) error { -// client := meta.(*clients.Client).NetApp.SnapshotPoliciesClient -// ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) -// defer cancel() - -// id, err := snapshotpolicy.ParseSnapshotPolicyID(d.Id()) -// if err != nil { -// return err -// } - -// // Deleting snapshot policy and waiting for it fo fully complete the operation -// if err = client.SnapshotPoliciesDeleteThenPoll(ctx, *id); err != nil { -// return fmt.Errorf("deleting %s: %+v", id, err) -// } - -// log.Printf("[DEBUG] Waiting for %s to be deleted", id) -// if err := waitForSnapshotPolicyDeletion(ctx, client, *id, d.Timeout(pluginsdk.TimeoutDelete)); err != nil { -// return err -// } - -// return nil -// } - -// func resourceNetAppSnapshotPolicyDelete(d *pluginsdk.ResourceData, meta interface{}) error { -// client := meta.(*clients.Client).NetApp.SnapshotPoliciesClient -// volumeClient := meta.(*clients.Client).NetApp.VolumeClient -// ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) -// defer cancel() - -// id, err := snapshotpolicy.ParseSnapshotPolicyID(d.Id()) -// if err != nil { -// return err -// } - -// // Try to delete the snapshot policy -// result, err := client.SnapshotPoliciesDelete(ctx, *id) - -// if err != nil { -// // Check if error is 409 with message about being used by volumes -// if result.HttpResponse != nil && result.HttpResponse.StatusCode == 409 && strings.Contains(err.Error(), "SnapshotPolicy is used") { -// // Get all volumes in the account that might be using this snapshot policy -// volumeIds, err := findVolumesUsingSnapshotPolicy(ctx, meta.(*clients.Client), *id) -// if err != nil { -// return fmt.Errorf("finding volumes using snapshot policy %s: %+v", *id, err) -// } - -// // Disassociate snapshot policy from each volume -// for _, volumeId := range volumeIds { -// volId, err := volumes.ParseVolumeID(volumeId) -// if err != nil { -// return fmt.Errorf("parsing volume ID %q: %+v", volumeId, err) -// } - -// // Update volume to remove snapshot policy -// update := volumes.VolumePatch{ -// Properties: &volumes.VolumePatchProperties{ -// DataProtection: &volumes.VolumePatchPropertiesDataProtection{ -// Snapshot: &volumes.VolumeSnapshotProperties{ -// SnapshotPolicyId: nil, -// }, -// }, -// }, -// } - -// if err = volumeClient.UpdateThenPoll(ctx, *volId, update); err != nil { -// return fmt.Errorf("removing snapshot policy from volume %s: %+v", *volId, err) -// } - -// // Wait for the update to complete -// if err := waitForVolumeCreateOrUpdate(ctx, volumeClient, *volId); err != nil { -// return fmt.Errorf("waiting for snapshot policy removal from volume %s: %+v", *volId, err) -// } -// } - -// // Try deleting the snapshot policy again using DeleteThenPoll -// if err = client.SnapshotPoliciesDeleteThenPoll(ctx, *id); err != nil { -// return fmt.Errorf("deleting %s after volume disassociation: %+v", *id, err) -// } -// } else { -// return fmt.Errorf("deleting %s: %+v", *id, err) -// } -// } - -// log.Printf("[DEBUG] Waiting for %s to be deleted", *id) -// if err := waitForSnapshotPolicyDeletion(ctx, client, *id, d.Timeout(pluginsdk.TimeoutDelete)); err != nil { -// return err -// } - -// return nil -// } - func resourceNetAppSnapshotPolicyDelete(d *pluginsdk.ResourceData, meta interface{}) error { client := meta.(*clients.Client).NetApp.SnapshotPoliciesClient volumeClient := meta.(*clients.Client).NetApp.VolumeClient @@ -444,32 +353,24 @@ func resourceNetAppSnapshotPolicyDelete(d *pluginsdk.ResourceData, meta interfac return err } - log.Printf("[INFO] Attempting to delete Snapshot Policy %s", *id) // Try to delete the snapshot policy using DeleteThenPoll err = client.SnapshotPoliciesDeleteThenPoll(ctx, *id) if err != nil { // Check if error is about snapshot policy being in use if strings.Contains(err.Error(), "SnapshotPolicy is used") { - log.Printf("[INFO] Snapshot Policy %s is in use, finding volumes using this policy...", *id) - // Get all volumes in the account that might be using this snapshot policy volumeIds, err := findVolumesUsingSnapshotPolicy(ctx, meta.(*clients.Client), *id) if err != nil { return fmt.Errorf("finding volumes using snapshot policy %s: %+v", *id, err) } - log.Printf("[INFO] Found %d volumes using Snapshot Policy %s", len(volumeIds), *id) - // Disassociate snapshot policy from each volume - for i, volumeId := range volumeIds { - log.Printf("[INFO] Processing volume %d of %d: %s", i+1, len(volumeIds), volumeId) - + for _, volumeId := range volumeIds { volId, err := volumes.ParseVolumeID(volumeId) if err != nil { return fmt.Errorf("parsing volume ID %q: %+v", volumeId, err) } - log.Printf("[INFO] Removing snapshot policy from volume %s", *volId) // Update volume to remove snapshot policy update := volumes.VolumePatch{ Properties: &volumes.VolumePatchProperties{ @@ -488,7 +389,6 @@ func resourceNetAppSnapshotPolicyDelete(d *pluginsdk.ResourceData, meta interfac return fmt.Errorf("removing snapshot policy from volume %s: %+v", *volId, err) } - log.Printf("[INFO] Waiting for snapshot policy removal to complete for volume %s", *volId) // Wait for the update to complete if err := waitForVolumeCreateOrUpdate(ctx, volumeClient, *volId); err != nil { locks.UnlockByID(volumeId) @@ -498,7 +398,6 @@ func resourceNetAppSnapshotPolicyDelete(d *pluginsdk.ResourceData, meta interfac locks.UnlockByID(volumeId) } - log.Printf("[INFO] All volumes processed, attempting to delete Snapshot Policy %s again", *id) // Try deleting the snapshot policy again if err = client.SnapshotPoliciesDeleteThenPoll(ctx, *id); err != nil { return fmt.Errorf("deleting %s after volume disassociation: %+v", *id, err) @@ -508,25 +407,18 @@ func resourceNetAppSnapshotPolicyDelete(d *pluginsdk.ResourceData, meta interfac } } - log.Printf("[INFO] Waiting for final confirmation of deletion for Snapshot Policy %s", *id) if err := waitForSnapshotPolicyDeletion(ctx, client, *id, d.Timeout(pluginsdk.TimeoutDelete)); err != nil { return err } - log.Printf("[INFO] Successfully deleted Snapshot Policy %s", *id) return nil } func findVolumesUsingSnapshotPolicy(ctx context.Context, client *clients.Client, snapshotPolicyId snapshotpolicy.SnapshotPolicyId) ([]string, error) { - const logPrefix = "[findVolumesUsingSnapshotPolicy]" - log.Printf("[INFO] %s Starting search for volumes using snapshot policy %s", logPrefix, snapshotPolicyId.ID()) - volumeIds := make([]string, 0) - poolClient := client.NetApp.PoolClient accountId := capacitypools.NewNetAppAccountID(snapshotPolicyId.SubscriptionId, snapshotPolicyId.ResourceGroupName, snapshotPolicyId.NetAppAccountName) - log.Printf("[INFO] %s Listing capacity pools in account %s", logPrefix, snapshotPolicyId.NetAppAccountName) poolsResult, err := poolClient.PoolsList(ctx, accountId) if err != nil { return nil, fmt.Errorf("listing capacity pools in account %s: %+v", snapshotPolicyId.NetAppAccountName, err) @@ -534,27 +426,22 @@ func findVolumesUsingSnapshotPolicy(ctx context.Context, client *clients.Client, if model := poolsResult.Model; model != nil { volumeClient := client.NetApp.VolumeClient - log.Printf("[INFO] %s Found %d pools to check", logPrefix, len(*model)) - for i, pool := range *model { + for _, pool := range *model { if pool.Name == nil { continue } poolNameParts := strings.Split(pointer.From(pool.Name), "/") poolName := poolNameParts[len(poolNameParts)-1] - - log.Printf("[INFO] %s Processing pool %d of %d: %s", logPrefix, i+1, len(*model), poolName) - volumeId := volumes.NewCapacityPoolID(snapshotPolicyId.SubscriptionId, snapshotPolicyId.ResourceGroupName, snapshotPolicyId.NetAppAccountName, poolName) + volumesResult, err := volumeClient.List(ctx, volumeId) if err != nil { return nil, fmt.Errorf("listing volumes in pool %s: %+v", poolName, err) } if volumesModel := volumesResult.Model; volumesModel != nil { - log.Printf("[INFO] %s Found %d volumes in pool %s", logPrefix, len(*volumesModel), poolName) - for _, volume := range *volumesModel { if volume.Id == nil || volume.Properties.DataProtection == nil || volume.Properties.DataProtection.Snapshot == nil || volume.Properties.DataProtection.Snapshot.SnapshotPolicyId == nil { @@ -562,7 +449,6 @@ func findVolumesUsingSnapshotPolicy(ctx context.Context, client *clients.Client, } if strings.EqualFold(*volume.Properties.DataProtection.Snapshot.SnapshotPolicyId, snapshotPolicyId.ID()) { - log.Printf("[INFO] %s Found volume using the snapshot policy: %s", logPrefix, *volume.Id) volumeIds = append(volumeIds, *volume.Id) } } @@ -570,7 +456,6 @@ func findVolumesUsingSnapshotPolicy(ctx context.Context, client *clients.Client, } } - log.Printf("[INFO] %s Completed search, found %d volumes using the snapshot policy", logPrefix, len(volumeIds)) return volumeIds, nil } From 2e46e8f14c74bfafcc50137d71e8b836bc922adc Mon Sep 17 00:00:00 2001 From: Paulo Costa Date: Sat, 28 Dec 2024 00:26:06 +0000 Subject: [PATCH 32/39] fixing linting issues --- .../services/netapp/netapp_volume_group_oracle_resource.go | 3 --- internal/services/netapp/netapp_volume_helper.go | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource.go b/internal/services/netapp/netapp_volume_group_oracle_resource.go index c0b3ec5cc0d8..34dea872b3b9 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource.go @@ -273,7 +273,6 @@ func (r NetAppVolumeGroupOracleResource) Arguments() map[string]*pluginsdk.Schem "network_features": { Type: pluginsdk.TypeString, Optional: true, - Default: "Basic", Computed: true, ValidateFunc: validation.StringInSlice(volumegroups.PossibleValuesForNetworkFeatures(), false), }, @@ -369,9 +368,7 @@ func (r NetAppVolumeGroupOracleResource) Update() sdk.ResourceFunc { metadata.Logger.Infof("Updating %s", id) if metadata.ResourceData.HasChange("volume") { - // Iterating over each volume and performing individual patch for i := 0; i < metadata.ResourceData.Get("volume.#").(int); i++ { - // Checking if individual volume has a change volumeItem := fmt.Sprintf("volume.%v", i) diff --git a/internal/services/netapp/netapp_volume_helper.go b/internal/services/netapp/netapp_volume_helper.go index b9f43dff02d8..77b2f061085d 100644 --- a/internal/services/netapp/netapp_volume_helper.go +++ b/internal/services/netapp/netapp_volume_helper.go @@ -717,7 +717,7 @@ func deleteVolume(ctx context.Context, metadata sdk.ResourceMetaData, volumeId s // Wait for the volume update to complete log.Printf("[INFO] Wait for the volume update to complete after unsetting snapshot policy") - if err := waitForVolumeCreateOrUpdate(ctx, client, volumes.VolumeId(pointer.From(id))); err != nil { + if err := waitForVolumeCreateOrUpdate(ctx, client, pointer.From(id)); err != nil { return fmt.Errorf("waiting for volume to reflect snapshotPolicyId unset from %q: %+v", pointer.From(id), err) } } From 2e4ae6e9e3065e7136c890debac4e045b535b8b2 Mon Sep 17 00:00:00 2001 From: Paulo Costa Date: Sat, 28 Dec 2024 00:26:52 +0000 Subject: [PATCH 33/39] Making network feature required --- .../netapp/netapp_volume_group_oracle_resource.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource.go b/internal/services/netapp/netapp_volume_group_oracle_resource.go index 34dea872b3b9..555b8da951cb 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource.go @@ -230,6 +230,13 @@ func (r NetAppVolumeGroupOracleResource) Arguments() map[string]*pluginsdk.Schem ForceNew: true, }, + "network_features": { + Type: pluginsdk.TypeString, + Required: true, + Computed: true, + ValidateFunc: validation.StringInSlice(volumegroups.PossibleValuesForNetworkFeatures(), false), + }, + "mount_ip_addresses": { Type: pluginsdk.TypeList, Computed: true, @@ -269,13 +276,6 @@ func (r NetAppVolumeGroupOracleResource) Arguments() map[string]*pluginsdk.Schem Computed: true, ValidateFunc: azure.ValidateResourceID, }, - - "network_features": { - Type: pluginsdk.TypeString, - Optional: true, - Computed: true, - ValidateFunc: validation.StringInSlice(volumegroups.PossibleValuesForNetworkFeatures(), false), - }, }, }, }, From 57d7ed68698cbb6d9fe43fe970dd5b7735a3ceaf Mon Sep 17 00:00:00 2001 From: Paulo Costa Date: Sat, 28 Dec 2024 00:29:55 +0000 Subject: [PATCH 34/39] Making network_features required --- .../netapp/netapp_volume_group_oracle_resource_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index b86ee6ead25f..f38adaa63bdb 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -188,6 +188,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { protocols = ["NFSv4.1"] security_style = "unix" snapshot_directory_visible = false + network_features = "Standard" export_policy_rule { rule_index = 1 @@ -218,6 +219,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { protocols = ["NFSv4.1"] security_style = "unix" snapshot_directory_visible = false + network_features = "Standard" export_policy_rule { rule_index = 1 @@ -264,6 +266,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { protocols = ["NFSv4.1"] security_style = "unix" snapshot_directory_visible = false + network_features = "Basic" export_policy_rule { rule_index = 1 @@ -294,6 +297,7 @@ resource "azurerm_netapp_volume_group_oracle" "test" { protocols = ["NFSv4.1"] security_style = "unix" snapshot_directory_visible = false + network_features = "Basic" export_policy_rule { rule_index = 1 From fc23b01e21f73d44576d82e9e74d2aa0e535b794 Mon Sep 17 00:00:00 2001 From: Paulo Costa Date: Sat, 28 Dec 2024 01:08:16 +0000 Subject: [PATCH 35/39] updating network addresses --- .../netapp_volume_group_oracle_resource.go | 5 +++-- ...netapp_volume_group_oracle_resource_test.go | 6 +++--- ...tapp_volume_group_sap_hana_resource_test.go | 12 ++++++------ .../netapp_volume_quota_rule_resource_test.go | 4 ++-- .../netapp/netapp_volume_resource_test.go | 18 +++++++++--------- .../r/netapp_volume_group_oracle.html.markdown | 4 ++-- .../netapp_volume_group_sap_hana.html.markdown | 6 +++--- ...ware_netapp_volume_attachment.html.markdown | 6 +++--- 8 files changed, 31 insertions(+), 30 deletions(-) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource.go b/internal/services/netapp/netapp_volume_group_oracle_resource.go index 555b8da951cb..700f6b49e7a9 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource.go @@ -232,8 +232,9 @@ func (r NetAppVolumeGroupOracleResource) Arguments() map[string]*pluginsdk.Schem "network_features": { Type: pluginsdk.TypeString, - Required: true, - Computed: true, + Optional: true, + Computed: true, // O+C - This is Optional/Computed because the service team is changing network features on the backend to upgrade everyone from Basic to Standard and there is a feature that allows customers to change network features from portal but not the API. This could cause drift that forces data loss that we want to avoid + Default: string(volumes.NetworkFeaturesBasic), ValidateFunc: validation.StringInSlice(volumegroups.PossibleValuesForNetworkFeatures(), false), }, diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go index f38adaa63bdb..1c85185dc30b 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource_test.go @@ -797,7 +797,7 @@ resource "azurerm_virtual_network" "test" { name = "acctest-VirtualNetwork-%[1]d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name - address_space = ["10.6.0.0/16"] + address_space = ["10.88.0.0/16"] tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", @@ -809,7 +809,7 @@ resource "azurerm_subnet" "test-delegated" { name = "acctest-Delegated-Subnet-%[1]d" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test.name - address_prefixes = ["10.6.1.0/24"] + address_prefixes = ["10.88.1.0/24"] delegation { name = "testdelegation" @@ -825,7 +825,7 @@ resource "azurerm_subnet" "test-non-delegated" { name = "acctest-Non-Delegated-Subnet-%[1]d" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test.name - address_prefixes = ["10.6.0.0/24"] + address_prefixes = ["10.88.0.0/24"] } resource "azurerm_private_endpoint" "test" { diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go index 7df6455e7f59..fd2a374dad3d 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource_test.go @@ -1062,7 +1062,7 @@ resource "azurerm_virtual_network" "test_secondary" { name = "acctest-VirtualNetwork-Secondary-%[2]d" location = "%[3]s" resource_group_name = azurerm_resource_group.test.name - address_space = ["10.6.0.0/16"] + address_space = ["10.88.0.0/16"] tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", @@ -1074,7 +1074,7 @@ resource "azurerm_subnet" "test_secondary" { name = "acctest-DelegatedSubnet-%[2]d" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test_secondary.name - address_prefixes = ["10.6.2.0/24"] + address_prefixes = ["10.88.2.0/24"] delegation { name = "testdelegation" @@ -1090,7 +1090,7 @@ resource "azurerm_subnet" "test1_secondary" { name = "acctest-HostsSubnet-%[2]d" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test_secondary.name - address_prefixes = ["10.6.1.0/24"] + address_prefixes = ["10.88.1.0/24"] } resource "azurerm_subnet_network_security_group_association" "test_secondary" { @@ -1270,7 +1270,7 @@ resource "azurerm_virtual_network" "test" { name = "acctest-VirtualNetwork-%[1]d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name - address_space = ["10.6.0.0/16"] + address_space = ["10.88.0.0/16"] tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", @@ -1282,7 +1282,7 @@ resource "azurerm_subnet" "test" { name = "acctest-DelegatedSubnet-%[1]d" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test.name - address_prefixes = ["10.6.2.0/24"] + address_prefixes = ["10.88.2.0/24"] delegation { name = "testdelegation" @@ -1298,7 +1298,7 @@ resource "azurerm_subnet" "test1" { name = "acctest-HostsSubnet-%[1]d" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test.name - address_prefixes = ["10.6.1.0/24"] + address_prefixes = ["10.88.1.0/24"] } resource "azurerm_subnet_network_security_group_association" "public" { diff --git a/internal/services/netapp/netapp_volume_quota_rule_resource_test.go b/internal/services/netapp/netapp_volume_quota_rule_resource_test.go index 06f9ad3405b9..0af5ac656111 100644 --- a/internal/services/netapp/netapp_volume_quota_rule_resource_test.go +++ b/internal/services/netapp/netapp_volume_quota_rule_resource_test.go @@ -198,7 +198,7 @@ resource "azurerm_virtual_network" "test" { name = "acctest-VirtualNetwork-%[1]d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name - address_space = ["10.6.0.0/16"] + address_space = ["10.88.0.0/16"] tags = { "CreatedOnDate" = "2023-08-17T08:01:00Z", @@ -210,7 +210,7 @@ resource "azurerm_subnet" "test" { name = "acctest-DelegatedSubnet-%[1]d" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test.name - address_prefixes = ["10.6.2.0/24"] + address_prefixes = ["10.88.2.0/24"] delegation { name = "testdelegation" diff --git a/internal/services/netapp/netapp_volume_resource_test.go b/internal/services/netapp/netapp_volume_resource_test.go index b71ef80213d6..58008022d12d 100644 --- a/internal/services/netapp/netapp_volume_resource_test.go +++ b/internal/services/netapp/netapp_volume_resource_test.go @@ -1218,7 +1218,7 @@ resource "azurerm_virtual_network" "test_secondary" { name = "acctest-VirtualNetwork-secondary-%[2]d" location = "%[3]s" resource_group_name = azurerm_resource_group.test.name - address_space = ["10.6.0.0/16"] + address_space = ["10.88.0.0/16"] tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", @@ -1230,7 +1230,7 @@ resource "azurerm_subnet" "test_secondary" { name = "acctest-Subnet-secondary-%[2]d" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test_secondary.name - address_prefixes = ["10.6.2.0/24"] + address_prefixes = ["10.88.2.0/24"] delegation { name = "testdelegation" @@ -1289,7 +1289,7 @@ resource "azurerm_virtual_network" "test" { name = "acctest-VirtualNetwork-%d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name - address_space = ["10.6.0.0/16"] + address_space = ["10.88.0.0/16"] tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", @@ -1301,7 +1301,7 @@ resource "azurerm_subnet" "test" { name = "acctest-Subnet-%d" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test.name - address_prefixes = ["10.6.2.0/24"] + address_prefixes = ["10.88.2.0/24"] delegation { name = "testdelegation" @@ -1372,7 +1372,7 @@ resource "azurerm_virtual_network" "test" { name = "acctest-VirtualNetwork-%d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name - address_space = ["10.6.0.0/16"] + address_space = ["10.88.0.0/16"] tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", @@ -1384,7 +1384,7 @@ resource "azurerm_subnet" "test" { name = "acctest-Subnet-%d" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test.name - address_prefixes = ["10.6.2.0/24"] + address_prefixes = ["10.88.2.0/24"] delegation { name = "testdelegation" @@ -1430,7 +1430,7 @@ resource "azurerm_virtual_network" "test" { name = "acctest-VirtualNetwork-%[1]d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name - address_space = ["10.6.0.0/16"] + address_space = ["10.88.0.0/16"] tags = { "CreatedOnDate" = "2022-07-08T23:50:21Z", @@ -1442,7 +1442,7 @@ resource "azurerm_subnet" "test-delegated" { name = "acctest-Delegated-Subnet-%[1]d" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test.name - address_prefixes = ["10.6.1.0/24"] + address_prefixes = ["10.88.1.0/24"] delegation { name = "testdelegation" @@ -1458,7 +1458,7 @@ resource "azurerm_subnet" "test-non-delegated" { name = "acctest-Non-Delegated-Subnet-%[1]d" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test.name - address_prefixes = ["10.6.0.0/24"] + address_prefixes = ["10.88.0.0/24"] } `, data.RandomInteger) } diff --git a/website/docs/r/netapp_volume_group_oracle.html.markdown b/website/docs/r/netapp_volume_group_oracle.html.markdown index 48e31602c63a..0a71b342e301 100644 --- a/website/docs/r/netapp_volume_group_oracle.html.markdown +++ b/website/docs/r/netapp_volume_group_oracle.html.markdown @@ -36,14 +36,14 @@ resource "azurerm_virtual_network" "example" { name = "${var.prefix}-vnet" location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name - address_space = ["10.6.0.0/16"] + address_space = ["10.88.0.0/16"] } resource "azurerm_subnet" "example" { name = "${var.prefix}-delegated-subnet" resource_group_name = azurerm_resource_group.example.name virtual_network_name = azurerm_virtual_network.example.name - address_prefixes = ["10.6.2.0/24"] + address_prefixes = ["10.88.2.0/24"] delegation { name = "exampledelegation" diff --git a/website/docs/r/netapp_volume_group_sap_hana.html.markdown b/website/docs/r/netapp_volume_group_sap_hana.html.markdown index 178b502ffdd5..9616d45de6a2 100644 --- a/website/docs/r/netapp_volume_group_sap_hana.html.markdown +++ b/website/docs/r/netapp_volume_group_sap_hana.html.markdown @@ -42,14 +42,14 @@ resource "azurerm_virtual_network" "example" { name = "${var.prefix}-vnet" location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name - address_space = ["10.6.0.0/16"] + address_space = ["10.88.0.0/16"] } resource "azurerm_subnet" "example" { name = "${var.prefix}-delegated-subnet" resource_group_name = azurerm_resource_group.example.name virtual_network_name = azurerm_virtual_network.example.name - address_prefixes = ["10.6.2.0/24"] + address_prefixes = ["10.88.2.0/24"] delegation { name = "testdelegation" @@ -65,7 +65,7 @@ resource "azurerm_subnet" "example1" { name = "${var.prefix}-hosts-subnet" resource_group_name = azurerm_resource_group.example.name virtual_network_name = azurerm_virtual_network.example.name - address_prefixes = ["10.6.1.0/24"] + address_prefixes = ["10.88.1.0/24"] } resource "azurerm_proximity_placement_group" "example" { diff --git a/website/docs/r/vmware_netapp_volume_attachment.html.markdown b/website/docs/r/vmware_netapp_volume_attachment.html.markdown index cc05170ddeaf..72dfaa8d32f4 100644 --- a/website/docs/r/vmware_netapp_volume_attachment.html.markdown +++ b/website/docs/r/vmware_netapp_volume_attachment.html.markdown @@ -37,14 +37,14 @@ resource "azurerm_virtual_network" "test" { name = "example-VirtualNetwork" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name - address_space = ["10.6.0.0/16"] + address_space = ["10.88.0.0/16"] } resource "azurerm_subnet" "netappSubnet" { name = "example-Subnet" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test.name - address_prefixes = ["10.6.2.0/24"] + address_prefixes = ["10.88.2.0/24"] delegation { name = "testdelegation" @@ -60,7 +60,7 @@ resource "azurerm_subnet" "gatewaySubnet" { name = "GatewaySubnet" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test.name - address_prefixes = ["10.6.1.0/24"] + address_prefixes = ["10.88.1.0/24"] } resource "azurerm_virtual_network_gateway" "test" { From 3b5a8b3b6666754250a55204396a2c3e273c43be Mon Sep 17 00:00:00 2001 From: Paulo Costa Date: Sat, 28 Dec 2024 01:10:21 +0000 Subject: [PATCH 36/39] updating O+C comment --- internal/services/netapp/netapp_volume_group_oracle_resource.go | 2 +- .../services/netapp/netapp_volume_group_sap_hana_resource.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource.go b/internal/services/netapp/netapp_volume_group_oracle_resource.go index 700f6b49e7a9..e19d718d85bc 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource.go @@ -249,7 +249,7 @@ func (r NetAppVolumeGroupOracleResource) Arguments() map[string]*pluginsdk.Schem "data_protection_snapshot_policy": { Type: pluginsdk.TypeList, Optional: true, - Computed: true, // Adding this because Terraform is not being able to build proper deletion graph, it is trying to delete the snapshot policy before the volume because this is in a deeper level within the schema + Computed: true, // O+C - Adding this because Terraform is not being able to build proper deletion graph, it is trying to delete the snapshot policy before the volume because this is in a deeper level within the schema inside an array of volumes MaxItems: 1, Elem: &pluginsdk.Resource{ Schema: map[string]*pluginsdk.Schema{ diff --git a/internal/services/netapp/netapp_volume_group_sap_hana_resource.go b/internal/services/netapp/netapp_volume_group_sap_hana_resource.go index cf383da1abe0..10fa9cb6507e 100644 --- a/internal/services/netapp/netapp_volume_group_sap_hana_resource.go +++ b/internal/services/netapp/netapp_volume_group_sap_hana_resource.go @@ -274,7 +274,7 @@ func (r NetAppVolumeGroupSAPHanaResource) Arguments() map[string]*pluginsdk.Sche "data_protection_snapshot_policy": { Type: pluginsdk.TypeList, Optional: true, - Computed: true, // Adding this because Terraform is not being able to build proper deletion graph, it is trying to delete the snapshot policy before the volume because this is in a deeper level within the schema + Computed: true, // O+C - Adding this because Terraform is not being able to build proper deletion graph, it is trying to delete the snapshot policy before the volume because this is in a deeper level within the schema inside an array of volumes MaxItems: 1, Elem: &pluginsdk.Resource{ Schema: map[string]*pluginsdk.Schema{ From f02e13d72491fee411656fe014701e269c355c4d Mon Sep 17 00:00:00 2001 From: Paulo Costa Date: Sat, 28 Dec 2024 16:45:21 +0000 Subject: [PATCH 37/39] Adding computed back and comment about it --- .../services/netapp/netapp_volume_group_oracle_resource.go | 1 - internal/services/netapp/netapp_volume_resource.go | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/services/netapp/netapp_volume_group_oracle_resource.go b/internal/services/netapp/netapp_volume_group_oracle_resource.go index e19d718d85bc..0d6ca9968a8b 100644 --- a/internal/services/netapp/netapp_volume_group_oracle_resource.go +++ b/internal/services/netapp/netapp_volume_group_oracle_resource.go @@ -234,7 +234,6 @@ func (r NetAppVolumeGroupOracleResource) Arguments() map[string]*pluginsdk.Schem Type: pluginsdk.TypeString, Optional: true, Computed: true, // O+C - This is Optional/Computed because the service team is changing network features on the backend to upgrade everyone from Basic to Standard and there is a feature that allows customers to change network features from portal but not the API. This could cause drift that forces data loss that we want to avoid - Default: string(volumes.NetworkFeaturesBasic), ValidateFunc: validation.StringInSlice(volumegroups.PossibleValuesForNetworkFeatures(), false), }, diff --git a/internal/services/netapp/netapp_volume_resource.go b/internal/services/netapp/netapp_volume_resource.go index ee1620b03bf5..105d417c97af 100644 --- a/internal/services/netapp/netapp_volume_resource.go +++ b/internal/services/netapp/netapp_volume_resource.go @@ -111,8 +111,7 @@ func resourceNetAppVolume() *pluginsdk.Resource { "network_features": { Type: pluginsdk.TypeString, Optional: true, - Computed: true, - Default: string(volumes.NetworkFeaturesBasic), + Computed: true, // O+C - This is Optional/Computed because the service team is changing network features on the backend to upgrade everyone from Basic to Standard and there is a feature that allows customers to change network features from portal but not the API. This could cause drift that forces data loss that we want to avoid ValidateFunc: validation.StringInSlice([]string{ string(volumes.NetworkFeaturesBasic), string(volumes.NetworkFeaturesStandard), From e05a0f807cfb5ec136f1887e1c1f7f089757645b Mon Sep 17 00:00:00 2001 From: Paulo Marques Date: Thu, 9 Jan 2025 17:18:03 -0700 Subject: [PATCH 38/39] Update website/docs/r/netapp_volume_group_oracle.html.markdown Co-authored-by: Matthew Frahry --- website/docs/r/netapp_volume_group_oracle.html.markdown | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/docs/r/netapp_volume_group_oracle.html.markdown b/website/docs/r/netapp_volume_group_oracle.html.markdown index 0a71b342e301..1fc41caf3e76 100644 --- a/website/docs/r/netapp_volume_group_oracle.html.markdown +++ b/website/docs/r/netapp_volume_group_oracle.html.markdown @@ -164,7 +164,9 @@ A `volume` block supports the following: * `protocols` - (Required) The target volume protocol expressed as a list. Changing this forces a new Application Volume Group to be created and data will be lost. Supported values for Application Volume Group include `NFSv3` or `NFSv4.1`. -* `proximity_placement_group_id` - (Optional) The ID of the proximity placement group (PPG). Changing this forces a new Application Volume Group to be created and data will be lost. For Oracle application, it is required to have PPG enabled so Azure NetApp Files can pin the volumes next to your compute resources, please check [Requirements and considerations for application volume group for Oracle](https://learn.microsoft.com/en-us/azure/azure-netapp-files/application-volume-group-oracle-considerations) for details and other requirements. Note that this cannot be used together with `zone`. +* `proximity_placement_group_id` - (Optional) The ID of the proximity placement group (PPG). Changing this forces a new Application Volume Group to be created and data will be lost. + +~> **NOTE**: For Oracle application, it is required to have PPG enabled so Azure NetApp Files can pin the volumes next to your compute resources, please check [Requirements and considerations for application volume group for Oracle](https://learn.microsoft.com/en-us/azure/azure-netapp-files/application-volume-group-oracle-considerations) for details and other requirements. Note that this cannot be used together with `zone`. * `zone` - (Optional) Specifies the Availability Zone in which the Volume should be located. Possible values are `1`, `2` and `3`, depending on the Azure region. Changing this forces a new resource to be created. This feature is currently in preview, for more information on how to enable it, please refer to [Manage availability zone volume placement for Azure NetApp Files](https://learn.microsoft.com/en-us/azure/azure-netapp-files/manage-availability-zone-volume-placement). Note that this cannot be used together with `proximity_placement_group_id`. From 5123fb4c397fd5006f8266e4e2907167ff60832f Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 10 Jan 2025 00:22:25 +0000 Subject: [PATCH 39/39] Removing not-needed deeper validations --- .../validate/volume_group_oracle_volumes_validation.go | 10 ---------- .../volume_group_sap_hana_volumes_validation.go | 10 ---------- 2 files changed, 20 deletions(-) diff --git a/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go b/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go index 15fd4c46392b..25038ad587a3 100644 --- a/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go +++ b/internal/services/netapp/validate/volume_group_oracle_volumes_validation.go @@ -68,11 +68,6 @@ func ValidateNetAppVolumeGroupOracleVolumes(volumeList *[]volumegroups.VolumeGro volumeSpecRepeatCount := make(map[string]int) applicationType := string(volumegroups.ApplicationTypeORACLE) - // Validating minimum volume count - if len(*volumeList) < len(RequiredVolumesForOracle()) { - errors = append(errors, fmt.Errorf("'minimum %v volumes are required for %v'", len(RequiredVolumesForOracle()), applicationType)) - } - // Validating each volume for _, volume := range pointer.From(volumeList) { // Get protocol list @@ -84,11 +79,6 @@ func ValidateNetAppVolumeGroupOracleVolumes(volumeList *[]volumegroups.VolumeGro errors = append(errors, fmt.Errorf("'protocol type list cannot be empty'")) } - // Validate protocol list is not > 1 - if len(protocolTypeList) > 1 { - errors = append(errors, fmt.Errorf("'multi-protocol volumes are not supported, protocol count is %v'", len(protocolTypeList))) - } - // Getting protocol for next validations if len(protocolTypeList) > 0 { protocolType = protocolTypeList[0] diff --git a/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation.go b/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation.go index f04c73279ade..2946afaaa478 100644 --- a/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation.go +++ b/internal/services/netapp/validate/volume_group_sap_hana_volumes_validation.go @@ -50,11 +50,6 @@ func ValidateNetAppVolumeGroupSAPHanaVolumes(volumeList *[]volumegroups.VolumeGr volumeSpecRepeatCount := make(map[string]int) applicationType := string(volumegroups.ApplicationTypeSAPNegativeHANA) - // Validating minimum volume count - if len(*volumeList) < len(RequiredVolumesForSAPHANA()) { - errors = append(errors, fmt.Errorf("'minimum %v volumes are required for %v'", len(RequiredVolumesForSAPHANA()), applicationType)) - } - // Validating each volume for _, volume := range pointer.From(volumeList) { // Get protocol list @@ -66,11 +61,6 @@ func ValidateNetAppVolumeGroupSAPHanaVolumes(volumeList *[]volumegroups.VolumeGr errors = append(errors, fmt.Errorf("'protocol type list cannot be empty'")) } - // Validate protocol list is not > 1 - if len(protocolTypeList) > 1 { - errors = append(errors, fmt.Errorf("'multi-protocol volumes are not supported, protocol count is %v'", len(protocolTypeList))) - } - // Getting protocol for next validations if len(protocolTypeList) > 0 { protocolType = protocolTypeList[0]