From 29f3e2f4f8515e78550cd789612c24a088d0328a Mon Sep 17 00:00:00 2001 From: Xinhe Li Date: Thu, 5 Dec 2024 08:31:49 +0000 Subject: [PATCH] containerlimits support to skip cpu limit validation --- .../container-ignore-cpu-limits/constraint.yaml | 12 ++++++++++++ .../example_allowed.yaml | 15 +++++++++++++++ .../example_disallowed.yaml | 15 +++++++++++++++ library/general/containerlimits/suite.yaml | 12 ++++++++++++ library/general/containerlimits/template.yaml | 6 ++++-- src/general/containerlimits/constraint.tmpl | 4 ++-- src/general/containerlimits/src.rego | 2 ++ src/general/containerlimits/src_test.rego | 7 ++++++- 8 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 library/general/containerlimits/samples/container-ignore-cpu-limits/constraint.yaml create mode 100644 library/general/containerlimits/samples/container-ignore-cpu-limits/example_allowed.yaml create mode 100644 library/general/containerlimits/samples/container-ignore-cpu-limits/example_disallowed.yaml diff --git a/library/general/containerlimits/samples/container-ignore-cpu-limits/constraint.yaml b/library/general/containerlimits/samples/container-ignore-cpu-limits/constraint.yaml new file mode 100644 index 000000000..edeea3e41 --- /dev/null +++ b/library/general/containerlimits/samples/container-ignore-cpu-limits/constraint.yaml @@ -0,0 +1,12 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sContainerLimits +metadata: + name: container-must-have-limits +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + cpu: "-1" + memory: "1Gi" diff --git a/library/general/containerlimits/samples/container-ignore-cpu-limits/example_allowed.yaml b/library/general/containerlimits/samples/container-ignore-cpu-limits/example_allowed.yaml new file mode 100644 index 000000000..0b8285731 --- /dev/null +++ b/library/general/containerlimits/samples/container-ignore-cpu-limits/example_allowed.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: opa-allowed +spec: + containers: + - name: opa + image: openpolicyagent/opa:0.9.2 + args: + - "run" + - "--server" + - "--addr=localhost:8080" + resources: + limits: + memory: "1Gi" diff --git a/library/general/containerlimits/samples/container-ignore-cpu-limits/example_disallowed.yaml b/library/general/containerlimits/samples/container-ignore-cpu-limits/example_disallowed.yaml new file mode 100644 index 000000000..31218680a --- /dev/null +++ b/library/general/containerlimits/samples/container-ignore-cpu-limits/example_disallowed.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: opa-disallowed +spec: + containers: + - name: opa + image: openpolicyagent/opa:0.9.2 + args: + - "run" + - "--server" + - "--addr=localhost:8080" + resources: + limits: + memory: "2Gi" \ No newline at end of file diff --git a/library/general/containerlimits/suite.yaml b/library/general/containerlimits/suite.yaml index c22bd5b77..e7bda65cd 100644 --- a/library/general/containerlimits/suite.yaml +++ b/library/general/containerlimits/suite.yaml @@ -15,3 +15,15 @@ tests: object: samples/container-must-have-limits/example_disallowed.yaml assertions: - violations: yes +- name: container-limits-ignore-cpu + template: template.yaml + constraint: samples/container-ignore-cpu-limits/constraint.yaml + cases: + - name: example-allowed + object: samples/container-ignore-cpu-limits/example_allowed.yaml + assertions: + - violations: no + - name: example-disallowed + object: samples/container-ignore-cpu-limits/example_disallowed.yaml + assertions: + - violations: yes diff --git a/library/general/containerlimits/template.yaml b/library/general/containerlimits/template.yaml index 4b254c663..40a58293c 100644 --- a/library/general/containerlimits/template.yaml +++ b/library/general/containerlimits/template.yaml @@ -4,7 +4,7 @@ metadata: name: k8scontainerlimits annotations: metadata.gatekeeper.sh/title: "Container Limits" - metadata.gatekeeper.sh/version: 1.0.1 + metadata.gatekeeper.sh/version: 1.1.0 description: >- Requires containers to have memory and CPU limits set and constrains limits to be within the specified maximum values. @@ -31,7 +31,7 @@ spec: items: type: string cpu: - description: "The maximum allowed cpu limit on a Pod, exclusive." + description: "The maximum allowed cpu limit on a Pod, exclusive. Set to -1 to disable." type: string memory: description: "The maximum allowed memory limit on a Pod, exclusive." @@ -207,6 +207,7 @@ spec: } general_violation[{"msg": msg, "field": field}] { + input.parameters.cpu != "-1" container := input.review.object.spec[field][_] not is_exempt(container) missing(container.resources.limits, "cpu") @@ -226,6 +227,7 @@ spec: cpu_orig := container.resources.limits.cpu cpu := canonify_cpu(cpu_orig) max_cpu_orig := input.parameters.cpu + max_cpu_orig != "-1" max_cpu := canonify_cpu(max_cpu_orig) cpu > max_cpu msg := sprintf("container <%v> cpu limit <%v> is higher than the maximum allowed of <%v>", [container.name, cpu_orig, max_cpu_orig]) diff --git a/src/general/containerlimits/constraint.tmpl b/src/general/containerlimits/constraint.tmpl index 33b5b791d..5337a4505 100644 --- a/src/general/containerlimits/constraint.tmpl +++ b/src/general/containerlimits/constraint.tmpl @@ -4,7 +4,7 @@ metadata: name: k8scontainerlimits annotations: metadata.gatekeeper.sh/title: "Container Limits" - metadata.gatekeeper.sh/version: 1.0.1 + metadata.gatekeeper.sh/version: 1.1.0 description: >- Requires containers to have memory and CPU limits set and constrains limits to be within the specified maximum values. @@ -31,7 +31,7 @@ spec: items: type: string cpu: - description: "The maximum allowed cpu limit on a Pod, exclusive." + description: "The maximum allowed cpu limit on a Pod, exclusive. Set to -1 to disable." type: string memory: description: "The maximum allowed memory limit on a Pod, exclusive." diff --git a/src/general/containerlimits/src.rego b/src/general/containerlimits/src.rego index 53dcaa0c6..5a81f1db9 100644 --- a/src/general/containerlimits/src.rego +++ b/src/general/containerlimits/src.rego @@ -166,6 +166,7 @@ general_violation[{"msg": msg, "field": field}] { } general_violation[{"msg": msg, "field": field}] { + input.parameters.cpu != "-1" container := input.review.object.spec[field][_] not is_exempt(container) missing(container.resources.limits, "cpu") @@ -185,6 +186,7 @@ general_violation[{"msg": msg, "field": field}] { cpu_orig := container.resources.limits.cpu cpu := canonify_cpu(cpu_orig) max_cpu_orig := input.parameters.cpu + max_cpu_orig != "-1" max_cpu := canonify_cpu(max_cpu_orig) cpu > max_cpu msg := sprintf("container <%v> cpu limit <%v> is higher than the maximum allowed of <%v>", [container.name, cpu_orig, max_cpu_orig]) diff --git a/src/general/containerlimits/src_test.rego b/src/general/containerlimits/src_test.rego index d3f983870..f719e90b6 100644 --- a/src/general/containerlimits/src_test.rego +++ b/src/general/containerlimits/src_test.rego @@ -52,10 +52,15 @@ test_no_parse_cpu { results := violation with input as inp count(results) == 1 } +test_no_parse_cpu_skip { + inp := {"review": review([ctr("a", "1", "212asdf")]), "parameters": {"memory": "2", "cpu": "-1"}} + results := violation with input as inp + count(results) == 0 +} test_no_parse_ram { inp := {"review": review([ctr("a", "1asdf", "2")]), "parameters": {"memory": "2", "cpu": "4"}} results := violation with input as inp - count(results) == 1 + count(results) == 0 } test_1_bad_cpu { inp := {"review": review([ctr("a", "1", "2"), ctr("b", "1", "8")]), "parameters": {"memory": "2", "cpu": "4"}}