Skip to content

Instantly share code, notes, and snippets.

@zparnold
Last active August 23, 2022 12:11
Show Gist options
  • Save zparnold/10d0c1f527b85f9dad68f0d6d32c58e5 to your computer and use it in GitHub Desktop.
Save zparnold/10d0c1f527b85f9dad68f0d6d32c58e5 to your computer and use it in GitHub Desktop.
A Gatekeeper Constraint Template (for AKS's implementation of Gatekeeper) capable of requiring liveness, readiness, and startup probes with exclusions for pod labels and container names
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8sazurecontainerprobesrequired
spec:
crd:
spec:
names:
kind: K8sAzureContainerProbesRequired
validation:
openAPIV3Schema:
properties:
requiredProbes:
type: array
items:
type: string
exclusionLabels:
type: array
items:
type: string
excludedContainerNames:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredprobes
probe_type_set = probe_types {
probe_types := {type | type := ["tcpSocket", "httpGet", "exec"][_]}
}
violation[{"msg": msg}] {
input.review.kind.kind == "Pod" #Ensure this only is running for pods
container := input.review.object.spec.containers[_]
probe := input.parameters.requiredProbes[_]
count(exclusions) == 0
probe_is_missing(container, probe)
msg := get_violation_message(container, input.review, probe)
}
exclusions[t] {
container_excluded_from_policy_by_name
t = true
}
exclusions[t] {
pod_excluded_from_policy_by_label
t = true
}
pod_excluded_from_policy_by_label {
count([key | input.review.object.metadata.labels[key]; key == input.parameters.exclusionLabels[_]]) > 0
}
container_excluded_from_policy_by_name {
count([name | name := input.review.object.spec.containers[_].name; name == input.parameters.excludedContainerNames[_]]) > 0
}
probe_is_missing(ctr, probe) {
not ctr[probe]
}
probe_is_missing(ctr, probe) {
probe_field_empty(ctr, probe)
}
probe_field_empty(ctr, probe) {
probe_fields := {field | ctr[probe][field]}
diff_fields := probe_type_set - probe_fields
count(diff_fields) == count(probe_type_set)
}
has_field(object, field) {
object[field]
}
get_violation_message(container, review, probe) = msg {
msg := sprintf("Container <%v> in your <%v> <%v> has no <%v>. Required probes: %v", [container.name, review.kind.kind, review.object.metadata.name, probe, input.parameters.requiredProbes])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment