diff --git a/20-1-allowedrepos-constraint-template.yaml b/20-1-allowedrepos-constraint-template.yaml new file mode 100644 index 0000000..aecff62 --- /dev/null +++ b/20-1-allowedrepos-constraint-template.yaml @@ -0,0 +1,42 @@ +apiVersion: templates.gatekeeper.sh/v1beta1 +kind: ConstraintTemplate +metadata: + name: k8sallowedrepos + annotations: + description: Requires container images to begin with a repo string from a + specified list. +spec: + crd: + spec: + names: + kind: K8sAllowedRepos + validation: + # Schema for the `parameters` field + openAPIV3Schema: + properties: + repos: + type: array + items: + type: string + targets: + - target: admission.k8s.gatekeeper.sh + rego: | + package k8sallowedrepos + + violation[{"msg": msg}] { + container := input.review.object.spec.containers[_] + not strings.any_prefix_match(container.image, input.parameters.repos) + msg := sprintf("container <%v> has an invalid image repo <%v>, allowed repos are %v", [container.name, container.image, input.parameters.repos]) + } + + violation[{"msg": msg}] { + container := input.review.object.spec.initContainers[_] + not strings.any_prefix_match(container.image, input.parameters.repos) + msg := sprintf("initContainer <%v> has an invalid image repo <%v>, allowed repos are %v", [container.name, container.image, input.parameters.repos]) + } + + violation[{"msg": msg}] { + container := input.review.object.spec.ephemeralContainers[_] + not strings.any_prefix_match(container.image, input.parameters.repos) + msg := sprintf("ephemeralContainer <%v> has an invalid image repo <%v>, allowed repos are %v", [container.name, container.image, input.parameters.repos]) + } diff --git a/20-2-allowedrepos-constraint.yaml b/20-2-allowedrepos-constraint.yaml new file mode 100644 index 0000000..0d89d94 --- /dev/null +++ b/20-2-allowedrepos-constraint.yaml @@ -0,0 +1,15 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sAllowedRepos +metadata: + name: repo-is-kuar-demo +spec: + enforcementAction: deny + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + namespaces: + - "default" + parameters: + repos: + - "gcr.io/kuar-demo/" diff --git a/20-3-compliant-pod.yaml b/20-3-compliant-pod.yaml new file mode 100644 index 0000000..f7795da --- /dev/null +++ b/20-3-compliant-pod.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Pod +metadata: + name: kuard +spec: + containers: + - image: gcr.io/kuar-demo/kuard-amd64:blue + name: kuard + ports: + - containerPort: 8080 + name: http + protocol: TCP diff --git a/20-4-noncompliant-pod.yaml b/20-4-noncompliant-pod.yaml new file mode 100644 index 0000000..c6712cc --- /dev/null +++ b/20-4-noncompliant-pod.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-noncompliant +spec: + containers: + - name: nginx + image: nginx diff --git a/20-5-allowedrepos-constraint-dryrun.yaml b/20-5-allowedrepos-constraint-dryrun.yaml new file mode 100644 index 0000000..3e13d2b --- /dev/null +++ b/20-5-allowedrepos-constraint-dryrun.yaml @@ -0,0 +1,15 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sAllowedRepos +metadata: + name: repo-is-kuar-demo +spec: + enforcementAction: dryrun + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + namespaces: + - "default" + parameters: + repos: + - "gcr.io/kuar-demo/" diff --git a/20-6-imagepullpolicyalways-mutation.yaml b/20-6-imagepullpolicyalways-mutation.yaml new file mode 100644 index 0000000..5cfbe6b --- /dev/null +++ b/20-6-imagepullpolicyalways-mutation.yaml @@ -0,0 +1,19 @@ +apiVersion: mutations.gatekeeper.sh/v1alpha1 +kind: Assign +metadata: + name: demo-image-pull-policy +spec: + applyTo: + - groups: [""] + kinds: ["Pod"] + versions: ["v1"] + match: + scope: Namespaced + kinds: + - apiGroups: ["*"] + kinds: ["Pod"] + excludedNamespaces: ["system"] + location: "spec.containers[name:*].imagePullPolicy" + parameters: + assign: + value: Always diff --git a/20-7-config-sync.yaml b/20-7-config-sync.yaml new file mode 100644 index 0000000..ff2c7ed --- /dev/null +++ b/20-7-config-sync.yaml @@ -0,0 +1,14 @@ +apiVersion: config.gatekeeper.sh/v1alpha1 +kind: Config +metadata: + name: config + namespace: "gatekeeper-system" +spec: + sync: + syncOnly: + - group: "" + version: "v1" + kind: "Namespace" + - group: "" + version: "v1" + kind: "Pod" diff --git a/20-8-uniqueingresshost-constraint-template.yaml b/20-8-uniqueingresshost-constraint-template.yaml new file mode 100644 index 0000000..a724faf --- /dev/null +++ b/20-8-uniqueingresshost-constraint-template.yaml @@ -0,0 +1,31 @@ +apiVersion: templates.gatekeeper.sh/v1beta1 +kind: ConstraintTemplate +metadata: + name: k8suniqueingresshost + annotations: + description: Requires all Ingress hosts to be unique. +spec: + crd: + spec: + names: + kind: K8sUniqueIngressHost + targets: + - target: admission.k8s.gatekeeper.sh + rego: | + package k8suniqueingresshost + + identical(obj, review) { + obj.metadata.namespace == review.object.metadata.namespace + obj.metadata.name == review.object.metadata.name + } + + violation[{"msg": msg}] { + input.review.kind.kind == "Ingress" + regex.match("^(extensions|networking.k8s.io)$", input.review.kind.group) + host := input.review.object.spec.rules[_].host + other := data.inventory.namespace[_][otherapiversion]["Ingress"][name] + regex.match("^(extensions|networking.k8s.io)/.+$", otherapiversion) + other.spec.rules[_].host == host + not identical(other, input.review) + msg := sprintf("ingress host conflicts with an existing ingress <%v>", [host]) + }