diff --git a/multitenancy-benchmarks/require-resource-quota/.chainsaw-test/chainsaw-enforce-assert.yaml b/multitenancy-benchmarks/require-resource-quota/.chainsaw-test/chainsaw-enforce-assert.yaml new file mode 100644 index 00000000..6c8049ed --- /dev/null +++ b/multitenancy-benchmarks/require-resource-quota/.chainsaw-test/chainsaw-enforce-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-resource-quota +spec: + validationFailureAction: Enforce diff --git a/multitenancy-benchmarks/require-resource-quota/.chainsaw-test/chainsaw-policy-assert.yaml b/multitenancy-benchmarks/require-resource-quota/.chainsaw-test/chainsaw-policy-assert.yaml new file mode 100755 index 00000000..696a98aa --- /dev/null +++ b/multitenancy-benchmarks/require-resource-quota/.chainsaw-test/chainsaw-policy-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-resource-quota +status: + ready: true diff --git a/multitenancy-benchmarks/require-resource-quota/.chainsaw-test/chainsaw-test.yaml b/multitenancy-benchmarks/require-resource-quota/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 00000000..7d6a54b5 --- /dev/null +++ b/multitenancy-benchmarks/require-resource-quota/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,38 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: require-resource-quota +spec: + steps: + - name: test-disallow-capabilities + try: + - apply: + file: ../require-resource-quota.yaml + - assert: + file: chainsaw-policy-assert.yaml + - apply: + file: ns-good.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: require-resource-quota + spec: + validationFailureAction: Enforce + # - script: + # content: | + # sed 's/validationFailureAction: Audit/validationFailureAction: Enforce/' ../require-resource-quota.yaml | kubectl apply -f - + - assert: + file: chainsaw-enforce-assert.yaml + - apply: + expect: + - check: + ($error != null): true + file: ns-bad.yaml + - delete: + ref: + apiVersion: v1 + kind: namespace + name: good-ns diff --git a/multitenancy-benchmarks/require-resource-quota/.chainsaw-test/ns-bad.yaml b/multitenancy-benchmarks/require-resource-quota/.chainsaw-test/ns-bad.yaml new file mode 100644 index 00000000..6894c69f --- /dev/null +++ b/multitenancy-benchmarks/require-resource-quota/.chainsaw-test/ns-bad.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: bad-ns +spec: {} diff --git a/multitenancy-benchmarks/require-resource-quota/.chainsaw-test/ns-good.yaml b/multitenancy-benchmarks/require-resource-quota/.chainsaw-test/ns-good.yaml new file mode 100644 index 00000000..fd845bd5 --- /dev/null +++ b/multitenancy-benchmarks/require-resource-quota/.chainsaw-test/ns-good.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: good-ns +spec: {} + +--- + +apiVersion: v1 +kind: ResourceQuota +metadata: + name: foo-resource-quota + namespace: good-ns +spec: + hard: + cpu: "1000" + memory: 200Gi + pods: "10" + scopeSelector: + matchExpressions: + - operator : In + scopeName: PriorityClass + values: ["high"] diff --git a/multitenancy-benchmarks/require-resource-quota/.kyverno-test/kyverno-test.yaml b/multitenancy-benchmarks/require-resource-quota/.kyverno-test/kyverno-test.yaml new file mode 100644 index 00000000..c4c55cad --- /dev/null +++ b/multitenancy-benchmarks/require-resource-quota/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,16 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: kyverno-test.yaml +policies: +- ../require-resource-quota.yaml +resources: +- resource.yaml +results: +- kind: Namespace + policy: require-resource-quota + resources: + - ns-resource-quota + result: pass + rule: resourcequotas +variables: values.yaml diff --git a/multitenancy-benchmarks/require-resource-quota/.kyverno-test/resource.yaml b/multitenancy-benchmarks/require-resource-quota/.kyverno-test/resource.yaml new file mode 100644 index 00000000..0aaaf25a --- /dev/null +++ b/multitenancy-benchmarks/require-resource-quota/.kyverno-test/resource.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: ns-resource-quota +spec: {} + +--- + +apiVersion: v1 +kind: ResourceQuota +metadata: + name: foo-resource-quota + namespace: ns-resource-quota +spec: + hard: + cpu: "1000" + memory: 200Gi + pods: "10" + scopeSelector: + matchExpressions: + - operator : In + scopeName: PriorityClass + values: ["high"] diff --git a/multitenancy-benchmarks/require-resource-quota/.kyverno-test/values.yaml b/multitenancy-benchmarks/require-resource-quota/.kyverno-test/values.yaml new file mode 100644 index 00000000..dbd626f4 --- /dev/null +++ b/multitenancy-benchmarks/require-resource-quota/.kyverno-test/values.yaml @@ -0,0 +1,8 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Values +policies: +- name: require-resource-quota + rules: + - name: resourcequotas + values: + resourcequotas: "1" diff --git a/multitenancy-benchmarks/require-resource-quota/require-resource-quota.yaml b/multitenancy-benchmarks/require-resource-quota/require-resource-quota.yaml new file mode 100644 index 00000000..f86d86f4 --- /dev/null +++ b/multitenancy-benchmarks/require-resource-quota/require-resource-quota.yaml @@ -0,0 +1,50 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-resource-quota + annotations: + policies.kyverno.io/title: Require Resource Quota + policies.kyverno.io/category: Multitenancy Benchmarks + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Namespace + policies.kyverno.io/description: >- + In cases such as multi-tenancy where new Namespaces must be fully + provisioned before they can be used, it may not be easy to declare and + understand if/when the Namespace is ready. Having a policy which defines + all the resources which are required for each Namespace can assist in determining + compliance. This policy, expected to be run in background mode only, performs a Namespace + check to ensure that all Namespaces have a ResourceQuota. + Additional rules may be written to extend the check for your needs. By default, background + scans occur every one hour which may be changed with an additional container flag. Please + see the installation documentation for details. +spec: + background: true + validationFailureAction: Audit + rules: + - name: resourcequotas + match: + any: + - resources: + kinds: + - Namespace + exclude: + any: + - resources: + namespaces: + - kube-system + - kube-public + - kube-node-lease + - kyverno + context: + - name: resourcequotas + apiCall: + urlPath: "/api/v1/namespaces/{{request.object.metadata.name}}/resourcequotas" + jmesPath: "items[] | length(@)" + validate: + message: "Every Namespace must have at least one ResourceQuota." + deny: + conditions: + all: + - key: "{{ resourcequotas }}" + operator: Equals + value: 0