-
Notifications
You must be signed in to change notification settings - Fork 255
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #392 from arjenhuitema/workflow-check-policy-build
Adding workflow to check for policy build
- Loading branch information
Showing
15 changed files
with
431 additions
and
49 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
<# | ||
.DESCRIPTION | ||
Uses git diff to return a list of policy definitions and policy set definition file paths. | ||
#> | ||
|
||
function Get-PolicyFiles | ||
{ | ||
[CmdletBinding(SupportsShouldProcess)] | ||
param ( | ||
[Parameter()] | ||
[String]$DiffFilter, | ||
|
||
[Parameter()] | ||
[String]$PolicyDir = "$($env:POLICY_DIR)", | ||
|
||
[Parameter()] | ||
[String]$PolicySetDir = "$($env:POLICYSET_DIR)", | ||
|
||
[Parameter()] | ||
[String]$PRBranch = "$($env:GITHUB_HEAD_REF)", | ||
|
||
[Parameter()] | ||
[String]$BaseBranch = "$($env:GITHUB_BASE_REF)" | ||
) | ||
|
||
$PolicyFiles = @(git diff --diff-filter=$DiffFilter --name-only origin/main $PRBranch -- $PolicyDir) | ||
$PolicySetsFiles = @(git diff --diff-filter=$DiffFilter --name-only origin/main $PRBranch -- $PolicySetDir) | ||
|
||
$PolicyAndSetFiles = $PolicyFiles + $PolicySetsFiles | ||
|
||
$PolicyAndSetFiles | ForEach-Object { | ||
return $_ | ||
} | ||
} | ||
|
||
function Remove-JSONMetadata { | ||
|
||
[CmdletBinding()] | ||
param ( | ||
[Parameter(Mandatory = $true)] | ||
[hashtable] $TemplateObject | ||
) | ||
$TemplateObject.Remove('metadata') | ||
|
||
# Differantiate case: With user defined types (resources property is hashtable) vs without user defined types (resources property is array) | ||
if ($TemplateObject.resources.GetType().BaseType.Name -eq 'Hashtable') { | ||
# Case: Hashtable | ||
$resourceIdentifiers = $TemplateObject.resources.Keys | ||
for ($index = 0; $index -lt $resourceIdentifiers.Count; $index++) { | ||
if ($TemplateObject.resources[$resourceIdentifiers[$index]].type -eq 'Microsoft.Resources/deployments' -and $TemplateObject.resources[$resourceIdentifiers[$index]].properties.template.GetType().BaseType.Name -eq 'Hashtable') { | ||
$TemplateObject.resources[$resourceIdentifiers[$index]] = Remove-JSONMetadata -TemplateObject $TemplateObject.resources[$resourceIdentifiers[$index]].properties.template | ||
} | ||
} | ||
} else { | ||
# Case: Array | ||
for ($index = 0; $index -lt $TemplateObject.resources.Count; $index++) { | ||
if ($TemplateObject.resources[$index].type -eq 'Microsoft.Resources/deployments' -and $TemplateObject.resources[$index].properties.template.GetType().BaseType.Name -eq 'Hashtable') { | ||
$TemplateObject.resources[$index] = Remove-JSONMetadata -TemplateObject $TemplateObject.resources[$index].properties.template | ||
} | ||
} | ||
} | ||
|
||
return $TemplateObject | ||
} | ||
|
||
function ConvertTo-OrderedHashtable { | ||
|
||
[CmdletBinding()] | ||
param ( | ||
[Parameter(Mandatory = $true)] | ||
[string] $JSONInputObject # Must be string to workaround auto-conversion | ||
) | ||
|
||
$JSONObject = ConvertFrom-Json $JSONInputObject -AsHashtable -Depth 99 -NoEnumerate | ||
$orderedLevel = [ordered]@{} | ||
|
||
if (-not ($JSONObject.GetType().BaseType.Name -eq 'Hashtable')) { | ||
return $JSONObject # E.g. in primitive data types [1,2,3] | ||
} | ||
|
||
foreach ($currentLevelKey in ($JSONObject.Keys | Sort-Object -Culture 'en-US')) { | ||
|
||
if ($null -eq $JSONObject[$currentLevelKey]) { | ||
# Handle case in which the value is 'null' and hence has no type | ||
$orderedLevel[$currentLevelKey] = $null | ||
continue | ||
} | ||
|
||
switch ($JSONObject[$currentLevelKey].GetType().BaseType.Name) { | ||
{ $PSItem -in @('Hashtable') } { | ||
$orderedLevel[$currentLevelKey] = ConvertTo-OrderedHashtable -JSONInputObject ($JSONObject[$currentLevelKey] | ConvertTo-Json -Depth 99) | ||
} | ||
'Array' { | ||
$arrayOutput = @() | ||
|
||
# Case: Array of arrays | ||
$arrayElements = $JSONObject[$currentLevelKey] | Where-Object { $_.GetType().BaseType.Name -eq 'Array' } | ||
foreach ($array in $arrayElements) { | ||
if ($array.Count -gt 1) { | ||
# Only sort for arrays with more than one item. Otherwise single-item arrays are casted | ||
$array = $array | Sort-Object -Culture 'en-US' | ||
} | ||
$arrayOutput += , (ConvertTo-OrderedHashtable -JSONInputObject ($array | ConvertTo-Json -Depth 99)) | ||
} | ||
|
||
# Case: Array of objects | ||
$hashTableElements = $JSONObject[$currentLevelKey] | Where-Object { $_.GetType().BaseType.Name -eq 'Hashtable' } | ||
foreach ($hashTable in $hashTableElements) { | ||
$arrayOutput += , (ConvertTo-OrderedHashtable -JSONInputObject ($hashTable | ConvertTo-Json -Depth 99)) | ||
} | ||
|
||
# Case: Primitive data types | ||
$primitiveElements = $JSONObject[$currentLevelKey] | Where-Object { $_.GetType().BaseType.Name -notin @('Array', 'Hashtable') } | ConvertTo-Json -Depth 99 | ConvertFrom-Json -AsHashtable -NoEnumerate -Depth 99 | ||
if ($primitiveElements.Count -gt 1) { | ||
$primitiveElements = $primitiveElements | Sort-Object -Culture 'en-US' | ||
} | ||
$arrayOutput += $primitiveElements | ||
|
||
if ($array.Count -gt 1) { | ||
# Only sort for arrays with more than one item. Otherwise single-item arrays are casted | ||
$arrayOutput = $arrayOutput | Sort-Object -Culture 'en-US' | ||
} | ||
$orderedLevel[$currentLevelKey] = $arrayOutput | ||
} | ||
Default { | ||
# string/int/etc. | ||
$orderedLevel[$currentLevelKey] = $JSONObject[$currentLevelKey] | ||
} | ||
} | ||
} | ||
|
||
return $orderedLevel | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
Describe 'UnitTest-BuildPolicies' { | ||
|
||
BeforeAll { | ||
Import-Module -Name $PSScriptRoot\PolicyPesterTestHelper.psm1 -Force -Verbose | ||
|
||
New-Item -Name "buildout" -Type Directory | ||
|
||
# Build the PR policies, and initiatives to a temp folder | ||
bicep build ./patterns/alz/templates/policies-Automation.bicep --outfile ./buildout/policies-Automation.json | ||
bicep build ./patterns/alz/templates/policies-Compute.bicep --outfile ./buildout/policies-Compute.json | ||
bicep build ./patterns/alz/templates/policies-Hybrid.bicep --outfile ./buildout/policies-Hybrid.json | ||
bicep build ./patterns/alz/templates/policies-KeyManagement.bicep --outfile ./buildout/policies-KeyManagement.json | ||
bicep build ./patterns/alz/templates/policies-Monitoring.bicep --outfile ./buildout/policies-Monitoring.json | ||
bicep build ./patterns/alz/templates/policies-Network.bicep --outfile ./buildout/policies-Network.json | ||
bicep build ./patterns/alz/templates/policies-NotificationAssets.bicep --outfile ./buildout/policies-NotificationAssets.json | ||
bicep build ./patterns/alz/templates/policies-RecoveryServices.bicep --outfile ./buildout/policies-RecoveryServices.json | ||
bicep build ./patterns/alz/templates/policies-ServiceHealth.bicep --outfile ./buildout/policies-ServiceHealth.json | ||
bicep build ./patterns/alz/templates/policies-Storage.bicep --outfile ./buildout/policies-Storage.json | ||
bicep build ./patterns/alz/templates/policies-Web.bicep --outfile ./buildout/policies-Web.json | ||
bicep build ./patterns/alz/templates/policySets.bicep --outfile ./buildout/policySets.json | ||
} | ||
|
||
Context "Check Policy Builds" { | ||
|
||
It "Check Automation policies build done" { | ||
$prFile = "./patterns/alz/policyDefinitions/policies-Automation.json" | ||
$buildFile = "./buildout/policies-Automation.json" | ||
|
||
$buildJson = Remove-JSONMetadata -TemplateObject (Get-Content $buildFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$buildJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $buildJson -Depth 99) | ||
|
||
$prJson = Remove-JSONMetadata -TemplateObject (Get-Content $prFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$prJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $prJson -Depth 99) | ||
|
||
# Compare files we built to the PR files | ||
(ConvertTo-Json $buildJson -Depth 99) | Should -Be (ConvertTo-Json $prJson -Depth 99) -Because "the [policies-Automation.json] should be based on the latest [policies-Automation.bicep] file. Please run [` bicep build ./patterns/alz/templates/policies-Automation.bicep --outfile ./patterns/alz/policyDefinitions/policies-Automation.json `] using the latest Bicep CLI version." | ||
} | ||
|
||
It "Check Compute policies build done" { | ||
$prFile = "./patterns/alz/policyDefinitions/policies-Compute.json" | ||
$buildFile = "./buildout/policies-Compute.json" | ||
|
||
$buildJson = Remove-JSONMetadata -TemplateObject (Get-Content $buildFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$buildJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $buildJson -Depth 99) | ||
|
||
$prJson = Remove-JSONMetadata -TemplateObject (Get-Content $prFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$prJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $prJson -Depth 99) | ||
|
||
# Compare files we built to the PR files | ||
(ConvertTo-Json $buildJson -Depth 99) | Should -Be (ConvertTo-Json $prJson -Depth 99) -Because "the [policies-Compute.json] should be based on the latest [policies-Compute.bicep] file. Please run [` bicep build ./patterns/alz/templates/policies-Compute.bicep --outfile ./patterns/alz/policyDefinitions/policies-Compute.json `] using the latest Bicep CLI version." | ||
} | ||
|
||
It "Check Hybrid policies build done" { | ||
$prFile = "./patterns/alz/policyDefinitions/policies-Hybrid.json" | ||
$buildFile = "./buildout/policies-Hybrid.json" | ||
|
||
$buildJson = Remove-JSONMetadata -TemplateObject (Get-Content $buildFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$buildJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $buildJson -Depth 99) | ||
|
||
$prJson = Remove-JSONMetadata -TemplateObject (Get-Content $prFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$prJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $prJson -Depth 99) | ||
|
||
# Compare files we built to the PR files | ||
(ConvertTo-Json $buildJson -Depth 99) | Should -Be (ConvertTo-Json $prJson -Depth 99) -Because "the [policies-Hybrid.json] should be based on the latest [policies-Hybrid.bicep] file. Please run [` bicep build ./patterns/alz/templates/policies-Hybrid.bicep --outfile ./patterns/alz/policyDefinitions/policies-Hybrid.json `] using the latest Bicep CLI version." | ||
} | ||
|
||
It "Check KeyManagement policies build done" { | ||
$prFile = "./patterns/alz/policyDefinitions/policies-KeyManagement.json" | ||
$buildFile = "./buildout/policies-KeyManagement.json" | ||
|
||
$buildJson = Remove-JSONMetadata -TemplateObject (Get-Content $buildFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$buildJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $buildJson -Depth 99) | ||
|
||
$prJson = Remove-JSONMetadata -TemplateObject (Get-Content $prFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$prJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $prJson -Depth 99) | ||
|
||
# Compare files we built to the PR files | ||
(ConvertTo-Json $buildJson -Depth 99) | Should -Be (ConvertTo-Json $prJson -Depth 99) -Because "the [policies-KeyManagement.json] should be based on the latest [policies-KeyManagement.bicep] file. Please run [` bicep build ./patterns/alz/templates/policies-KeyManagement.bicep --outfile ./patterns/alz/policyDefinitions/policies-KeyManagement.json `] using the latest Bicep CLI version." | ||
} | ||
|
||
It "Check Monitoring policies build done" { | ||
$prFile = "./patterns/alz/policyDefinitions/policies-Monitoring.json" | ||
$buildFile = "./buildout/policies-Monitoring.json" | ||
|
||
$buildJson = Remove-JSONMetadata -TemplateObject (Get-Content $buildFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$buildJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $buildJson -Depth 99) | ||
|
||
$prJson = Remove-JSONMetadata -TemplateObject (Get-Content $prFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$prJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $prJson -Depth 99) | ||
|
||
# Compare files we built to the PR files | ||
(ConvertTo-Json $buildJson -Depth 99) | Should -Be (ConvertTo-Json $prJson -Depth 99) -Because "the [policies-Monitoring.json] should be based on the latest [policies-Monitoring.bicep] file. Please run [` bicep build ./patterns/alz/templates/policies-Monitoring.bicep --outfile ./patterns/alz/policyDefinitions/policies-Monitoring.json `] using the latest Bicep CLI version." | ||
} | ||
|
||
It "Check Network policies build done" { | ||
$prFile = "./patterns/alz/policyDefinitions/policies-Network.json" | ||
$buildFile = "./buildout/policies-Network.json" | ||
|
||
$buildJson = Remove-JSONMetadata -TemplateObject (Get-Content $buildFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$buildJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $buildJson -Depth 99) | ||
|
||
$prJson = Remove-JSONMetadata -TemplateObject (Get-Content $prFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$prJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $prJson -Depth 99) | ||
|
||
# Compare files we built to the PR files | ||
(ConvertTo-Json $buildJson -Depth 99) | Should -Be (ConvertTo-Json $prJson -Depth 99) -Because "the [policies-Network.json] should be based on the latest [policies-Network.bicep] file. Please run [` bicep build ./patterns/alz/templates/policies-Network.bicep --outfile ./patterns/alz/policyDefinitions/policies-Network.json `] using the latest Bicep CLI version." | ||
} | ||
|
||
It "Check NotificationAssets policies build done" { | ||
$prFile = "./patterns/alz/policyDefinitions/policies-NotificationAssets.json" | ||
$buildFile = "./buildout/policies-NotificationAssets.json" | ||
|
||
$buildJson = Remove-JSONMetadata -TemplateObject (Get-Content $buildFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$buildJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $buildJson -Depth 99) | ||
|
||
$prJson = Remove-JSONMetadata -TemplateObject (Get-Content $prFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$prJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $prJson -Depth 99) | ||
|
||
# Compare files we built to the PR files | ||
(ConvertTo-Json $buildJson -Depth 99) | Should -Be (ConvertTo-Json $prJson -Depth 99) -Because "the [policies-NotificationAssets.json] should be based on the latest [policies-NotificationAssets.bicep] file. Please run [` bicep build ./patterns/alz/templates/policies-NotificationAssets.bicep --outfile ./patterns/alz/policyDefinitions/policies-NotificationAssets.json `] using the latest Bicep CLI version." | ||
} | ||
|
||
It "Check RecoveryServices policies build done" { | ||
$prFile = "./patterns/alz/policyDefinitions/policies-RecoveryServices.json" | ||
$buildFile = "./buildout/policies-RecoveryServices.json" | ||
|
||
$buildJson = Remove-JSONMetadata -TemplateObject (Get-Content $buildFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$buildJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $buildJson -Depth 99) | ||
|
||
$prJson = Remove-JSONMetadata -TemplateObject (Get-Content $prFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$prJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $prJson -Depth 99) | ||
|
||
# Compare files we built to the PR files | ||
(ConvertTo-Json $buildJson -Depth 99) | Should -Be (ConvertTo-Json $prJson -Depth 99) -Because "the [policies-RecoveryServices.json] should be based on the latest [policies-RecoveryServices.bicep] file. Please run [` bicep build ./patterns/alz/templates/policies-RecoveryServices.bicep --outfile ./patterns/alz/policyDefinitions/policies-RecoveryServices.json `] using the latest Bicep CLI version." | ||
} | ||
|
||
It "Check ServiceHealth policies build done" { | ||
$prFile = "./patterns/alz/policyDefinitions/policies-ServiceHealth.json" | ||
$buildFile = "./buildout/policies-ServiceHealth.json" | ||
|
||
$buildJson = Remove-JSONMetadata -TemplateObject (Get-Content $buildFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$buildJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $buildJson -Depth 99) | ||
|
||
$prJson = Remove-JSONMetadata -TemplateObject (Get-Content $prFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$prJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $prJson -Depth 99) | ||
|
||
# Compare files we built to the PR files | ||
(ConvertTo-Json $buildJson -Depth 99) | Should -Be (ConvertTo-Json $prJson -Depth 99) -Because "the [policies-ServiceHealth.json] should be based on the latest [policies-ServiceHealth.bicep] file. Please run [` bicep build ./patterns/alz/templates/policies-ServiceHealth.bicep --outfile ./patterns/alz/policyDefinitions/policies-ServiceHealth.json `] using the latest Bicep CLI version." | ||
} | ||
|
||
It "Check Storage policies build done" { | ||
$prFile = "./patterns/alz/policyDefinitions/policies-Storage.json" | ||
$buildFile = "./buildout/policies-Storage.json" | ||
|
||
$buildJson = Remove-JSONMetadata -TemplateObject (Get-Content $buildFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$buildJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $buildJson -Depth 99) | ||
|
||
$prJson = Remove-JSONMetadata -TemplateObject (Get-Content $prFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$prJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $prJson -Depth 99) | ||
|
||
# Compare files we built to the PR files | ||
(ConvertTo-Json $buildJson -Depth 99) | Should -Be (ConvertTo-Json $prJson -Depth 99) -Because "the [policies-Storage.json] should be based on the latest [policies-Storage.bicep] file. Please run [` bicep build ./patterns/alz/templates/policies-Storage.bicep --outfile ./patterns/alz/policyDefinitions/policies-Storage.json `] using the latest Bicep CLI version." | ||
} | ||
|
||
It "Check Web policies build done" { | ||
$prFile = "./patterns/alz/policyDefinitions/policies-Web.json" | ||
$buildFile = "./buildout/policies-Web.json" | ||
|
||
$buildJson = Remove-JSONMetadata -TemplateObject (Get-Content $buildFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$buildJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $buildJson -Depth 99) | ||
|
||
$prJson = Remove-JSONMetadata -TemplateObject (Get-Content $prFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$prJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $prJson -Depth 99) | ||
|
||
# Compare files we built to the PR files | ||
(ConvertTo-Json $buildJson -Depth 99) | Should -Be (ConvertTo-Json $prJson -Depth 99) -Because "the [policies-Web.json] should be based on the latest [policies-Web.bicep] file. Please run [` bicep build ./patterns/alz/templates/policies-Web.bicep --outfile ./patterns/alz/policyDefinitions/policies-Web.json `] using the latest Bicep CLI version." | ||
} | ||
|
||
It "Check PolicySets build done" { | ||
$prFile = "./patterns/alz/policyDefinitions/policySets.json" | ||
$buildFile = "./buildout/policySets.json" | ||
|
||
$buildJson = Remove-JSONMetadata -TemplateObject (Get-Content $buildFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$buildJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $buildJson -Depth 99) | ||
|
||
$prJson = Remove-JSONMetadata -TemplateObject (Get-Content $prFile -Raw | ConvertFrom-Json -Depth 99 -AsHashtable) | ||
$prJson = ConvertTo-OrderedHashtable -JSONInputObject (ConvertTo-Json $prJson -Depth 99) | ||
|
||
# Compare files we built to the PR files | ||
(ConvertTo-Json $buildJson -Depth 99) | Should -Be (ConvertTo-Json $prJson -Depth 99) -Because "the [policySets.json] should be based on the latest [policySets.bicep] file. Please run [` bicep build ./patterns/alz/templates/policySets.bicep --outfile ./patterns/alz/policyDefinitions/policySets.json `] using the latest Bicep CLI version." | ||
} | ||
|
||
} | ||
|
||
AfterAll { | ||
# These are not the droids you are looking for... | ||
} | ||
} |
Oops, something went wrong.