All Policies
Backup All Volumes
In order for Velero to backup volumes in a Pod using an opt-in approach, it requires an annotation on the Pod called `backup.velero.io/backup-volumes` with the value being a comma-separated list of the volumes mounted to that Pod. This policy automatically annotates Pods (and Pod controllers) which refer to a PVC so that all volumes are listed in the aforementioned annotation if a Namespace with the label `velero-backup-pvc=true`.
Policy Definition
/velero-mpol/backup-all-volumes/backup-all-volumes.yaml
1apiVersion: policies.kyverno.io/v1alpha1
2kind: MutatingPolicy
3metadata:
4 name: backup-all-volumes
5 annotations:
6 policies.kyverno.io/title: Backup All Volumes
7 policies.kyverno.io/category: Velero
8 policies.kyverno.io/severity: medium
9 policies.kyverno.io/subject: Pod, Deployment, CronJob, Annotation
10 policies.kyverno.io/description: >-
11 In order for Velero to backup volumes in a Pod using an opt-in approach, it
12 requires an annotation on the Pod called `backup.velero.io/backup-volumes` with the
13 value being a comma-separated list of the volumes mounted to that Pod. This policy
14 automatically annotates Pods (and Pod controllers) which refer to a PVC so that
15 all volumes are listed in the aforementioned annotation if a Namespace with the label
16 `velero-backup-pvc=true`.
17spec:
18 evaluation:
19 admission:
20 enabled: true
21 matchConstraints:
22 resourceRules:
23 - apiGroups: [""]
24 apiVersions: ["v1"]
25 operations: ["CREATE", "UPDATE"]
26 resources: ["pods"]
27 - apiGroups: ["apps"]
28 apiVersions: ["v1"]
29 operations: ["CREATE", "UPDATE"]
30 resources: ["deployments", "daemonsets", "statefulsets"]
31 - apiGroups: ["batch"]
32 apiVersions: ["v1"]
33 operations: ["CREATE", "UPDATE"]
34 resources: ["jobs", "cronjobs"]
35 namespaceSelector:
36 matchLabels:
37 velero-backup-pvc: "true"
38 variables:
39 # For Pods
40 - name: podPvcVolumes
41 expression: >-
42 object.kind == "Pod" && has(object.spec.volumes) ?
43 object.spec.volumes.filter(v, has(v.persistentVolumeClaim)).map(v, v.name) :
44 []
45 - name: podVolumesList
46 expression: >-
47 variables.podPvcVolumes.size() > 0 ? variables.podPvcVolumes.join(',') : ''
48 # For Deployments, DaemonSets, StatefulSets
49 - name: deploymentPvcVolumes
50 expression: >-
51 (object.kind == "Deployment" || object.kind == "DaemonSet" || object.kind == "StatefulSet") &&
52 has(object.spec.template.spec.volumes) ?
53 object.spec.template.spec.volumes.filter(v, has(v.persistentVolumeClaim)).map(v, v.name) :
54 []
55 - name: deploymentVolumesList
56 expression: >-
57 variables.deploymentPvcVolumes.size() > 0 ? variables.deploymentPvcVolumes.join(',') : ''
58 # For Jobs
59 - name: jobPvcVolumes
60 expression: >-
61 object.kind == "Job" && has(object.spec.template.spec.volumes) ?
62 object.spec.template.spec.volumes.filter(v, has(v.persistentVolumeClaim)).map(v, v.name) :
63 []
64 - name: jobVolumesList
65 expression: >-
66 variables.jobPvcVolumes.size() > 0 ? variables.jobPvcVolumes.join(',') : ''
67 # For CronJobs
68 - name: cronjobPvcVolumes
69 expression: >-
70 object.kind == "CronJob" && has(object.spec.jobTemplate.spec.template.spec.volumes) ?
71 object.spec.jobTemplate.spec.template.spec.volumes.filter(v, has(v.persistentVolumeClaim)).map(v, v.name) :
72 []
73 - name: cronjobVolumesList
74 expression: >-
75 variables.cronjobPvcVolumes.size() > 0 ? variables.cronjobPvcVolumes.join(',') : ''
76 mutations:
77 # Mutation for Pods
78 - patchType: JSONPatch
79 jsonPatch:
80 expression: |
81 object.kind == "Pod" && variables.podVolumesList != '' ?
82 (
83 !has(object.metadata.annotations) ?
84 [
85 JSONPatch{
86 op: "add",
87 path: "/metadata/annotations",
88 value: {"backup.velero.io/backup-volumes": variables.podVolumesList}
89 }
90 ] :
91 [
92 JSONPatch{
93 op: "add",
94 path: "/metadata/annotations/" + jsonpatch.escapeKey("backup.velero.io/backup-volumes"),
95 value: variables.podVolumesList
96 }
97 ]
98 ) : []
99 # Mutation for Deployments, DaemonSets, StatefulSets
100 - patchType: JSONPatch
101 jsonPatch:
102 expression: |
103 (object.kind == "Deployment" || object.kind == "DaemonSet" || object.kind == "StatefulSet") &&
104 variables.deploymentVolumesList != '' ?
105 (
106 !has(object.spec.template.metadata.annotations) ?
107 [
108 JSONPatch{
109 op: "add",
110 path: "/spec/template/metadata/annotations",
111 value: {"backup.velero.io/backup-volumes": variables.deploymentVolumesList}
112 }
113 ] :
114 [
115 JSONPatch{
116 op: "add",
117 path: "/spec/template/metadata/annotations/" + jsonpatch.escapeKey("backup.velero.io/backup-volumes"),
118 value: variables.deploymentVolumesList
119 }
120 ]
121 ) : []
122 # Mutation for Jobs
123 - patchType: JSONPatch
124 jsonPatch:
125 expression: |
126 object.kind == "Job" && variables.jobVolumesList != '' ?
127 (
128 !has(object.spec.template.metadata.annotations) ?
129 [
130 JSONPatch{
131 op: "add",
132 path: "/spec/template/metadata/annotations",
133 value: {"backup.velero.io/backup-volumes": variables.jobVolumesList}
134 }
135 ] :
136 [
137 JSONPatch{
138 op: "add",
139 path: "/spec/template/metadata/annotations/" + jsonpatch.escapeKey("backup.velero.io/backup-volumes"),
140 value: variables.jobVolumesList
141 }
142 ]
143 ) : []
144 # Mutation for CronJobs
145 - patchType: JSONPatch
146 jsonPatch:
147 expression: |
148 object.kind == "CronJob" && variables.cronjobVolumesList != '' ?
149 (
150 !has(object.spec.jobTemplate.spec.template.metadata.annotations) ?
151 [
152 JSONPatch{
153 op: "add",
154 path: "/spec/jobTemplate/spec/template/metadata/annotations",
155 value: {"backup.velero.io/backup-volumes": variables.cronjobVolumesList}
156 }
157 ] :
158 [
159 JSONPatch{
160 op: "add",
161 path: "/spec/jobTemplate/spec/template/metadata/annotations/" + jsonpatch.escapeKey("backup.velero.io/backup-volumes"),
162 value: variables.cronjobVolumesList
163 }
164 ]
165 ) : []