diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 0959247..91ffa15 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -11,4 +11,4 @@ - **Code changes** - [ ] Have unit tests created/ updated - [ ] Link to a filed issue - - [ ] [Change log](https://github.com/Microsoft/PSRule.Rules.Kubernetes/blob/main/CHANGELOG.md) has been updated with change under unreleased section + - [ ] [Change log](https://github.com/microsoft/PSRule.Rules.Kubernetes/blob/main/CHANGELOG.md) has been updated with change under unreleased section diff --git a/.github/workflows/analyze.yaml b/.github/workflows/analyze.yaml index 5e8ccd3..291170e 100644 --- a/.github/workflows/analyze.yaml +++ b/.github/workflows/analyze.yaml @@ -1,13 +1,29 @@ # -# Repository validation +# Repository analysis # + +# NOTES: +# This workflow uses PSRule, CodeQL, and DevSkim. +# You can read more about these linting tools and configuration options here: +# PSRule - https://aka.ms/ps-rule and https://github.com/Microsoft/PSRule.Rules.MSFT.OSS +# DevSkim - https://github.com/microsoft/DevSkim-Action and https://github.com/Microsoft/DevSkim + name: Analyze on: -- pull_request + push: + branches: [ main, 'release/*' ] + pull_request: + branches: [ main, 'release/*' ] + schedule: + - cron: '50 20 * * 0' # At 08:50 PM, on Sunday each week + workflow_dispatch: + jobs: - analyze: - name: Analyze repository + oss: + name: Analyze with PSRule runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Checkout @@ -16,5 +32,27 @@ jobs: - name: Run PSRule analysis uses: microsoft/ps-rule@v2.6.0 with: - modules: 'PSRule.Rules.MSFT.OSS' + modules: PSRule.Rules.MSFT.OSS prerelease: true + + devskim: + name: Analyze with DevSkim + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + steps: + + - name: Checkout + uses: actions/checkout@v3 + + - name: Run DevSkim scanner + uses: microsoft/DevSkim-Action@v1 + with: + directory-to-scan: src/ + + - name: Upload results to security tab + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: devskim-results.sarif diff --git a/.github/workflows/dependencies.yaml b/.github/workflows/dependencies.yaml new file mode 100644 index 0000000..5d54388 --- /dev/null +++ b/.github/workflows/dependencies.yaml @@ -0,0 +1,47 @@ +# +# Automated dependency updates +# + +# NOTES: +# This automatically bumps PowerShell dependency versions. + +name: Dependencies +on: + schedule: + - cron: '0 1 * * 1' # At 01:00 AM, on Monday each week + workflow_dispatch: + +env: + WORKING_BRANCH: dependencies/powershell-bump + +jobs: + dependencies: + name: Bump dependencies + runs-on: ubuntu-latest + if: github.repository == 'microsoft/PSRule.Rules.Kubernetes' + permissions: + contents: write + pull-requests: write + steps: + + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Configure + run: | + git config user.name github-actions + git config user.email '41898282+github-actions[bot]@users.noreply.github.com' + + - name: Get working branch + run: | + git checkout -B ${{ env.WORKING_BRANCH }} --force + + - name: Check dependencies + run: | + Import-Module ./scripts/dependencies.psm1; + Update-Dependencies -Path ./modules.json; + shell: pwsh + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml new file mode 100644 index 0000000..dccfaca --- /dev/null +++ b/.github/workflows/stale.yaml @@ -0,0 +1,40 @@ +# +# Stale issues +# + +# NOTES: +# Repository stale issue management. +# Issues with open ended labels are automatically closed if no activity occurs. +# Issues are marked stale after 14 days, then closed after a further 7 days. + +name: 'Close stale issues' +on: + schedule: + - cron: '50 2 * * *' # At 2:50 AM, daily + +jobs: + stale: + runs-on: ubuntu-latest + if: github.repository == 'microsoft/PSRule.Rules.Kubernetes' + permissions: + issues: write + pull-requests: write + steps: + + - uses: actions/stale@v6 + with: + stale-issue-message: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs within 7 days. + Thank you for your contributions. + + close-issue-message: 'This issue was closed because it has not had any recent activity.' + + days-before-stale: 14 + days-before-pr-stale: -1 + + days-before-close: 7 + days-before-pr-close: -1 + + any-of-labels: 'question,duplicate,incomplete,waiting-feedback' + stale-issue-label: stale diff --git a/CHANGELOG.md b/CHANGELOG.md index 68b47d4..64d2d38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ What's changed since v0.2.0: - Engineering: - - Bump PSRule dependency to v1.11.0. [#52](https://github.com/microsoft/PSRule.Rules.Kubernetes/issues/52) + - Bump PSRule dependency to v2.6.0. [#74](https://github.com/microsoft/PSRule.Rules.Kubernetes/issues/74) ## v0.2.0 diff --git a/README.md b/README.md index d9e0426..959a0ce 100644 --- a/README.md +++ b/README.md @@ -181,6 +181,7 @@ or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any addi ## Maintainers - [Bernie White](https://github.com/BernieWhite) +- [Sam Bell](https://github.com/ms-sambell) ## License diff --git a/modules.json b/modules.json new file mode 100644 index 0000000..dd67304 --- /dev/null +++ b/modules.json @@ -0,0 +1,21 @@ +{ + "dependencies": { + "PSRule": { + "version": "2.6.0" + } + }, + "devDependencies": { + "Pester": { + "version": "5.3.3" + }, + "platyPS": { + "version": "0.14.2" + }, + "PSDocs": { + "version": "0.9.0" + }, + "PSScriptAnalyzer": { + "version": "1.21.0" + } + } +} diff --git a/pipeline.build.ps1 b/pipeline.build.ps1 index 11dd42a..08f9b74 100644 --- a/pipeline.build.ps1 +++ b/pipeline.build.ps1 @@ -104,10 +104,11 @@ task VersionModule ModuleDependencies, { } } + $dependencies = Get-Content -Path $PWD/modules.json -Raw | ConvertFrom-Json; $manifest = Test-ModuleManifest -Path $manifestPath; $requiredModules = $manifest.RequiredModules | ForEach-Object -Process { if ($_.Name -eq 'PSRule' -and $Configuration -eq 'Release') { - @{ ModuleName = 'PSRule'; ModuleVersion = '1.11.0' } + @{ ModuleName = 'PSRule'; ModuleVersion = $dependencies.dependencies.PSRule.version } } else { @{ ModuleName = $_.Name; ModuleVersion = $_.Version } @@ -136,47 +137,13 @@ task NuGet { } } -# Synopsis: Install Pester module -task Pester NuGet, { - if ($Null -eq (Get-InstalledModule -Name Pester -RequiredVersion 4.10.1 -ErrorAction Ignore)) { - Install-Module -Name Pester -RequiredVersion 4.10.1 -Scope CurrentUser -Force -SkipPublisherCheck; - } - Import-Module -Name Pester -RequiredVersion 4.10.1 -Verbose:$False; -} - -# Synopsis: Install PSScriptAnalyzer module -task PSScriptAnalyzer NuGet, { - if ($Null -eq (Get-InstalledModule -Name PSScriptAnalyzer -MinimumVersion 1.17.0 -ErrorAction Ignore)) { - Install-Module -Name PSScriptAnalyzer -MinimumVersion 1.17.0 -Scope CurrentUser -Force; - } - Import-Module -Name PSScriptAnalyzer -Verbose:$False; -} - -# Synopsis: Install PSRule -task PSRule NuGet, { - if ($Null -eq (Get-InstalledModule -Name PSRule -MinimumVersion 1.11.0 -ErrorAction Ignore)) { - Install-Module -Name PSRule -MinimumVersion 1.11.0 -Scope CurrentUser -Force; - } - Import-Module -Name PSRule -Verbose:$False; -} - -# Synopsis: Install PSDocs -task PSDocs NuGet, { - if ($Null -eq (Get-InstalledModule -Name PSDocs -MinimumVersion 0.9.0 -ErrorAction Ignore)) { - Install-Module -Name PSDocs -MinimumVersion 0.9.0 -AllowPrerelease -Scope CurrentUser -Force; - } - Import-Module -Name PSDocs -Verbose:$False; -} - -# Synopsis: Install PlatyPS module -task platyPS { - if ($Null -eq (Get-InstalledModule -Name PlatyPS -MinimumVersion 0.14.0 -ErrorAction Ignore)) { - Install-Module -Name PlatyPS -Scope CurrentUser -MinimumVersion 0.14.0 -Force; - } -} - # Synopsis: Install module dependencies -task ModuleDependencies NuGet, PSRule, { +task ModuleDependencies Dependencies, { +} + +task Dependencies NuGet, { + Import-Module $PWD/scripts/dependencies.psm1; + Install-Dependencies -Path $PWD/modules.json -Dev; } task CopyModule { @@ -186,20 +153,42 @@ task CopyModule { # Synopsis: Build modules only task BuildModule CopyModule -task TestModule PSRule, Pester, PSScriptAnalyzer, { +task TestModule ModuleDependencies, { # Run Pester tests - $pesterParams = @{ Path = $PWD; OutputFile = 'reports/pester-unit.xml'; OutputFormat = 'NUnitXml'; PesterOption = @{ IncludeVSCodeMarker = $True }; PassThru = $True; }; + $pesterOptions = @{ + Run = @{ + Path = (Join-Path -Path $PWD -ChildPath tests/PSRule.Rules.Kubernetes.Tests); + PassThru = $True; + }; + TestResult = @{ + Enabled = $True; + OutputFormat = 'NUnitXml'; + OutputPath = 'reports/pester-unit.xml'; + }; + }; if ($CodeCoverage) { - $pesterParams.Add('CodeCoverage', (Join-Path -Path $PWD -ChildPath 'out/modules/**/*.psm1')); - $pesterParams.Add('CodeCoverageOutputFile', (Join-Path -Path $PWD -ChildPath reports/pester-coverage.xml)); + $codeCoverageOptions = @{ + Enabled = $True; + OutputPath = (Join-Path -Path $PWD -ChildPath 'reports/pester-coverage.xml'); + Path = (Join-Path -Path $PWD -ChildPath 'out/modules/**/*.psm1'); + }; + + $pesterOptions.Add('CodeCoverage', $codeCoverageOptions); } if (!(Test-Path -Path reports)) { $Null = New-Item -Path reports -ItemType Directory -Force; } - $results = Invoke-Pester @pesterParams; + if ($Null -ne $TestGroup) { + $pesterOptions.Add('Filter', @{ Tag = $TestGroup }); + } + + # https://pester.dev/docs/commands/New-PesterConfiguration + $pesterConfiguration = New-PesterConfiguration -Hashtable $pesterOptions; + + $results = Invoke-Pester -Configuration $pesterConfiguration; # Throw an error if pester tests failed if ($Null -eq $results) { @@ -211,34 +200,34 @@ task TestModule PSRule, Pester, PSScriptAnalyzer, { } # Synopsis: Run validation -task Rules PSRule, { +task Rules Dependencies, { $assertParams = @{ - Path = './.ps-rule/' - Style = $AssertStyle + Path = './.ps-rule/' + Style = $AssertStyle OutputFormat = 'NUnit3' - ErrorAction = 'Stop' - As = 'Summary' + ErrorAction = 'Stop' + As = 'Summary' } + Import-Module (Join-Path -Path $PWD -ChildPath out/modules/PSRule.Rules.Kubernetes) -Force; Assert-PSRule @assertParams -InputPath $PWD -Module PSRule.Rules.MSFT.OSS -Format File -OutputPath reports/ps-rule-file.xml; - Import-Module (Join-Path -Path $PWD -ChildPath out/modules/PSRule.Rules.Kubernetes) -Force; $rules = Get-PSRule -Module PSRule.Rules.Kubernetes; $rules | Assert-PSRule @assertParams -OutputPath reports/ps-rule-file2.xml; } # Synopsis: Run script analyzer -task Analyze Build, PSScriptAnalyzer, { +task Analyze Build, ModuleDependencies, { Invoke-ScriptAnalyzer -Path out/modules/PSRule.Rules.Kubernetes; } # Synopsis: Build table of content for rules -task BuildRuleDocs Build, PSRule, PSDocs, { +task BuildRuleDocs Build, ModuleDependencies, { Import-Module (Join-Path -Path $PWD -ChildPath out/modules/PSRule.Rules.Kubernetes) -Force; $Null = Invoke-PSDocument -Name module -OutputPath .\docs\rules\en\ -Path .\RuleToc.Doc.ps1; } # Synopsis: Build help -task BuildHelp BuildModule, PlatyPS, { +task BuildHelp BuildModule, ModuleDependencies, { if (!(Test-Path out/modules/PSRule.Rules.Kubernetes/en/)) { $Null = New-Item -Path out/modules/PSRule.Rules.Kubernetes/en/ -ItemType Directory -Force; } @@ -252,13 +241,6 @@ task ScaffoldHelp Build, BuildRuleDocs, { # Update-MarkdownHelp -Path '.\docs\commands\PSRule.Rules.Kubernetes\en'; } -# Synopsis: Add shipit build tag -task TagBuild { - if ($Null -ne $Env:BUILD_DEFINITIONNAME) { - Write-Host "`#`#vso[build.addbuildtag]shipit"; - } -} - # Synopsis: Remove temp files. task Clean { Remove-Item -Path out,reports -Recurse -Force -ErrorAction SilentlyContinue; @@ -268,6 +250,6 @@ task Build Clean, BuildModule, VersionModule, BuildHelp task Test Build, Rules, TestModule -task Release ReleaseModule, TagBuild +task Release ReleaseModule task . Build, Rules diff --git a/scripts/dependencies.psm1 b/scripts/dependencies.psm1 new file mode 100644 index 0000000..5e230e8 --- /dev/null +++ b/scripts/dependencies.psm1 @@ -0,0 +1,152 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +# Note: +# Handles dependencies updates. + +function Update-Dependencies { + [CmdletBinding()] + param ( + [Parameter(Mandatory = $False)] + [String]$Path = (Join-Path -Path $PWD -ChildPath 'modules.json'), + + [Parameter(Mandatory = $False)] + [String]$Repository = 'PSGallery' + ) + process { + $modules = Get-Content -Path $Path -Raw | ConvertFrom-Json -AsHashtable; + $dependencies = CheckVersion $modules.dependencies -Repository $Repository; + $devDependencies = CheckVersion $modules.devDependencies -Repository $Repository -Dev; + + $modules = [Ordered]@{ + dependencies = $dependencies + devDependencies = $devDependencies + } + $modules | ConvertTo-Json -Depth 10 | Set-Content -Path $Path; + + $updates = @(git status --porcelain); + if ($Null -ne $Env:WORKING_BRANCH -and $Null -ne $updates -and $updates.Length -gt 0) { + git add modules.json; + git commit -m "Update $path"; + git push --force -u origin $Env:WORKING_BRANCH; + + $existingBranch = @(gh pr list --head $Env:WORKING_BRANCH --state open --json number | ConvertFrom-Json); + if ($Null -eq $existingBranch -or $existingBranch.Length -eq 0) { + gh pr create -B 'main' -H $Env:WORKING_BRANCH -l 'dependencies' -t 'Bump PowerShell dependencies' -F 'out/updates.txt'; + } + else { + $pr = $existingBranch[0].number + gh pr edit $pr -F 'out/updates.txt'; + } + } + } +} + +function Install-Dependencies { + [CmdletBinding()] + param ( + [Parameter(Mandatory = $False)] + [String]$Path = (Join-Path -Path $PWD -ChildPath 'modules.json'), + + [Parameter(Mandatory = $False)] + [String]$Repository = 'PSGallery', + + [Parameter(Mandatory = $False)] + [Switch]$Dev + ) + process { + $modules = Get-Content -Path $Path -Raw | ConvertFrom-Json; + InstallVersion $modules.dependencies -Repository $Repository; + if ($Dev) { + InstallVersion $modules.devDependencies -Repository $Repository -Dev; + } + } +} + +function CheckVersion { + [CmdletBinding()] + [OutputType([System.Collections.Specialized.OrderedDictionary])] + param ( + [Parameter(Mandatory = $True)] + [Hashtable]$InputObject, + + [Parameter(Mandatory = $True)] + [String]$Repository, + + [Parameter(Mandatory = $False)] + [Switch]$Dev, + + [Parameter(Mandatory = $False)] + [String]$OutputPath = 'out/' + ) + begin { + $group = 'Dependencies'; + if ($Dev) { + $group = 'DevDependencies'; + } + if (!(Test-Path -Path $OutputPath)) { + $Null = New-Item -Path $OutputPath -ItemType Directory -Force; + } + $changeNotes = Join-Path -Path $OutputPath -ChildPath 'updates.txt'; + } + process { + $dependencies = [Ordered]@{ }; + $InputObject.GetEnumerator() | Sort-Object -Property Name | ForEach-Object { + $dependencies[$_.Name] = $_.Value + } + foreach ($module in $dependencies.GetEnumerator()) { + Write-Host -Object "[$group] -- Checking $($module.Name)"; + $installParams = @{} + $installParams += $module.Value; + $installParams.MinimumVersion = $installParams.version; + $installParams.Remove('version'); + $available = @(Find-Module -Repository $Repository -Name $module.Name @installParams -ErrorAction Ignore); + foreach ($found in $available) { + if (([Version]$found.Version) -gt ([Version]$module.Value.version)) { + Write-Host -Object "[$group] -- Newer version found $($found.Version)"; + $dependencies[$module.Name].version = $found.Version; + $Null = Add-Content -Path $changeNotes -Value "Bump $($module.Name) to v$($found.Version)."; + } + else { + Write-Host -Object "[$group] -- Already up to date."; + } + } + } + return $dependencies; + } +} + +function InstallVersion { + [CmdletBinding()] + [OutputType([void])] + param ( + [Parameter(Mandatory = $True)] + [PSObject]$InputObject, + + [Parameter(Mandatory = $True)] + [String]$Repository, + + [Parameter(Mandatory = $False)] + [Switch]$Dev + ) + begin { + $group = 'Dependencies'; + if ($Dev) { + $group = 'DevDependencies'; + } + } + process { + foreach ($module in $InputObject.PSObject.Properties.GetEnumerator()) { + Write-Host -Object "[$group] -- Installing $($module.Name) v$($module.Value.version)"; + $installParams = @{ RequiredVersion = $module.Value.version }; + if ($Null -eq (Get-InstalledModule -Name $module.Name @installParams -ErrorAction Ignore)) { + Install-Module -Name $module.Name @installParams -Force -Repository $Repository; + } + } + } +} + +Export-ModuleMember -Function @( + 'Update-Dependencies' + 'Install-Dependencies' +) diff --git a/tests/PSRule.Rules.Kubernetes.Tests/Kubernetes.AKS.Tests.ps1 b/tests/PSRule.Rules.Kubernetes.Tests/Kubernetes.AKS.Tests.ps1 index 101af23..97cb559 100644 --- a/tests/PSRule.Rules.Kubernetes.Tests/Kubernetes.AKS.Tests.ps1 +++ b/tests/PSRule.Rules.Kubernetes.Tests/Kubernetes.AKS.Tests.ps1 @@ -8,27 +8,31 @@ [CmdletBinding()] param () -# Setup error handling -$ErrorActionPreference = 'Stop'; -Set-StrictMode -Version latest; +BeforeAll { + # Setup error handling + $ErrorActionPreference = 'Stop'; + Set-StrictMode -Version latest; -if ($Env:SYSTEM_DEBUG -eq 'true') { - $VerbosePreference = 'Continue'; -} - -# Setup tests paths -$rootPath = $PWD; -Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule.Rules.Kubernetes) -Force; -$here = (Resolve-Path $PSScriptRoot).Path; - -Describe 'Kubernetes.AKS' { - $testParams = @{ - Module = 'PSRule.Rules.Kubernetes' - InputPath = Join-Path -Path $here -ChildPath Resources.AKS.yaml - Baseline = 'AKS' + if ($Env:SYSTEM_DEBUG -eq 'true') { + $VerbosePreference = 'Continue'; } - $result = Invoke-PSRule @testParams -WarningAction Ignore; + # Setup tests paths + $rootPath = $PWD; + Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule.Rules.Kubernetes) -Force; + $here = (Resolve-Path $PSScriptRoot).Path; +} + +Describe 'Kubernetes.AKS' { + BeforeAll { + $testParams = @{ + Module = 'PSRule.Rules.Kubernetes' + InputPath = Join-Path -Path $here -ChildPath Resources.AKS.yaml + Baseline = 'AKS' + } + + $result = Invoke-PSRule @testParams -WarningAction Ignore; + } Context 'Security' { It 'Kubernetes.AKS.PublicLB' { diff --git a/tests/PSRule.Rules.Kubernetes.Tests/Kubernetes.API.Tests.ps1 b/tests/PSRule.Rules.Kubernetes.Tests/Kubernetes.API.Tests.ps1 index 9665a59..8824c56 100644 --- a/tests/PSRule.Rules.Kubernetes.Tests/Kubernetes.API.Tests.ps1 +++ b/tests/PSRule.Rules.Kubernetes.Tests/Kubernetes.API.Tests.ps1 @@ -8,27 +8,31 @@ [CmdletBinding()] param () -# Setup error handling -$ErrorActionPreference = 'Stop'; -Set-StrictMode -Version latest; +BeforeAll { + # Setup error handling + $ErrorActionPreference = 'Stop'; + Set-StrictMode -Version latest; -if ($Env:SYSTEM_DEBUG -eq 'true') { - $VerbosePreference = 'Continue'; -} - -# Setup tests paths -$rootPath = $PWD; -Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule.Rules.Kubernetes) -Force; -$here = (Resolve-Path $PSScriptRoot).Path; - -Describe 'Kubernetes.API' { - $testParams = @{ - Module = 'PSRule.Rules.Kubernetes' - Option = Join-Path -Path $here -ChildPath ps-rule.yaml - InputPath = Join-Path -Path $here -ChildPath Resources.API.yaml + if ($Env:SYSTEM_DEBUG -eq 'true') { + $VerbosePreference = 'Continue'; } - $result = Invoke-PSRule @testParams -WarningAction Ignore; + # Setup tests paths + $rootPath = $PWD; + Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule.Rules.Kubernetes) -Force; + $here = (Resolve-Path $PSScriptRoot).Path; +} + +Describe 'Kubernetes.API' { + BeforeAll { + $testParams = @{ + Module = 'PSRule.Rules.Kubernetes' + Option = Join-Path -Path $here -ChildPath ps-rule.yaml + InputPath = Join-Path -Path $here -ChildPath Resources.API.yaml + } + + $result = Invoke-PSRule @testParams -WarningAction Ignore; + } Context 'API' { It 'Kubernetes.API.v1.16' { diff --git a/tests/PSRule.Rules.Kubernetes.Tests/Kubernetes.Metadata.Tests.ps1 b/tests/PSRule.Rules.Kubernetes.Tests/Kubernetes.Metadata.Tests.ps1 index 3c55388..712cf43 100644 --- a/tests/PSRule.Rules.Kubernetes.Tests/Kubernetes.Metadata.Tests.ps1 +++ b/tests/PSRule.Rules.Kubernetes.Tests/Kubernetes.Metadata.Tests.ps1 @@ -8,27 +8,31 @@ [CmdletBinding()] param () -# Setup error handling -$ErrorActionPreference = 'Stop'; -Set-StrictMode -Version latest; +BeforeAll { + # Setup error handling + $ErrorActionPreference = 'Stop'; + Set-StrictMode -Version latest; -if ($Env:SYSTEM_DEBUG -eq 'true') { - $VerbosePreference = 'Continue'; -} - -# Setup tests paths -$rootPath = $PWD; -Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule.Rules.Kubernetes) -Force; -$here = (Resolve-Path $PSScriptRoot).Path; - -Describe 'Kubernetes.Metadata' { - $testParams = @{ - Module = 'PSRule.Rules.Kubernetes' - Option = Join-Path -Path $here -ChildPath ps-rule.yaml - InputPath = Join-Path -Path $here -ChildPath Resources.Metadata.yaml + if ($Env:SYSTEM_DEBUG -eq 'true') { + $VerbosePreference = 'Continue'; } - $result = Invoke-PSRule @testParams -WarningAction Ignore; + # Setup tests paths + $rootPath = $PWD; + Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule.Rules.Kubernetes) -Force; + $here = (Resolve-Path $PSScriptRoot).Path; +} + +Describe 'Kubernetes.Metadata' { + BeforeAll { + $testParams = @{ + Module = 'PSRule.Rules.Kubernetes' + Option = Join-Path -Path $here -ChildPath ps-rule.yaml + InputPath = Join-Path -Path $here -ChildPath Resources.Metadata.yaml + } + + $result = Invoke-PSRule @testParams -WarningAction Ignore; + } Context 'Resource metadata' { It 'Kubernetes.Metadata' { diff --git a/tests/PSRule.Rules.Kubernetes.Tests/Kubernetes.Pod.Tests.ps1 b/tests/PSRule.Rules.Kubernetes.Tests/Kubernetes.Pod.Tests.ps1 index 9d04aad..56f0085 100644 --- a/tests/PSRule.Rules.Kubernetes.Tests/Kubernetes.Pod.Tests.ps1 +++ b/tests/PSRule.Rules.Kubernetes.Tests/Kubernetes.Pod.Tests.ps1 @@ -8,27 +8,31 @@ [CmdletBinding()] param () -# Setup error handling -$ErrorActionPreference = 'Stop'; -Set-StrictMode -Version latest; +BeforeAll { + # Setup error handling + $ErrorActionPreference = 'Stop'; + Set-StrictMode -Version latest; -if ($Env:SYSTEM_DEBUG -eq 'true') { - $VerbosePreference = 'Continue'; -} - -# Setup tests paths -$rootPath = $PWD; -Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule.Rules.Kubernetes) -Force; -$here = (Resolve-Path $PSScriptRoot).Path; - -Describe 'Kubernetes.Pod' { - $testParams = @{ - Module = 'PSRule.Rules.Kubernetes' - Option = Join-Path -Path $here -ChildPath ps-rule.yaml - InputPath = Join-Path -Path $here -ChildPath Resources.Pod.yaml + if ($Env:SYSTEM_DEBUG -eq 'true') { + $VerbosePreference = 'Continue'; } - $result = Invoke-PSRule @testParams -WarningAction Ignore; + # Setup tests paths + $rootPath = $PWD; + Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule.Rules.Kubernetes) -Force; + $here = (Resolve-Path $PSScriptRoot).Path; +} + +Describe 'Kubernetes.Pod' { + BeforeAll { + $testParams = @{ + Module = 'PSRule.Rules.Kubernetes' + Option = Join-Path -Path $here -ChildPath ps-rule.yaml + InputPath = Join-Path -Path $here -ChildPath Resources.Pod.yaml + } + + $result = Invoke-PSRule @testParams -WarningAction Ignore; + } Context 'Security' { It 'Kubernetes.Pod.PrivilegeEscalation' { diff --git a/tests/PSRule.Rules.Kubernetes.Tests/Module.PSGallery.Tests.ps1 b/tests/PSRule.Rules.Kubernetes.Tests/Module.PSGallery.Tests.ps1 index 3f0b12a..8708445 100644 --- a/tests/PSRule.Rules.Kubernetes.Tests/Module.PSGallery.Tests.ps1 +++ b/tests/PSRule.Rules.Kubernetes.Tests/Module.PSGallery.Tests.ps1 @@ -8,18 +8,20 @@ [CmdletBinding()] param () -# Setup error handling -$ErrorActionPreference = 'Stop'; -Set-StrictMode -Version latest; +BeforeAll { + # Setup error handling + $ErrorActionPreference = 'Stop'; + Set-StrictMode -Version latest; -if ($Env:SYSTEM_DEBUG -eq 'true') { - $VerbosePreference = 'Continue'; + if ($Env:SYSTEM_DEBUG -eq 'true') { + $VerbosePreference = 'Continue'; + } + + # Setup tests paths + $rootPath = $PWD; + $modulePath = Join-Path -Path $rootPath -ChildPath out/modules/PSRule.Rules.Kubernetes; } -# Setup tests paths -$rootPath = $PWD; -$modulePath = Join-Path -Path $rootPath -ChildPath out/modules/PSRule.Rules.Kubernetes; - Describe 'PSRule.Rules.Kubernetes' -Tag 'PowerShellGallery' { Context 'Module' { It 'Can be imported' { @@ -28,10 +30,10 @@ Describe 'PSRule.Rules.Kubernetes' -Tag 'PowerShellGallery' { } Context 'Manifest' { - $manifestPath = (Join-Path -Path $modulePath -ChildPath PSRule.Rules.Kubernetes.psd1); - $result = Test-ModuleManifest -Path $manifestPath; It 'Has required fields' { + $manifestPath = (Join-Path -Path $modulePath -ChildPath PSRule.Rules.Kubernetes.psd1); + $result = Test-ModuleManifest -Path $manifestPath; $result.Name | Should -Be 'PSRule.Rules.Kubernetes'; $result.Description | Should -Not -BeNullOrEmpty; $result.LicenseUri | Should -Not -BeNullOrEmpty; diff --git a/tests/PSRule.Rules.Kubernetes.Tests/Rule.Common.Tests.ps1 b/tests/PSRule.Rules.Kubernetes.Tests/Rule.Common.Tests.ps1 index f8ec105..32193fc 100644 --- a/tests/PSRule.Rules.Kubernetes.Tests/Rule.Common.Tests.ps1 +++ b/tests/PSRule.Rules.Kubernetes.Tests/Rule.Common.Tests.ps1 @@ -8,39 +8,39 @@ [CmdletBinding()] param () -# Setup error handling -$ErrorActionPreference = 'Stop'; -Set-StrictMode -Version latest; +BeforeAll { + # Setup error handling + $ErrorActionPreference = 'Stop'; + Set-StrictMode -Version latest; -if ($Env:SYSTEM_DEBUG -eq 'true') { - $VerbosePreference = 'Continue'; + if ($Env:SYSTEM_DEBUG -eq 'true') { + $VerbosePreference = 'Continue'; + } + + # Setup tests paths + $rootPath = $PWD; + Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule.Rules.Kubernetes) -Force; + $here = (Resolve-Path $PSScriptRoot).Path; } -# Setup tests paths -$rootPath = $PWD; -Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule.Rules.Kubernetes) -Force; -$here = (Resolve-Path $PSScriptRoot).Path; - Describe 'Rule quality' { - $rules = Get-PSRule -Module PSRule.Rules.Kubernetes -WarningAction Ignore; + BeforeDiscovery { + $rules = Get-PSRule -Module PSRule.Rules.Kubernetes -WarningAction Ignore; + } Context 'Naming' { - foreach ($rule in $rules) { - It $rule.RuleName { - $rule.RuleName.Length -le 35 | Should -Be $True; - } + It '<_.RuleName>' -ForEach $rules { + $_.RuleName.Length -le 35 | Should -Be $True; } } Context 'Metadata' { - foreach ($rule in $rules) { - It $rule.RuleName { - $rule.Synopsis | Should -Not -BeNullOrEmpty; - $rule.Description | Should -Not -BeNullOrEmpty; - $rule.Info.Annotations.category | Should -Not -BeNullOrEmpty; - $rule.Info.Annotations.severity | Should -Not -BeNullOrEmpty; - $rule.Info.Annotations.'online version' | Should -Not -BeNullOrEmpty; - } + It '<_.RuleName>' -ForEach $rules { + $_.Synopsis | Should -Not -BeNullOrEmpty; + $_.Description | Should -Not -BeNullOrEmpty; + $_.Info.Annotations.category | Should -Not -BeNullOrEmpty; + $_.Info.Annotations.severity | Should -Not -BeNullOrEmpty; + $_.Info.Annotations.'online version' | Should -Not -BeNullOrEmpty; } } }