Skip to content

Commit 99c7ff8

Browse files
committed
Check that string probe port match container port
1 parent 9428eea commit 99c7ff8

File tree

10 files changed

+280
-0
lines changed

10 files changed

+280
-0
lines changed

docs/generated/checks.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,15 @@ strategyTypeRegex: ^(RollingUpdate|Rolling)$
428428
**Remediation**: Ensure privileged ports [0, 1024] are not mapped within containers.
429429
430430
**Template**: [privileged-ports](templates.md#privileged-ports)
431+
## probe-port
432+
433+
**Enabled by default**: Yes
434+
435+
**Description**: Alert on probe port that does not match a port defined in container ports
436+
437+
**Remediation**: Ensure probe port matches a port defined in container ports.
438+
439+
**Template**: [probe-port](templates.md#probe-port)
431440
## read-secret-from-env-var
432441
433442
**Enabled by default**: No

docs/generated/templates.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,15 @@ KubeLinter supports the following templates:
557557
**Supported Objects**: DeploymentLike
558558

559559

560+
## Probe Port
561+
562+
**Key**: `probe-port`
563+
564+
**Description**: Flag unknown probe port
565+
566+
**Supported Objects**: DeploymentLike
567+
568+
560569
## Read-only Root Filesystems
561570

562571
**Key**: `read-only-root-fs`

e2etests/bats-tests.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,21 @@ get_value_from() {
608608
[[ "${count}" == "2" ]]
609609
}
610610

611+
@test "probe-port" {
612+
tmp="tests/checks/probe-port.yml"
613+
cmd="${KUBE_LINTER_BIN} lint --include probe-port --do-not-auto-add-defaults --format json ${tmp}"
614+
run ${cmd}
615+
616+
print_info "${status}" "${output}" "${cmd}" "${tmp}"
617+
[ "$status" -eq 1 ]
618+
619+
message1=$(get_value_from "${lines[0]}" '.Reports[0].Object.K8sObject.GroupVersionKind.Kind + ": " + .Reports[0].Diagnostic.Message')
620+
count=$(get_value_from "${lines[0]}" '.Reports | length')
621+
622+
[[ "${message1}" == "Deployment: probe port \"bar\" does not match a port in container \"myapp\"." ]]
623+
[[ "${count}" == "1" ]]
624+
}
625+
611626
@test "read-secret-from-env-var" {
612627
tmp="tests/checks/read-secret-from-env-var.yml"
613628
cmd="${KUBE_LINTER_BIN} lint --include read-secret-from-env-var --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
@@ -26,6 +26,7 @@ var (
2626
"ssh-port",
2727
"privilege-escalation-container",
2828
"privileged-container",
29+
"probe-port",
2930
"run-as-non-root",
3031
"unsafe-sysctls",
3132
"unset-cpu-requirements",
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
name: "probe-port"
2+
description: "Alert on probe port that does not match a port defined in container ports"
3+
remediation: "Ensure probe port matches a port defined in container ports."
4+
scope:
5+
objectKinds:
6+
- DeploymentLike
7+
template: "probe-port"

pkg/templates/all/all.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
_ "golang.stackrox.io/kube-linter/pkg/templates/privileged"
3636
_ "golang.stackrox.io/kube-linter/pkg/templates/privilegedports"
3737
_ "golang.stackrox.io/kube-linter/pkg/templates/privilegeescalation"
38+
_ "golang.stackrox.io/kube-linter/pkg/templates/probeport"
3839
_ "golang.stackrox.io/kube-linter/pkg/templates/readinessprobe"
3940
_ "golang.stackrox.io/kube-linter/pkg/templates/readonlyrootfs"
4041
_ "golang.stackrox.io/kube-linter/pkg/templates/readsecret"

pkg/templates/probeport/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+
}

pkg/templates/probeport/template.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package probeport
2+
3+
import (
4+
"fmt"
5+
6+
"golang.stackrox.io/kube-linter/internal/set"
7+
"golang.stackrox.io/kube-linter/pkg/check"
8+
"golang.stackrox.io/kube-linter/pkg/config"
9+
"golang.stackrox.io/kube-linter/pkg/diagnostic"
10+
"golang.stackrox.io/kube-linter/pkg/objectkinds"
11+
"golang.stackrox.io/kube-linter/pkg/templates"
12+
"golang.stackrox.io/kube-linter/pkg/templates/probeport/internal/params"
13+
"golang.stackrox.io/kube-linter/pkg/templates/util"
14+
v1 "k8s.io/api/core/v1"
15+
"k8s.io/apimachinery/pkg/util/intstr"
16+
)
17+
18+
func init() {
19+
templates.Register(check.Template{
20+
HumanName: "Probe Port",
21+
Key: "probe-port",
22+
Description: "Flag unknown probe port",
23+
SupportedObjectKinds: config.ObjectKindsDesc{
24+
ObjectKinds: []string{objectkinds.DeploymentLike},
25+
},
26+
Parameters: params.ParamDescs,
27+
ParseAndValidateParams: params.ParseAndValidate,
28+
Instantiate: params.WrapInstantiateFunc(func(_ params.Params) (check.Func, error) {
29+
return util.PerNonInitContainerCheck(func(container *v1.Container) []diagnostic.Diagnostic {
30+
var portNames set.StringSet
31+
for _, port := range container.Ports {
32+
if name := port.Name; len(name) > 0 {
33+
portNames.Add(name)
34+
}
35+
}
36+
var results []diagnostic.Diagnostic
37+
for _, probe := range []*v1.Probe{container.LivenessProbe, container.ReadinessProbe, container.StartupProbe} {
38+
if probe == nil {
39+
continue
40+
}
41+
var port intstr.IntOrString
42+
if httpGet := probe.HTTPGet; httpGet != nil {
43+
port = httpGet.Port
44+
} else if tcpSocket := probe.TCPSocket; tcpSocket != nil {
45+
port = tcpSocket.Port
46+
} else {
47+
continue
48+
}
49+
if port.Type == intstr.String && !portNames.Contains(port.StrVal) && port.IntValue() == 0 {
50+
results = append(results, diagnostic.Diagnostic{
51+
Message: fmt.Sprintf("probe port %q does not match a port in container %q.", port.StrVal, container.Name),
52+
})
53+
}
54+
}
55+
return results
56+
}), nil
57+
}),
58+
})
59+
}

tests/checks/probe-port.yml

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: no-probe
5+
spec:
6+
selector:
7+
matchLabels:
8+
app: myapp
9+
template:
10+
metadata:
11+
labels:
12+
app: myapp
13+
spec:
14+
containers:
15+
- name: myapp
16+
image: myimage
17+
resources:
18+
limits:
19+
memory: "128Mi"
20+
cpu: "500m"
21+
---
22+
apiVersion: apps/v1
23+
kind: Deployment
24+
metadata:
25+
name: livenessProbe-int
26+
spec:
27+
selector:
28+
matchLabels:
29+
app: myapp
30+
template:
31+
metadata:
32+
labels:
33+
app: myapp
34+
spec:
35+
containers:
36+
- name: myapp
37+
image: myimage
38+
resources:
39+
limits:
40+
memory: "128Mi"
41+
cpu: "500m"
42+
livenessProbe:
43+
httpGet:
44+
port: 1234
45+
---
46+
apiVersion: apps/v1
47+
kind: Deployment
48+
metadata:
49+
name: readinessProbe-int-str
50+
spec:
51+
selector:
52+
matchLabels:
53+
app: myapp
54+
template:
55+
metadata:
56+
labels:
57+
app: myapp
58+
spec:
59+
containers:
60+
- name: myapp
61+
image: myimage
62+
resources:
63+
limits:
64+
memory: "128Mi"
65+
cpu: "500m"
66+
readinessProbe:
67+
tcpCheck:
68+
port: "1234"
69+
---
70+
apiVersion: apps/v1
71+
kind: Deployment
72+
metadata:
73+
name: startupProbe-str-container-port-ok
74+
spec:
75+
selector:
76+
matchLabels:
77+
app: myapp
78+
template:
79+
metadata:
80+
labels:
81+
app: myapp
82+
spec:
83+
containers:
84+
- name: myapp
85+
image: myimage
86+
resources:
87+
limits:
88+
memory: "128Mi"
89+
cpu: "500m"
90+
ports:
91+
- containerPort: 1234
92+
name: foo
93+
startupProbe:
94+
httpGet:
95+
port: foo
96+
---
97+
apiVersion: apps/v1
98+
kind: Deployment
99+
metadata:
100+
name: startupProbe-str-container-port-ko
101+
spec:
102+
selector:
103+
matchLabels:
104+
app: myapp
105+
template:
106+
metadata:
107+
labels:
108+
app: myapp
109+
spec:
110+
containers:
111+
- name: myapp
112+
image: myimage
113+
resources:
114+
limits:
115+
memory: "128Mi"
116+
cpu: "500m"
117+
ports:
118+
- containerPort: 1234
119+
name: foo
120+
startupProbe:
121+
httpGet:
122+
port: bar

0 commit comments

Comments
 (0)