Prevent Bare Pods
The same policy has two effects, either when used as a precondition for a mutation or as a condition for a validation.
When used as a condition for a validation the rule correctly ignores pods owned by deployments as one might expect based on the business logic. However used as a precondition for a mutation it fails to ignore the pods owned by the deployment.
Steps to reproduce:
Create a chainsaw-equipped kyverno cluster with the below definition of a deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
annotations:
"cluster-autoscaler.kubernetes.io/safe-to-evict": "false"
spec:
containers:
- name: nginx
image: nginx:1.14.2
and either the prevent-bare-pods policy or the below mutation policy
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: mutate-bare-pods-with-annotation
annotations:
policies.kyverno.io/title: Mutate bare pods with safe-to-evict annotation
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
kyverno.io/kubernetes-version: "1.23"
kyverno.io/kyverno-version: 1.13.1
policies.kyverno.io/description: >-
Pods not created by workload controllers such as Deployments block
autoscaling unless safe-to-evict annotation is found. This policy applies
the safe-to-evict annotation to these "bare" Pods automatically.
spec:
rules:
- name: add-safe-to-evict-annotation
match:
resources:
kinds:
- Pod
preconditions:
any:
- key: ownerReferences
operator: AnyNotIn
value: "{{request.object.metadata.keys(@)}}"
message: "precondition failed for owner references not found"
mutate:
patchStrategicMerge:
metadata:
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
Observe that (using the below chainsaw file) the tests fail because the precondition unfortunately matches.
apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Test
metadata:
name: safe-to-evict
spec:
steps:
- name: Apply policy
try:
- apply:
file: ../../../../k8s/base/kyverno-policies/bare-pods-safe-to-evict-annotation.yml
- assert:
file: ./policy-ready.yaml
- name: standard-deployments-exempt
try:
- apply:
file: ./deployment.yaml
- assert:
resource:
apiVersion: v1
kind: Pod
metadata:
labels:
app: nginx
annotations:
"cluster-autoscaler.kubernetes.io/safe-to-evict": "false"
Does it have to do with the lack of request operation precondition on my policy above? I need to do a any condition on the rule to handle another edge case, so I couldn't get away with an "all" rule unfortunately.