public static CapacityPool CreatePool(AzureNetAppFilesManagementClient netAppMgmtClient, string poolName = poolName1, string accountName = accountName1, string resourceGroup = resourceGroup, string location = location, IDictionary <string, string> tags = default(IDictionary <string, string>), bool poolOnly = false, string serviceLevel = "Premium", long poolSize = 4398046511104) { if (!poolOnly) { CreateAccount(netAppMgmtClient, accountName, resourceGroup: resourceGroup, location: location, tags: tags); } var pool = new CapacityPool { Location = location, Size = poolSize, ServiceLevel = serviceLevel, Tags = tags }; CapacityPool resource; try { resource = netAppMgmtClient.Pools.CreateOrUpdate(pool, resourceGroup, accountName, poolName); } catch { // try one more time resource = netAppMgmtClient.Pools.CreateOrUpdate(pool, resourceGroup, accountName, poolName); } Assert.Equal(resource.Name, accountName + '/' + poolName); if (Environment.GetEnvironmentVariable("AZURE_TEST_MODE") == "Record") { Thread.Sleep(delay); // some robustness against ARM caching } return(resource); }
public override void ExecuteCmdlet() { IDictionary <string, string> tagPairs = null; if (ParameterSetName == ResourceIdParameterSet) { var resourceIdentifier = new ResourceIdentifier(ResourceId); ResourceGroupName = resourceIdentifier.ResourceGroupName; var parentResources = resourceIdentifier.ParentResource.Split('/'); AccountName = parentResources[1]; Name = resourceIdentifier.ResourceName; } if (Tag != null) { tagPairs = new Dictionary <string, string>(); foreach (string key in Tag.Keys) { tagPairs.Add(key, Tag[key].ToString()); } } CapacityPool existingPool = null; try { existingPool = AzureNetAppFilesManagementClient.Pools.Get(ResourceGroupName, AccountName, Name); } catch { existingPool = null; } if (existingPool == null) { throw new AzPSResourceNotFoundCloudException($"A Capacity Pool with name '{this.Name}' in resource group '{this.ResourceGroupName}' does not exist. Please use New-AzNetAppFilesPool to create a new Capacity Pool."); } if (ParameterSetName == ParentObjectParameterSet) { ResourceGroupName = AccountObject.ResourceGroupName; AccountName = AccountObject.Name; Location = AccountObject.Location; } var capacityPoolBody = new CapacityPool() { ServiceLevel = ServiceLevel, Size = PoolSize, Location = Location, Tags = tagPairs, QosType = QosType, CoolAccess = CoolAccess }; if (ShouldProcess(Name, string.Format(PowerShell.Cmdlets.NetAppFiles.Properties.Resources.UpdateResourceMessage, ResourceGroupName))) { var anfPool = AzureNetAppFilesManagementClient.Pools.CreateOrUpdate(capacityPoolBody, ResourceGroupName, AccountName, Name); WriteObject(anfPool.ToPsNetAppFilesPool()); } }
public override void ExecuteCmdlet() { IDictionary <string, string> tagPairs = null; if (Tag != null) { tagPairs = new Dictionary <string, string>(); foreach (string key in Tag.Keys) { tagPairs.Add(key, Tag[key].ToString()); } } if (ParameterSetName == ParentObjectParameterSet) { ResourceGroupName = AccountObject.ResourceGroupName; AccountName = AccountObject.Name; Location = AccountObject.Location; } var capacityPoolBody = new CapacityPool() { ServiceLevel = ServiceLevel, Size = PoolSize, Location = Location, Tags = tagPairs }; if (ShouldProcess(Name, string.Format(PowerShell.Cmdlets.NetAppFiles.Properties.Resources.CreateResourceMessage, ResourceGroupName))) { var anfPool = AzureNetAppFilesManagementClient.Pools.CreateOrUpdate(capacityPoolBody, ResourceGroupName, AccountName, Name); WriteObject(anfPool); } }
public override void ExecuteCmdlet() { if (ParameterSetName == ObjectParameterSet) { ResourceGroupName = InputObject.ResourceGroupName; Location = InputObject.Location; var NameParts = InputObject.Name.Split('/'); AccountName = NameParts[0]; Name = NameParts[1]; } else if (ParameterSetName == ParentObjectParameterSet) { ResourceGroupName = AccountObject.ResourceGroupName; Location = AccountObject.Location; AccountName = AccountObject.Name; } var capacityPoolBody = new CapacityPool() { ServiceLevel = ServiceLevel, Size = PoolSize, Location = Location }; if (ShouldProcess(Name, "Update the pool")) { var anfPool = AzureNetAppFilesManagementClient.Pools.CreateOrUpdate(capacityPoolBody, ResourceGroupName, AccountName, Name); WriteObject(anfPool); } }
public static CapacityPool CreatePool(AzureNetAppFilesManagementClient netAppMgmtClient, string poolName = poolName1, string accountName = accountName1, string resourceGroup = resourceGroup, string location = location, object tags = null, bool poolOnly = false) { if (!poolOnly) { CreateAccount(netAppMgmtClient, accountName); } var pool = new CapacityPool { Location = location, Size = 4398046511104, ServiceLevel = "Premium", Tags = tags }; CapacityPool resource; try { resource = netAppMgmtClient.Pools.CreateOrUpdate(pool, resourceGroup, accountName, poolName); } catch { // try one more time resource = netAppMgmtClient.Pools.CreateOrUpdate(pool, resourceGroup, accountName, poolName); } Assert.Equal(resource.Name, accountName + '/' + poolName); Thread.Sleep(delay); // some robustness against ARM caching return(resource); }
/// <summary> /// Creates or updates a capacity pool /// </summary> /// <param name="client">Azure NetApp Files Management Client</param> /// <param name="resourceGroup">Resource Group name where capacity pool will be created</param> /// <param name="account">Account object generated from information contained at the appsettings.json file at Accounts section</param> /// <param name="pool">ModelCapacityPool object that describes the capacity pool to be created, this information comes from appsettings.json</param> /// <returns>CapacityPool object</returns> public static async Task <CapacityPool> CreateOrUpdateCapacityPoolAsync(AzureNetAppFilesManagementClient client, string resourceGroup, ModelNetAppAccount account, ModelCapacityPool pool) { CapacityPool capacityPoolBody = new CapacityPool() { Location = account.Location.ToLower(), ServiceLevel = pool.ServiceLevel, Size = pool.Size }; return(await client.Pools.CreateOrUpdateAsync(capacityPoolBody, resourceGroup, account.Name, pool.Name)); }
/// <summary> /// Creates or Updates Azure NetApp Files Capacity Pool /// </summary> /// <param name="anfClient">ANF client object</param> /// <param name="resourceGroupName">Resource group name</param> /// <param name="location">Azure location</param> /// <param name="accountName">Azure NetApp Files Account name</param> /// <param name="poolName">Azure NetApp Files Capacity Pool name</param> /// <param name="poolSize">Azure NetApp Files Capacity Pool size</param> /// <param name="serviceLevel">Service Level</param> /// <returns>Azure NetApp Files Capacity Pool</returns> public static async Task <CapacityPool> CreateOrUpdateANFCapacityPoolAsync(AzureNetAppFilesManagementClient anfClient, string resourceGroupName, string location, string accountName, string poolName, long poolSize, string serviceLevel) { CapacityPool primaryCapacityPoolBody = new CapacityPool() { Location = location.ToLower(), // Important: location needs to be lower case ServiceLevel = serviceLevel, //Service level can be one of three levels -> { Standard, Premium, Ultra } Size = poolSize }; return(await anfClient.Pools.CreateOrUpdateAsync(primaryCapacityPoolBody, resourceGroupName, accountName, poolName)); }
public override void ExecuteCmdlet() { IDictionary <string, string> tagPairs = null; if (Tag != null) { tagPairs = new Dictionary <string, string>(); foreach (string key in Tag.Keys) { tagPairs.Add(key, Tag[key].ToString()); } } //check existing CapacityPool existingPool = null; try { existingPool = AzureNetAppFilesManagementClient.Pools.Get(ResourceGroupName, AccountName, Name); } catch { existingPool = null; } if (existingPool != null) { throw new Exception(string.Format("A Capacity Pool with name '{0}' in resource group '{1}' already exists. Please use Set/Update-AzNetAppFilesPool to update an existing Capacity Pool.", this.Name, this.ResourceGroupName)); } if (ParameterSetName == ParentObjectParameterSet) { ResourceGroupName = AccountObject.ResourceGroupName; AccountName = AccountObject.Name; Location = AccountObject.Location; } var capacityPoolBody = new CapacityPool() { ServiceLevel = ServiceLevel, Size = PoolSize, Location = Location, Tags = tagPairs, QosType = QosType }; if (ShouldProcess(Name, string.Format(PowerShell.Cmdlets.NetAppFiles.Properties.Resources.CreateResourceMessage, ResourceGroupName))) { var anfPool = AzureNetAppFilesManagementClient.Pools.CreateOrUpdate(capacityPoolBody, ResourceGroupName, AccountName, Name); WriteObject(anfPool.ToPsNetAppFilesPool()); } }
public static PSNetAppFilesPool ToPsNetAppFilesPool(this CapacityPool capacityPool) { return(new PSNetAppFilesPool { ResourceGroupName = new ResourceIdentifier(capacityPool.Id).ResourceGroupName, Location = capacityPool.Location, Id = capacityPool.Id, Name = capacityPool.Name, Type = capacityPool.Type, Tags = capacityPool.Tags, PoolId = capacityPool.PoolId, Size = capacityPool.Size, ServiceLevel = capacityPool.ServiceLevel, ProvisioningState = capacityPool.ProvisioningState }); }
/// <summary> /// Creates or retrieves a Capacity Pool /// </summary> /// <param name="client">Azure NetApp Files Management Client</param> /// <param name="resourceGroup">Resource Group name where the capacity pool will be created</param> /// <param name="account">ModelNetAppAccount object that contains the data configured in the appsettings.json file for the ANF account</param> /// <param name="pool">ModelCapacityPool object that describes the capacity pool to be created, this information comes from appsettings.json</param> /// <returns>CapacityPool object</returns> private static async Task <CapacityPool> CreateOrRetrieveCapacityPoolAsync(AzureNetAppFilesManagementClient client, string resourceGroup, ModelNetAppAccount account, ModelCapacityPool pool) { CapacityPool anfCapacityPool = await GetResourceAsync <CapacityPool>(client, resourceGroup, account.Name, pool.Name); if (anfCapacityPool == null) { anfCapacityPool = await CreateOrUpdateCapacityPoolAsync(client, resourceGroup, account, pool); Utils.WriteConsoleMessage($"\tCapacity Pool successfully created, resource id: {anfCapacityPool.Id}"); } else { Utils.WriteConsoleMessage($"\tCapacity already exists, resource id: {anfCapacityPool.Id}"); } return(anfCapacityPool); }
public static PSNetAppFilesPool ToPsNetAppFilesPool(this CapacityPool capacityPool) { return(new PSNetAppFilesPool { ResourceGroupName = new ResourceIdentifier(capacityPool.Id).ResourceGroupName, Location = capacityPool.Location, Id = capacityPool.Id, Name = capacityPool.Name, Type = capacityPool.Type, Tags = capacityPool.Tags, PoolId = capacityPool.PoolId, Size = capacityPool.Size, ServiceLevel = capacityPool.ServiceLevel, ProvisioningState = capacityPool.ProvisioningState, QosType = capacityPool.QosType, TotalThroughputMibps = capacityPool.TotalThroughputMibps, UtilizedThroughputMibps = capacityPool.UtilizedThroughputMibps, CoolAccess = capacityPool.CoolAccess }); }
public override void ExecuteCmdlet() { if (ParameterSetName == ParentObjectParameterSet) { ResourceGroupName = AccountObject.ResourceGroupName; AccountName = AccountObject.Name; Location = AccountObject.Location; } var capacityPoolBody = new CapacityPool() { ServiceLevel = ServiceLevel, Size = PoolSize, Location = Location, Tags = Tag }; if (ShouldProcess(Name, string.Format(PowerShell.Cmdlets.NetAppFiles.Properties.Resources.CreateResourceMessage, ResourceGroupName))) { var anfPool = AzureNetAppFilesManagementClient.Pools.CreateOrUpdate(capacityPoolBody, ResourceGroupName, AccountName, Name); WriteObject(anfPool); } }
/// <summary> /// Create or Update a capacity pool /// </summary> /// <param name='operations'> /// The operations group for this extension method. /// </param> /// <param name='body'> /// Capacity pool object supplied in the body of the operation. /// </param> /// <param name='resourceGroupName'> /// The name of the resource group. /// </param> /// <param name='accountName'> /// The name of the NetApp account /// </param> /// <param name='poolName'> /// The name of the capacity pool /// </param> /// <param name='cancellationToken'> /// The cancellation token. /// </param> public static async Task <CapacityPool> BeginCreateOrUpdateAsync(this IPoolsOperations operations, CapacityPool body, string resourceGroupName, string accountName, string poolName, CancellationToken cancellationToken = default(CancellationToken)) { using (var _result = await operations.BeginCreateOrUpdateWithHttpMessagesAsync(body, resourceGroupName, accountName, poolName, null, cancellationToken).ConfigureAwait(false)) { return(_result.Body); } }
/// <summary> /// Create or Update a capacity pool /// </summary> /// <param name='operations'> /// The operations group for this extension method. /// </param> /// <param name='body'> /// Capacity pool object supplied in the body of the operation. /// </param> /// <param name='resourceGroupName'> /// The name of the resource group. /// </param> /// <param name='accountName'> /// The name of the NetApp account /// </param> /// <param name='poolName'> /// The name of the capacity pool /// </param> public static CapacityPool BeginCreateOrUpdate(this IPoolsOperations operations, CapacityPool body, string resourceGroupName, string accountName, string poolName) { return(operations.BeginCreateOrUpdateAsync(body, resourceGroupName, accountName, poolName).GetAwaiter().GetResult()); }
static private async Task RunAsync() { //--------------------------------------------------------------------------------------------------------------------- // Setting variables necessary for resources creation - change these to appropriated values related to your environment //--------------------------------------------------------------------------------------------------------------------- string subscriptionId = "<subscriptionId>"; string location = "eastus2"; string resourceGroupName = "anf01-rg"; string vnetName = "vnet-02"; string subnetName = "anf-sn"; string vnetResourceGroupName = "anf01-rg"; string anfAccountName = "anfaccount03"; string capacityPoolName = "Pool01"; string capacityPoolServiceLevel = "Standard"; long capacitypoolSize = 4398046511104; // 4TiB which is minimum size long volumeSize = 107374182400; // 100GiB - volume minimum size //---------------------------------------------------------------------------------------- // Authenticating using service principal, refer to README.md file for requirement details //---------------------------------------------------------------------------------------- WriteConsoleMessage("Authenticating..."); var credentials = await ServicePrincipalAuth.GetServicePrincipalCredential("AZURE_AUTH_LOCATION"); //------------------------------------------ // Instantiating a new ANF management client //------------------------------------------ WriteConsoleMessage("Instantiating a new Azure NetApp Files management client..."); AzureNetAppFilesManagementClient anfClient = new AzureNetAppFilesManagementClient(credentials) { SubscriptionId = subscriptionId }; WriteConsoleMessage($"\tApi Version: {anfClient.ApiVersion}"); //---------------------- // Creating ANF Account //---------------------- // Setting up NetApp Files account body object NetAppAccount anfAccountBody = new NetAppAccount(location, null, anfAccountName); // Requesting account to be created WriteConsoleMessage("Requesting account to be created..."); var anfAccount = await anfClient.Accounts.CreateOrUpdateAsync(anfAccountBody, resourceGroupName, anfAccountName); WriteConsoleMessage($"\tAccount Resource Id: {anfAccount.Id}"); //----------------------- // Creating Capacity Pool //----------------------- // Setting up capacity pool body object CapacityPool capacityPoolBody = new CapacityPool() { Location = location.ToLower(), // Important: location needs to be lower case ServiceLevel = capacityPoolServiceLevel, Size = capacitypoolSize }; // Creating capacity pool WriteConsoleMessage("Requesting capacity pool to be created..."); var capacityPool = await anfClient.Pools.CreateOrUpdateAsync(capacityPoolBody, resourceGroupName, anfAccount.Name, capacityPoolName); WriteConsoleMessage($"\tCapacity Pool Resource Id: {capacityPool.Id}"); //------------------------ // Creating NFS 4.1 Volume //------------------------ // Creating export policy object VolumePropertiesExportPolicy exportPolicies = new VolumePropertiesExportPolicy() { Rules = new List <ExportPolicyRule> { new ExportPolicyRule() { AllowedClients = "0.0.0.0", Cifs = false, Nfsv3 = false, Nfsv41 = true, RuleIndex = 1, UnixReadOnly = false, UnixReadWrite = true } } }; // Creating volume body object string subnetId = $"/subscriptions/{subscriptionId}/resourceGroups/{vnetResourceGroupName}/providers/Microsoft.Network/virtualNetworks/{vnetName}/subnets/{subnetName}"; string volumeName = $"Vol-{anfAccountName}-{capacityPoolName}"; Volume volumeBody = new Volume() { ExportPolicy = exportPolicies, Location = location.ToLower(), ServiceLevel = capacityPoolServiceLevel, CreationToken = volumeName, SubnetId = subnetId, UsageThreshold = volumeSize, ProtocolTypes = new List <string>() { "NFSv4.1" } }; // Creating NFS 4.1 volume WriteConsoleMessage("Requesting volume to be created..."); var volume = await anfClient.Volumes.CreateOrUpdateAsync(volumeBody, resourceGroupName, anfAccount.Name, ResourceUriUtils.GetAnfCapacityPool(capacityPool.Id), volumeName); WriteConsoleMessage($"\tVolume Resource Id: {volume.Id}"); //------------------------ // Cleaning up //------------------------ //WriteConsoleMessage("Cleaning up created resources..."); //WriteConsoleMessage("\tDeleting volume..."); //await anfClient.Volumes.DeleteAsync(resourceGroupName, anfAccount.Name, ResourceUriUtils.GetAnfCapacityPool(capacityPool.Id), ResourceUriUtils.GetAnfVolume(volume.Id)); //// Adding a final verification if the resource completed deletion since it may have a few secs between ARM the Resource Provider be fully in sync //await WaitForNoAnfResource<Volume>(anfClient, volume.Id); //Utils.WriteConsoleMessage($"\t\tDeleted volume: {volume.Id}"); //WriteConsoleMessage("\tDeleting capacity pool..."); //await anfClient.Pools.DeleteAsync(resourceGroupName, anfAccount.Name, ResourceUriUtils.GetAnfCapacityPool(capacityPool.Id)); //await WaitForNoAnfResource<CapacityPool>(anfClient, capacityPool.Id); //Utils.WriteConsoleMessage($"\t\tDeleted capacity pool: {capacityPool.Id}"); //WriteConsoleMessage("\tDeleting account..."); //await anfClient.Accounts.DeleteAsync(resourceGroupName, anfAccount.Name); //await WaitForNoAnfResource<NetAppAccount>(anfClient, anfAccount.Id); //Utils.WriteConsoleMessage($"\t\tDeleted account: {anfAccount.Id}"); }
/// <summary> /// Executes some updates on first capacity pool and first volume listed in the configuration file (appsettings.json) /// </summary> /// <returns></returns> public static async Task RunUpdateOperationsSampleAsync(ProjectConfiguration config, AzureNetAppFilesManagementClient anfClient) { // // Capacity Pool Updates // Utils.WriteConsoleMessage("Performing size update on a Capacity Pool"); // Get current Capacity Pool information CapacityPool capacityPool = null; try { capacityPool = await anfClient.Pools.GetAsync( config.ResourceGroup, config.Accounts[0].Name, config.Accounts[0].CapacityPools[0].Name); } catch (Exception ex) { Utils.WriteErrorMessage($"An error occured while getting current Capacity Pool information ({config.Accounts[0].CapacityPools[0].Name}).\nError message: {ex.Message}"); throw; } int newCapacityPoolSizeTiB = 10; Utils.WriteConsoleMessage($"\tChanging Capacity Pools size from {Utils.GetBytesInTiB(capacityPool.Size)}TiB to {newCapacityPoolSizeTiB}TiB"); // New size in bytes long newCapacityPoolSizeBytes = Utils.GetTiBInBytes(newCapacityPoolSizeTiB); // Create capacity pool patch object passing required arguments and the updated size CapacityPoolPatch capacityPoolPatch = new CapacityPoolPatch( capacityPool.Location, size: newCapacityPoolSizeBytes); // Update capacity pool resource try { CapacityPool updatedCapacityPool = await anfClient.Pools.UpdateAsync( capacityPoolPatch, config.ResourceGroup, config.Accounts[0].Name, config.Accounts[0].CapacityPools[0].Name); Utils.WriteConsoleMessage($"\tCapacity Pool successfully updated, new size: {Utils.GetBytesInTiB(updatedCapacityPool.Size)}TiB, resource id: {updatedCapacityPool.Id}"); } catch (Exception ex) { Utils.WriteErrorMessage($"An error occured while updating Capacity Pool {capacityPool.Id}.\nError message: {ex.Message}"); throw; } // // Volume Updates // Utils.WriteConsoleMessage("Performing size and export policy update on a volume"); // Get current Volume information Volume volume = null; try { volume = await anfClient.Volumes.GetAsync( config.ResourceGroup, config.Accounts[0].Name, config.Accounts[0].CapacityPools[0].Name, config.Accounts[0].CapacityPools[0].Volumes[0].Name); } catch (Exception ex) { Utils.WriteErrorMessage($"An error occured while getting current Volume information ({config.Accounts[0].CapacityPools[0].Volumes[0].Name}).\nError message: {ex.Message}"); throw; } int newVolumeSizeTiB = 1; Utils.WriteConsoleMessage($"\tChanging Volume size from {Utils.GetBytesInTiB(volume.UsageThreshold)}TiB to {newVolumeSizeTiB}TiB. Also adding new export policy rule, current count is {volume.ExportPolicy.Rules.Count}."); // New size in bytes long newVolumeSizeBytes = Utils.GetTiBInBytes(newVolumeSizeTiB); // New Export Policy rule List <ExportPolicyRule> ruleList = volume.ExportPolicy.Rules.OrderByDescending(r => r.RuleIndex).ToList(); // Currently, ANF's volume export policy supports up to 5 rules VolumePatchPropertiesExportPolicy exportPoliciesPatch = null; if (ruleList.Count <= 4) { ruleList.Add(new ExportPolicyRule() { AllowedClients = "10.0.0.4/32", Cifs = false, Nfsv3 = true, Nfsv4 = false, RuleIndex = ruleList.ToList()[0].RuleIndex + 1, UnixReadOnly = false, UnixReadWrite = true }); exportPoliciesPatch = new VolumePatchPropertiesExportPolicy() { Rules = ruleList }; } // Create volume patch object passing required arguments and the updated size VolumePatch volumePatch = null; if (exportPoliciesPatch != null) { volumePatch = new VolumePatch( volume.Location, usageThreshold: newVolumeSizeBytes, exportPolicy: exportPoliciesPatch); } else { volumePatch = new VolumePatch( volume.Location, usageThreshold: newVolumeSizeBytes); } // Update size at volume resource try { Volume updatedVolume = await anfClient.Volumes.UpdateAsync( volumePatch, config.ResourceGroup, config.Accounts[0].Name, config.Accounts[0].CapacityPools[0].Name, config.Accounts[0].CapacityPools[0].Volumes[0].Name); Utils.WriteConsoleMessage($"\tVolume successfully updated, new size: {Utils.GetBytesInTiB(updatedVolume.UsageThreshold)}TiB, export policy count: {updatedVolume.ExportPolicy.Rules.Count}, resource id: {updatedVolume.Id}"); } catch (Exception ex) { Utils.WriteErrorMessage($"An error occured while updating Volume {volume.Id}.\nError message: {ex.Message}"); throw; } }
/// <summary> /// Removes all created resources /// </summary> /// <returns></returns> public static async Task RunCleanupTasksSampleAsync(ProjectConfiguration config, AzureNetAppFilesManagementClient anfClient) { // // Cleaning up snapshots // Utils.WriteConsoleMessage("Cleaning up snapshots..."); List <Task> snapshotCleanupTasks = new List <Task>(); foreach (ModelNetAppAccount anfAcct in config.Accounts) { if (anfAcct.CapacityPools != null) { foreach (ModelCapacityPool pool in anfAcct.CapacityPools) { if (pool.Volumes != null) { foreach (ModelVolume volume in pool.Volumes) { IEnumerable <Snapshot> anfSnapshotList = await CommonSdk.ListResourceAsync <Snapshot>(anfClient, config.ResourceGroup, anfAcct.Name, pool.Name, volume.Name); if (anfSnapshotList != null && anfSnapshotList.Count() > 0) { // Snapshot Name property (and other ANF's related nested resources) returns a relative path up to the name // and to use this property with DeleteAsync for example, the argument needs to be sanitized and just the // actual name needs to be used. // Snapshot Name poperty example: "pmarques-anf01/pool01/pmarques-anf01-pool01-vol01/test-a" // "test-a" is the actual name that needs to be used instead. Below you will see a sample function that // parses the name from snapshot resource id snapshotCleanupTasks.AddRange(anfSnapshotList.ToList().Select( async snapshot => { await anfClient.Snapshots.DeleteAsync(config.ResourceGroup, anfAcct.Name, pool.Name, volume.Name, ResourceUriUtils.GetAnfSnapshot(snapshot.Id)); Utils.WriteConsoleMessage($"\tDeleted snapshot: {snapshot.Id}"); }).ToList()); } } } } } } await WaitForTasksCompletion(snapshotCleanupTasks).ConfigureAwait(false); // // Cleaning up all volumes // // Note: Volume deletion operations at the RP level are executed serially Utils.WriteConsoleMessage("Cleaning up Volumes..."); foreach (ModelNetAppAccount anfAcct in config.Accounts) { if (anfAcct.CapacityPools != null) { foreach (ModelCapacityPool pool in anfAcct.CapacityPools) { if (pool.Volumes != null) { IEnumerable <Volume> anfVolumeList = await CommonSdk.ListResourceAsync <Volume>(anfClient, config.ResourceGroup, anfAcct.Name, pool.Name); if (anfVolumeList != null && anfVolumeList.Count() > 0) { foreach (Volume volume in anfVolumeList) { try { await anfClient.Volumes.DeleteAsync(config.ResourceGroup, anfAcct.Name, pool.Name, ResourceUriUtils.GetAnfVolume(volume.Id)); Utils.WriteConsoleMessage($"\tDeleted volume: {volume.Id}"); } catch (Exception ex) { Utils.WriteErrorMessage($"An error ocurred while deleting volume {volume.Id}.\nError message: {ex.Message}"); throw; } } } } else { Utils.WriteConsoleMessage($"\tNo volumes defined for Account: {anfAcct.Name}, Capacity Pool: {pool.Name}"); } } } } // // Cleaning up capacity pools // Utils.WriteConsoleMessage("Cleaning up capacity pools..."); List <Task> poolCleanupTasks = new List <Task>(); foreach (ModelNetAppAccount anfAcct in config.Accounts) { if (anfAcct.CapacityPools != null) { poolCleanupTasks.AddRange(anfAcct.CapacityPools.Select( async pool => { CapacityPool anfPool = await GetResourceAsync <CapacityPool>(anfClient, config.ResourceGroup, anfAcct.Name, pool.Name); if (anfPool != null) { await anfClient.Pools.DeleteAsync(config.ResourceGroup, anfAcct.Name, ResourceUriUtils.GetAnfCapacityPool(anfPool.Id)); Utils.WriteConsoleMessage($"\tDeleted volume: {anfPool.Id}"); } }).ToList()); } } await WaitForTasksCompletion(poolCleanupTasks).ConfigureAwait(false); // // Cleaning up accounts // Utils.WriteConsoleMessage("Cleaning up accounts..."); List <Task> accountCleanupTasks = new List <Task>(); if (config.Accounts != null) { accountCleanupTasks.AddRange(config.Accounts.Select( async account => { NetAppAccount anfAccount = await GetResourceAsync <NetAppAccount>(anfClient, config.ResourceGroup, account.Name); if (anfAccount != null) { await anfClient.Accounts.DeleteAsync(config.ResourceGroup, anfAccount.Name); Utils.WriteConsoleMessage($"\tDeleted account: {anfAccount.Id}"); } }).ToList()); } await WaitForTasksCompletion(accountCleanupTasks).ConfigureAwait(false); }
public static VolumeGroupDetails CreateVolumeGroup(AzureNetAppFilesManagementClient netAppMgmtClient, string volumeGroupName = volumeGroupName1, string poolName = poolName1, string accountName = accountName1, string resourceGroup = resourceGroup, string location = vgLocation, List <string> protocolTypes = null, IDictionary <string, string> tags = default(IDictionary <string, string>), VolumePropertiesExportPolicy exportPolicy = null, string vnet = vgVnet, bool volumeGroupOnly = false, string snapshotId = null, string snapshotPolicyId = null, string backupVnetLocation = "", long poolSize = 4398046511104) { CapacityPool pool = null; if (!volumeGroupOnly) { pool = CreatePool(netAppMgmtClient, poolName, accountName, resourceGroup: resourceGroup, location: location, poolSize: poolSize, qosType: QosType.Manual); } var defaultProtocolType = new List <string>() { "NFSv4.1" }; var volumeProtocolTypes = protocolTypes == null ? defaultProtocolType : protocolTypes; if (exportPolicy == null) { exportPolicy = new VolumePropertiesExportPolicy { Rules = new List <ExportPolicyRule>() { new ExportPolicyRule { Nfsv3 = false, Nfsv41 = true, RuleIndex = 1, AllowedClients = "0.0.0.0/0" }, new ExportPolicyRule { Nfsv3 = false, Nfsv41 = true, RuleIndex = 2, AllowedClients = "0.0.0.0/0" } } }; } var volumeGroupVolumeProperties = new List <VolumeGroupVolumeProperties> { new VolumeGroupVolumeProperties { Name = $"{volumeGroupName}-log-1", VolumeSpecName = "log", CapacityPoolResourceId = pool.Id, ProximityPlacementGroup = proximityPlacementGroup, UsageThreshold = 100 * gibibyte, ThroughputMibps = 6, ProtocolTypes = volumeProtocolTypes, CreationToken = $"{volumeGroupName}-log-1", SubnetId = "/subscriptions/" + netAppMgmtClient.SubscriptionId + "/resourceGroups/" + resourceGroup + "/providers/Microsoft.Network/virtualNetworks/" + vnet + "/subnets/default", Tags = tags, ExportPolicy = exportPolicy }, new VolumeGroupVolumeProperties { Name = $"{volumeGroupName}-DataBackup-2", VolumeSpecName = "data-backup", CapacityPoolResourceId = pool.Id, ProximityPlacementGroup = proximityPlacementGroup, ThroughputMibps = 6, UsageThreshold = 100 * gibibyte, ProtocolTypes = volumeProtocolTypes, CreationToken = $"{volumeGroupName}-DataBackup-2", SubnetId = "/subscriptions/" + netAppMgmtClient.SubscriptionId + "/resourceGroups/" + resourceGroup + "/providers/Microsoft.Network/virtualNetworks/" + vnet + "/subnets/default", Tags = tags, ExportPolicy = exportPolicy }, new VolumeGroupVolumeProperties { Name = $"{volumeGroupName}-DataVol-3", VolumeSpecName = "data", ProximityPlacementGroup = proximityPlacementGroup, CapacityPoolResourceId = pool.Id, ThroughputMibps = 6, UsageThreshold = 100 * gibibyte, ProtocolTypes = volumeProtocolTypes, CreationToken = $"{volumeGroupName}-DataVol-3", SubnetId = "/subscriptions/" + netAppMgmtClient.SubscriptionId + "/resourceGroups/" + resourceGroup + "/providers/Microsoft.Network/virtualNetworks/" + vnet + "/subnets/default", Tags = tags, ExportPolicy = exportPolicy } }; var volumeGroup = new VolumeGroupDetails() { Location = location, Tags = tags, GroupMetaData = new VolumeGroupMetaData() { ApplicationType = ApplicationType.SAPHANA, ApplicationIdentifier = "SH1", GlobalPlacementRules = new List <PlacementKeyValuePairs> { new PlacementKeyValuePairs { Key = "Key1", Value = "value1" } }, DeploymentSpecId = SAPHANAOnGENPOPDeploymentSpecID, GroupDescription = "group description" }, Volumes = volumeGroupVolumeProperties }; var resource = netAppMgmtClient.VolumeGroups.Create(volumeGroup, resourceGroup, accountName, volumeGroupName); Assert.Equal(accountName + '/' + volumeGroupName, resource.Name); if (Environment.GetEnvironmentVariable("AZURE_TEST_MODE") == "Record") { Thread.Sleep(delay); // some robustness against ARM caching } return(resource); }
static private async Task RunAsync() { //--------------------------------------------------------------------------------------------------------------------- // Setting variables necessary for resources creation - change these to appropriated values related to your environment //--------------------------------------------------------------------------------------------------------------------- bool cleanup = false; string subscriptionId = "[Subscription Id]"; string location = "[Location]"; string resourceGroupName = "[Resource group name where ANF resources will be created]"; string vnetName = "[Existing Vnet Name]"; string subnetName = "[Existing Subnet where ANF volumes will be created]"; string vnetResourceGroupName = "[Vnet Resource Group Name]"; string anfAccountName = "[ANF Account Name]"; string capacityPoolName = "[ANF Capacity Pool Name]"; string capacityPoolServiceLevel = "Standard"; // Valid service levels are: Standard, Premium and Ultra long capacitypoolSize = 4398046511104; // 4TiB which is minimum size long volumeSize = 107374182400; // 100GiB - volume minimum size // SMB/CIFS related variables string domainJoinUsername = "******"; string dnsList = "[DNS Ip Address]"; // Please notice that this is a comma-separated string string adFQDN = "[Active Directory FQDN]"; string smbServerNamePrefix = "[SMB Server Name Prefix]"; // this needs to be maximum 10 characters in length and during the domain join process a random string gets appended. //------------------------------------------------------------------------------------------------------ // Getting Active Directory Identity's password (from identity that has rights to domain join computers) //------------------------------------------------------------------------------------------------------ Console.WriteLine("Please type Active Directory's user password that will domain join ANF's SMB server and press [ENTER]:"); string DomainJoinUserPassword = Utils.GetConsolePassword(); // Basic validation if (string.IsNullOrWhiteSpace(DomainJoinUserPassword)) { throw new Exception("Invalid password, password cannot be null or empty string"); } //---------------------------------------------------------------------------------------- // Authenticating using service principal, refer to README.md file for requirement details //---------------------------------------------------------------------------------------- WriteConsoleMessage("Authenticating..."); var credentials = await ServicePrincipalAuth.GetServicePrincipalCredential("AZURE_AUTH_LOCATION"); //------------------------------------------ // Instantiating a new ANF management client //------------------------------------------ WriteConsoleMessage("Instantiating a new Azure NetApp Files management client..."); AzureNetAppFilesManagementClient anfClient = new AzureNetAppFilesManagementClient(credentials) { SubscriptionId = subscriptionId }; WriteConsoleMessage($"\tApi Version: {anfClient.ApiVersion}"); //---------------------- // Creating ANF Account //---------------------- NetAppAccount anfAccount = await GetResourceAsync <NetAppAccount>(anfClient, resourceGroupName, anfAccountName); if (anfAccount == null) { // Setting up Active Directories Object // Despite of this being a list, currently ANF accepts only one Active Directory object and only one Active Directory should exist per subscription. List <ActiveDirectory> activeDirectories = new List <ActiveDirectory>() { new ActiveDirectory() { Dns = dnsList, Domain = adFQDN, Username = domainJoinUsername, Password = DomainJoinUserPassword, SmbServerName = smbServerNamePrefix } }; // Setting up NetApp Files account body object NetAppAccount anfAccountBody = new NetAppAccount() { Location = location.ToLower(), // Important: location needs to be lower case, ActiveDirectories = activeDirectories }; // Requesting account to be created WriteConsoleMessage("Creating account..."); anfAccount = await anfClient.Accounts.CreateOrUpdateAsync(anfAccountBody, resourceGroupName, anfAccountName); } else { WriteConsoleMessage("Account already exists..."); } WriteConsoleMessage($"\tAccount Resource Id: {anfAccount.Id}"); //----------------------- // Creating Capacity Pool //----------------------- CapacityPool capacityPool = await GetResourceAsync <CapacityPool>(anfClient, resourceGroupName, anfAccountName, capacityPoolName); if (capacityPool == null) { // Setting up capacity pool body object CapacityPool capacityPoolBody = new CapacityPool() { Location = location.ToLower(), ServiceLevel = capacityPoolServiceLevel, Size = capacitypoolSize }; // Creating capacity pool WriteConsoleMessage("Creating capacity pool..."); capacityPool = await anfClient.Pools.CreateOrUpdateAsync(capacityPoolBody, resourceGroupName, anfAccount.Name, capacityPoolName); } else { WriteConsoleMessage("Capacity pool already exists..."); } WriteConsoleMessage($"\tCapacity Pool Resource Id: {capacityPool.Id}"); //------------------------ // Creating SMB Volume //------------------------ string volumeName = $"Vol-{anfAccountName}-{capacityPoolName}"; Volume volume = await GetResourceAsync <Volume>(anfClient, resourceGroupName, anfAccountName, ResourceUriUtils.GetAnfCapacityPool(capacityPool.Id), volumeName); if (volume == null) { string subnetId = $"/subscriptions/{subscriptionId}/resourceGroups/{vnetResourceGroupName}/providers/Microsoft.Network/virtualNetworks/{vnetName}/subnets/{subnetName}"; // Creating volume body object Volume volumeBody = new Volume() { Location = location.ToLower(), ServiceLevel = capacityPoolServiceLevel, CreationToken = volumeName, SubnetId = subnetId, UsageThreshold = volumeSize, ProtocolTypes = new List <string>() { "CIFS" } // Despite of this being a list, only one protocol is supported at this time }; // Creating SMB volume // Please notice that the SMB Server gets created at this point by using information stored in ANF Account resource about Active Directory WriteConsoleMessage("Creating volume..."); volume = await anfClient.Volumes.CreateOrUpdateAsync(volumeBody, resourceGroupName, anfAccount.Name, ResourceUriUtils.GetAnfCapacityPool(capacityPool.Id), volumeName); } else { WriteConsoleMessage("Volume already exists..."); } WriteConsoleMessage($"\tVolume Resource Id: {volume.Id}"); //// Outputs SMB Server Name WriteConsoleMessage($"\t====> SMB Server FQDN: {volume.MountTargets[0].SmbServerFqdn}"); //------------------------ // Cleaning up //------------------------ if (cleanup) { WriteConsoleMessage("Cleaning up created resources..."); WriteConsoleMessage("\tDeleting volume..."); await anfClient.Volumes.DeleteAsync(resourceGroupName, anfAccount.Name, ResourceUriUtils.GetAnfCapacityPool(capacityPool.Id), ResourceUriUtils.GetAnfVolume(volume.Id)); // Adding a final verification if the resource completed deletion since it may have a few secs between ARM the Resource Provider be fully in sync await WaitForNoAnfResource <Volume>(anfClient, volume.Id); Utils.WriteConsoleMessage($"\t\tDeleted volume: {volume.Id}"); WriteConsoleMessage("\tDeleting capacity pool..."); await anfClient.Pools.DeleteAsync(resourceGroupName, anfAccount.Name, ResourceUriUtils.GetAnfCapacityPool(capacityPool.Id)); await WaitForNoAnfResource <CapacityPool>(anfClient, capacityPool.Id); Utils.WriteConsoleMessage($"\t\tDeleted capacity pool: {capacityPool.Id}"); WriteConsoleMessage("\tDeleting account..."); await anfClient.Accounts.DeleteAsync(resourceGroupName, anfAccount.Name); await WaitForNoAnfResource <NetAppAccount>(anfClient, anfAccount.Id); Utils.WriteConsoleMessage($"\t\tDeleted account: {anfAccount.Id}"); } }
static private async Task CreateANFCRRAsync() { //---------------------------------------------------------------------------------------- // Authenticating using service principal, refer to README.md file for requirement details //---------------------------------------------------------------------------------------- WriteConsoleMessage("Authenticating..."); Credentials = await ServicePrincipalAuth.GetServicePrincipalCredential("AZURE_AUTH_LOCATION"); //------------------------------------------ // Instantiating a new ANF management client //------------------------------------------ WriteConsoleMessage("Instantiating a new Azure NetApp Files management client..."); AzureNetAppFilesManagementClient anfClient = new AzureNetAppFilesManagementClient(Credentials) { SubscriptionId = subscriptionId }; WriteConsoleMessage($"\tApi Version: {anfClient.ApiVersion}"); //---------------------- // Creating ANF Primary Account //---------------------- // Setting up Primary NetApp Files account body object NetAppAccount anfPrimaryAccountBody = new NetAppAccount(primaryLocation, null, primaryAnfAccountName); WriteConsoleMessage($"Requesting Primary account to be created in {primaryLocation}"); var anfPrimaryAccount = await anfClient.Accounts.CreateOrUpdateAsync(anfPrimaryAccountBody, primaryResourceGroupName, primaryAnfAccountName); WriteConsoleMessage($"\tAccount Resource Id: {anfPrimaryAccount.Id}"); // Setting up capacity pool body object for Primary Account CapacityPool primaryCapacityPoolBody = new CapacityPool() { Location = primaryLocation.ToLower(), // Important: location needs to be lower case ServiceLevel = ServiceLevel.Premium, //Service level can be one of three levels -> { Standard, Premium, Ultra } Size = capacitypoolSize }; WriteConsoleMessage("Requesting capacity pool to be created for Primary Account"); var primaryCapacityPool = await anfClient.Pools.CreateOrUpdateAsync(primaryCapacityPoolBody, primaryResourceGroupName, anfPrimaryAccount.Name, primarycapacityPoolName); WriteConsoleMessage($"\tCapacity Pool Resource Id: {primaryCapacityPool.Id}"); // Creating export policy object VolumePropertiesExportPolicy exportPolicies = new VolumePropertiesExportPolicy() { Rules = new List <ExportPolicyRule> { new ExportPolicyRule() { AllowedClients = "0.0.0.0", Cifs = false, Nfsv3 = false, Nfsv41 = true, RuleIndex = 1, UnixReadOnly = false, UnixReadWrite = true } } }; // Creating primary volume body object string primarySubnetId = $"/subscriptions/{subscriptionId}/resourceGroups/{primaryResourceGroupName}/providers/Microsoft.Network/virtualNetworks/{primaryVNETName}/subnets/{primarySubnetName}"; Volume primaryVolumeBody = new Volume() { ExportPolicy = exportPolicies, Location = primaryLocation.ToLower(), ServiceLevel = ServiceLevel.Premium, //Service level can be one of three levels -> { Standard, Premium, Ultra } CreationToken = primaryVolumeName, SubnetId = primarySubnetId, UsageThreshold = volumeSize, ProtocolTypes = new List <string>() { "NFSv4.1" } }; // Creating NFS 4.1 volume WriteConsoleMessage($"Requesting volume to be created in {primarycapacityPoolName}"); var primaryVolume = await anfClient.Volumes.CreateOrUpdateAsync(primaryVolumeBody, primaryResourceGroupName, primaryAnfAccountName, ResourceUriUtils.GetAnfCapacityPool(primaryCapacityPool.Id), primaryVolumeName); WriteConsoleMessage($"\tVolume Resource Id: {primaryVolume.Id}"); WriteConsoleMessage($"Waiting for {primaryVolume.Id} to be available..."); await ResourceUriUtils.WaitForAnfResource <Volume>(anfClient, primaryVolume.Id); //---------------------- // Creating ANF Secondary Account //---------------------- // Setting up Secondary NetApp Files account body object NetAppAccount anfSecondaryAccountBody = new NetAppAccount(secondaryLocation, null, secondaryAnfAccountName); WriteConsoleMessage($"Requesting Secondary account to be created in {secondaryLocation}"); var anfSecondaryAccount = await anfClient.Accounts.CreateOrUpdateAsync(anfSecondaryAccountBody, secondaryResourceGroupName, secondaryAnfAccountName); WriteConsoleMessage($"\tAccount Resource Id: {anfSecondaryAccount.Id}"); // Setting up capacity pool body object for Secondary Account CapacityPool secondaryCapacityPoolBody = new CapacityPool() { Location = secondaryLocation.ToLower(), // Important: location needs to be lower case ServiceLevel = ServiceLevel.Standard, //Service level can be one of three levels -> { Standard, Premium, Ultra } Size = capacitypoolSize }; WriteConsoleMessage("Requesting capacity pool to be created for Secondary Account"); var secondaryCapacityPool = await anfClient.Pools.CreateOrUpdateAsync(secondaryCapacityPoolBody, secondaryResourceGroupName, anfSecondaryAccount.Name, secondarycapacityPoolName); WriteConsoleMessage($"\tCapacity Pool Resource Id: {secondaryCapacityPool.Id}"); // Creating secondary volume body object string secondarySubnetId = $"/subscriptions/{subscriptionId}/resourceGroups/{secondaryResourceGroupName}/providers/Microsoft.Network/virtualNetworks/{secondaryVNETName}/subnets/{secondarySubnetName}"; Volume secondaryVolumeBody = new Volume() { ExportPolicy = exportPolicies, Location = secondaryLocation.ToLower(), ServiceLevel = ServiceLevel.Standard, //Service level can be one of three levels -> { Standard, Premium, Ultra }, CreationToken = secondaryVolumeName, SubnetId = secondarySubnetId, UsageThreshold = volumeSize, ProtocolTypes = new List <string>() { "NFSv4.1" }, VolumeType = "DataProtection", DataProtection = new VolumePropertiesDataProtection() { Replication = new ReplicationObject() { EndpointType = "dst", RemoteVolumeRegion = primaryLocation, RemoteVolumeResourceId = primaryVolume.Id, ReplicationSchedule = "_10minutely" } } }; //------------------------------------------------------------- // Creating Data Replication Volume on the Destination Account //------------------------------------------------------------- // Creating NFS 4.1 Data Replication Volume WriteConsoleMessage("Adding Data Replication in Destination region..."); var dataReplicationVolume = await anfClient.Volumes.CreateOrUpdateAsync(secondaryVolumeBody, secondaryResourceGroupName, anfSecondaryAccount.Name, ResourceUriUtils.GetAnfCapacityPool(secondaryCapacityPool.Id), secondaryVolumeName); //Wait for Data Replication Volume to get be ready WriteConsoleMessage($"Waiting for {dataReplicationVolume.Id} to be available..."); await ResourceUriUtils.WaitForAnfResource <Volume>(anfClient, dataReplicationVolume.Id); //-------------------------- // Authorizing Source volume //-------------------------- AuthorizeRequest authRequest = new AuthorizeRequest() { RemoteVolumeResourceId = dataReplicationVolume.Id }; WriteConsoleMessage("Authorizing replication in Source region..."); await anfClient.Volumes.AuthorizeReplicationAsync(primaryResourceGroupName, primaryAnfAccountName, ResourceUriUtils.GetAnfCapacityPool(primaryCapacityPool.Id), primaryVolumeName, authRequest); WriteConsoleMessage("ANF Cross-Region Replication has completed successfully"); //----------------------------------------- // Clean up Resources //----------------------------------------- if (shouldCleanUp) { //Wait for replication status to be "Mirrored" WriteConsoleMessage("Checking replication status to become Mirrored before start deleting..."); await ResourceUriUtils.WaitForCompleteReplicationStatus(anfClient, dataReplicationVolume.Id); // Break the replication WriteConsoleMessage("Breaking the replication connection"); await anfClient.Volumes.BreakReplicationAsync(secondaryResourceGroupName, secondaryAnfAccountName, ResourceUriUtils.GetAnfCapacityPool(secondaryCapacityPool.Id), secondaryVolumeName); // Check if replication status is "Broken" WriteConsoleMessage("Checking replication status to become Broken... "); await ResourceUriUtils.WaitForBrokenReplicationStatus(anfClient, dataReplicationVolume.Id); // Delete replication and send confirmation to Source volume WriteConsoleMessage("Deleting the replication connection on the destination volume"); await anfClient.Volumes.DeleteReplicationAsync(secondaryResourceGroupName, secondaryAnfAccountName, ResourceUriUtils.GetAnfCapacityPool(secondaryCapacityPool.Id), secondaryVolumeName); // Delete secondary ANF resources WriteConsoleMessage("Deleting Secondary ANF resources..."); WriteConsoleMessage("Deleting Secondary Volume"); await anfClient.Volumes.DeleteAsync(secondaryResourceGroupName, secondaryAnfAccountName, ResourceUriUtils.GetAnfCapacityPool(secondaryCapacityPool.Id), secondaryVolumeName); // Wait for Data replication volume to be fully deleted await ResourceUriUtils.WaitForNoAnfResource <Volume>(anfClient, dataReplicationVolume.Id); // Delete secondary Capacity Pool WriteConsoleMessage("Deleting Secondary Capacity Pool"); await anfClient.Pools.DeleteAsync(secondaryResourceGroupName, secondaryAnfAccountName, ResourceUriUtils.GetAnfCapacityPool(secondaryCapacityPool.Id)); // wait for secondary Capacity Pool to be fully deleted await ResourceUriUtils.WaitForNoAnfResource <CapacityPool>(anfClient, secondaryCapacityPool.Id); // Delete Secondary ANF account WriteConsoleMessage("Deleting Secondary Account"); await anfClient.Accounts.DeleteAsync(secondaryResourceGroupName, secondaryAnfAccountName); // Delete primary ANF resources WriteConsoleMessage("Deleting Primary ANF resources..."); WriteConsoleMessage("Deleting Primary Volume"); await anfClient.Volumes.DeleteAsync(primaryResourceGroupName, primaryAnfAccountName, ResourceUriUtils.GetAnfCapacityPool(primaryCapacityPool.Id), primaryVolumeName); // Wait for primary Volume to be fully deleted await ResourceUriUtils.WaitForNoAnfResource <Volume>(anfClient, primaryVolume.Id); // Delete primary capacity pool WriteConsoleMessage("Deleting Primary Capacity Pool"); await anfClient.Pools.DeleteAsync(primaryResourceGroupName, primaryAnfAccountName, ResourceUriUtils.GetAnfCapacityPool(primaryCapacityPool.Id)); // Wait for primary capacity pool to be fully deleted await ResourceUriUtils.WaitForNoAnfResource <CapacityPool>(anfClient, primaryCapacityPool.Id); // Delete Primary ANF account WriteConsoleMessage("Deleting Primary Account"); await anfClient.Accounts.DeleteAsync(primaryResourceGroupName, primaryAnfAccountName); } }