Confirm-AzBPResource Initial Implementation (#152)

* Initial PoC for custom assertion

* Add help comments, unit tests, and cleanup code

* Resolve linting issues

* Revert renaming of New Object function:

* PR feedback
This commit is contained in:
Mary Sha 2023-02-14 09:31:46 -08:00 коммит произвёл GitHub
Родитель ac0e088f99
Коммит 1fa8249b03
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 340 добавлений и 9 удалений

Просмотреть файл

@ -47,6 +47,7 @@
"Get-KeyVaultCertificate",
"Get-KeyVaultCertificateExist",
"Get-ResourceByType",
"Confirm-Resource"
"Get-Resource",
"Get-ResourceGroup",
"Get-ResourceGroupExist",

Просмотреть файл

@ -53,6 +53,72 @@ Describe "Get-Resource" {
}
}
Describe "Confirm-Resource" {
Context "unit tests" -Tag "Unit" {
BeforeEach {
Mock -ModuleName Common Format-NotExistError{}
Mock -ModuleName Common Format-IncorrectValueError{}
}
It "Calls Get-ResourceByType; returns true when Get-ResourceByType returns non empty object." {
Mock -ModuleName Common Get-ResourceByType{ return "SomethingReturned" } -Verifiable
$result = Confirm-Resource -ResourceType "ResourceGroup" -ResourceName "mockResourceName"
Should -InvokeVerifiable
Should -Invoke -ModuleName Common -CommandName "Format-NotExistError" -Times 0
Should -Invoke -ModuleName Common -CommandName "Format-IncorrectValueError" -Times 0
$result.Success | Should -Be $true
}
It "Calls Get-ResourceByType and Format-NotExistError; returns false when Get-ResourceByType returns empty object." {
Mock -ModuleName Common Get-ResourceByType{ return $null } -Verifiable
$result = Confirm-Resource -ResourceType "ResourceGroup" -ResourceName "mockResourceName"
Should -InvokeVerifiable
Should -Invoke -ModuleName Common -CommandName "Format-NotExistError" -Times 1
Should -Invoke -ModuleName Common -CommandName "Format-IncorrectValueError" -Times 0
$result.Success | Should -Be $false
}
It "Calls Get-ResourceByType and Format-IncorrectValueError; returns false when property does not match value." {
Mock -ModuleName Common Get-ResourceByType{ return @{TestKey = "WrongValue"} } -Verifiable
$result = Confirm-Resource -ResourceType "ResourceGroup" -ResourceName "mockResourceName" `
-PropertyKey "TestKey" -PropertyValue "RightValue"
Should -InvokeVerifiable
Should -Invoke -ModuleName Common -CommandName "Format-NotExistError" -Times 0
Should -Invoke -ModuleName Common -CommandName "Format-IncorrectValueError" -Times 1
$result.Success | Should -Be $false
}
}
}
Describe "ErrorRecord Helper Methods" {
Context "unit tests" -Tag "Unit" {
It "Calls Format-ErrorRecord when Format-NotExistError is called" {
Mock -ModuleName Common Format-ErrorRecord{} -Verifiable
Format-NotExistError -Message "testMessage"
Should -InvokeVerifiable
}
It "Calls Format-ErrorRecord when Format-IncorrectValueError is called" {
Mock -ModuleName Common Format-ErrorRecord{} -Verifiable
Format-IncorrectValueError -Message "testMessage"
Should -InvokeVerifiable
}
It "Creates ErrorRecord with correct message and ID when Format-ErrorRecord is called" {
Mock -ModuleName Common New-Object{} -Verifiable
Format-ErrorRecord -Message "testMessage" -ErrorID "testErrorID"
Should -InvokeVerifiable
}
}
}
AfterAll {
Remove-Module Common
Remove-Module ResourceGroup

Просмотреть файл

@ -22,6 +22,12 @@ enum ResourceType {
WebApp
}
class ConfirmResult {
[boolean]$Success
[System.Management.Automation.ErrorRecord]$Error
[System.Object]$ResourceDetails
}
<#
.SYNOPSIS
Gets an Azure Resource.
@ -74,8 +80,7 @@ function Get-ResourceByType {
[ResourceType]$ResourceType
)
switch ($ResourceType)
{
switch ($ResourceType) {
ActionGroup { return Get-ActionGroup -ActionGroupName $ResourceName -ResourceGroupName $ResourceGroupName }
AKSCluster { return Get-AKSCluster -AKSName $ResourceName -ResourceGroupName $ResourceGroupName }
AppServicePlan { return Get-AppServicePlan -AppServicePlanName $ResourceName -ResourceGroupName $ResourceGroupName }
@ -136,4 +141,186 @@ function Get-Resource {
}
}
Export-ModuleMember -Function Get-Resource, Get-ResourceByType
<#
.SYNOPSIS
Confirms whether a resource exists or properties on a resource are configured correctly.
.DESCRIPTION
The Confirm-AzBPResource cmdlet confirms whether an Azure resource exists and/or confirms whether properties
on a resource exist and are configured to the correct value. The cmdlet will return a ConfirmResult object
which contains the following properties:
- Success: True if the resource exists and/or the property is set to the expected value. Otherwise, false.
- Error: System.Management.Automation.ErrorRecord containing an ErrorRecord with a message explaining
that a resource did not exist or property was not set to the expected value.
- ResourceDetails: System.Object that contains the details of the Azure Resource that is being confirmed.
.PARAMETER ResourceName
The name of the Resource
.PARAMETER ResourceGroupName
The name of the Resource Group
.PARAMETER ResourceType
The type of the Resource (currently supports the following:
ActionGroup
AKSCluster
AppServicePlan
ContainerRegistry
KeyVault
ResourceGroup
SqlDatabase
SqlServer
VirtualMachine
WebApp)
.PARAMETER PropertyKey
The name of the property to check on the resource
.PARAMETER PropertyValue
The expected value of the property to check
.EXAMPLE
Checking whether a resource exists (i.e. Resource Group)
Confirm-AzBPResource -ResourceType $resourceType -ResourceName $resourceGroupName
.EXAMPLE
Confirm whether a resource has a property configured correctly (i.e. Resource Group located in West US 3)
Confirm-AzBPResource -ResourceType $resourceType -ResourceName $resourceGroupName -PropertyKey "Location" `
-PropertyValue "WestUS3"
.INPUTS
ResourceType
System.String
.OUTPUTS
ConfirmResult
#>
function Confirm-Resource {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[ResourceType]$ResourceType,
[Parameter(Mandatory = $true)]
[string]$ResourceName,
[Parameter(Mandatory = $false)]
[string]$ResourceGroupName,
[Parameter(Mandatory = $false)]
[string]$PropertyKey,
[Parameter(Mandatory = $false)]
[string]$PropertyValue
)
$ConfirmResult = [ConfirmResult]::new()
$ConfirmResult.ResourceDetails = Get-ResourceByType -ResourceGroupName $ResourceGroupName -ResourceName $ResourceName -ResourceType $ResourceType
if ($null -ne $ConfirmResult.ResourceDetails) {
$ConfirmResult.Success = $true
if ($PropertyKey) {
if ($ConfirmResult.ResourceDetails.$PropertyKey -ne $PropertyValue) {
$ConfirmResult.Success = $false
$ConfirmResult.Error = Format-IncorrectValueError -ExpectedKey $PropertyKey -ExpectedValue $PropertyValue -ActualResult $ConfirmResult.ResourceDetails.$PropertyKey
}
}
}
else {
$ConfirmResult.Success = $false
$ConfirmResult.Error = Format-NotExistError -Expected $ResourceName
}
return $ConfirmResult
}
<#
.SYNOPSIS
Private function to create a message and ErrorRecord for when a resource does not exist.
.DESCRIPTION
Format-NotExistError is a private helper function that can be used to construct a message and ErrorRecord
for when a resource does not exist.
.PARAMETER Expected
The name of the resource that was expected to exist.
.EXAMPLE
Format-NotExistError -Expected "MyVM"
.INPUTS
System.String
.OUTPUTS
System.Management.Automation.ErrorRecord
#>
function Format-NotExistError([string]$Expected) {
$Message = "Expected $Expected to exist, but it does not exist."
return Format-ErrorRecord -Message $Message -ErrorID "BenchPressExistFail"
}
<#
.SYNOPSIS
Private function to create a message and ErrorRecord for when a resource property is not set correctly.
.DESCRIPTION
Format-IncorrectValueError is a private helper function that can be used to construct a message and ErrorRecord
for when a resource property is not set to the expected value.
.PARAMETER ExpectedKey
The resource property name that is checked
.PARAMETER ExpectedValue
The expected value of the resource property
.PARAMETER ActualValue
The actual value of the resource property
.EXAMPLE
Format-IncorrectValueError -ExpectedKey "Location" -ExpectedValue "WestUS3" -ActualValue "EastUS"
.INPUTS
System.String
.OUTPUTS
System.Management.Automation.ErrorRecord
#>
function Format-IncorrectValueError([string]$ExpectedKey, [string]$ExpectedValue, [string]$ActualValue) {
$Message = "Expected $ExpectedKey to be $ExpectedValue, but got $ActualValue"
return Format-ErrorRecord -Message $Message -ErrorID "BenchPressValueFail"
}
<#
.SYNOPSIS
Private function to help construct a ErrorRecord.
.DESCRIPTION
Format-ErrorRecord is a private helper function that can be used to construct an ErrorRecord.
.PARAMETER Message
Message for the ErrorRecord
.PARAMETER ErrorID
A string that can be used to uniquily identify the ErrorRecord.
.EXAMPLE
Format-ErrorRecord -Message $incorrectValueMessage -ErrorID "BenchPressValueFail"
.INPUTS
System.String
.OUTPUTS
System.Management.Automation.ErrorRecord
#>
function Format-ErrorRecord ([string] $Message, [string]$ErrorID) {
$Exception = [Exception] $Message
$ErrorCategory = [System.Management.Automation.ErrorCategory]::InvalidResult
$TargetObject = @{ Message = $Message }
$ErrorRecord = New-Object System.Management.Automation.ErrorRecord $Exception, $ErrorID, $ErrorCategory, $TargetObject
return $ErrorRecord
}
Export-ModuleMember -Function Get-Resource, Get-ResourceByType, Confirm-Resource, `
Format-NotExistError, Format-IncorrectValueError, Format-ErrorRecord

Просмотреть файл

@ -48,3 +48,80 @@ Describe 'Verify Resource Exists' {
$exists | Should -Be $true
}
}
Describe 'Use Confirm-AzBPResource to confirm resource and/or properties exist'{
Describe 'Verify Container Registry' {
it 'Should contain a container registry named testcontaineregistry' {
#arrange
$resourceGroupName = "testrg"
$resourceType = "ContainerRegistry"
$containerRegistryName = "testcontaineregistry"
#act
$result = Confirm-AzBPResource -ResourceGroupName $resourceGroupName -ResourceType $resourceType `
-ResourceName $containerRegistryName
#assert
$result.Success | Should -Be $true
}
it 'Should contain a container registry named testcontaineregistry is Standard' {
#arrange
$resourceGroupName = "testrg"
$resourceType = "ContainerRegistry"
$containerRegistryName = "testcontaineregistry"
$property = "SkuName"
$expectedValue = "Standard"
#act
$result = Confirm-AzBPResource -ResourceGroupName $resourceGroupName -ResourceType $resourceType `
-ResourceName $containerRegistryName -PropertyKey $property -PropertyValue $expectedValue
#assert
$result.Success | Should -Be $true
}
}
Describe 'Verify Resource Group' {
it 'Should contain a resource group named testrg' {
#arrange
$resourceGroupName = "testrg"
$resourceType = "ResourceGroup"
#act
$result = Confirm-AzBPResource -ResourceType $resourceType -ResourceName $resourceGroupName
#assert
$result.Success | Should -Be $true
}
it 'Should contain a a resource group named testrg in WestUS3' {
#arrange
$resourceGroupName = "testrg"
$resourceType = "ResourceGroup"
$property = "Location"
$expectedValue = "WestUS3"
#act
$result = Confirm-AzBPResource -ResourceType $resourceType -ResourceName $resourceGroupName `
-PropertyKey $property -PropertyValue $expectedValue
#assert
$result.Success | Should -Be $true
}
}
Describe 'Verify SQL Server' {
it 'Should contain a SQL Server named testserver' {
#arrange
$resourceGroupName = "testrg"
$sqlServerName = "testserver"
$resourceType = "SqlServer"
#act
$result = Confirm-AzBPResource -ResourceGroupName $resourceGroupName -ResourceType $resourceType `
-ResourceName $sqlServerName
#assert
$result.Success | Should -Be $true
}
}
}