Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create new check for liveness port #661

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/generated/checks.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,15 @@ BlockList:
- ^[^:]*$
- (.*/[^:]+)$
```
## liveness-port

**Enabled by default**: Yes

**Description**: Indicates when containers have a liveness probe to a not exposed port.

**Remediation**: Check which ports you've opened and ensure they match what you have specified in the liveness probe.

**Template**: [liveness-http-port](templates.md#liveness-port-not-open)
## minimum-three-replicas

**Enabled by default**: No
Expand Down
9 changes: 9 additions & 0 deletions docs/generated/templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,15 @@ KubeLinter supports the following templates:
type: array
```

## Liveness Port Not Open

**Key**: `liveness-http-port`

**Description**: Flag containers with an HTTP liveness probe to not exposed port.

**Supported Objects**: DeploymentLike


## Liveness Probe Not Specified

**Key**: `liveness-probe`
Expand Down
26 changes: 24 additions & 2 deletions e2etests/bats-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,28 @@ get_value_from() {
[[ "${count}" == "2" ]]
}

@test "liveness-port" {
tmp="tests/checks/liveness-port.yml"
cmd="${KUBE_LINTER_BIN} lint --include liveness-port --do-not-auto-add-defaults --format json ${tmp}"
run ${cmd}

print_info "${status}" "${output}" "${cmd}" "${tmp}"
[ "$status" -eq 1 ]

message1=$(get_value_from "${lines[0]}" '.Reports[0].Object.K8sObject.GroupVersionKind.Kind + ": " + .Reports[0].Diagnostic.Message')
message2=$(get_value_from "${lines[0]}" '.Reports[1].Object.K8sObject.GroupVersionKind.Kind + ": " + .Reports[1].Diagnostic.Message')
message3=$(get_value_from "${lines[0]}" '.Reports[2].Object.K8sObject.GroupVersionKind.Kind + ": " + .Reports[2].Diagnostic.Message')
message4=$(get_value_from "${lines[0]}" '.Reports[3].Object.K8sObject.GroupVersionKind.Kind + ": " + .Reports[3].Diagnostic.Message')
count=$(get_value_from "${lines[0]}" '.Reports | length')

[[ "${message1}" == "Deployment: container \"fire-deployment-name\" does not expose port http for the HTTPGet" ]]
[[ "${message2}" == "Deployment: container \"fire-deployment-int\" does not expose port 8080 for the HTTPGet" ]]
[[ "${message3}" == "Deployment: container \"fire-deployment-udp\" does not expose port udp for the TCPSocket" ]]
[[ "${message4}" == "StatefulSet: container \"fire-stateful-name\" does not expose port healthcheck for the HTTPGet" ]]
[[ "${count}" == "4" ]]
}


