- Add initial rules and tests
- Add GitHub templates
This commit is contained in:
Bernie White 2019-05-08 08:46:11 +10:00 коммит произвёл GitHub
Родитель 9360a1e554
Коммит 70295c1836
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
24 изменённых файлов: 953 добавлений и 4 удалений

2
.github/CODEOWNERS поставляемый Normal file
Просмотреть файл

@ -0,0 +1,2 @@
# https://help.github.com/articles/about-codeowners/
* @BernieWhite

43
.github/ISSUE_TEMPLATE/bug_report.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,43 @@
---
name: Bug report
about: Report errors or unexpected behaviour
---
**Description of the issue**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the issue:
```powershell
```
**Expected behaviour**
A clear and concise description of what you expected to happen.
**Error output**
Capture any error messages and or verbose messages with `-Verbose`.
```text
```
**Module in use and version:**
- Module: PSRule.Rules.Kubernetes
- Version: **[e.g. 0.1.0]**
Captured output from `$PSVersionTable`:
```text
```
**Additional context**
Add any other context about the problem here.

20
.github/ISSUE_TEMPLATE/feature_request.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

14
.github/PULL_REQUEST_TEMPLATE.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,14 @@
## PR Summary
<!-- summarize your PR between here and the checklist -->
## PR Checklist
- [ ] PR has a meaningful title
- [ ] Summarized changes
- [ ] Change is not breaking
- [ ] This PR is ready to merge and is not **Work in Progress**
- **Code changes**
- [ ] Have unit tests created/ updated
- [ ] Link to a filed issue
- [ ] [Change log](https://github.com/BernieWhite/PSRule.Rules.Kubernetes/blob/master/CHANGELOG.md) has been updated with change under unreleased section

12
.vscode/settings.json поставляемый
Просмотреть файл

@ -1,7 +1,11 @@
{
"files.exclude": {
"**/.git": true,
"**/reports": true,
"**/out": true
}
"reports/": true,
"out/": true
},
"search.exclude": {
"out/": true
},
"editor.insertSpaces": true,
"editor.tabSize": 4
}

21
.vscode/tasks.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,21 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "test",
"type": "shell",
"command": "Invoke-Build Test",
"group": {
"kind": "test",
"isDefault": true
},
"problemMatcher": [ "$pester" ],
"presentation": {
"clear": true,
"panel": "dedicated"
}
}
]
}

2
CHANGELOG.md Normal file
Просмотреть файл

@ -0,0 +1,2 @@
## Unreleased

58
README.md Normal file
Просмотреть файл

@ -0,0 +1,58 @@
# PSRule for Kubernetes
A suite of rules to validate Kubernetes resources using PSRule.
![ci-badge]
## Disclaimer
This project is to be considered a **proof-of-concept** and **not a supported product**.
For issues with rules and documentation please check our GitHub [issues](https://github.com/BernieWhite/PSRule.Rules.Kubernetes/issues) page. If you do not see your problem captured, please file a new issue and follow the provided template.
If you have any problems with the [PSRule][project] engine, please check the project GitHub [issues](https://github.com/BernieWhite/PSRule/issues) page instead.
## Getting the modules
This project requires the PowerShell module PSRule.
You can download and install these modules from the PowerShell Gallery.
Module | Description | Downloads / instructions
------ | ----------- | ------------------------
PSRule.Rules.Kubernetes | Validate Kubernetes resources | [latest][module] / [instructions][install]
## Getting started
### Offline with a manifest
Kubernetes resources can be evaluated within a YAML manifest file.
```powershell
Invoke-PSRule -Module PSRule.Rules.Kubernetes -InputPath .\service.yaml;
```
### Online with kubectl
```powershell
Invoke-PSRule -Module PSRule.Rules.Kubernetes -InputObject (kubectl get services -o yaml | Out-String) -Format Yaml -ObjectPath items;
```
## Changes and versioning
Modules in this repository will use the [semantic versioning](http://semver.org/) model to declare breaking changes from v1.0.0. Prior to v1.0.0, breaking changes may be introduced in minor (0.x.0) version increments. For a list of module changes please see the [change log](CHANGELOG.md).
> Pre-release module versions are created on major commits and can be installed from the PowerShell Gallery. Pre-release versions should be considered experimental. Modules and change log details for pre-releases will be removed as standard releases are made available.
## Maintainers
- [Bernie White](https://github.com/BernieWhite)
## License
This project is [licensed under the MIT License](LICENSE).
[install]: docs/scenarios/install-instructions.md
[ci-badge]: https://dev.azure.com/bewhite/PSRule.Rules.Kubernetes/_apis/build/status/PSRule.Rules.Kubernetes-CI?branchName=master
[module]: https://www.powershellgallery.com/packages/PSRule.Rules.Kubernetes
[project]: https://github.com/BernieWhite/PSRule

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

@ -0,0 +1,37 @@
# Install instructions
## Prerequisites
A separate `PSRule` module is required for `PSRule.Rules.Kubernetes` to work. The required version will automatically be installed along-side `PSRule.Rules.Kubernetes` when using `Install-Module` or `Update-Module` cmdlets.
- Windows PowerShell 5.1 with .NET Framework 4.7.2+ or
- PowerShell Core 6.0 or greater on Windows, macOS and Linux
For a list of platforms that PowerShell Core is supported on [see](https://github.com/PowerShell/PowerShell#get-powershell).
## Getting the modules
Install from [PowerShell Gallery][psg] for all users (requires permissions)
```powershell
# Install PSRule module
Install-Module -Name 'PSRule.Rules.Kubernetes';
```
Install from [PowerShell Gallery][psg] for current user only
```powershell
# Install PSRule module
Install-Module -Name 'PSRule.Rules.Kubernetes' -Scope CurrentUser;
```
Save for offline use from PowerShell Gallery
```powershell
# Save PSRule module, in the .\modules directory
Save-Module -Name 'PSRule', 'PSRule.Rules.Kubernetes' -Path '.\modules';
```
> For pre-release versions the `-AllowPrerelease` switch must be added when calling `Install-Module` or `Save-Module`.
[psg]: https://www.powershellgallery.com/packages/PSRule.Rules.Kubernetes

107
pipeline.build.ps1 Normal file
Просмотреть файл

@ -0,0 +1,107 @@
[CmdletBinding()]
param (
)
# Copy the PowerShell modules files to the destination path
function CopyModuleFiles {
param (
[Parameter(Mandatory = $True)]
[String]$Path,
[Parameter(Mandatory = $True)]
[String]$DestinationPath
)
process {
$sourcePath = Resolve-Path -Path $Path;
Get-ChildItem -Path $sourcePath -Recurse -File -Include *.ps1,*.psm1,*.psd1,*.ps1xml | Where-Object -FilterScript {
($_.FullName -notmatch '(\.(cs|csproj)|(\\|\/)(obj|bin))')
} | ForEach-Object -Process {
$filePath = $_.FullName.Replace($sourcePath, $destinationPath);
$parentPath = Split-Path -Path $filePath -Parent;
if (!(Test-Path -Path $parentPath)) {
$Null = New-Item -Path $parentPath -ItemType Directory -Force;
}
Copy-Item -Path $_.FullName -Destination $filePath -Force;
};
}
}
# Synopsis: Install NuGet provider
task NuGet {
if ($Null -eq (Get-PackageProvider -Name NuGet -ErrorAction Ignore)) {
Install-PackageProvider -Name NuGet -Force -Scope CurrentUser;
}
}
# Synopsis: Install Pester module
task Pester NuGet, {
if ($Null -eq (Get-InstalledModule -Name Pester -MinimumVersion 4.0.0 -ErrorAction Ignore)) {
Install-Module -Name Pester -MinimumVersion 4.0.0 -Scope CurrentUser -Force -SkipPublisherCheck;
}
Import-Module -Name Pester -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 0.5.0 -ErrorAction Ignore)) {
Install-Module -Name PSRule -MinimumVersion 0.5.0 -Scope CurrentUser -Force;
}
Import-Module -Name PSRule -Verbose:$False;
}
task CopyModule {
CopyModuleFiles -Path src/PSRule.Rules.Kubernetes -DestinationPath out/modules/PSRule.Rules.Kubernetes;
# Copy generated help into module out path
# $Null = Copy-Item -Path docs/rules/en-US/* -Destination out/modules/PSrule.Rules.Kubernetes/en-US;
# $Null = Copy-Item -Path docs/rules/en-US/* -Destination out/modules/PSrule.Rules.Kubernetes/en-AU;
}
# Synopsis: Build modules only
task BuildModule CopyModule
task TestRules PSRule, Pester, PSScriptAnalyzer, {
# Run Pester tests
$pesterParams = @{ Path = $PWD; OutputFile = 'reports/Pester.xml'; OutputFormat = 'NUnitXml'; PesterOption = @{ IncludeVSCodeMarker = $True }; PassThru = $True; };
if (!(Test-Path -Path reports)) {
$Null = New-Item -Path reports -ItemType Directory -Force;
}
$results = Invoke-Pester @pesterParams;
# Throw an error if pester tests failed
if ($Null -eq $results) {
throw 'Failed to get Pester test results.';
}
elseif ($results.FailedCount -gt 0) {
throw "$($results.FailedCount) tests failed.";
}
}
# Synopsis: Remove temp files.
task Clean {
Remove-Item -Path out,reports -Recurse -Force -ErrorAction SilentlyContinue;
}
task Build Clean, BuildModule
task Test Build, TestRules
task . Build

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

@ -0,0 +1,22 @@
#
# CI script for integration with Azure DevOps
#
[CmdletBinding()]
param (
[Parameter(Mandatory = $True)]
[String]$File,
[Parameter(Mandatory = $False)]
[String]$Task
)
if ($Null -eq (Get-PackageProvider -Name NuGet -ErrorAction Ignore)) {
Install-PackageProvider -Name NuGet -Force -Scope CurrentUser;
}
if ($Null -eq (Get-InstalledModule -Name InvokeBuild -MinimumVersion 5.4.0 -ErrorAction Ignore)) {
Install-Module InvokeBuild -MinimumVersion 5.4.0 -Scope CurrentUser -Force;
}
Invoke-Build @PSBoundParameters

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

@ -0,0 +1,123 @@
#
# PSRule.Rules.Kubernetes
#
@{
# Script module or binary module file associated with this manifest.
# RootModule = ''
# Version number of this module.
ModuleVersion = '0.0.1'
# Supported PSEditions
CompatiblePSEditions = 'Core', 'Desktop'
# ID used to uniquely identify this module
GUID = 'efaacb4d-b447-4de3-96b9-93860fd87a8c'
# Author of this module
Author = 'Bernie White'
# Company or vendor of this module
CompanyName = 'Bernie White'
# Copyright statement for this module
Copyright = '(c) Bernie White. All rights reserved.'
# Description of the functionality provided by this module
Description = 'Validate Kubernetes resources using PSRule.
This project is to be considered a proof-of-concept and not a supported product.'
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '5.1'
# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''
# Minimum version of the Windows PowerShell host required by this module
# PowerShellHostVersion = ''
# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
DotNetFrameworkVersion = '4.7.2'
# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
# CLRVersion = ''
# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''
# Modules that must be imported into the global environment prior to importing this module
RequiredModules = @(
@{ ModuleName = 'PSRule'; ModuleVersion = '0.5.0' }
)
# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = @()
# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = @()
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
CmdletsToExport = @()
# Variables to export from this module
VariablesToExport = '*'
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
AliasesToExport = @()
# DSC resources to export from this module
# DscResourcesToExport = @()
# List of all modules packaged with this module
# ModuleList = @()
# List of all files packaged with this module
# FileList = @()
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
Tags = @('PSRule', 'Rule', 'Kubernetes')
# A URL to the license for this module.
LicenseUri = 'https://github.com/BernieWhite/PSRule.Rules.Kubernetes/blob/master/LICENSE'
# A URL to the main website for this project.
ProjectUri = 'https://github.com/BernieWhite/PSRule.Rules.Kubernetes'
# A URL to an icon representing this module.
# IconUri = ''
# ReleaseNotes of this module
ReleaseNotes = 'https://github.com/BernieWhite/PSRule.Rules.Kubernetes/blob/master/CHANGELOG.md'
} # End of PSData hashtable
} # End of PrivateData hashtable
# HelpInfo URI of this module
# HelpInfoURI = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''
}

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

@ -0,0 +1,11 @@
#
# Validation rules for Azure Kubernetes Service (AKS)
#
# Description: Services should not include a public load balancer
Rule 'Kubernetes.AKS.PublicLoadBalancer' -Type Service -Tag @{ category = 'Service exposure'; severity = 'Critical'; } -If { $Rule.TargetName -ne 'addon-http-application-routing-nginx-ingress' } {
AnyOf {
Exists 'spec.type' -Not
$TargetObject.spec.type -ne 'LoadBalancer'
}
}

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

@ -0,0 +1,29 @@
#
# Validation rules for Kubernetes deployments
#
# Description: Containers should deny privilege escalation
Rule 'Kubernetes.Deployment.PrivilegeEscalation' -Type Deployment -Tag @{ category = 'Pod security'; severity = 'Critical'; } {
foreach ($container in $TargetObject.spec.template.spec.containers) {
$container | Exists 'securityContext.allowPrivilegeEscalation'
$container.securityContext.allowPrivilegeEscalation -eq $False
}
}
# Description: Containers should use specific tags instead of latest
Rule 'Kubernetes.Deployment.NotLatestImage' -Type Deployment -Tag @{ category = 'Pod security'; severity = 'Important' } {
foreach ($container in $TargetObject.spec.template.spec.containers) {
$container.image -like '*:*' -and
$container.image -notlike '*:latest'
}
}
# Description: Resource requirements are set for each container
Rule 'Kubernetes.Deployment.ResourcesSet' -Type Deployment -Tag @{ category = 'Resource management'; severity = 'Important' } {
foreach ($container in $TargetObject.spec.template.spec.containers) {
$container | Exists 'resources.requests.cpu'
$container | Exists 'resources.requests.memory'
$container | Exists 'resources.limits.cpu'
$container | Exists 'resources.limits.memory'
}
}

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

@ -0,0 +1,10 @@
#
# Validation rules for Kubernetes metadata requirements
#
# Description: Must have the app.kubernetes.io/name label
Rule 'Kubernetes.Metadata' -Type 'Deployment', 'Service' -Tag @{ category = 'Resource management'; severity = 'Important' } {
Exists 'metadata.labels.''app.kubernetes.io/name'''
Exists 'metadata.labels.''app.kubernetes.io/version'''
Exists 'metadata.labels.''app.kubernetes.io/component'''
}

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

@ -0,0 +1,49 @@
#
# Unit tests for Kubernetes AKS rules
#
[CmdletBinding()]
param (
)
# 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'
Option = Join-Path -Path $here -ChildPath ps-rule.yaml
InputPath = Join-Path -Path $here -ChildPath Resources.AKS.yaml
}
$result = Invoke-PSRule @testParams -WarningAction Ignore;
Context 'Security' {
It 'Kubernetes.AKS.PublicLoadBalancer' {
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Kubernetes.AKS.PublicLoadBalancer' };
# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 1;
$ruleResult.TargetName | Should -Be 'service-B';
# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 1;
$ruleResult.TargetName | Should -Be 'service-A';
}
}
}

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

@ -0,0 +1,83 @@
#
# Unit tests for Kubernetes deployment rules
#
[CmdletBinding()]
param (
)
# 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.Deployment' {
$testParams = @{
Module = 'PSRule.Rules.Kubernetes'
Option = Join-Path -Path $here -ChildPath ps-rule.yaml
InputPath = Join-Path -Path $here -ChildPath Resources.Deployment.yaml
}
$result = Invoke-PSRule @testParams -WarningAction Ignore;
Context 'Security' {
It 'Kubernetes.Deployment.PrivilegeEscalation' {
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Kubernetes.Deployment.PrivilegeEscalation' };
# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 1;
$ruleResult.TargetName | Should -Be 'deployment-B';
# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 1;
$ruleResult.TargetName | Should -Be 'deployment-A';
}
It 'Kubernetes.Deployment.NotLatestImage' {
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Kubernetes.Deployment.NotLatestImage' };
# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 1;
$ruleResult.TargetName | Should -Be 'deployment-B';
# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 1;
$ruleResult.TargetName | Should -Be 'deployment-A';
}
}
Context 'Resource management' {
It 'Kubernetes.Deployment.ResourcesSet' {
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Kubernetes.Deployment.ResourcesSet' };
# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 1;
$ruleResult.TargetName | Should -Be 'deployment-B';
# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 1;
$ruleResult.TargetName | Should -Be 'deployment-A';
}
}
}

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

