From d5c0cf1c46949f98e8b82c05075ce995fc441af5 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Tue, 4 Jun 2024 00:17:10 +0000 Subject: [PATCH 1/3] chore: adding CEL for psp-host-network-ports policy Signed-off-by: Jaydip Gabani --- .../1.1.0/artifacthub-pkg.yml | 22 +++ .../1.1.0/kustomization.yaml | 2 + .../psp-host-network-ports/constraint.yaml | 13 ++ .../disallowed_ephemeral.yaml | 14 ++ .../example_allowed.yaml | 14 ++ .../example_disallowed.yaml | 14 ++ .../psp-host-network-ports/update.yaml | 19 ++ .../host-network-ports/1.1.0/suite.yaml | 25 +++ .../host-network-ports/1.1.0/template.yaml | 156 +++++++++++++++ .../host-network-ports/template.yaml | 154 +++++++++------ .../host-network-ports/constraint.tmpl | 22 ++- .../host-network-ports/src.cel | 33 ++++ website/docs/validation/host-network-ports.md | 180 +++++++++++------- 13 files changed, 531 insertions(+), 137 deletions(-) create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.0/artifacthub-pkg.yml create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.0/kustomization.yaml create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/constraint.yaml create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/disallowed_ephemeral.yaml create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/example_allowed.yaml create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/example_disallowed.yaml create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/update.yaml create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.0/suite.yaml create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.0/template.yaml create mode 100644 src/pod-security-policy/host-network-ports/src.cel diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/artifacthub-pkg.yml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/artifacthub-pkg.yml new file mode 100644 index 000000000..7bbf162f3 --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/artifacthub-pkg.yml @@ -0,0 +1,22 @@ +version: 1.1.0 +name: k8spsphostnetworkingports +displayName: Host Networking Ports +createdAt: "2024-06-04T00:04:23Z" +description: Controls usage of host network namespace by pod containers. Specific ports must be specified. Corresponds to the `hostNetwork` and `hostPorts` fields in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces +digest: 5204259e7e30eb4a752aefa71ace7c577027779c16b0a31875a6c423abf70840 +license: Apache-2.0 +homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/host-network-ports +keywords: + - gatekeeper + - open-policy-agent + - policies +readme: |- + # Host Networking Ports + Controls usage of host network namespace by pod containers. Specific ports must be specified. Corresponds to the `hostNetwork` and `hostPorts` fields in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces +install: |- + ### Usage + ```shell + kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/template.yaml + ``` +provider: + name: Gatekeeper Library diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/kustomization.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/kustomization.yaml new file mode 100644 index 000000000..7d70d11b7 --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/kustomization.yaml @@ -0,0 +1,2 @@ +resources: + - template.yaml diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/constraint.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/constraint.yaml new file mode 100644 index 000000000..fcbc5d805 --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/constraint.yaml @@ -0,0 +1,13 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPHostNetworkingPorts +metadata: + name: psp-host-network-ports +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + hostNetwork: true + min: 80 + max: 9000 diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/disallowed_ephemeral.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/disallowed_ephemeral.yaml new file mode 100644 index 000000000..7a4fa3114 --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/disallowed_ephemeral.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-host-networking-ports-disallowed + labels: + app: nginx-host-networking-ports +spec: + hostNetwork: true + ephemeralContainers: + - name: nginx + image: nginx + ports: + - containerPort: 9001 + hostPort: 9001 diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/example_allowed.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/example_allowed.yaml new file mode 100644 index 000000000..08b321fe5 --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/example_allowed.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-host-networking-ports-allowed + labels: + app: nginx-host-networking-ports +spec: + hostNetwork: false + containers: + - name: nginx + image: nginx + ports: + - containerPort: 9000 + hostPort: 80 diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/example_disallowed.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/example_disallowed.yaml new file mode 100644 index 000000000..9a496cd60 --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/example_disallowed.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-host-networking-ports-disallowed + labels: + app: nginx-host-networking-ports +spec: + hostNetwork: true + containers: + - name: nginx + image: nginx + ports: + - containerPort: 9001 + hostPort: 9001 diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/update.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/update.yaml new file mode 100644 index 000000000..231096430 --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/update.yaml @@ -0,0 +1,19 @@ +kind: AdmissionReview +apiVersion: admission.k8s.io/v1beta1 +request: + operation: "UPDATE" + object: + apiVersion: v1 + kind: Pod + metadata: + name: nginx-host-networking-ports-disallowed + labels: + app: nginx-host-networking-ports + spec: + hostNetwork: true + containers: + - name: nginx + image: nginx + ports: + - containerPort: 9001 + hostPort: 9001 diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/suite.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/suite.yaml new file mode 100644 index 000000000..710df69eb --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/suite.yaml @@ -0,0 +1,25 @@ +kind: Suite +apiVersion: test.gatekeeper.sh/v1alpha1 +metadata: + name: host-network-ports +tests: +- name: use-of-host-networking-ports-blocked + template: template.yaml + constraint: samples/psp-host-network-ports/constraint.yaml + cases: + - name: example-disallowed + object: samples/psp-host-network-ports/example_disallowed.yaml + assertions: + - violations: yes + - name: example-allowed + object: samples/psp-host-network-ports/example_allowed.yaml + assertions: + - violations: no + - name: disallowed-ephemeral + object: samples/psp-host-network-ports/disallowed_ephemeral.yaml + assertions: + - violations: yes + - name: update + object: samples/psp-host-network-ports/update.yaml + assertions: + - violations: no diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/template.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/template.yaml new file mode 100644 index 000000000..146cac6b2 --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/template.yaml @@ -0,0 +1,156 @@ +apiVersion: templates.gatekeeper.sh/v1 +kind: ConstraintTemplate +metadata: + name: k8spsphostnetworkingports + annotations: + metadata.gatekeeper.sh/title: "Host Networking Ports" + metadata.gatekeeper.sh/version: 1.1.0 + description: >- + Controls usage of host network namespace by pod containers. Specific + ports must be specified. Corresponds to the `hostNetwork` and + `hostPorts` fields in a PodSecurityPolicy. For more information, see + https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces +spec: + crd: + spec: + names: + kind: K8sPSPHostNetworkingPorts + validation: + # Schema for the `parameters` field + openAPIV3Schema: + type: object + description: >- + Controls usage of host network namespace by pod containers. Specific + ports must be specified. Corresponds to the `hostNetwork` and + `hostPorts` fields in a PodSecurityPolicy. For more information, see + https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces + properties: + exemptImages: + description: >- + Any container that uses an image that matches an entry in this list will be excluded + from enforcement. Prefix-matching can be signified with `*`. For example: `my-image-*`. + + It is recommended that users use the fully-qualified Docker image name (e.g. start with a domain name) + in order to avoid unexpectedly exempting images from an untrusted repository. + type: array + items: + type: string + hostNetwork: + description: "Determines if the policy allows the use of HostNetwork in the pod spec." + type: boolean + min: + description: "The start of the allowed port range, inclusive." + type: integer + max: + description: "The end of the allowed port range, inclusive." + type: integer + targets: + - target: admission.k8s.gatekeeper.sh + code: + - engine: K8sNativeValidation + source: + variables: + - name: containers + expression: 'has(variables.anyObject.spec.containers) ? variables.anyObject.spec.containers : []' + - name: initContainers + expression: 'has(variables.anyObject.spec.initContainers) ? variables.anyObject.spec.initContainers : []' + - name: ephemeralContainers + expression: 'has(variables.anyObject.spec.ephemeralContainers) ? variables.anyObject.spec.ephemeralContainers : []' + - name: exemptImagePrefixes + expression: | + !has(variables.params.exemptImages) ? [] : + variables.params.exemptImages.filter(image, image.endsWith("*")).map(image, string(image).replace("*", "")) + - name: exemptImageExplicit + expression: | + !has(variables.params.exemptImages) ? [] : + variables.params.exemptImages.filter(image, !image.endsWith("*")) + - name: exemptImages + expression: | + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + container.image in variables.exemptImageExplicit || + variables.exemptImagePrefixes.exists(exemption, string(container.image).startsWith(exemption))) + - name: badContainers + expression: | + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + !(container.image in variables.exemptImages) && + ( + (has(variables.params.hostNetwork) && variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || + (container.ports.all(port, has(port.hostPort) && port.hostPort < variables.params.min)) || + (container.ports.all(port, has(port.hostPort) && port.hostPort > variables.params.max)) + ) + ) + validations: + - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' + messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name + ". Allowed values: " + variables.params' + - engine: Rego + source: + rego: | + package k8spsphostnetworkingports + + import data.lib.exclude_update.is_update + import data.lib.exempt_container.is_exempt + + violation[{"msg": msg, "details": {}}] { + # spec.hostNetwork field is immutable. + not is_update(input.review) + + input_share_hostnetwork(input.review.object) + msg := sprintf("The specified hostNetwork and hostPort are not allowed, pod: %v. Allowed values: %v", [input.review.object.metadata.name, input.parameters]) + } + + input_share_hostnetwork(o) { + not input.parameters.hostNetwork + o.spec.hostNetwork + } + + input_share_hostnetwork(_) { + hostPort := input_containers[_].ports[_].hostPort + hostPort < input.parameters.min + } + + input_share_hostnetwork(_) { + hostPort := input_containers[_].ports[_].hostPort + hostPort > input.parameters.max + } + + input_containers[c] { + c := input.review.object.spec.containers[_] + not is_exempt(c) + } + + input_containers[c] { + c := input.review.object.spec.initContainers[_] + not is_exempt(c) + } + + input_containers[c] { + c := input.review.object.spec.ephemeralContainers[_] + not is_exempt(c) + } + libs: + - | + package lib.exclude_update + + is_update(review) { + review.operation == "UPDATE" + } + - | + package lib.exempt_container + + is_exempt(container) { + exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) + img := container.image + exemption := exempt_images[_] + _matches_exemption(img, exemption) + } + + _matches_exemption(img, exemption) { + not endswith(exemption, "*") + exemption == img + } + + _matches_exemption(img, exemption) { + endswith(exemption, "*") + prefix := trim_suffix(exemption, "*") + startswith(img, prefix) + } diff --git a/library/pod-security-policy/host-network-ports/template.yaml b/library/pod-security-policy/host-network-ports/template.yaml index 0f04aae03..146cac6b2 100644 --- a/library/pod-security-policy/host-network-ports/template.yaml +++ b/library/pod-security-policy/host-network-ports/template.yaml @@ -4,7 +4,7 @@ metadata: name: k8spsphostnetworkingports annotations: metadata.gatekeeper.sh/title: "Host Networking Ports" - metadata.gatekeeper.sh/version: 1.0.2 + metadata.gatekeeper.sh/version: 1.1.0 description: >- Controls usage of host network namespace by pod containers. Specific ports must be specified. Corresponds to the `hostNetwork` and @@ -46,73 +46,111 @@ spec: type: integer targets: - target: admission.k8s.gatekeeper.sh - rego: | - package k8spsphostnetworkingports + code: + - engine: K8sNativeValidation + source: + variables: + - name: containers + expression: 'has(variables.anyObject.spec.containers) ? variables.anyObject.spec.containers : []' + - name: initContainers + expression: 'has(variables.anyObject.spec.initContainers) ? variables.anyObject.spec.initContainers : []' + - name: ephemeralContainers + expression: 'has(variables.anyObject.spec.ephemeralContainers) ? variables.anyObject.spec.ephemeralContainers : []' + - name: exemptImagePrefixes + expression: | + !has(variables.params.exemptImages) ? [] : + variables.params.exemptImages.filter(image, image.endsWith("*")).map(image, string(image).replace("*", "")) + - name: exemptImageExplicit + expression: | + !has(variables.params.exemptImages) ? [] : + variables.params.exemptImages.filter(image, !image.endsWith("*")) + - name: exemptImages + expression: | + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + container.image in variables.exemptImageExplicit || + variables.exemptImagePrefixes.exists(exemption, string(container.image).startsWith(exemption))) + - name: badContainers + expression: | + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + !(container.image in variables.exemptImages) && + ( + (has(variables.params.hostNetwork) && variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || + (container.ports.all(port, has(port.hostPort) && port.hostPort < variables.params.min)) || + (container.ports.all(port, has(port.hostPort) && port.hostPort > variables.params.max)) + ) + ) + validations: + - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' + messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name + ". Allowed values: " + variables.params' + - engine: Rego + source: + rego: | + package k8spsphostnetworkingports - import data.lib.exclude_update.is_update - import data.lib.exempt_container.is_exempt + import data.lib.exclude_update.is_update + import data.lib.exempt_container.is_exempt - violation[{"msg": msg, "details": {}}] { - # spec.hostNetwork field is immutable. - not is_update(input.review) + violation[{"msg": msg, "details": {}}] { + # spec.hostNetwork field is immutable. + not is_update(input.review) - input_share_hostnetwork(input.review.object) - msg := sprintf("The specified hostNetwork and hostPort are not allowed, pod: %v. Allowed values: %v", [input.review.object.metadata.name, input.parameters]) - } + input_share_hostnetwork(input.review.object) + msg := sprintf("The specified hostNetwork and hostPort are not allowed, pod: %v. Allowed values: %v", [input.review.object.metadata.name, input.parameters]) + } - input_share_hostnetwork(o) { - not input.parameters.hostNetwork - o.spec.hostNetwork - } + input_share_hostnetwork(o) { + not input.parameters.hostNetwork + o.spec.hostNetwork + } - input_share_hostnetwork(_) { - hostPort := input_containers[_].ports[_].hostPort - hostPort < input.parameters.min - } + input_share_hostnetwork(_) { + hostPort := input_containers[_].ports[_].hostPort + hostPort < input.parameters.min + } - input_share_hostnetwork(_) { - hostPort := input_containers[_].ports[_].hostPort - hostPort > input.parameters.max - } + input_share_hostnetwork(_) { + hostPort := input_containers[_].ports[_].hostPort + hostPort > input.parameters.max + } - input_containers[c] { - c := input.review.object.spec.containers[_] - not is_exempt(c) - } + input_containers[c] { + c := input.review.object.spec.containers[_] + not is_exempt(c) + } - input_containers[c] { - c := input.review.object.spec.initContainers[_] - not is_exempt(c) - } + input_containers[c] { + c := input.review.object.spec.initContainers[_] + not is_exempt(c) + } - input_containers[c] { - c := input.review.object.spec.ephemeralContainers[_] - not is_exempt(c) - } - libs: - - | - package lib.exclude_update + input_containers[c] { + c := input.review.object.spec.ephemeralContainers[_] + not is_exempt(c) + } + libs: + - | + package lib.exclude_update - is_update(review) { - review.operation == "UPDATE" - } - - | - package lib.exempt_container + is_update(review) { + review.operation == "UPDATE" + } + - | + package lib.exempt_container - is_exempt(container) { - exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) - img := container.image - exemption := exempt_images[_] - _matches_exemption(img, exemption) - } + is_exempt(container) { + exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) + img := container.image + exemption := exempt_images[_] + _matches_exemption(img, exemption) + } - _matches_exemption(img, exemption) { - not endswith(exemption, "*") - exemption == img - } + _matches_exemption(img, exemption) { + not endswith(exemption, "*") + exemption == img + } - _matches_exemption(img, exemption) { - endswith(exemption, "*") - prefix := trim_suffix(exemption, "*") - startswith(img, prefix) - } + _matches_exemption(img, exemption) { + endswith(exemption, "*") + prefix := trim_suffix(exemption, "*") + startswith(img, prefix) + } diff --git a/src/pod-security-policy/host-network-ports/constraint.tmpl b/src/pod-security-policy/host-network-ports/constraint.tmpl index c8fd7a131..e6f005ef9 100644 --- a/src/pod-security-policy/host-network-ports/constraint.tmpl +++ b/src/pod-security-policy/host-network-ports/constraint.tmpl @@ -4,7 +4,7 @@ metadata: name: k8spsphostnetworkingports annotations: metadata.gatekeeper.sh/title: "Host Networking Ports" - metadata.gatekeeper.sh/version: 1.0.2 + metadata.gatekeeper.sh/version: 1.1.0 description: >- Controls usage of host network namespace by pod containers. Specific ports must be specified. Corresponds to the `hostNetwork` and @@ -46,10 +46,16 @@ spec: type: integer targets: - target: admission.k8s.gatekeeper.sh - rego: | -{{ file.Read "src/pod-security-policy/host-network-ports/src.rego" | strings.Indent 8 | strings.TrimSuffix "\n" }} - libs: - - | -{{ file.Read "src/pod-security-policy/host-network-ports/lib_exclude_update.rego" | strings.Indent 10 | strings.TrimSuffix "\n" }} - - | -{{ file.Read "src/pod-security-policy/host-network-ports/lib_exempt_container.rego" | strings.Indent 10 | strings.TrimSuffix "\n" }} + code: + - engine: K8sNativeValidation + source: +{{ file.Read "src/pod-security-policy/host-network-ports/src.cel" | strings.Indent 10 | strings.TrimSuffix "\n" }} + - engine: Rego + source: + rego: | +{{ file.Read "src/pod-security-policy/host-network-ports/src.rego" | strings.Indent 12 | strings.TrimSuffix "\n" }} + libs: + - | +{{ file.Read "src/pod-security-policy/host-network-ports/lib_exclude_update.rego" | strings.Indent 14 | strings.TrimSuffix "\n" }} + - | +{{ file.Read "src/pod-security-policy/host-network-ports/lib_exempt_container.rego" | strings.Indent 14 | strings.TrimSuffix "\n" }} diff --git a/src/pod-security-policy/host-network-ports/src.cel b/src/pod-security-policy/host-network-ports/src.cel new file mode 100644 index 000000000..019fc3247 --- /dev/null +++ b/src/pod-security-policy/host-network-ports/src.cel @@ -0,0 +1,33 @@ +variables: +- name: containers + expression: 'has(variables.anyObject.spec.containers) ? variables.anyObject.spec.containers : []' +- name: initContainers + expression: 'has(variables.anyObject.spec.initContainers) ? variables.anyObject.spec.initContainers : []' +- name: ephemeralContainers + expression: 'has(variables.anyObject.spec.ephemeralContainers) ? variables.anyObject.spec.ephemeralContainers : []' +- name: exemptImagePrefixes + expression: | + !has(variables.params.exemptImages) ? [] : + variables.params.exemptImages.filter(image, image.endsWith("*")).map(image, string(image).replace("*", "")) +- name: exemptImageExplicit + expression: | + !has(variables.params.exemptImages) ? [] : + variables.params.exemptImages.filter(image, !image.endsWith("*")) +- name: exemptImages + expression: | + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + container.image in variables.exemptImageExplicit || + variables.exemptImagePrefixes.exists(exemption, string(container.image).startsWith(exemption))) +- name: badContainers + expression: | + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + !(container.image in variables.exemptImages) && + ( + (has(variables.params.hostNetwork) && variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || + (container.ports.all(port, has(port.hostPort) && port.hostPort < variables.params.min)) || + (container.ports.all(port, has(port.hostPort) && port.hostPort > variables.params.max)) + ) + ) +validations: +- expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' + messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name + ". Allowed values: " + variables.params' \ No newline at end of file diff --git a/website/docs/validation/host-network-ports.md b/website/docs/validation/host-network-ports.md index 1e7928894..463351220 100644 --- a/website/docs/validation/host-network-ports.md +++ b/website/docs/validation/host-network-ports.md @@ -16,7 +16,7 @@ metadata: name: k8spsphostnetworkingports annotations: metadata.gatekeeper.sh/title: "Host Networking Ports" - metadata.gatekeeper.sh/version: 1.0.2 + metadata.gatekeeper.sh/version: 1.1.0 description: >- Controls usage of host network namespace by pod containers. Specific ports must be specified. Corresponds to the `hostNetwork` and @@ -58,76 +58,114 @@ spec: type: integer targets: - target: admission.k8s.gatekeeper.sh - rego: | - package k8spsphostnetworkingports - - import data.lib.exclude_update.is_update - import data.lib.exempt_container.is_exempt - - violation[{"msg": msg, "details": {}}] { - # spec.hostNetwork field is immutable. - not is_update(input.review) - - input_share_hostnetwork(input.review.object) - msg := sprintf("The specified hostNetwork and hostPort are not allowed, pod: %v. Allowed values: %v", [input.review.object.metadata.name, input.parameters]) - } - - input_share_hostnetwork(o) { - not input.parameters.hostNetwork - o.spec.hostNetwork - } - - input_share_hostnetwork(_) { - hostPort := input_containers[_].ports[_].hostPort - hostPort < input.parameters.min - } - - input_share_hostnetwork(_) { - hostPort := input_containers[_].ports[_].hostPort - hostPort > input.parameters.max - } - - input_containers[c] { - c := input.review.object.spec.containers[_] - not is_exempt(c) - } - - input_containers[c] { - c := input.review.object.spec.initContainers[_] - not is_exempt(c) - } - - input_containers[c] { - c := input.review.object.spec.ephemeralContainers[_] - not is_exempt(c) - } - libs: - - | - package lib.exclude_update - - is_update(review) { - review.operation == "UPDATE" - } - - | - package lib.exempt_container - - is_exempt(container) { - exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) - img := container.image - exemption := exempt_images[_] - _matches_exemption(img, exemption) - } - - _matches_exemption(img, exemption) { - not endswith(exemption, "*") - exemption == img - } - - _matches_exemption(img, exemption) { - endswith(exemption, "*") - prefix := trim_suffix(exemption, "*") - startswith(img, prefix) - } + code: + - engine: K8sNativeValidation + source: + variables: + - name: containers + expression: 'has(variables.anyObject.spec.containers) ? variables.anyObject.spec.containers : []' + - name: initContainers + expression: 'has(variables.anyObject.spec.initContainers) ? variables.anyObject.spec.initContainers : []' + - name: ephemeralContainers + expression: 'has(variables.anyObject.spec.ephemeralContainers) ? variables.anyObject.spec.ephemeralContainers : []' + - name: exemptImagePrefixes + expression: | + !has(variables.params.exemptImages) ? [] : + variables.params.exemptImages.filter(image, image.endsWith("*")).map(image, string(image).replace("*", "")) + - name: exemptImageExplicit + expression: | + !has(variables.params.exemptImages) ? [] : + variables.params.exemptImages.filter(image, !image.endsWith("*")) + - name: exemptImages + expression: | + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + container.image in variables.exemptImageExplicit || + variables.exemptImagePrefixes.exists(exemption, string(container.image).startsWith(exemption))) + - name: badContainers + expression: | + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + !(container.image in variables.exemptImages) && + ( + (has(variables.params.hostNetwork) && variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || + (container.ports.all(port, has(port.hostPort) && port.hostPort < variables.params.min)) || + (container.ports.all(port, has(port.hostPort) && port.hostPort > variables.params.max)) + ) + ) + validations: + - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' + messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name + ". Allowed values: " + variables.params' + - engine: Rego + source: + rego: | + package k8spsphostnetworkingports + + import data.lib.exclude_update.is_update + import data.lib.exempt_container.is_exempt + + violation[{"msg": msg, "details": {}}] { + # spec.hostNetwork field is immutable. + not is_update(input.review) + + input_share_hostnetwork(input.review.object) + msg := sprintf("The specified hostNetwork and hostPort are not allowed, pod: %v. Allowed values: %v", [input.review.object.metadata.name, input.parameters]) + } + + input_share_hostnetwork(o) { + not input.parameters.hostNetwork + o.spec.hostNetwork + } + + input_share_hostnetwork(_) { + hostPort := input_containers[_].ports[_].hostPort + hostPort < input.parameters.min + } + + input_share_hostnetwork(_) { + hostPort := input_containers[_].ports[_].hostPort + hostPort > input.parameters.max + } + + input_containers[c] { + c := input.review.object.spec.containers[_] + not is_exempt(c) + } + + input_containers[c] { + c := input.review.object.spec.initContainers[_] + not is_exempt(c) + } + + input_containers[c] { + c := input.review.object.spec.ephemeralContainers[_] + not is_exempt(c) + } + libs: + - | + package lib.exclude_update + + is_update(review) { + review.operation == "UPDATE" + } + - | + package lib.exempt_container + + is_exempt(container) { + exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) + img := container.image + exemption := exempt_images[_] + _matches_exemption(img, exemption) + } + + _matches_exemption(img, exemption) { + not endswith(exemption, "*") + exemption == img + } + + _matches_exemption(img, exemption) { + endswith(exemption, "*") + prefix := trim_suffix(exemption, "*") + startswith(img, prefix) + } ``` From 6796c26f9e8703ae4bc4e1105d90c4479095db84 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Wed, 5 Jun 2024 22:02:23 +0000 Subject: [PATCH 2/3] fixing bug, adding tests Signed-off-by: Jaydip Gabani --- .../1.1.0/artifacthub-pkg.yml | 2 +- .../constraint_block_host_network.yaml | 11 ++ .../host-network-ports/1.1.0/suite.yaml | 20 +++ .../host-network-ports/1.1.0/template.yaml | 6 +- .../constraint_block_host_network.yaml | 11 ++ .../host-network-ports/suite.yaml | 20 +++ .../host-network-ports/template.yaml | 6 +- .../host-network-ports/src.cel | 6 +- website/docs/validation/host-network-ports.md | 120 +++++++++++++++++- 9 files changed, 189 insertions(+), 13 deletions(-) create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/constraint_block_host_network.yaml create mode 100644 library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/constraint_block_host_network.yaml diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/artifacthub-pkg.yml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/artifacthub-pkg.yml index 7bbf162f3..8ac8cbc66 100644 --- a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/artifacthub-pkg.yml +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/artifacthub-pkg.yml @@ -3,7 +3,7 @@ name: k8spsphostnetworkingports displayName: Host Networking Ports createdAt: "2024-06-04T00:04:23Z" description: Controls usage of host network namespace by pod containers. Specific ports must be specified. Corresponds to the `hostNetwork` and `hostPorts` fields in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces -digest: 5204259e7e30eb4a752aefa71ace7c577027779c16b0a31875a6c423abf70840 +digest: 8f2101f24edf284624fff6b2812a22e6692998502122dde7cc0c52d332180db7 license: Apache-2.0 homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/host-network-ports keywords: diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/constraint_block_host_network.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/constraint_block_host_network.yaml new file mode 100644 index 000000000..7d468802f --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/samples/psp-host-network-ports/constraint_block_host_network.yaml @@ -0,0 +1,11 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPHostNetworkingPorts +metadata: + name: psp-host-network +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + hostNetwork: false \ No newline at end of file diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/suite.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/suite.yaml index 710df69eb..bb7e60a56 100644 --- a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/suite.yaml +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/suite.yaml @@ -23,3 +23,23 @@ tests: object: samples/psp-host-network-ports/update.yaml assertions: - violations: no +- name: use-of-host-network-blocked + template: template.yaml + constraint: samples/psp-host-network-ports/constraint_block_host_network.yaml + cases: + - name: example-disallowed + object: samples/psp-host-network-ports/example_disallowed.yaml + assertions: + - violations: yes + - name: example-allowed + object: samples/psp-host-network-ports/example_allowed.yaml + assertions: + - violations: no + - name: disallowed-ephemeral + object: samples/psp-host-network-ports/disallowed_ephemeral.yaml + assertions: + - violations: yes + - name: update + object: samples/psp-host-network-ports/update.yaml + assertions: + - violations: no diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/template.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/template.yaml index 146cac6b2..c135b9ea9 100644 --- a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/template.yaml +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/template.yaml @@ -74,9 +74,9 @@ spec: (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, !(container.image in variables.exemptImages) && ( - (has(variables.params.hostNetwork) && variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || - (container.ports.all(port, has(port.hostPort) && port.hostPort < variables.params.min)) || - (container.ports.all(port, has(port.hostPort) && port.hostPort > variables.params.max)) + (has(variables.params.hostNetwork) && !variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || + (container.ports.all(port, has(port.hostPort) && has(variables.params.min) && port.hostPort < variables.params.min)) || + (container.ports.all(port, has(port.hostPort) && has(variables.params.max) && port.hostPort > variables.params.max)) ) ) validations: diff --git a/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/constraint_block_host_network.yaml b/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/constraint_block_host_network.yaml new file mode 100644 index 000000000..7d468802f --- /dev/null +++ b/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/constraint_block_host_network.yaml @@ -0,0 +1,11 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPHostNetworkingPorts +metadata: + name: psp-host-network +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + hostNetwork: false \ No newline at end of file diff --git a/library/pod-security-policy/host-network-ports/suite.yaml b/library/pod-security-policy/host-network-ports/suite.yaml index 710df69eb..bb7e60a56 100644 --- a/library/pod-security-policy/host-network-ports/suite.yaml +++ b/library/pod-security-policy/host-network-ports/suite.yaml @@ -23,3 +23,23 @@ tests: object: samples/psp-host-network-ports/update.yaml assertions: - violations: no +- name: use-of-host-network-blocked + template: template.yaml + constraint: samples/psp-host-network-ports/constraint_block_host_network.yaml + cases: + - name: example-disallowed + object: samples/psp-host-network-ports/example_disallowed.yaml + assertions: + - violations: yes + - name: example-allowed + object: samples/psp-host-network-ports/example_allowed.yaml + assertions: + - violations: no + - name: disallowed-ephemeral + object: samples/psp-host-network-ports/disallowed_ephemeral.yaml + assertions: + - violations: yes + - name: update + object: samples/psp-host-network-ports/update.yaml + assertions: + - violations: no diff --git a/library/pod-security-policy/host-network-ports/template.yaml b/library/pod-security-policy/host-network-ports/template.yaml index 146cac6b2..c135b9ea9 100644 --- a/library/pod-security-policy/host-network-ports/template.yaml +++ b/library/pod-security-policy/host-network-ports/template.yaml @@ -74,9 +74,9 @@ spec: (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, !(container.image in variables.exemptImages) && ( - (has(variables.params.hostNetwork) && variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || - (container.ports.all(port, has(port.hostPort) && port.hostPort < variables.params.min)) || - (container.ports.all(port, has(port.hostPort) && port.hostPort > variables.params.max)) + (has(variables.params.hostNetwork) && !variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || + (container.ports.all(port, has(port.hostPort) && has(variables.params.min) && port.hostPort < variables.params.min)) || + (container.ports.all(port, has(port.hostPort) && has(variables.params.max) && port.hostPort > variables.params.max)) ) ) validations: diff --git a/src/pod-security-policy/host-network-ports/src.cel b/src/pod-security-policy/host-network-ports/src.cel index 019fc3247..340230827 100644 --- a/src/pod-security-policy/host-network-ports/src.cel +++ b/src/pod-security-policy/host-network-ports/src.cel @@ -23,9 +23,9 @@ variables: (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, !(container.image in variables.exemptImages) && ( - (has(variables.params.hostNetwork) && variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || - (container.ports.all(port, has(port.hostPort) && port.hostPort < variables.params.min)) || - (container.ports.all(port, has(port.hostPort) && port.hostPort > variables.params.max)) + (has(variables.params.hostNetwork) && !variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || + (container.ports.all(port, has(port.hostPort) && has(variables.params.min) && port.hostPort < variables.params.min)) || + (container.ports.all(port, has(port.hostPort) && has(variables.params.max) && port.hostPort > variables.params.max)) ) ) validations: diff --git a/website/docs/validation/host-network-ports.md b/website/docs/validation/host-network-ports.md index 463351220..6f51bc17c 100644 --- a/website/docs/validation/host-network-ports.md +++ b/website/docs/validation/host-network-ports.md @@ -86,9 +86,9 @@ spec: (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, !(container.image in variables.exemptImages) && ( - (has(variables.params.hostNetwork) && variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || - (container.ports.all(port, has(port.hostPort) && port.hostPort < variables.params.min)) || - (container.ports.all(port, has(port.hostPort) && port.hostPort > variables.params.max)) + (has(variables.params.hostNetwork) && !variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || + (container.ports.all(port, has(port.hostPort) && has(variables.params.min) && port.hostPort < variables.params.min)) || + (container.ports.all(port, has(port.hostPort) && has(variables.params.max) && port.hostPort > variables.params.max)) ) ) validations: @@ -291,4 +291,118 @@ kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper- +
+use-of-host-network-blocked + +
+constraint + +```yaml +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPHostNetworkingPorts +metadata: + name: psp-host-network +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + hostNetwork: false +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/constraint_block_host_network.yaml +``` + +
+ +
+example-disallowed + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx-host-networking-ports-disallowed + labels: + app: nginx-host-networking-ports +spec: + hostNetwork: true + containers: + - name: nginx + image: nginx + ports: + - containerPort: 9001 + hostPort: 9001 + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_disallowed.yaml +``` + +
+
+example-allowed + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx-host-networking-ports-allowed + labels: + app: nginx-host-networking-ports +spec: + hostNetwork: false + containers: + - name: nginx + image: nginx + ports: + - containerPort: 9000 + hostPort: 80 + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed.yaml +``` + +
+
+disallowed-ephemeral + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx-host-networking-ports-disallowed + labels: + app: nginx-host-networking-ports +spec: + hostNetwork: true + ephemeralContainers: + - name: nginx + image: nginx + ports: + - containerPort: 9001 + hostPort: 9001 + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/disallowed_ephemeral.yaml +``` + +
+ +
\ No newline at end of file From ab85f940a5d91aa19a1c79935e661c1885ebadb5 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Mon, 10 Jun 2024 20:53:05 +0000 Subject: [PATCH 3/3] fixing cel bug, matching rego logic Signed-off-by: Jaydip Gabani --- .../host-network-ports/1.1.0/artifacthub-pkg.yml | 2 +- .../pod-security-policy/host-network-ports/1.1.0/template.yaml | 2 +- library/pod-security-policy/host-network-ports/template.yaml | 2 +- src/pod-security-policy/host-network-ports/src.cel | 2 +- website/docs/validation/host-network-ports.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/artifacthub-pkg.yml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/artifacthub-pkg.yml index 8ac8cbc66..306675130 100644 --- a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/artifacthub-pkg.yml +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/artifacthub-pkg.yml @@ -3,7 +3,7 @@ name: k8spsphostnetworkingports displayName: Host Networking Ports createdAt: "2024-06-04T00:04:23Z" description: Controls usage of host network namespace by pod containers. Specific ports must be specified. Corresponds to the `hostNetwork` and `hostPorts` fields in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces -digest: 8f2101f24edf284624fff6b2812a22e6692998502122dde7cc0c52d332180db7 +digest: b4b275420d181ab6a007360e37bdda6356b0d2692982f192fbb2aa37d18bbe3b license: Apache-2.0 homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/host-network-ports keywords: diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/template.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/template.yaml index c135b9ea9..d697e74e6 100644 --- a/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/template.yaml +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.0/template.yaml @@ -74,7 +74,7 @@ spec: (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, !(container.image in variables.exemptImages) && ( - (has(variables.params.hostNetwork) && !variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || + (!has(variables.params.hostNetwork) || !variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || (container.ports.all(port, has(port.hostPort) && has(variables.params.min) && port.hostPort < variables.params.min)) || (container.ports.all(port, has(port.hostPort) && has(variables.params.max) && port.hostPort > variables.params.max)) ) diff --git a/library/pod-security-policy/host-network-ports/template.yaml b/library/pod-security-policy/host-network-ports/template.yaml index c135b9ea9..d697e74e6 100644 --- a/library/pod-security-policy/host-network-ports/template.yaml +++ b/library/pod-security-policy/host-network-ports/template.yaml @@ -74,7 +74,7 @@ spec: (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, !(container.image in variables.exemptImages) && ( - (has(variables.params.hostNetwork) && !variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || + (!has(variables.params.hostNetwork) || !variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || (container.ports.all(port, has(port.hostPort) && has(variables.params.min) && port.hostPort < variables.params.min)) || (container.ports.all(port, has(port.hostPort) && has(variables.params.max) && port.hostPort > variables.params.max)) ) diff --git a/src/pod-security-policy/host-network-ports/src.cel b/src/pod-security-policy/host-network-ports/src.cel index 340230827..eb60e5c16 100644 --- a/src/pod-security-policy/host-network-ports/src.cel +++ b/src/pod-security-policy/host-network-ports/src.cel @@ -23,7 +23,7 @@ variables: (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, !(container.image in variables.exemptImages) && ( - (has(variables.params.hostNetwork) && !variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || + (!has(variables.params.hostNetwork) || !variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || (container.ports.all(port, has(port.hostPort) && has(variables.params.min) && port.hostPort < variables.params.min)) || (container.ports.all(port, has(port.hostPort) && has(variables.params.max) && port.hostPort > variables.params.max)) ) diff --git a/website/docs/validation/host-network-ports.md b/website/docs/validation/host-network-ports.md index 6f51bc17c..1824b5c36 100644 --- a/website/docs/validation/host-network-ports.md +++ b/website/docs/validation/host-network-ports.md @@ -86,7 +86,7 @@ spec: (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, !(container.image in variables.exemptImages) && ( - (has(variables.params.hostNetwork) && !variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || + (!has(variables.params.hostNetwork) || !variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork) : false) || (container.ports.all(port, has(port.hostPort) && has(variables.params.min) && port.hostPort < variables.params.min)) || (container.ports.all(port, has(port.hostPort) && has(variables.params.max) && port.hostPort > variables.params.max)) )