Родитель
a19407c0e9
Коммит
0732999c26
|
@ -2,8 +2,13 @@
|
|||
|
||||
## Unreleased
|
||||
|
||||
- Added new rules for API deprecation removals:
|
||||
- Planned Kubernetes v1.17.0 deprecation removals. [#38](https://github.com/Microsoft/PSRule.Rules.Kubernetes/issues/38)
|
||||
- Planned Kubernetes v1.20.0 deprecation removals. [#39](https://github.com/Microsoft/PSRule.Rules.Kubernetes/issues/39)
|
||||
- **Breaking change**: Use qualified target names. [#36](https://github.com/Microsoft/PSRule.Rules.Kubernetes/issues/36)
|
||||
- If using suppression, update suppressed target name with qualified name.
|
||||
- **Breaking change**: Renamed `Kubernetes.API.Removal` to handle future API deprecations. [#40](https://github.com/Microsoft/PSRule.Rules.Kubernetes/issues/40)
|
||||
- The rule `Kubernetes.API.Removal` is now `Kubernetes.API.v1.16`.
|
||||
|
||||
## v0.1.0
|
||||
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
---
|
||||
severity: Important
|
||||
category: API
|
||||
online version: https://github.com/Microsoft/PSRule.Rules.Kubernetes/blob/master/docs/rules/en/Kubernetes.API.Removal.md
|
||||
---
|
||||
|
||||
# Use supported APIs
|
||||
|
||||
## SYNOPSIS
|
||||
|
||||
Avoid using legacy API endpoints.
|
||||
|
||||
## DESCRIPTION
|
||||
|
||||
In Kubernetes v1.16.0 a number of previously deprecated API endpoints have been removed.
|
||||
These removed endpoints will no longer work for new deployments after upgrading to Kubernetes v1.16.0 or greater.
|
||||
|
||||
To prevent deployment issues use the newer API endpoints for these resources.
|
||||
|
||||
- NetworkPolicy should use `networking.k8s.io/v1`.
|
||||
- PodSecurityPolicy should use `policy/v1beta1`.
|
||||
- DaemonSet, Deployment, StatefulSet, and ReplicaSet should use `apps/v1`.
|
||||
|
||||
## RECOMMENDATION
|
||||
|
||||
Consider updating resource deployments to use newer API endpoints prior to upgrading to Kubernetes >= v1.16.0.
|
||||
|
||||
## LINKS
|
||||
|
||||
- [Kubernetes v1.15.0 deprecations and removals](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.15.md#deprecations-and-removals)
|
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
severity: Important
|
||||
category: API
|
||||
online version: https://github.com/microsoft/PSRule.Rules.Kubernetes/blob/master/docs/rules/en/Kubernetes.API.v1.16.md
|
||||
---
|
||||
|
||||
# Use APIs supported in v1.16
|
||||
|
||||
## SYNOPSIS
|
||||
|
||||
Avoid using legacy API endpoints not served by Kubernetes v1.16.
|
||||
|
||||
## DESCRIPTION
|
||||
|
||||
In Kubernetes v1.16.0 a number of previously deprecated API endpoints are no longer served.
|
||||
These endpoints will no longer work for new deployments after upgrading to Kubernetes v1.16.0 or greater.
|
||||
|
||||
To prevent deployment issues use the newer API endpoints for these resources.
|
||||
|
||||
- NetworkPolicy should use `networking.k8s.io/v1`.
|
||||
- PodSecurityPolicy should use `policy/v1beta1`.
|
||||
- DaemonSet, Deployment, StatefulSet and ReplicaSet should use `apps/v1`.
|
||||
|
||||
## RECOMMENDATION
|
||||
|
||||
Consider updating resource deployments to use newer API endpoints prior to upgrading to Kubernetes >= v1.16.0.
|
||||
|
||||
## LINKS
|
||||
|
||||
- [Kubernetes v1.15.0 deprecations and removals](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.15.md#deprecations-and-removals)
|
||||
- [Kubernetes Deprecation Policy](https://kubernetes.io/docs/reference/using-api/deprecation-policy/)
|
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
severity: Important
|
||||
category: API
|
||||
online version: https://github.com/microsoft/PSRule.Rules.Kubernetes/blob/master/docs/rules/en/Kubernetes.API.v1.17.md
|
||||
---
|
||||
|
||||
# Use APIs supported in v1.17
|
||||
|
||||
## SYNOPSIS
|
||||
|
||||
Avoid using legacy API endpoints not served by Kubernetes v1.17.
|
||||
|
||||
## DESCRIPTION
|
||||
|
||||
In Kubernetes v1.17.0 previously deprecated API endpoints are no longer served.
|
||||
These endpoints will no longer work for new deployments after upgrading to Kubernetes v1.17.0 or greater.
|
||||
|
||||
To prevent deployment issues use the newer API endpoints for these resources.
|
||||
|
||||
- PriorityClass should use `scheduling.k8s.io/v1`.
|
||||
|
||||
## RECOMMENDATION
|
||||
|
||||
Consider updating resource deployments to use newer API endpoints prior to upgrading to Kubernetes >= v1.17.0.
|
||||
|
||||
## LINKS
|
||||
|
||||
- [Kubernetes v1.16.0 deprecations and removals](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.16.md#deprecations-and-removals)
|
||||
- [Kubernetes Deprecation Policy](https://kubernetes.io/docs/reference/using-api/deprecation-policy/)
|
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
severity: Important
|
||||
category: API
|
||||
online version: https://github.com/microsoft/PSRule.Rules.Kubernetes/blob/master/docs/rules/en/Kubernetes.API.v1.20.md
|
||||
---
|
||||
|
||||
# Use APIs supported in v1.20
|
||||
|
||||
## SYNOPSIS
|
||||
|
||||
Avoid using legacy API endpoints not served by Kubernetes v1.20.
|
||||
|
||||
## DESCRIPTION
|
||||
|
||||
In Kubernetes v1.20.0 a number of previously deprecated API endpoints are planned to be no longer served.
|
||||
These endpoints will no longer work for new deployments after upgrading to Kubernetes v1.20.0 or greater.
|
||||
|
||||
To prevent deployment issues use the newer API endpoints for these resources.
|
||||
|
||||
- Ingress should use `networking.k8s.io/v1beta1`.
|
||||
- Role, RoleBinding, ClusterRoleBinding and ClusterRole should use `rbac.authorization.k8s.io/v1`.
|
||||
|
||||
## RECOMMENDATION
|
||||
|
||||
Consider updating resource deployments to use newer API endpoints prior to upgrading to Kubernetes >= v1.20.0.
|
||||
|
||||
## LINKS
|
||||
|
||||
- [Kubernetes v1.15.0 deprecations and removals](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.15.md#deprecations-and-removals)
|
||||
- [Kubernetes v1.17.0 deprecations and removals](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.17.md#deprecations-and-removals)
|
||||
- [Kubernetes Deprecation Policy](https://kubernetes.io/docs/reference/using-api/deprecation-policy/)
|
|
@ -5,15 +5,50 @@
|
|||
# Validation rules for Kubernetes resource requirements
|
||||
#
|
||||
|
||||
# Synopsis: Avoid using legacy API endpoints
|
||||
Rule 'Kubernetes.API.Removal' -Type DaemonSet, Deployment, StatefulSet, ReplicaSet, NetworkPolicy, PodSecurityPolicy -Tag @{ group = 'core' } {
|
||||
if ($PSRule.TargetType -in 'DaemonSet', 'Deployment', 'StatefulSet', 'ReplicaSet') {
|
||||
$TargetObject.apiVersion -eq 'apps/v1'
|
||||
# Synopsis: Avoid using legacy API endpoints for v1.16.0
|
||||
Rule 'Kubernetes.API.v1.16' -Type DaemonSet, Deployment, StatefulSet, ReplicaSet, NetworkPolicy, PodSecurityPolicy -Tag @{ group = 'core' } {
|
||||
if ($PSRule.TargetType -eq 'ReplicaSet') {
|
||||
# Use apps/v1
|
||||
$TargetObject.apiVersion -notin 'extensions/v1beta1', 'apps/v1beta1', 'apps/v1beta2'
|
||||
}
|
||||
elseif ($PSRule.TargetType -eq 'StatefulSet') {
|
||||
# Use apps/v1
|
||||
$TargetObject.apiVersion -notin 'apps/v1beta1', 'apps/v1beta2'
|
||||
}
|
||||
elseif ($PSRule.TargetType -eq 'Deployment') {
|
||||
# Use apps/v1
|
||||
$TargetObject.apiVersion -notin 'extensions/v1beta1', 'apps/v1beta1', 'apps/v1beta2'
|
||||
}
|
||||
elseif ($PSRule.TargetType -eq 'DaemonSet') {
|
||||
# Use apps/v1
|
||||
$TargetObject.apiVersion -notin 'extensions/v1beta1', 'apps/v1beta2'
|
||||
}
|
||||
elseif ($PSRule.TargetType -eq 'NetworkPolicy') {
|
||||
$TargetObject.apiVersion -eq 'networking.k8s.io/v1'
|
||||
# Use networking.k8s.io/v1
|
||||
$TargetObject.apiVersion -notin 'extensions/v1beta1'
|
||||
}
|
||||
elseif ($PSRule.TargetType -eq 'PodSecurityPolicy') {
|
||||
$TargetObject.apiVersion -eq 'policy/v1beta1'
|
||||
# Use policy/v1beta1
|
||||
$TargetObject.apiVersion -notin 'extensions/v1beta1'
|
||||
}
|
||||
}
|
||||
|
||||
# Synopsis: Avoid using legacy API endpoints for v1.17.0
|
||||
Rule 'Kubernetes.API.v1.17' -Type PriorityClass -Tag @{ group = 'core' } {
|
||||
if ($PSRule.TargetType -eq 'PriorityClass') {
|
||||
# Use scheduling.k8s.io/v1
|
||||
$TargetObject.apiVersion -notin 'scheduling.k8s.io/v1beta1', 'scheduling.k8s.io/v1alpha1'
|
||||
}
|
||||
}
|
||||
|
||||
# Synopsis: Avoid using legacy API endpoints for v1.20.0
|
||||
Rule 'Kubernetes.API.v1.20' -Type Ingress, Role, RoleBinding, ClusterRoleBinding, ClusterRole -Tag @{ group = 'core' } {
|
||||
if ($PSRule.TargetType -eq 'Ingress') {
|
||||
# Use networking.k8s.io/v1beta1
|
||||
$TargetObject.apiVersion -notin 'extensions/v1beta1'
|
||||
}
|
||||
elseif ($PSRule.TargetType -in 'Role', 'RoleBinding', 'ClusterRoleBinding', 'ClusterRole') {
|
||||
# Use rbac.authorization.k8s.io/v1
|
||||
$TargetObject.apiVersion -notin 'rbac.authorization.k8s.io/v1alpha1', 'rbac.authorization.k8s.io/v1beta1'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,30 +21,62 @@ $rootPath = $PWD;
|
|||
Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule.Rules.Kubernetes) -Force;
|
||||
$here = (Resolve-Path $PSScriptRoot).Path;
|
||||
|
||||
Describe 'Kubernetes.API.Removal' {
|
||||
Describe 'Kubernetes.API' {
|
||||
$testParams = @{
|
||||
Module = 'PSRule.Rules.Kubernetes'
|
||||
Option = Join-Path -Path $here -ChildPath ps-rule.yaml
|
||||
InputPath = Join-Path -Path $here -ChildPath Resources.Pod.yaml
|
||||
InputPath = Join-Path -Path $here -ChildPath Resources.API.yaml
|
||||
}
|
||||
|
||||
$result = Invoke-PSRule @testParams -WarningAction Ignore;
|
||||
|
||||
Context 'API' {
|
||||
It 'Kubernetes.API.Removal' {
|
||||
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Kubernetes.API.Removal' };
|
||||
It 'Kubernetes.API.v1.16' {
|
||||
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Kubernetes.API.v1.16' };
|
||||
|
||||
# Fail
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 1;
|
||||
$ruleResult.TargetName | Should -Be 'deployment/deployment-B';
|
||||
$ruleResult.TargetName | Should -Be 'Deployment/deployment-B';
|
||||
|
||||
# Pass
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 1;
|
||||
$ruleResult.TargetName | Should -Be 'deployment/deployment-A';
|
||||
$ruleResult.TargetName | Should -Be 'Deployment/deployment-A';
|
||||
}
|
||||
|
||||
It 'Kubernetes.API.v1.17' {
|
||||
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Kubernetes.API.v1.17' };
|
||||
|
||||
# Fail
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 1;
|
||||
$ruleResult.TargetName | Should -Be 'PriorityClass/priority-B';
|
||||
|
||||
# Pass
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 1;
|
||||
$ruleResult.TargetName | Should -Be 'PriorityClass/priority-A';
|
||||
}
|
||||
|
||||
It 'Kubernetes.API.v1.20' {
|
||||
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Kubernetes.API.v1.20' };
|
||||
|
||||
# Fail
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 5;
|
||||
$ruleResult.TargetName | Should -BeIn 'Ingress/ingress-A', 'ClusterRole/clusterRole-B', 'Role/role-B', 'ClusterRoleBinding/clusterRoleBinding-B', 'RoleBinding/roleBinding-B';
|
||||
|
||||
# Pass
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 5;
|
||||
$ruleResult.TargetName | Should -BeIn 'Ingress/ingress-B', 'ClusterRole/clusterRole-A', 'Role/role-A', 'ClusterRoleBinding/clusterRoleBinding-A', 'RoleBinding/roleBinding-A';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
#
|
||||
# Kubernetes Pod resources for unit tests
|
||||
#
|
||||
|
||||
---
|
||||
# An example deployment that should pass all rules.
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deployment-A
|
||||
spec:
|
||||
replicas: 2
|
||||
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
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 80
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 3
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 80
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 3
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
---
|
||||
apiVersion: apps/v1beta1
|
||||
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
|
||||
env:
|
||||
- name: insecure-password
|
||||
value: Pass123
|
||||
|
||||
---
|
||||
apiVersion: scheduling.k8s.io/v1
|
||||
kind: PriorityClass
|
||||
metadata:
|
||||
name: priority-A
|
||||
value: 1000000
|
||||
globalDefault: false
|
||||
description: "This is a high priority class."
|
||||
|
||||
---
|
||||
apiVersion: scheduling.k8s.io/v1beta1
|
||||
kind: PriorityClass
|
||||
metadata:
|
||||
name: priority-B
|
||||
value: 100
|
||||
globalDefault: false
|
||||
description: "This is a low priority class."
|
||||
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ingress-A
|
||||
spec: {}
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ingress-B
|
||||
spec: {}
|
||||
|
||||
---
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: clusterRole-A
|
||||
rules: []
|
||||
|
||||
---
|
||||
kind: Role
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: role-A
|
||||
rules: []
|
||||
|
||||
---
|
||||
kind: RoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: roleBinding-A
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: role-A
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
subjects: []
|
||||
|
||||
---
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: clusterRoleBinding-A
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: clusterRole-A
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
subjects: []
|
||||
|
||||
---
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: clusterRole-B
|
||||
rules: []
|
||||
|
||||
---
|
||||
kind: Role
|
||||
apiVersion: rbac.authorization.k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: role-B
|
||||
rules: []
|
||||
|
||||
---
|
||||
kind: RoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: roleBinding-B
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: role-B
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
subjects: []
|
||||
|
||||
---
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: clusterRoleBinding-B
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: clusterRole-B
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
subjects: []
|
Загрузка…
Ссылка в новой задаче