From d475c367283795341debf269f22e3e7b65e254e0 Mon Sep 17 00:00:00 2001 From: Malcolm Morgan Date: Mon, 22 Jan 2024 15:38:18 -0800 Subject: [PATCH 1/4] Implemented smb_non_browsable_enabled and smb_access_based_enumeration_enabled for create and update volume operations --- .../services/netapp/netapp_volume_resource.go | 74 +++++++++++++++---- 1 file changed, 60 insertions(+), 14 deletions(-) diff --git a/internal/services/netapp/netapp_volume_resource.go b/internal/services/netapp/netapp_volume_resource.go index 22606346a139..0fe96c55e729 100644 --- a/internal/services/netapp/netapp_volume_resource.go +++ b/internal/services/netapp/netapp_volume_resource.go @@ -119,6 +119,18 @@ func resourceNetAppVolume() *pluginsdk.Resource { }, false), }, + "smb_non_browsable_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, + + "smb_access_based_enumeration_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, + "protocols": { Type: pluginsdk.TypeSet, ForceNew: true, @@ -328,6 +340,16 @@ func resourceNetAppVolumeCreate(d *pluginsdk.ResourceData, meta interface{}) err } networkFeatures = volumes.NetworkFeatures(networkFeaturesString) + smbNonBrowsable := volumes.SmbNonBrowsableDisabled + if d.Get("smb_non_browsable_enabled").(bool) { + smbNonBrowsable = volumes.SmbNonBrowsableEnabled + } + + smbAccessBasedEnumeration := volumes.SmbAccessBasedEnumerationDisabled + if d.Get("smb_access_based_enumeration_enabled").(bool) { + smbAccessBasedEnumeration = volumes.SmbAccessBasedEnumerationEnabled + } + protocols := d.Get("protocols").(*pluginsdk.Set).List() if len(protocols) == 0 { protocols = append(protocols, "NFSv3") @@ -438,23 +460,25 @@ func resourceNetAppVolumeCreate(d *pluginsdk.ResourceData, meta interface{}) err parameters := volumes.Volume{ Location: location, - Properties: volumes.VolumeProperties{ - CreationToken: volumePath, - ServiceLevel: &serviceLevel, - SubnetId: subnetID, - NetworkFeatures: &networkFeatures, - ProtocolTypes: utils.ExpandStringSlice(protocols), - SecurityStyle: &securityStyle, - UsageThreshold: storageQuotaInGB, - ExportPolicy: exportPolicyRule, - VolumeType: utils.String(volumeType), - SnapshotId: utils.String(snapshotID), - DataProtection: &volumes.VolumePropertiesDataProtection{ + Properties: volumes.VolumeProperties{ + CreationToken: volumePath, + ServiceLevel: &serviceLevel, + SubnetId: subnetID, + NetworkFeatures: &networkFeatures, + SmbNonBrowsable: &smbNonBrowsable, + SmbAccessBasedEnumeration: &smbAccessBasedEnumeration, + ProtocolTypes: utils.ExpandStringSlice(protocols), + SecurityStyle: &securityStyle, + UsageThreshold: storageQuotaInGB, + ExportPolicy: exportPolicyRule, + VolumeType: utils.String(volumeType), + SnapshotId: utils.String(snapshotID), + DataProtection: &volumes.VolumePropertiesDataProtection{ Replication: dataProtectionReplication.Replication, Snapshot: dataProtectionSnapshotPolicy.Snapshot, }, - AvsDataStore: &avsDataStoreEnabled, - SnapshotDirectoryVisible: utils.Bool(snapshotDirectoryVisible), + AvsDataStore: &avsDataStoreEnabled, + SnapshotDirectoryVisible: utils.Bool(snapshotDirectoryVisible), }, Tags: tags.Expand(d.Get("tags").(map[string]interface{})), Zones: zones, @@ -553,6 +577,26 @@ func resourceNetAppVolumeUpdate(d *pluginsdk.ResourceData, meta interface{}) err update.Properties.ThroughputMibps = utils.Float(throughputMibps.(float64)) } + if d.HasChange("smb_non_browsable_enabled") { + shouldUpdate = true + smbNonBrowsable := volumes.SmbNonBrowsableDisabled + update.Properties.SmbNonBrowsable = &smbNonBrowsable + if d.Get("smb_non_browsable_enabled").(bool) { + smbNonBrowsable := volumes.SmbNonBrowsableEnabled + update.Properties.SmbNonBrowsable = &smbNonBrowsable + } + } + + if d.HasChange("smb_access_based_enumeration_enabled") { + shouldUpdate = true + smbAccessBasedEnumeration := volumes.SmbAccessBasedEnumerationDisabled + update.Properties.SmbAccessBasedEnumeration = &smbAccessBasedEnumeration + if d.Get("smb_access_based_enumeration_enabled").(bool) { + smbAccessBasedEnumeration := volumes.SmbAccessBasedEnumerationEnabled + update.Properties.SmbAccessBasedEnumeration = &smbAccessBasedEnumeration + } + } + if d.HasChange("tags") { shouldUpdate = true tagsRaw := d.Get("tags").(map[string]interface{}) @@ -614,6 +658,8 @@ func resourceNetAppVolumeRead(d *pluginsdk.ResourceData, meta interface{}) error d.Set("service_level", string(pointer.From(props.ServiceLevel))) d.Set("subnet_id", props.SubnetId) d.Set("network_features", string(pointer.From(props.NetworkFeatures))) + d.Set("smb_non_browsable_enabled", string(pointer.From(props.SmbNonBrowsable))) + d.Set("smb_access_based_enumeration_enabled", string(pointer.From(props.SmbAccessBasedEnumeration))) d.Set("protocols", props.ProtocolTypes) d.Set("security_style", string(pointer.From(props.SecurityStyle))) d.Set("snapshot_directory_visible", props.SnapshotDirectoryVisible) From 28f77888d9fbf24bad3e17f494074cf56000f057 Mon Sep 17 00:00:00 2001 From: Malcolm Morgan Date: Tue, 23 Jan 2024 12:41:43 -0800 Subject: [PATCH 2/4] Updated documentation to include smb_non_browsable_enabled and smb_access_based_enumeration_enabled --- website/docs/r/netapp_volume.html.markdown | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/website/docs/r/netapp_volume.html.markdown b/website/docs/r/netapp_volume.html.markdown index 91962d196bbc..d3e1c9ff092c 100644 --- a/website/docs/r/netapp_volume.html.markdown +++ b/website/docs/r/netapp_volume.html.markdown @@ -143,6 +143,10 @@ The following arguments are supported: * `throughput_in_mibps` - (Optional) Throughput of this volume in Mibps. +* `smb_non_browsable_enabled` - (Optional) Limits clients from browsing for an SMB share by hiding the share from view in Windows Explorer or when listing shares in "net view." Only end users that know the absolute paths to the share are able to find the share. Defaults to `false`. For more information, please refer to [Understand NAS share permissions in Azure NetApp Files](https://learn.microsoft.com/en-us/azure/azure-netapp-files/network-attached-storage-permissions#:~:text=Non%2Dbrowsable%20shares,find%20the%20share.) + +* `smb_access_based_enumeration_enabled` - (Optional) Limits enumeration of files and folders (that is, listing the contents) in SMB only to users with allowed access on the share. For instance, if a user doesn't have access to read a file or folder in a share with access-based enumeration enabled, then the file or folder doesn't show up in directory listings. Defaults to `false`. For more information, please refer to [Understand NAS share permissions in Azure NetApp Files](https://learn.microsoft.com/en-us/azure/azure-netapp-files/network-attached-storage-permissions#:~:text=security%20for%20administrators.-,Access%2Dbased%20enumeration,in%20an%20Azure%20NetApp%20Files%20SMB%20volume.%20Only%20contosoadmin%20has%20access.,-In%20the%20below) + * `tags` - (Optional) A mapping of tags to assign to the resource. -> **Note:** It is highly recommended to use the **lifecycle** property as noted in the example since it will prevent an accidental deletion of the volume if the `protocols` argument changes to a different protocol type. From 56e0c2f10bb372f72a94fac2ddcf6537e3870a8b Mon Sep 17 00:00:00 2001 From: Malcolm Morgan Date: Thu, 25 Jan 2024 09:45:06 -0800 Subject: [PATCH 3/4] Added smb_non_browsable_enabled and smb_access_based_enumeration_enabled to the data source --- .../netapp/netapp_volume_data_source.go | 25 ++++++++++ .../services/netapp/netapp_volume_resource.go | 46 +++++++++++-------- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/internal/services/netapp/netapp_volume_data_source.go b/internal/services/netapp/netapp_volume_data_source.go index 6c070b6ac794..144ca3ee48b1 100644 --- a/internal/services/netapp/netapp_volume_data_source.go +++ b/internal/services/netapp/netapp_volume_data_source.go @@ -5,6 +5,7 @@ package netapp import ( "fmt" + "strings" "time" "github.com/hashicorp/go-azure-helpers/lang/pointer" @@ -129,6 +130,18 @@ func dataSourceNetAppVolume() *pluginsdk.Resource { Type: pluginsdk.TypeString, Computed: true, }, + + "smb_non_browsable_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, + + "smb_access_based_enumeration_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, }, } } @@ -174,6 +187,18 @@ func dataSourceNetAppVolumeRead(d *pluginsdk.ResourceData, meta interface{}) err d.Set("encryption_key_source", string(pointer.From(props.EncryptionKeySource))) d.Set("key_vault_private_endpoint_id", props.KeyVaultPrivateEndpointResourceId) + smbNonBrowsable := false + if props.SmbNonBrowsable != nil { + smbNonBrowsable = strings.EqualFold(string(*props.SmbNonBrowsable), string(volumes.SmbNonBrowsableEnabled)) + } + d.Set("smb_non_browsable_enabled", smbNonBrowsable) + + smbAccessBasedEnumeration := false + if props.SmbAccessBasedEnumeration != nil { + smbAccessBasedEnumeration = strings.EqualFold(string(*props.SmbAccessBasedEnumeration), string(volumes.SmbAccessBasedEnumerationEnabled)) + } + d.Set("smb_access_based_enumeration_enabled", smbAccessBasedEnumeration) + protocolTypes := make([]string, 0) if prtclTypes := props.ProtocolTypes; prtclTypes != nil { protocolTypes = append(protocolTypes, *prtclTypes...) diff --git a/internal/services/netapp/netapp_volume_resource.go b/internal/services/netapp/netapp_volume_resource.go index 7e1717836873..7dfe48d51d74 100644 --- a/internal/services/netapp/netapp_volume_resource.go +++ b/internal/services/netapp/netapp_volume_resource.go @@ -118,18 +118,6 @@ func resourceNetAppVolume() *pluginsdk.Resource { }, false), }, - "smb_non_browsable_enabled": { - Type: pluginsdk.TypeBool, - Optional: true, - Default: false, - }, - - "smb_access_based_enumeration_enabled": { - Type: pluginsdk.TypeBool, - Optional: true, - Default: false, - }, - "protocols": { Type: pluginsdk.TypeSet, ForceNew: true, @@ -313,6 +301,18 @@ func resourceNetAppVolume() *pluginsdk.Resource { ValidateFunc: azure.ValidateResourceID, RequiredWith: []string{"encryption_key_source"}, }, + + "smb_non_browsable_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, + + "smb_access_based_enumeration_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, }, } } @@ -476,7 +476,7 @@ func resourceNetAppVolumeCreate(d *pluginsdk.ResourceData, meta interface{}) err parameters := volumes.Volume{ Location: location, - Properties: volumes.VolumeProperties{ + Properties: volumes.VolumeProperties{ CreationToken: volumePath, ServiceLevel: &serviceLevel, SubnetId: subnetID, @@ -489,12 +489,12 @@ func resourceNetAppVolumeCreate(d *pluginsdk.ResourceData, meta interface{}) err ExportPolicy: exportPolicyRule, VolumeType: utils.String(volumeType), SnapshotId: utils.String(snapshotID), - DataProtection: &volumes.VolumePropertiesDataProtection{ + DataProtection: &volumes.VolumePropertiesDataProtection{ Replication: dataProtectionReplication.Replication, Snapshot: dataProtectionSnapshotPolicy.Snapshot, }, - AvsDataStore: &avsDataStoreEnabled, - SnapshotDirectoryVisible: utils.Bool(snapshotDirectoryVisible), + AvsDataStore: &avsDataStoreEnabled, + SnapshotDirectoryVisible: utils.Bool(snapshotDirectoryVisible), }, Tags: tags.Expand(d.Get("tags").(map[string]interface{})), Zones: zones, @@ -687,8 +687,6 @@ func resourceNetAppVolumeRead(d *pluginsdk.ResourceData, meta interface{}) error d.Set("service_level", string(pointer.From(props.ServiceLevel))) d.Set("subnet_id", props.SubnetId) d.Set("network_features", string(pointer.From(props.NetworkFeatures))) - d.Set("smb_non_browsable_enabled", string(pointer.From(props.SmbNonBrowsable))) - d.Set("smb_access_based_enumeration_enabled", string(pointer.From(props.SmbAccessBasedEnumeration))) d.Set("protocols", props.ProtocolTypes) d.Set("security_style", string(pointer.From(props.SecurityStyle))) d.Set("snapshot_directory_visible", props.SnapshotDirectoryVisible) @@ -697,6 +695,18 @@ func resourceNetAppVolumeRead(d *pluginsdk.ResourceData, meta interface{}) error d.Set("encryption_key_source", string(pointer.From(props.EncryptionKeySource))) d.Set("key_vault_private_endpoint_id", props.KeyVaultPrivateEndpointResourceId) + smbNonBrowsable := false + if props.SmbNonBrowsable != nil { + smbNonBrowsable = strings.EqualFold(string(*props.SmbNonBrowsable), string(volumes.SmbNonBrowsableEnabled)) + } + d.Set("smb_non_browsable_enabled", smbNonBrowsable) + + smbAccessBasedEnumeration := false + if props.SmbAccessBasedEnumeration != nil { + smbAccessBasedEnumeration = strings.EqualFold(string(*props.SmbAccessBasedEnumeration), string(volumes.SmbAccessBasedEnumerationEnabled)) + } + d.Set("smb_access_based_enumeration_enabled", smbAccessBasedEnumeration) + avsDataStore := false if props.AvsDataStore != nil { avsDataStore = strings.EqualFold(string(*props.AvsDataStore), string(volumes.AvsDataStoreEnabled)) From 650619a3a5a15dbd1642b22a729d144a52d5d579 Mon Sep 17 00:00:00 2001 From: Malcolm Morgan Date: Thu, 15 Feb 2024 11:35:11 -0800 Subject: [PATCH 4/4] Addressed PR comments --- internal/services/netapp/netapp_volume_data_source.go | 6 ++---- website/docs/d/netapp_volume.html.markdown | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/internal/services/netapp/netapp_volume_data_source.go b/internal/services/netapp/netapp_volume_data_source.go index 144ca3ee48b1..49b7d826c0c5 100644 --- a/internal/services/netapp/netapp_volume_data_source.go +++ b/internal/services/netapp/netapp_volume_data_source.go @@ -133,14 +133,12 @@ func dataSourceNetAppVolume() *pluginsdk.Resource { "smb_non_browsable_enabled": { Type: pluginsdk.TypeBool, - Optional: true, - Default: false, + Computed: true, }, "smb_access_based_enumeration_enabled": { Type: pluginsdk.TypeBool, - Optional: true, - Default: false, + Computed: true, }, }, } diff --git a/website/docs/d/netapp_volume.html.markdown b/website/docs/d/netapp_volume.html.markdown index b19af556d80f..7feb86e4b7d0 100644 --- a/website/docs/d/netapp_volume.html.markdown +++ b/website/docs/d/netapp_volume.html.markdown @@ -63,6 +63,9 @@ The following attributes are exported: * `volume_path` - The unique file path of the volume. +* `smb_non_browsable_enabled` - Limits clients from browsing for an SMB share. + +* `smb_access_based_enumeration_enabled` - Limits enumeration of files and folders (that is, listing the contents) in SMB only to users with allowed access on the share. --- A `data_protection_replication` block exports the following: