diff --git a/artifacthub/library/general/replicalimits/1.0.2/artifacthub-pkg.yml b/artifacthub/library/general/replicalimits/1.0.2/artifacthub-pkg.yml index 3b46cf798..e951d5230 100644 --- a/artifacthub/library/general/replicalimits/1.0.2/artifacthub-pkg.yml +++ b/artifacthub/library/general/replicalimits/1.0.2/artifacthub-pkg.yml @@ -3,7 +3,7 @@ name: k8sreplicalimits displayName: Replica Limits createdAt: "2023-10-30T21:00:00Z" description: Requires that objects with the field `spec.replicas` (Deployments, ReplicaSets, etc.) specify a number of replicas within defined ranges. -digest: 858bf59f6c7408f2fb390a181b2f6db5e4d8fbe5eb580aa45b5601d6ae2d4064 +digest: ae243682840ce6d52554ff467a90a953bd010355b0410d82380fb6a34a9cda4a license: Apache-2.0 homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/replicalimits keywords: diff --git a/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits/constraint.yaml b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits/constraint.yaml index b496235f3..db3488afe 100644 --- a/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits/constraint.yaml +++ b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits/constraint.yaml @@ -7,6 +7,8 @@ spec: kinds: - apiGroups: ["apps"] kinds: ["Deployment"] + - apiGroups: ["autoscaling"] + kinds: ["Scale"] parameters: ranges: - min_replicas: 3 diff --git a/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits/example_scale_allowed.yaml b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits/example_scale_allowed.yaml new file mode 100644 index 000000000..4ec230bd3 --- /dev/null +++ b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits/example_scale_allowed.yaml @@ -0,0 +1,6 @@ +apiVersion: autoscaling/v1 +kind: Scale +metadata: + name: allowed-deployment +spec: + replicas: 3 diff --git a/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits/example_scale_disallowed.yaml b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits/example_scale_disallowed.yaml new file mode 100644 index 000000000..7baf42c62 --- /dev/null +++ b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits/example_scale_disallowed.yaml @@ -0,0 +1,6 @@ +apiVersion: autoscaling/v1 +kind: Scale +metadata: + name: allowed-deployment +spec: + replicas: 100 diff --git a/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/constraint.yaml b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/constraint.yaml new file mode 100644 index 000000000..28f0b6d09 --- /dev/null +++ b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/constraint.yaml @@ -0,0 +1,15 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sReplicaLimits +metadata: + name: replica-limits +spec: + match: + kinds: + - apiGroups: ["apps"] + kinds: ["Deployment"] + - apiGroups: ["autoscaling"] + kinds: ["Scale"] + parameters: + ranges: + - min_replicas: 0 + max_replicas: 50 diff --git a/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/example_allowed.yaml b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/example_allowed.yaml new file mode 100644 index 000000000..ac33574d9 --- /dev/null +++ b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/example_allowed.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: allowed-deployment +spec: + selector: + matchLabels: + app: nginx + replicas: 0 + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 diff --git a/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/example_disallowed.yaml b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/example_disallowed.yaml new file mode 100644 index 000000000..1c4899d20 --- /dev/null +++ b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/example_disallowed.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: disallowed-deployment +spec: + selector: + matchLabels: + app: nginx + replicas: 100 + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 diff --git a/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/example_scale_allowed.yaml b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/example_scale_allowed.yaml new file mode 100644 index 000000000..55cef478b --- /dev/null +++ b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/example_scale_allowed.yaml @@ -0,0 +1,7 @@ +apiVersion: autoscaling/v1 +kind: Scale +metadata: + name: allowed-deployment +# kubectl scale deploy --replicas=0 creates a Scale +# resource with an empty spec, not replicas:0 +spec: {} diff --git a/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/example_scale_allowed2.yaml b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/example_scale_allowed2.yaml new file mode 100644 index 000000000..0beba2784 --- /dev/null +++ b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/example_scale_allowed2.yaml @@ -0,0 +1,8 @@ +apiVersion: autoscaling/v1 +kind: Scale +metadata: + name: allowed-deployment +# kubectl scale deploy --replicas=0 creates a Scale +# resource with an empty spec, not replicas:0 +spec: + replicas: 0 diff --git a/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/example_scale_disallowed.yaml b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/example_scale_disallowed.yaml new file mode 100644 index 000000000..7baf42c62 --- /dev/null +++ b/artifacthub/library/general/replicalimits/1.0.2/samples/replicalimits_zero/example_scale_disallowed.yaml @@ -0,0 +1,6 @@ +apiVersion: autoscaling/v1 +kind: Scale +metadata: + name: allowed-deployment +spec: + replicas: 100 diff --git a/artifacthub/library/general/replicalimits/1.0.2/suite.yaml b/artifacthub/library/general/replicalimits/1.0.2/suite.yaml index 598efb814..c5a7b480a 100644 --- a/artifacthub/library/general/replicalimits/1.0.2/suite.yaml +++ b/artifacthub/library/general/replicalimits/1.0.2/suite.yaml @@ -11,7 +11,39 @@ tests: object: samples/replicalimits/example_allowed.yaml assertions: - violations: no + - name: example-scale-allowed + object: samples/replicalimits/example_scale_allowed.yaml + assertions: + - violations: no - name: example-disallowed object: samples/replicalimits/example_disallowed.yaml assertions: - violations: yes + - name: example-scale-disallowed + object: samples/replicalimits/example_scale_disallowed.yaml + assertions: + - violations: yes +- name: replica-limit-zero + template: template.yaml + constraint: samples/replicalimits_zero/constraint.yaml + cases: + - name: example-allowed + object: samples/replicalimits_zero/example_allowed.yaml + assertions: + - violations: no + - name: example-scale-allowed + object: samples/replicalimits_zero/example_scale_allowed.yaml + assertions: + - violations: no + - name: example-scale-allowed + object: samples/replicalimits_zero/example_scale_allowed2.yaml + assertions: + - violations: no + - name: example-disallowed + object: samples/replicalimits_zero/example_disallowed.yaml + assertions: + - violations: yes + - name: example-scale-disallowed + object: samples/replicalimits_zero/example_scale_disallowed.yaml + assertions: + - violations: yes diff --git a/artifacthub/library/general/replicalimits/1.0.2/template.yaml b/artifacthub/library/general/replicalimits/1.0.2/template.yaml index 2e44fb2c1..8366de834 100644 --- a/artifacthub/library/general/replicalimits/1.0.2/template.yaml +++ b/artifacthub/library/general/replicalimits/1.0.2/template.yaml @@ -46,7 +46,7 @@ spec: } input_replica_limit(spec) { - provided := spec.replicas + provided := object.get(spec, "replicas", 0) count(input.parameters.ranges) > 0 range := input.parameters.ranges[_] value_within_range(range, provided) diff --git a/library/general/replicalimits/samples/replicalimits/constraint.yaml b/library/general/replicalimits/samples/replicalimits/constraint.yaml index b496235f3..db3488afe 100644 --- a/library/general/replicalimits/samples/replicalimits/constraint.yaml +++ b/library/general/replicalimits/samples/replicalimits/constraint.yaml @@ -7,6 +7,8 @@ spec: kinds: - apiGroups: ["apps"] kinds: ["Deployment"] + - apiGroups: ["autoscaling"] + kinds: ["Scale"] parameters: ranges: - min_replicas: 3 diff --git a/library/general/replicalimits/samples/replicalimits/example_scale_allowed.yaml b/library/general/replicalimits/samples/replicalimits/example_scale_allowed.yaml new file mode 100644 index 000000000..4ec230bd3 --- /dev/null +++ b/library/general/replicalimits/samples/replicalimits/example_scale_allowed.yaml @@ -0,0 +1,6 @@ +apiVersion: autoscaling/v1 +kind: Scale +metadata: + name: allowed-deployment +spec: + replicas: 3 diff --git a/library/general/replicalimits/samples/replicalimits/example_scale_disallowed.yaml b/library/general/replicalimits/samples/replicalimits/example_scale_disallowed.yaml new file mode 100644 index 000000000..7baf42c62 --- /dev/null +++ b/library/general/replicalimits/samples/replicalimits/example_scale_disallowed.yaml @@ -0,0 +1,6 @@ +apiVersion: autoscaling/v1 +kind: Scale +metadata: + name: allowed-deployment +spec: + replicas: 100 diff --git a/library/general/replicalimits/samples/replicalimits_zero/constraint.yaml b/library/general/replicalimits/samples/replicalimits_zero/constraint.yaml new file mode 100644 index 000000000..28f0b6d09 --- /dev/null +++ b/library/general/replicalimits/samples/replicalimits_zero/constraint.yaml @@ -0,0 +1,15 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sReplicaLimits +metadata: + name: replica-limits +spec: + match: + kinds: + - apiGroups: ["apps"] + kinds: ["Deployment"] + - apiGroups: ["autoscaling"] + kinds: ["Scale"] + parameters: + ranges: + - min_replicas: 0 + max_replicas: 50 diff --git a/library/general/replicalimits/samples/replicalimits_zero/example_allowed.yaml b/library/general/replicalimits/samples/replicalimits_zero/example_allowed.yaml new file mode 100644 index 000000000..ac33574d9 --- /dev/null +++ b/library/general/replicalimits/samples/replicalimits_zero/example_allowed.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: allowed-deployment +spec: + selector: + matchLabels: + app: nginx + replicas: 0 + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 diff --git a/library/general/replicalimits/samples/replicalimits_zero/example_disallowed.yaml b/library/general/replicalimits/samples/replicalimits_zero/example_disallowed.yaml new file mode 100644 index 000000000..1c4899d20 --- /dev/null +++ b/library/general/replicalimits/samples/replicalimits_zero/example_disallowed.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: disallowed-deployment +spec: + selector: + matchLabels: + app: nginx + replicas: 100 + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 diff --git a/library/general/replicalimits/samples/replicalimits_zero/example_scale_allowed.yaml b/library/general/replicalimits/samples/replicalimits_zero/example_scale_allowed.yaml new file mode 100644 index 000000000..55cef478b --- /dev/null +++ b/library/general/replicalimits/samples/replicalimits_zero/example_scale_allowed.yaml @@ -0,0 +1,7 @@ +apiVersion: autoscaling/v1 +kind: Scale +metadata: + name: allowed-deployment +# kubectl scale deploy --replicas=0 creates a Scale +# resource with an empty spec, not replicas:0 +spec: {} diff --git a/library/general/replicalimits/samples/replicalimits_zero/example_scale_allowed2.yaml b/library/general/replicalimits/samples/replicalimits_zero/example_scale_allowed2.yaml new file mode 100644 index 000000000..0beba2784 --- /dev/null +++ b/library/general/replicalimits/samples/replicalimits_zero/example_scale_allowed2.yaml @@ -0,0 +1,8 @@ +apiVersion: autoscaling/v1 +kind: Scale +metadata: + name: allowed-deployment +# kubectl scale deploy --replicas=0 creates a Scale +# resource with an empty spec, not replicas:0 +spec: + replicas: 0 diff --git a/library/general/replicalimits/samples/replicalimits_zero/example_scale_disallowed.yaml b/library/general/replicalimits/samples/replicalimits_zero/example_scale_disallowed.yaml new file mode 100644 index 000000000..7baf42c62 --- /dev/null +++ b/library/general/replicalimits/samples/replicalimits_zero/example_scale_disallowed.yaml @@ -0,0 +1,6 @@ +apiVersion: autoscaling/v1 +kind: Scale +metadata: + name: allowed-deployment +spec: + replicas: 100 diff --git a/library/general/replicalimits/suite.yaml b/library/general/replicalimits/suite.yaml index 598efb814..c5a7b480a 100644 --- a/library/general/replicalimits/suite.yaml +++ b/library/general/replicalimits/suite.yaml @@ -11,7 +11,39 @@ tests: object: samples/replicalimits/example_allowed.yaml assertions: - violations: no + - name: example-scale-allowed + object: samples/replicalimits/example_scale_allowed.yaml + assertions: + - violations: no - name: example-disallowed object: samples/replicalimits/example_disallowed.yaml assertions: - violations: yes + - name: example-scale-disallowed + object: samples/replicalimits/example_scale_disallowed.yaml + assertions: + - violations: yes +- name: replica-limit-zero + template: template.yaml + constraint: samples/replicalimits_zero/constraint.yaml + cases: + - name: example-allowed + object: samples/replicalimits_zero/example_allowed.yaml + assertions: + - violations: no + - name: example-scale-allowed + object: samples/replicalimits_zero/example_scale_allowed.yaml + assertions: + - violations: no + - name: example-scale-allowed + object: samples/replicalimits_zero/example_scale_allowed2.yaml + assertions: + - violations: no + - name: example-disallowed + object: samples/replicalimits_zero/example_disallowed.yaml + assertions: + - violations: yes + - name: example-scale-disallowed + object: samples/replicalimits_zero/example_scale_disallowed.yaml + assertions: + - violations: yes diff --git a/library/general/replicalimits/template.yaml b/library/general/replicalimits/template.yaml index 2e44fb2c1..8366de834 100644 --- a/library/general/replicalimits/template.yaml +++ b/library/general/replicalimits/template.yaml @@ -46,7 +46,7 @@ spec: } input_replica_limit(spec) { - provided := spec.replicas + provided := object.get(spec, "replicas", 0) count(input.parameters.ranges) > 0 range := input.parameters.ranges[_] value_within_range(range, provided) diff --git a/src/general/replicalimits/src.rego b/src/general/replicalimits/src.rego index 066fe924b..4a2666d71 100644 --- a/src/general/replicalimits/src.rego +++ b/src/general/replicalimits/src.rego @@ -10,7 +10,7 @@ violation[{"msg": msg}] { } input_replica_limit(spec) { - provided := spec.replicas + provided := object.get(spec, "replicas", 0) count(input.parameters.ranges) > 0 range := input.parameters.ranges[_] value_within_range(range, provided) diff --git a/src/general/replicalimits/src_test.rego b/src/general/replicalimits/src_test.rego index 5cb1f8a97..57ede7cbb 100644 --- a/src/general/replicalimits/src_test.rego +++ b/src/general/replicalimits/src_test.rego @@ -51,6 +51,7 @@ empty = { } review(replicas) = output { + replicas > 0 output = { "kind": { "kind": "Deployment", @@ -58,16 +59,31 @@ review(replicas) = output { "group": "apps", }, "object": { - "metadata": { + "metadata": { "name": "nginx" - }, + }, "spec": { "replicas": replicas, }, } } } - +review(replicas) = output { + replicas == 0 + output = { + "kind": { + "kind": "Deployment", + "version": "v1", + "group": "apps", + }, + "object": { + "metadata": { + "name": "nginx" + }, + "spec": { }, + } + } +} input_parameters_valid_range = { "ranges": [ { diff --git a/website/docs/validation/replicalimits.md b/website/docs/validation/replicalimits.md index d2da9c9e0..262c1d728 100644 --- a/website/docs/validation/replicalimits.md +++ b/website/docs/validation/replicalimits.md @@ -58,7 +58,7 @@ spec: } input_replica_limit(spec) { - provided := spec.replicas + provided := object.get(spec, "replicas", 0) count(input.parameters.ranges) > 0 range := input.parameters.ranges[_] value_within_range(range, provided) @@ -92,6 +92,8 @@ spec: kinds: - apiGroups: ["apps"] kinds: ["Deployment"] + - apiGroups: ["autoscaling"] + kinds: ["Scale"] parameters: ranges: - min_replicas: 3 @@ -139,6 +141,26 @@ Usage kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/general/replicalimits/samples/replicalimits/example_allowed.yaml ``` + +
+example-scale-allowed + +```yaml +apiVersion: autoscaling/v1 +kind: Scale +metadata: + name: allowed-deployment +spec: + replicas: 3 + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/general/replicalimits/samples/replicalimits/example_scale_allowed.yaml +``` +
example-disallowed @@ -172,6 +194,190 @@ Usage kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/general/replicalimits/samples/replicalimits/example_disallowed.yaml ``` +
+
+example-scale-disallowed + +```yaml +apiVersion: autoscaling/v1 +kind: Scale +metadata: + name: allowed-deployment +spec: + replicas: 100 + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/general/replicalimits/samples/replicalimits/example_scale_disallowed.yaml +``` + +
+ + +
+replica-limit-zero
+ +
+constraint + +```yaml +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sReplicaLimits +metadata: + name: replica-limits +spec: + match: + kinds: + - apiGroups: ["apps"] + kinds: ["Deployment"] + - apiGroups: ["autoscaling"] + kinds: ["Scale"] + parameters: + ranges: + - min_replicas: 0 + max_replicas: 50 + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/general/replicalimits/samples/replicalimits_zero/constraint.yaml +``` + +
+ +
+example-allowed + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: allowed-deployment +spec: + selector: + matchLabels: + app: nginx + replicas: 0 + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/general/replicalimits/samples/replicalimits_zero/example_allowed.yaml +``` + +
+
+example-scale-allowed + +```yaml +apiVersion: autoscaling/v1 +kind: Scale +metadata: + name: allowed-deployment +# kubectl scale deploy --replicas=0 creates a Scale +# resource with an empty spec, not replicas:0 +spec: {} + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/general/replicalimits/samples/replicalimits_zero/example_scale_allowed.yaml +``` + +
+
+example-scale-allowed + +```yaml +apiVersion: autoscaling/v1 +kind: Scale +metadata: + name: allowed-deployment +# kubectl scale deploy --replicas=0 creates a Scale +# resource with an empty spec, not replicas:0 +spec: + replicas: 0 + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/general/replicalimits/samples/replicalimits_zero/example_scale_allowed2.yaml +``` + +
+
+example-disallowed + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: disallowed-deployment +spec: + selector: + matchLabels: + app: nginx + replicas: 100 + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/general/replicalimits/samples/replicalimits_zero/example_disallowed.yaml +``` + +
+
+example-scale-disallowed + +```yaml +apiVersion: autoscaling/v1 +kind: Scale +metadata: + name: allowed-deployment +spec: + replicas: 100 + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/general/replicalimits/samples/replicalimits_zero/example_scale_disallowed.yaml +``` +