Skip to content

Commit

Permalink
feat: added apim soft delete scripts (#278)
Browse files Browse the repository at this point in the history
Co-authored-by: Stijn Moreels <[email protected]>
Co-authored-by: Pim Simons <[email protected]>
  • Loading branch information
3 people authored Apr 1, 2022
1 parent f7402d9 commit 2a82457
Show file tree
Hide file tree
Showing 13 changed files with 576 additions and 0 deletions.
73 changes: 73 additions & 0 deletions docs/preview/02-Features/powershell/azure-management.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@

---
title: "Azure Management"
layout: default
---

# Azure Management

This module provides the following capabilities:
- [Azure Management](#azure-management)
- [Installation](#installation)
- [Removing a soft deleted API Management instance](#removing-a-soft-deleted-api-management-instance)
- [Restoring a soft deleted API Management instance](#restoring-a-soft-deleted-api-management-instance)

## Installation

To have access to the following features, you have to import the module:

```powershell
PS> Install-Module -Name Arcus.Scripting.Management
```

## Removing a soft deleted API Management instance

Removes a soft deleted API Management instance.
For more information on API Management and soft deletion see [here](https://docs.microsoft.com/en-us/azure/api-management/soft-delete#soft-delete-behavior).

| Parameter | Mandatory | Description |
| ---------------- | --------- | ---------------------------------------------------------------------------------------------------------- |
| `Name` | yes | The name of the API Management instance that has been soft deleted. |
| `SubscriptionId` | no | The Id of the subscription containing the Azure API Management instance. |
| | | When not provided, it will be retrieved from the current context (Get-AzContext). |
| `EnvironmentName`| no | The name of the Azure environment where the Azure API Management instance resides. (default: `AzureCloud`) |
| `AccessToken` | no | The access token to be used to remove the Azure API Management instance. |
| | | When not provided, it will be retrieved from the current context (Get-AzContext). |
| `ApiVersion ` | no | The version of the management API to be used. (default: `2021-08-01`) |

> :bulb: The `ApiVersion` has successfully been tested with version `2021-08-01`.
**Example**
```powershell
PS> Remove-AzApiManagementSoftDeletedService -Name "my-apim"
# Checking if the API Management instance with name 'my-apim' is listed as a soft deleted service
# API Management instance has been found for name 'my-apim' as a soft deleted service
# Removing the soft deleted API Management instance 'my-apim'
# Successfully removed the soft deleted API Management instance 'my-apim'
```

## Restoring a soft deleted API Management instance

Restores a soft deleted API Management instance.
For more information on API Management and soft deletion see [here](https://docs.microsoft.com/en-us/azure/api-management/soft-delete#soft-delete-behavior).

| Parameter | Mandatory | Description |
| ---------------- | --------- | ---------------------------------------------------------------------------------------------------------- |
| `Name` | yes | The name of the API Management instance that has been soft deleted. |
| `SubscriptionId` | no | The Id of the subscription containing the Azure API Management instance. |
| | | When not provided, it will be retrieved from the current context (Get-AzContext). |
| `EnvironmentName`| no | The name of the Azure environment where the Azure API Management instance resides. (default: `AzureCloud`) |
| `AccessToken` | no | The access token to be used to restore the Azure API Management instance. |
| | | When not provided, it will be retrieved from the current context (Get-AzContext). |
| `ApiVersion ` | no | The version of the management API to be used. (default: `2021-08-01`) |

> :bulb: The `ApiVersion` has successfully been tested with version `2021-08-01`.
**Example**
```powershell
PS> Restore-AzApiManagementSoftDeletedService -Name "my-apim"
# Checking if the API Management instance with name 'my-apim' is listed as a soft deleted service
# API Management instance has been found for name 'my-apim' as a soft deleted service
# Restoring the soft deleted API Management instance 'my-apim'
# Successfully restored the soft deleted API Management instance 'my-apim'
```
Binary file not shown.
71 changes: 71 additions & 0 deletions src/Arcus.Scripting.Management/Arcus.Scripting.Management.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<#
.Synopsis
Remove a soft deleted API Management instance.
.Description
Permanently remove a soft deleted API Management instance.
.Parameter Name
The name of the Azure API Management instance which has been soft deleted and will be permanently removed.
.Parameter SubscriptionId
[Optional] The Id of the subscription containing the Azure API Management instance. When not provided, it will be retrieved from the current context (Get-AzContext).
.Parameter EnvironmentName
[Optional] The Azure Cloud environment in which the Azure API Management instance resides.
.Parameter AccessToken
[Optional] The access token to be used to restore the Azure API Management instance.
.Parameter ApiVersion
[Optional] The version of the api to be used.
#>
function Remove-AzApiManagementSoftDeletedService {
param(
[Parameter(Mandatory = $true)][string] $Name = $(throw "Name of the API Management instance is required"),
[Parameter(Mandatory = $false)][string] $SubscriptionId = "",
[Parameter(Mandatory = $false)][string] $EnvironmentName = "AzureCloud",
[Parameter(Mandatory = $false)][string] $AccessToken = "",
[Parameter(Mandatory = $false)][string] $ApiVersion = "2021-08-01"
)

. $PSScriptRoot\Scripts\Remove-AzApiManagementSoftDeletedService.ps1 -Name $Name -SubscriptionId $SubscriptionId -EnvironmentName $EnvironmentName -AccessToken $AccessToken -ApiVersion $ApiVersion
}

Export-ModuleMember -Function Remove-AzApiManagementSoftDeletedService

<#
.Synopsis
Restore a soft deleted API Management instance.
.Description
Restore a soft deleted API Management instance.
.Parameter Name
The name of the Azure API Management instance which has been soft deleted and will be restored.
.Parameter SubscriptionId
[Optional] The Id of the subscription containing the Azure API Management instance. When not provided, it will be retrieved from the current context (Get-AzContext).
.Parameter EnvironmentName
[Optional] The Azure Cloud environment in which the Azure API Management instance resides.
.Parameter AccessToken
[Optional] The access token to be used to restore the Azure API Management instance.
.Parameter ApiVersion
[Optional] The version of the api to be used.
#>
function Restore-AzApiManagementSoftDeletedService {
param(
[Parameter(Mandatory = $true)][string] $Name = $(throw "Name of the API Management instance is required"),
[Parameter(Mandatory = $false)][string] $SubscriptionId = "",
[Parameter(Mandatory = $false)][string] $EnvironmentName = "AzureCloud",
[Parameter(Mandatory = $false)][string] $AccessToken = "",
[Parameter(Mandatory = $false)][string] $ApiVersion = "2021-08-01"
)

. $PSScriptRoot\Scripts\Restore-AzApiManagementSoftDeletedService.ps1 -Name $Name -SubscriptionId $SubscriptionId -EnvironmentName $EnvironmentName -AccessToken $AccessToken -ApiVersion $ApiVersion
}

Export-ModuleMember -Function Restore-AzApiManagementSoftDeletedService
43 changes: 43 additions & 0 deletions src/Arcus.Scripting.Management/Arcus.Scripting.Management.pssproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{a7b00f0f-4e7b-48d3-9a3e-6ae99602d2cd}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>Arcus.Scripting.Management</RootNamespace>
<AssemblyName>Arcus.Scripting.Management</AssemblyName>
<Name>Arcus.Scripting.Management</Name>
<ProjectHome />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Folder Include="Scripts\" />
</ItemGroup>
<ItemGroup>
<Compile Include="Arcus.Scripting.Management.psd1" />
<Compile Include="Arcus.Scripting.Management.psm1" />
<Compile Include="Scripts\Get-AzApiManagementSoftDeletedResources.ps1" />
<Compile Include="Scripts\Get-AzApiManagementResourceManagementUrl.ps1" />
<Compile Include="Scripts\Remove-AzApiManagementSoftDeletedService.ps1" />
<Compile Include="Scripts\Restore-AzApiManagementSoftDeletedService.ps1" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Target Name="Build" />
<Import Project="$(MSBuildExtensionsPath)\PowerShell Tools for Visual Studio\PowerShellTools.targets" Condition="Exists('$(MSBuildExtensionsPath)\PowerShell Tools for Visual Studio\PowerShellTools.targets')" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
param(
[Parameter(Mandatory = $true)][string] $EnvironmentName
)

try {
$resourceManagerUrl = ""

$environments = (Get-AzEnvironment).Name
if ($EnvironmentName -notin $environments) {
$supportedEnvironments = ""

foreach ($env in $environments) {
if ($supportedEnvironments.Length -eq 0) {
$supportedEnvironments += $env
}
else {
$supportedEnvironments += ", " + $env
}
}

Write-Error "Unrecognized environment specified. Supported values are: $supportedEnvironments"
}

$resourceManagerUrl = (Get-AzEnvironment -Name $EnvironmentName).ResourceManagerUrl

return $resourceManagerUrl
}
catch {
Write-Warning "Failed to retrieve the resource management endpoint"
$ErrorMessage = $_.Exception.Message
Write-Warning "Error: $ErrorMessage"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
param(
[Parameter(Mandatory = $true)][string] $Name,
[Parameter(Mandatory = $true)][string] $SubscriptionId,
[Parameter(Mandatory = $true)][string] $ResourceManagerUrl,
[Parameter(Mandatory = $true)][object] $AuthHeader,
[Parameter(Mandatory = $true)][string] $ApiVersion
)

Write-Verbose "Checking if the API Management instance with name '$Name' is listed as a soft deleted service"
$getUri = "$ResourceManagerUrl" + "subscriptions/$SubscriptionId/providers/Microsoft.ApiManagement/deletedservices" + "?api-version=$ApiVersion"

$deletedServices = (Invoke-RestMethod -Method GET -Uri $getUri -Headers $AuthHeader)

if ($deletedServices.value.count -eq 0 -or ($deletedServices.value | Where-Object name -eq $Name).count -eq 0) {
throw "API Management instance with name '$Name' is not listed as a soft deleted service and therefore it cannot be removed or restored"
}

Write-Host "API Management instance has been found for name '$Name' as a soft deleted service"

return $deletedServices
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
param(
[Parameter(Mandatory = $true)][string] $Name = $(throw "Name of the API Management instance is required"),
[Parameter(Mandatory = $false)][string] $SubscriptionId = "",
[Parameter(Mandatory = $false)][string] $EnvironmentName = "AzureCloud",
[Parameter(Mandatory = $false)][string] $AccessToken = "",
[Parameter(Mandatory = $false)][string] $ApiVersion = "2021-08-01"
)

if ($SubscriptionId -eq "" -or $AccessToken -eq "") {
# Request accessToken in case the script contains no records
$token = Get-AzCachedAccessToken

$AccessToken = $token.AccessToken
$SubscriptionId = $token.SubscriptionId
}

$authHeader = @{
'Authorization'='Bearer ' + $AccessToken
}

$resourceManagerUrl = . $PSScriptRoot\Get-AzApiManagementResourceManagementUrl.ps1 -EnvironmentName $EnvironmentName

$deletedServices = . $PSScriptRoot\Get-AzApiManagementSoftDeletedResources.ps1 -Name $Name -SubscriptionId $SubscriptionId -ResourceManagerUrl $resourceManagerUrl -AuthHeader $authHeader -ApiVersion $ApiVersion

Write-Host "Removing the soft deleted API Management instance '$Name'"
try {
$serviceId = ($deletedServices.value | Where-Object name -eq $Name).id
$deleteUri = "$resourceManagerUrl" + "$serviceId" + "?api-version=$ApiVersion"
$removeService = Invoke-RestMethod -Method DELETE -Uri $deleteUri -Headers $authHeader
} catch {
throw "The soft deleted API Management instance '$Name' could not be removed. Details: $($_.Exception.Message)"
}

Write-Host "Successfully removed the soft deleted API Management instance '$Name'"
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
param(
[Parameter(Mandatory = $true)][string] $Name = $(throw "Name of the API Management instance is required"),
[Parameter(Mandatory = $false)][string] $SubscriptionId = "",
[Parameter(Mandatory = $false)][string] $EnvironmentName = "AzureCloud",
[Parameter(Mandatory = $false)][string] $AccessToken = "",
[Parameter(Mandatory = $false)][string] $ApiVersion = "2021-08-01"
)

if ($SubscriptionId -eq "" -or $AccessToken -eq "") {
# Request accessToken in case the script contains no records
$token = Get-AzCachedAccessToken

$AccessToken = $token.AccessToken
$SubscriptionId = $token.SubscriptionId
}

$authHeader = @{
'Authorization'='Bearer ' + $AccessToken
}

$resourceManagerUrl = . $PSScriptRoot\Get-AzApiManagementResourceManagementUrl.ps1 -EnvironmentName $EnvironmentName

$deletedServices = . $PSScriptRoot\Get-AzApiManagementSoftDeletedResources.ps1 -Name $Name -SubscriptionId $SubscriptionId -ResourceManagerUrl $resourceManagerUrl -AuthHeader $authHeader -ApiVersion $ApiVersion

Write-Host "Restoring the soft deleted API Management instance '$Name'"
try {
$location = ($deletedServices.value | Where-Object name -eq $Name).location
$serviceId = ($deletedServices.value | Where-Object name -eq $Name).properties.serviceId
$data = @{
location = $location
properties = @{
restore = $true
};
};
$body = $data | ConvertTo-Json;
$putUri = "$resourceManagerUrl" + "$serviceId" + "?api-version=$ApiVersion"
$restoreService = Invoke-RestMethod -Method PUT -Uri $putUri -ContentType 'application/json' -Headers $authHeader -Body $body
} catch {
throw "The soft deleted API Management instance '$Name' could not be restored. Details: $($_.Exception.Message)"
}

Write-Host "Successfully restored the soft deleted API Management instance '$Name'"
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Import-Module -Name $PSScriptRoot\..\Arcus.Scripting.Management -ErrorAction Stop
Import-Module -Name $PSScriptRoot\..\Arcus.Scripting.Security -ErrorAction Stop

InModuleScope Arcus.Scripting.Management {
Describe "Arcus Azure Management integration tests" {
BeforeEach {
$config = & $PSScriptRoot\Load-JsonAppsettings.ps1 -fileName "appsettings.json"
& $PSScriptRoot\Connect-AzAccountFromConfig.ps1 -config $config
}
Context "Remove soft deleted Azure API Management service" {
It "Providing an API Management name that does not exist as a soft deleted service should fail" {
# Arrange
$Name = 'unexisting-apim-instance'

# Act
{
Remove-AzApiManagementSoftDeletedService -Name $Name
} | Should -Throw -ExpectedMessage "API Management instance with name '$Name' is not listed as a soft deleted service and therefore it cannot be removed or restored"
}
}
Context "Restore soft deleted Azure API Management service" {
It "Providing an API Management name that does not exist as a soft deleted service should fail" {
# Arrange
$Name = 'unexisting-apim-instance'

# Act
{
Restore-AzApiManagementSoftDeletedService -Name $Name
} | Should -Throw -ExpectedMessage "API Management instance with name '$Name' is not listed as a soft deleted service and therefore it cannot be removed or restored"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Compile Include="Arcus.Scripting.Management.tests.ps1" />
<Compile Include="Arcus.Scripting.ARM.tests.ps1" />
<Compile Include="Arcus.Scripting.DevOps.tests.ps1" />
<Compile Include="Arcus.Scripting.AppService.tests.ps1" />
Expand Down
Loading

0 comments on commit 2a82457

Please sign in to comment.