From 0674f2219abd36ed1e8cbdeb4895447027321795 Mon Sep 17 00:00:00 2001 From: lijinpei2008 <31384087+lijinpei2008@users.noreply.github.com> Date: Fri, 16 Aug 2024 14:58:16 +0800 Subject: [PATCH] [Resources] Remove-AzResourceGroup - support parameter 'forceDeletion' (#25819) * Remove-AzResourceGroup - support parameter 'forceDeletion' * update changelog * update logic in remove-azresourcegroup * update unit test coverage * Remove unnecessary updates --- .../RemoveAzureResourceGroupCmdlet.cs | 28 +++++++++++--- .../SdkClient/NewResourceManagerSdkClient.cs | 38 +++++++++++++++---- .../RemoveAzureResourceGroupCommandTests.cs | 23 ++++++++++- src/Resources/Resources/ChangeLog.md | 1 + .../Resources/help/Remove-AzResourceGroup.md | 31 +++++++++++++-- 5 files changed, 102 insertions(+), 19 deletions(-) diff --git a/src/Resources/ResourceManager/Implementation/ResourceGroups/RemoveAzureResourceGroupCmdlet.cs b/src/Resources/ResourceManager/Implementation/ResourceGroups/RemoveAzureResourceGroupCmdlet.cs index a17e9545e5c8..dc57352f759d 100644 --- a/src/Resources/ResourceManager/Implementation/ResourceGroups/RemoveAzureResourceGroupCmdlet.cs +++ b/src/Resources/ResourceManager/Implementation/ResourceGroups/RemoveAzureResourceGroupCmdlet.cs @@ -16,6 +16,7 @@ using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation; using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels; using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters; +using System.Linq; using System.Management.Automation; using ProjectResources = Microsoft.Azure.Commands.ResourceManager.Cmdlets.Properties.Resources; @@ -48,6 +49,9 @@ public class RemoveAzureResourceGroupCmdlet : ResourceManagerCmdletBaseWithApiVe [ValidateNotNullOrEmpty] public string Id { get; set; } + [Parameter(Mandatory = false, HelpMessage = "The resource types you want to force delete.Currently, only the following is supported: forceDeletionTypes=Microsoft.Compute/virtualMachineScaleSets,Microsoft.Compute/virtualMachines,Microsoft.Databricks/workspaces")] + public string ForceDeletionType { get; set; } + [Parameter(Mandatory = false, HelpMessage = "Do not ask for confirmation.")] public SwitchParameter Force { get; set; } @@ -58,12 +62,24 @@ protected override void OnProcessRecord() { Name = Name ?? ResourceIdentifier.FromResourceGroupIdentifier(this.Id).ResourceGroupName; - ConfirmAction( - Force.IsPresent, - string.Format(ProjectResources.RemovingResourceGroup, Name), - ProjectResources.RemoveResourceGroupMessage, - Name, - () => ResourceManagerSdkClient.DeleteResourceGroup(Name)); + if (string.IsNullOrWhiteSpace(ForceDeletionType)) + { + ConfirmAction( + Force.IsPresent, + string.Format(ProjectResources.RemovingResourceGroup, Name), + ProjectResources.RemoveResourceGroupMessage, + Name, + () => ResourceManagerSdkClient.DeleteResourceGroup(Name)); + } + else + { + ConfirmAction( + Force.IsPresent, + string.Format(ProjectResources.RemovingResourceGroup, Name), + ProjectResources.RemoveResourceGroupMessage, + Name, + () => NewResourceManagerSdkClient.DeleteResourceGroup(Name, ForceDeletionType)); + } WriteObject(true); } diff --git a/src/Resources/ResourceManager/SdkClient/NewResourceManagerSdkClient.cs b/src/Resources/ResourceManager/SdkClient/NewResourceManagerSdkClient.cs index aa1329cc71ae..3715d80c7198 100644 --- a/src/Resources/ResourceManager/SdkClient/NewResourceManagerSdkClient.cs +++ b/src/Resources/ResourceManager/SdkClient/NewResourceManagerSdkClient.cs @@ -208,7 +208,7 @@ public DeploymentExtended ProvisionDeploymentStatus(PSDeploymentCmdletParameters Action writeProgressAction = () => this.WriteDeploymentProgress(parameters, deployment, deploymentOperationError); - var deploymentExtended = this.WaitDeploymentStatus( + var deploymentExtended = this.WaitDeploymentStatus( getDeploymentFunc, writeProgressAction, ProvisioningState.Canceled, @@ -217,8 +217,8 @@ public DeploymentExtended ProvisionDeploymentStatus(PSDeploymentCmdletParameters if (deploymentOperationError.ErrorMessages.Count > 0) { - WriteError(GetDeploymentErrorMessagesWithOperationId(deploymentOperationError, - parameters.DeploymentName, + WriteError(GetDeploymentErrorMessagesWithOperationId(deploymentOperationError, + parameters.DeploymentName, deploymentExtended?.Properties?.CorrelationId)); } @@ -260,11 +260,11 @@ private void WriteDeploymentProgress(PSDeploymentCmdletParameters parameters, De } else { - deploymentOperationError.ProcessError(operation); + deploymentOperationError.ProcessError(operation); } } } - + private DeploymentExtended WaitDeploymentStatus( Func>> getDeployment, Action listDeploymentOperations, @@ -680,7 +680,7 @@ private Dictionary> ConvertAuxTenantDictionary(IDictionary< { if (auxTenants == null) return null; - var headers = new Dictionary> (); + var headers = new Dictionary>(); foreach (KeyValuePair> entry in auxTenants) { headers[entry.Key] = entry.Value.ToList(); @@ -950,6 +950,27 @@ public virtual void DeleteResourceGroup(string name) } } + /// + /// Deletes a given resource group + /// + /// The resource group name + /// + /// The resource types you want to force delete. Currently, only the following + /// is supported: + /// forceDeletionTypes=Microsoft.Compute/virtualMachines,Microsoft.Compute/virtualMachineScaleSets + /// + public virtual void DeleteResourceGroup(string name, string forceDeletionTypes) + { + if (!ResourceManagementClient.ResourceGroups.CheckExistence(name)) + { + WriteError(ProjectResources.ResourceGroupDoesntExists); + } + else + { + ResourceManagementClient.ResourceGroups.Delete(name, forceDeletionTypes); + } + } + /// /// Filters the resource group deployments with provided options /// @@ -1691,7 +1712,8 @@ private void CancelDeploymentAtResourceGroup(List deployments, str /// The validation errors if there's any, or empty list otherwise. public virtual List ValidateDeployment(PSDeploymentCmdletParameters parameters) { - if (parameters.DeploymentName == null){ + if (parameters.DeploymentName == null) + { parameters.DeploymentName = GenerateDeploymentName(parameters); } Deployment deployment = CreateBasicDeployment(parameters, parameters.DeploymentMode, null); @@ -1729,7 +1751,7 @@ public string GetDeploymentErrorMessagesWithOperationId(DeploymentOperationError .AppendLine()); // Add correlationId - sb.AppendLine().AppendFormat(ProjectResources.DeploymentCorrelationId, correlationId); + sb.AppendLine().AppendFormat(ProjectResources.DeploymentCorrelationId, correlationId); return sb.ToString(); } diff --git a/src/Resources/Resources.Test/ResourceGroups/RemoveAzureResourceGroupCommandTests.cs b/src/Resources/Resources.Test/ResourceGroups/RemoveAzureResourceGroupCommandTests.cs index 72304a3aafdf..9d723b5e2732 100644 --- a/src/Resources/Resources.Test/ResourceGroups/RemoveAzureResourceGroupCommandTests.cs +++ b/src/Resources/Resources.Test/ResourceGroups/RemoveAzureResourceGroupCommandTests.cs @@ -30,21 +30,26 @@ public class RemoveAzureResourceGroupCommandTests : RMTestBase private Mock resourcesClientMock; + private Mock newResourceClientMock; + private Mock commandRuntimeMock; private string resourceGroupName = "myResourceGroup"; private string resourceGroupId = "/subscriptions/subId/resourceGroups/myResourceGroup"; private string resourceId = "/subscriptions/subId/resourceGroups/myResourceGroup/providers/myResourceProvider/resourceType/myResource"; + private string resourceForceDeletionType = "Microsoft.Compute/virtualMachineScaleSets,Microsoft.Compute/virtualMachines,Microsoft.Databricks/workspaces"; public RemoveAzureResourceGroupCommandTests(ITestOutputHelper output) { resourcesClientMock = new Mock(); + newResourceClientMock = new Mock(); XunitTracingInterceptor.AddToContext(new XunitTracingInterceptor(output)); commandRuntimeMock = new Mock(); cmdlet = new RemoveAzureResourceGroupCmdlet() { CommandRuntime = commandRuntimeMock.Object, - ResourceManagerSdkClient = resourcesClientMock.Object + ResourceManagerSdkClient = resourcesClientMock.Object, + NewResourceManagerSdkClient = newResourceClientMock.Object }; } @@ -99,5 +104,21 @@ public void RemovesResourceGroupFromResourceId() resourcesClientMock.Verify(f => f.DeleteResourceGroup(resourceGroupName), Times.Never()); } + + [Fact] + [Trait(Category.AcceptanceType, Category.CheckIn)] + public void RemovesResourceGroupFromForceDeletionType() + { + commandRuntimeMock.Setup(f => f.ShouldProcess(It.IsAny(), It.IsAny())).Returns(true); + newResourceClientMock.Setup(f => f.DeleteResourceGroup(resourceGroupName, resourceForceDeletionType)); + + cmdlet.Name = resourceGroupName; + cmdlet.ForceDeletionType = resourceForceDeletionType; + cmdlet.Force = true; + + cmdlet.ExecuteCmdlet(); + + newResourceClientMock.Verify(f => f.DeleteResourceGroup(resourceGroupName, resourceForceDeletionType), Times.Once()); + } } } diff --git a/src/Resources/Resources/ChangeLog.md b/src/Resources/Resources/ChangeLog.md index 12b4bf9ae2f3..25cf03ca4e31 100644 --- a/src/Resources/Resources/ChangeLog.md +++ b/src/Resources/Resources/ChangeLog.md @@ -19,6 +19,7 @@ --> ## Upcoming Release +* `Remove-AzResourceGroup` - support parameter "[-ForceDeletionType]". * Removed specific characters from the codebase to unblock digital signature verification. ## Version 7.3.0 diff --git a/src/Resources/Resources/help/Remove-AzResourceGroup.md b/src/Resources/Resources/help/Remove-AzResourceGroup.md index 8ff0ed21d774..edd9b3fa45aa 100644 --- a/src/Resources/Resources/help/Remove-AzResourceGroup.md +++ b/src/Resources/Resources/help/Remove-AzResourceGroup.md @@ -15,15 +15,15 @@ Removes a resource group. ### RemoveByResourceGroupName (Default) ``` -Remove-AzResourceGroup [-Name] [-Force] [-AsJob] [-ApiVersion ] [-Pre] - [-DefaultProfile ] [-ProgressAction ] [-WhatIf] [-Confirm] +Remove-AzResourceGroup [-Name] [-ForceDeletionType ] [-Force] [-AsJob] [-ApiVersion ] + [-Pre] [-DefaultProfile ] [-WhatIf] [-Confirm] [] ``` ### RemoveByResourceGroupId ``` -Remove-AzResourceGroup -Id [-Force] [-AsJob] [-ApiVersion ] [-Pre] - [-DefaultProfile ] [-ProgressAction ] [-WhatIf] [-Confirm] +Remove-AzResourceGroup -Id [-ForceDeletionType ] [-Force] [-AsJob] [-ApiVersion ] + [-Pre] [-DefaultProfile ] [-WhatIf] [-Confirm] [] ``` @@ -55,6 +55,14 @@ Get-AzResourceGroup | Remove-AzResourceGroup This command uses the **Get-AzResourceGroup** cmdlet to get all resource groups, and then passes them to **Remove-AzResourceGroup** by using the pipeline operator. +### Example 4: Remove a resource groups use ForceDeletionType +```powershell +Remove-AzResourceGroup -Name "ContosoRG01" -ForceDeletionType "Microsoft.Compute/virtualMachineScaleSets,Microsoft.Compute/virtualMachines,Microsoft.Databricks/workspaces" +``` + +This command removes the ContosoRG01 resource group use the ForceDeletionType. +The cmdlet prompts you for confirmation and returns no output. + ## PARAMETERS ### -ApiVersion @@ -118,6 +126,21 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -ForceDeletionType +The resource types you want to force delete.Currently, only the following is supported: forceDeletionTypes=Microsoft.Compute/virtualMachines,Microsoft.Compute/virtualMachineScaleSets + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -Id Specifies the ID of resource group to remove. Wildcard characters are not permitted.