Skip to content

Commit 8d68919

Browse files
authored
Add new check pdb-unhealthy-pod-eviction-policy (#855) (#856)
1 parent ed0a2ca commit 8d68919

File tree

11 files changed

+232
-0
lines changed

11 files changed

+232
-0
lines changed

docs/generated/checks.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,15 @@ strategyTypeRegex: ^(RollingUpdate|Rolling)$
446446
**Remediation**: Change the PodDisruptionBudget to have minAvailable set to a number lower than the number of replicas in the related deployment-like objects. Refer to https://kubernetes.io/docs/tasks/run-application/configure-pdb/ for more information.
447447
448448
**Template**: [pdb-min-available](templates.md#no-pod-disruptions-allowed---minavailable)
449+
## pdb-unhealthy-pod-eviction-policy
450+
451+
**Enabled by default**: Yes
452+
453+
**Description**: Indicates when a PodDisruptionBudget does not explicitly set the unhealthyPodEvictionPolicy field.
454+
455+
**Remediation**: Set unhealthyPodEvictionPolicy to AlwaysAllow. Refer to https://kubernetes.io/docs/tasks/run-application/configure-pdb/#unhealthy-pod-eviction-policy for more information.
456+
457+
**Template**: [pdb-unhealthy-pod-eviction-policy](templates.md#.spec.unhealthypodevictionpolicy-in-pdb-is-set-to-default)
449458
## privilege-escalation-container
450459
451460
**Enabled by default**: Yes

docs/generated/templates.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,15 @@ KubeLinter supports the following templates:
564564
**Supported Objects**: PodDisruptionBudget
565565

566566

567+
## .spec.unhealthyPodEvictionPolicy in PDB is set to default
568+
569+
**Key**: `pdb-unhealthy-pod-eviction-policy`
570+
571+
**Description**: Flag PodDisruptionBudget objects that do not explicitly set unhealthyPodEvictionPolicy.
572+
573+
**Supported Objects**: PodDisruptionBudget
574+
575+
567576
## Ports
568577

569578
**Key**: `ports`

e2etests/bats-tests.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,20 @@ get_value_from() {
648648
[[ "${count}" == "3" ]]
649649
}
650650

651+
@test "pdb-unhealthy-pod-eviction-policy" {
652+
653+
tmp="tests/checks/pdb-unhealthy-pod-eviction-policy.yaml"
654+
cmd="${KUBE_LINTER_BIN} lint --include pdb-unhealthy-pod-eviction-policy --do-not-auto-add-defaults --format json ${tmp}"
655+
run ${cmd}
656+
657+
message1=$(get_value_from "${lines[0]}" '.Reports[0].Object.K8sObject.GroupVersionKind.Kind + ": " + .Reports[0].Diagnostic.Message')
658+
659+
[[ "${message1}" == "PodDisruptionBudget: unhealthyPodEvictionPolicy is not explicitly set" ]]
660+
count=$(get_value_from "${lines[0]}" '.Reports | length')
661+
[[ "${count}" == "1" ]]
662+
663+
}
664+
651665
@test "privilege-escalation-container" {
652666
tmp="tests/checks/privilege-escalation-container.yml"
653667
cmd="${KUBE_LINTER_BIN} lint --include privilege-escalation-container --do-not-auto-add-defaults --format json ${tmp}"

internal/defaultchecks/default_checks.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,6 @@ var (
3636
"unsafe-sysctls",
3737
"unset-cpu-requirements",
3838
"unset-memory-requirements",
39+
"pdb-unhealthy-pod-eviction-policy",
3940
)
4041
)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
name: "pdb-unhealthy-pod-eviction-policy"
2+
description: "Indicates when a PodDisruptionBudget does not explicitly set the unhealthyPodEvictionPolicy field."
3+
remediation: "Set unhealthyPodEvictionPolicy to AlwaysAllow. Refer to https://kubernetes.io/docs/tasks/run-application/configure-pdb/#unhealthy-pod-eviction-policy for more information."
4+
scope:
5+
objectKinds:
6+
- PodDisruptionBudget
7+
template: "pdb-unhealthy-pod-eviction-policy"

pkg/templates/all/all.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636
_ "golang.stackrox.io/kube-linter/pkg/templates/nonisolatedpod"
3737
_ "golang.stackrox.io/kube-linter/pkg/templates/pdbmaxunavailable"
3838
_ "golang.stackrox.io/kube-linter/pkg/templates/pdbminavailable"
39+
_ "golang.stackrox.io/kube-linter/pkg/templates/pdbunhealthypodevictionpolicy"
3940
_ "golang.stackrox.io/kube-linter/pkg/templates/ports"
4041
_ "golang.stackrox.io/kube-linter/pkg/templates/privileged"
4142
_ "golang.stackrox.io/kube-linter/pkg/templates/privilegedports"

pkg/templates/pdbunhealthypodevictionpolicy/internal/params/gen-params.go

Lines changed: 52 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package params
2+
3+
// Params represents the params accepted by this template.
4+
type Params struct {
5+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package pdbunhealthypodevictionpolicy
2+
3+
import (
4+
"golang.stackrox.io/kube-linter/pkg/check"
5+
"golang.stackrox.io/kube-linter/pkg/config"
6+
"golang.stackrox.io/kube-linter/pkg/diagnostic"
7+
"golang.stackrox.io/kube-linter/pkg/lintcontext"
8+
"golang.stackrox.io/kube-linter/pkg/objectkinds"
9+
"golang.stackrox.io/kube-linter/pkg/templates"
10+
"golang.stackrox.io/kube-linter/pkg/templates/pdbunhealthypodevictionpolicy/internal/params"
11+
pdbV1 "k8s.io/api/policy/v1"
12+
)
13+
14+
const (
15+
templateKey = "pdb-unhealthy-pod-eviction-policy"
16+
)
17+
18+
func init() {
19+
templates.Register(check.Template{
20+
HumanName: ".spec.unhealthyPodEvictionPolicy in PDB is set to default",
21+
Key: templateKey,
22+
Description: "Flag PodDisruptionBudget objects that do not explicitly set unhealthyPodEvictionPolicy.",
23+
SupportedObjectKinds: config.ObjectKindsDesc{
24+
ObjectKinds: []string{
25+
objectkinds.PodDisruptionBudget},
26+
},
27+
Parameters: params.ParamDescs,
28+
ParseAndValidateParams: params.ParseAndValidate,
29+
Instantiate: params.WrapInstantiateFunc(func(_ params.Params) (check.Func, error) {
30+
return func(_ lintcontext.LintContext, object lintcontext.Object) []diagnostic.Diagnostic {
31+
pdb, ok := object.K8sObject.(*pdbV1.PodDisruptionBudget)
32+
if !ok {
33+
return nil
34+
}
35+
if pdb.Spec.UnhealthyPodEvictionPolicy == nil {
36+
return []diagnostic.Diagnostic{{Message: "unhealthyPodEvictionPolicy is not explicitly set"}}
37+
}
38+
return nil
39+
}, nil
40+
}),
41+
})
42+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package pdbunhealthypodevictionpolicy
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/suite"
7+
"golang.stackrox.io/kube-linter/pkg/diagnostic"
8+
"golang.stackrox.io/kube-linter/pkg/lintcontext/mocks"
9+
"golang.stackrox.io/kube-linter/pkg/templates"
10+
"golang.stackrox.io/kube-linter/pkg/templates/pdbunhealthypodevictionpolicy/internal/params"
11+
pdbv1 "k8s.io/api/policy/v1"
12+
)
13+
14+
func TestUnhealthyPodEvictionPolicyPDB(t *testing.T) {
15+
suite.Run(t, new(UnhealthyPodEvictionPolicyPDBTestSuite))
16+
}
17+
18+
type UnhealthyPodEvictionPolicyPDBTestSuite struct {
19+
templates.TemplateTestSuite
20+
21+
ctx *mocks.MockLintContext
22+
}
23+
24+
func (s *UnhealthyPodEvictionPolicyPDBTestSuite) SetupTest() {
25+
s.Init(templateKey)
26+
s.ctx = mocks.NewMockContext()
27+
}
28+
29+
func (s *UnhealthyPodEvictionPolicyPDBTestSuite) TestNoUnhealthyPodEvictionPolicy() {
30+
s.ctx.AddMockPodDisruptionBudget(s.T(), "test-pdb-no-unhealthy-pod-eviction-policy")
31+
s.ctx.ModifyPodDisruptionBudget(s.T(), "test-pdb-no-unhealthy-pod-eviction-policy", func(pdb *pdbv1.PodDisruptionBudget) {
32+
pdb.Spec.UnhealthyPodEvictionPolicy = nil
33+
})
34+
s.Validate(s.ctx, []templates.TestCase{
35+
{
36+
Param: params.Params{},
37+
Diagnostics: map[string][]diagnostic.Diagnostic{
38+
"test-pdb-no-unhealthy-pod-eviction-policy": {{Message: "unhealthyPodEvictionPolicy is not explicitly set"}},
39+
},
40+
ExpectInstantiationError: false,
41+
},
42+
})
43+
}
44+
45+
func (s *UnhealthyPodEvictionPolicyPDBTestSuite) TestUnhealthyPodEvictionPolicyIsSet() {
46+
s.ctx.AddMockPodDisruptionBudget(s.T(), "test-pdb-unhealthy-pod-eviction-policy-is-set")
47+
s.ctx.ModifyPodDisruptionBudget(s.T(), "test-pdb-unhealthy-pod-eviction-policy-is-set", func(pdb *pdbv1.PodDisruptionBudget) {
48+
var policy pdbv1.UnhealthyPodEvictionPolicyType = "AlwaysAllow"
49+
pdb.Spec.UnhealthyPodEvictionPolicy = &policy
50+
})
51+
s.Validate(s.ctx, []templates.TestCase{
52+
{
53+
Param: params.Params{},
54+
Diagnostics: map[string][]diagnostic.Diagnostic{
55+
"test-pdb-unhealthy-pod-eviction-policy-is-set": nil,
56+
},
57+
ExpectInstantiationError: false,
58+
},
59+
})
60+
}

0 commit comments

Comments
 (0)