@ -0,0 +1,49 @@
#
# Unit tests for Kubernetes metadata rules
#
[CmdletBinding()]
param (
)
# 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
}
$result = Invoke-PSRule @testParams -WarningAction Ignore;
Context 'Resource metadata' {
It 'Kubernetes.Metadata' {
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Kubernetes.Metadata' };
# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 2;
$ruleResult.TargetName | Should -BeIn 'deployment-B', 'service-B';
# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 2;
$ruleResult.TargetName | Should -BeIn 'deployment-A', 'service-A';
}
}
}

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

@ -0,0 +1,55 @@
#
# Unit tests for validating module for publishing
#
[CmdletBinding()]
param (
)
# Setup error handling
$ErrorActionPreference = 'Stop';
Set-StrictMode -Version latest;
if ($Env:SYSTEM_DEBUG -eq 'true') {
$VerbosePreference = 'Continue';
}
# 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' {
Import-Module $modulePath -Force;
}
}
Context 'Manifest' {
$manifestPath = (Join-Path -Path $modulePath -ChildPath PSRule.Rules.Kubernetes.psd1);
$result = Test-ModuleManifest -Path $manifestPath;
It 'Has required fields' {
$result.Name | Should -Be 'PSRule.Rules.Kubernetes';
$result.Description | Should -Not -BeNullOrEmpty;
$result.LicenseUri | Should -Not -BeNullOrEmpty;
$result.ReleaseNotes | Should -Not -BeNullOrEmpty;
}
}
Context 'Static analysis' {
$result = Invoke-ScriptAnalyzer -Path $modulePath;
$warningCount = ($result | Where-Object { $_.Severity -eq 'Warning' } | Measure-Object).Count;
$errorCount = ($result | Where-Object { $_.Severity -eq 'Error' } | Measure-Object).Count;
if ($warningCount -gt 0) {
Write-Warning -Message "PSScriptAnalyzer reports $warningCount warnings.";
}
It 'Has no quality errors' {
$errorCount | Should -BeLessOrEqual 0;
}
}
}

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

@ -0,0 +1,29 @@
#
# Kubernetes Service resources for unit tests
#
---
# An example service that should pass all rules.
apiVersion: v1
kind: Service
metadata:
name: service-A
spec:
ports:
- port: 80
name: http
selector:
app: app-A
---
# This service should fail kubernetes.AKS.PublicLoadBalancer
apiVersion: v1
kind: Service
metadata:
name: service-B
spec:
type: LoadBalancer
ports:
- port: 6379
selector:
app: app-B

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

@ -0,0 +1,53 @@
#
# Kubernetes Deployment resources for unit tests
#
---
# An example deployment that should pass all rules.
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-A
spec:
replicas: 1
selector:
matchLabels:
app: app-A
template:
metadata:
labels:
app: app-A
spec:
containers:
- name: app-a
image: app-a-image:v1
securityContext:
allowPrivilegeEscalation: false
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-B
spec:
replicas: 1
selector:
matchLabels:
app: app-B
template:
metadata:
labels:
app: app-B
spec:
containers:
- name: app-b
image: app-b-image

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

@ -0,0 +1,84 @@
# An example deployment that should pass all rules.
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-A
labels:
app.kubernetes.io/name: solution-A
app.kubernetes.io/version: 0.0.1
app.kubernetes.io/component: unit-test
spec:
replicas: 1
selector:
matchLabels:
app: app-A
template:
metadata:
labels:
app: app-A
spec:
containers:
- name: green-app
image: green-image:v1
securityContext:
allowPrivilegeEscalation: false
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-B
spec:
replicas: 1
selector:
matchLabels:
app: unconstrained-app
template:
metadata:
labels:
app: unconstrained-app
spec:
containers:
- name: unconstrained-app
image: unconstrained-image
---
# An example service that should pass all rules.
apiVersion: v1
kind: Service
metadata:
name: service-A
labels:
app.kubernetes.io/name: solution-A
app.kubernetes.io/version: 0.0.1
app.kubernetes.io/component: unit-test
spec:
ports:
- port: 80
name: http
selector:
app: app-A
---
# This service should fail kubernetes.AKS.PublicLoadBalancer
apiVersion: v1
kind: Service
metadata:
name: service-B
spec:
type: LoadBalancer
ports:
- port: 6379
selector:
app: red-app

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

@ -0,0 +1,35 @@
#
# Unit tests for PSRule rule quality
#
[CmdletBinding()]
param (
)
# 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 'Rule quality' {
Context 'Metadata' {
$result = Get-PSRule -Module PSRule.Rules.Kubernetes -WarningAction Ignore;
foreach ($rule in $result) {
It $rule.RuleName {
$rule.Description | Should -Not -BeNullOrEmpty;
$rule.Tag.severity | Should -Not -BeNullOrEmpty;
$rule.Tag.category | Should -Not -BeNullOrEmpty;
}
}
}
}

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

@ -0,0 +1,9 @@
binding:
targetName:
- metadata.name
targetType:
- kind
execution:
notProcessedWarning: false