@test "minimum-three-replicas" {
tmp="tests/checks/minimum-three-replicas.yml"
cmd="${KUBE_LINTER_BIN} lint --include minimum-three-replicas --do-not-auto-add-defaults --format json ${tmp}"
Expand Down Expand Up @@ -603,7 +625,7 @@ get_value_from() {
run ${cmd}

message1=$(get_value_from "${lines[0]}" '.Reports[0].Object.K8sObject.GroupVersionKind.Kind + ": " + .Reports[0].Diagnostic.Message')

[[ "${message1}" == "PodDisruptionBudget: MaxUnavailable is set to 0" ]]

}
Expand All @@ -614,7 +636,7 @@ get_value_from() {
cmd="${KUBE_LINTER_BIN} lint --include pdb-min-available --do-not-auto-add-defaults --format json ${tmp}"
run ${cmd}


message1=$(get_value_from "${lines[0]}" '.Reports[0].Object.K8sObject.GroupVersionKind.Kind + ": " + .Reports[0].Diagnostic.Message')

[[ "${message1}" == "PodDisruptionBudget: The current number of replicas for deployment foo is equal to or lower than the minimum number of replicas specified by its PDB." ]]
Expand Down
1 change: 1 addition & 0 deletions internal/defaultchecks/default_checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ var (
"host-pid",
"invalid-target-ports",
"latest-tag",
"liveness-port",
"mismatching-selector",
"no-anti-affinity",
"no-extensions-v1beta",
Expand Down
9 changes: 9 additions & 0 deletions pkg/builtinchecks/yamls/liveness-port.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: "liveness-port"
description: "Indicates when containers have a liveness probe to a not exposed port."
remediation: >-
Check which ports you've opened and ensure they match what you have specified
in the liveness probe.
scope:
objectKinds:
- DeploymentLike
template: "liveness-http-port"
1 change: 1 addition & 0 deletions pkg/templates/all/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
_ "golang.stackrox.io/kube-linter/pkg/templates/hpareplicas"
_ "golang.stackrox.io/kube-linter/pkg/templates/imagepullpolicy"
_ "golang.stackrox.io/kube-linter/pkg/templates/latesttag"
_ "golang.stackrox.io/kube-linter/pkg/templates/livenessport"
_ "golang.stackrox.io/kube-linter/pkg/templates/livenessprobe"
_ "golang.stackrox.io/kube-linter/pkg/templates/memoryrequirements"
_ "golang.stackrox.io/kube-linter/pkg/templates/mismatchingselector"
Expand Down
52 changes: 52 additions & 0 deletions pkg/templates/livenessport/internal/params/gen-params.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions pkg/templates/livenessport/internal/params/params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package params

// Params represents the params accepted by this template.
type Params struct{}
65 changes: 65 additions & 0 deletions pkg/templates/livenessport/template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package livenessport

import (
"fmt"

"golang.stackrox.io/kube-linter/pkg/check"
"golang.stackrox.io/kube-linter/pkg/config"
"golang.stackrox.io/kube-linter/pkg/diagnostic"
"golang.stackrox.io/kube-linter/pkg/objectkinds"
"golang.stackrox.io/kube-linter/pkg/templates"
"golang.stackrox.io/kube-linter/pkg/templates/livenessport/internal/params"
"golang.stackrox.io/kube-linter/pkg/templates/util"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/intstr"
)

const templateKey = "liveness-http-port"

var sentinel = struct{}{}

func init() {
templates.Register(check.Template{
HumanName: "Liveness Port Not Open",
Key: templateKey,
Description: "Flag containers with an HTTP liveness probe to not exposed port.",
SupportedObjectKinds: config.ObjectKindsDesc{
ObjectKinds: []string{objectkinds.DeploymentLike},
},
Parameters: params.ParamDescs,
ParseAndValidateParams: params.ParseAndValidate,
Instantiate: params.WrapInstantiateFunc(func(_ params.Params) (check.Func, error) {
return util.PerNonInitContainerCheck(func(container *v1.Container) []diagnostic.Diagnostic {
if container.LivenessProbe == nil {
return nil
}

ports := map[intstr.IntOrString]struct{}{}
for _, port := range container.Ports {
janisz marked this conversation as resolved.
Show resolved Hide resolved
if port.Protocol != "" && port.Protocol != v1.ProtocolTCP {
continue
}
ports[intstr.FromInt32(port.ContainerPort)] = sentinel
ports[intstr.FromString(port.Name)] = sentinel
}

if httpProbe := container.LivenessProbe.ProbeHandler.HTTPGet; httpProbe != nil {
if _, ok := ports[httpProbe.Port]; !ok {
return []diagnostic.Diagnostic{{
Message: fmt.Sprintf("container %q does not expose port %s for the HTTPGet", container.Name, httpProbe.Port.String()),
}}
}
}

if tcpProbe := container.LivenessProbe.ProbeHandler.TCPSocket; tcpProbe != nil {
if _, ok := ports[tcpProbe.Port]; !ok {
return []diagnostic.Diagnostic{{
Message: fmt.Sprintf("container %q does not expose port %s for the TCPSocket", container.Name, tcpProbe.Port.String()),
}}
}
}
return nil
}), nil
}),
})
}
Loading
Loading