Last active
April 9, 2017 01:21
-
-
Save midacts/91406149a003cb61e8137ec0ff140232 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
This file exists to combine simple user input (Invoke-Vester), simple | |
user test authoring (*.Vester.ps1), and properly scoped inventory objects | |
into a single test session that loops through all necessary combinations. | |
It is called by Invoke-Vester via the Invoke-Pester command. | |
http://vester.readthedocs.io/en/latest/ | |
#> | |
# Accept -WhatIf input from Invoke-Vester | |
[CmdletBinding(SupportsShouldProcess = $true, | |
ConfirmImpact = 'Medium')] | |
Param( | |
# The $cfg hashtable from a single config file | |
[object]$Cfg, | |
# Array of paths for tests to run against this config file | |
[object]$TestFiles, | |
# Pass through the user's preference to fix differences or not | |
[switch]$Remediate | |
) | |
# Gets the scope, the objects for the scope and their requested test files | |
$Scopes = Split-Path (Split-Path $TestFiles -Parent) -Leaf | Select -Unique | |
$Final = @() | |
$InventoryList = @() | |
$Datacenter = Get-Datacenter -Name $cfg.scope.datacenter -Server $cfg.vcenter.vc | |
foreach($Scope in $Scopes) | |
{ | |
Write-Verbose "Processing $Scope" | |
Remove-Variable InventoryList -ErrorAction SilentlyContinue # Makes sure the variable is always fresh | |
# Use $Scope (parent folder) to get the correct objects to test against | |
# If changing values here, update the "$Scope -notmatch" test below as well | |
$InventoryList = switch ($Scope) { | |
'vCenter' {$cfg.vcenter.vc} | |
'Datacenter' {$Datacenter} | |
'Cluster' {$Datacenter | Get-Cluster -Name $cfg.scope.cluster} | |
'DSCluster' {$Datacenter | Get-DatastoreCluster -Name $cfg.scope.dscluster} | |
'Host' {$Datacenter | Get-Cluster -Name $cfg.scope.cluster | Get-VMHost -Name $cfg.scope.host} | |
'VM' {$Datacenter | Get-Cluster -Name $cfg.scope.cluster | Get-VM -Name $cfg.scope.vm} | |
'Network' {$Datacenter | Get-VDSwitch -Name $cfg.scope.vds} | |
} | |
$ScopeObj = [pscustomobject] @{ | |
'Scope' = $Scope | |
'InventoryList' = $InventoryList | |
'TestFiles' = $TestFiles | Where-Object { (Split-Path (Split-Path $_ -Parent) -Leaf) -eq $Scope } | |
} | |
$Final += $ScopeObj | |
} | |
# Removes scopes that have empty inventory lists or no test files | |
$Final = $Final | Where-Object { ($_.InventoryList -ne $NULL) -and ($_.TestFiles -ne $NULL)} | |
# Loops through each Scope | |
foreach($Scope in $Final.Scope) | |
{ | |
# Pulling the inventory and test files for this scope | |
$Inventory = ($Final | Where-Object { $_.Scope -eq $Scope }).InventoryList | |
$Tests = ($Final | Where-Object { $_.Scope -eq $Scope }).TestFiles | |
# The parent folder must be one of these names, to help with $Object scoping below | |
# If adding here, also needs to be added to the switch below | |
If ('vCenter|Datacenter|Cluster|DSCluster|Host|VM|Network' -notmatch $Scope) { | |
Write-Warning "Skipping test $TestName. Use -Verbose for more details" | |
Write-Verbose 'Test files should be in a folder with one of the following names:' | |
Write-Verbose 'vCenter / Datacenter / Cluster / Host / VM / Network' | |
Write-Verbose 'This helps Vester determine which inventory object(s) to use during the test.' | |
# Use continue to skip this test and go to the next loop iteration | |
continue | |
} | |
# Check for non-core modules only as tests require them | |
# Will need to be revisited as more tests added & more modules required... | |
# ...maybe don't care about this at all and let it fail naturally? | |
If ($Scope -eq 'Network' -and (Get-Module VMware.VimAutomation.Vds) -eq $null) { | |
Try { | |
Import-Module VMware.VimAutomation.Vds -ErrorAction Stop | |
} Catch { | |
Write-Warning 'Failed to import PowerCLI module "VMware.VimAutomation.Vds"' | |
Write-Warning "Skipping network test $TestName" | |
# Use continue to skip this test and go to the next loop iteration | |
continue | |
} | |
} | |
If (($Final | Where-Object { $_.Scope -eq $Scope }).InventoryList -eq $null) { | |
Write-Verbose "No objects found in scope $Scope, skipping tests" | |
# Use continue to skip this test and go to the next loop iteration | |
continue | |
} | |
# Loops through each object in the inventory list for the specific scope | |
foreach($Object in $Inventory) | |
{ | |
# Runs through each test file on the above objects in the currect scope | |
foreach($Test in $Tests) | |
{ | |
Write-Verbose "Processing test file $Test" | |
$TestName = Split-Path $Test -Leaf | |
Describe -Name "$Scope Configuration: $TestName" -Fixture { | |
# Pull in $Title/$Description/$Desired/$Type/$Actual/$Fix from the test file | |
. $Test | |
# Pump the brakes if the config value is $null | |
If ($Desired -eq $null) { | |
Write-Verbose "Due to null config value, skipping test $TestName" | |
# Use continue to skip this test and go to the next loop iteration | |
continue | |
} | |
It -Name "$Scope $($Object.Name) - $Title" -Test { | |
Try { | |
# "& $Actual" is running the first script block to compare to $Desired | |
# The comparison should be empty | |
# (meaning everything is the same, as expected) | |
Compare-Object -ReferenceObject $Desired -DifferenceObject (& $Actual -as $Type) | | |
Should BeNullOrEmpty | |
} Catch { | |
# If the comparison found something different, | |
# Then check if we're going to fix it | |
If ($Remediate) { | |
Write-Warning -Message $_ | |
# -WhatIf support wraps the command that would change values | |
If ($PSCmdlet.ShouldProcess("vCenter '$($cfg.vcenter.vc)' - $Scope '$Object'", "Set '$Title' value to '$Desired'")) { | |
Write-Warning -Message "Remediating $Object" | |
# Execute the $Fix script block | |
& $Fix | |
} | |
} Else { | |
# -Remediate is not active, so just report the error | |
throw $_ | |
} | |
} #Try/Catch | |
} #It | |
} #Describe | |
}#Foreach Testfiles | |
}#Foreach $Final.InventoryList | |
}#Foreach Scopes |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment