From 1f4139a5bfc204d3aca127ba90fb8868a1814e3a Mon Sep 17 00:00:00 2001 From: Adnan Abdulhussein Date: Wed, 19 Jun 2019 07:58:02 -0700 Subject: [PATCH] allow exclusion of resources using standard label (#1588) * allow exclusion of resources using standard label excludes any resources with the velero.io/exclude-from-backup=true label Signed-off-by: Adnan Abdulhussein --- changelogs/unreleased/1588-prydonius | 1 + pkg/backup/backup_new_test.go | 84 +++++++++++++++++++++++++++- pkg/backup/resource_backupper.go | 4 +- 3 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 changelogs/unreleased/1588-prydonius diff --git a/changelogs/unreleased/1588-prydonius b/changelogs/unreleased/1588-prydonius new file mode 100644 index 000000000..a8481eff4 --- /dev/null +++ b/changelogs/unreleased/1588-prydonius @@ -0,0 +1 @@ +allows excluding resources from backups with the velero.io/exclude-from-backup=true label diff --git a/pkg/backup/backup_new_test.go b/pkg/backup/backup_new_test.go index 7a8b93338..ca5912910 100644 --- a/pkg/backup/backup_new_test.go +++ b/pkg/backup/backup_new_test.go @@ -218,6 +218,81 @@ func TestBackupResourceFiltering(t *testing.T) { "resources/persistentvolumes/cluster/bar.json", }, }, + { + name: "resources with velero.io/exclude-from-backup=true label are not included", + backup: defaultBackup(). + Backup(), + apiResources: []*apiResource{ + pods( + withLabel(newPod("foo", "bar"), "velero.io/exclude-from-backup", "true"), + newPod("zoo", "raz"), + ), + deployments( + newDeployment("foo", "bar"), + withLabel(newDeployment("zoo", "raz"), "velero.io/exclude-from-backup", "true"), + ), + pvs( + withLabel(newPV("bar"), "a", "b"), + withLabel(newPV("baz"), "velero.io/exclude-from-backup", "true"), + ), + }, + want: []string{ + "resources/pods/namespaces/zoo/raz.json", + "resources/deployments.apps/namespaces/foo/bar.json", + "resources/persistentvolumes/cluster/bar.json", + }, + }, + { + name: "resources with velero.io/exclude-from-backup=true label are not included even if matching label selector", + backup: defaultBackup(). + LabelSelector(&metav1.LabelSelector{MatchLabels: map[string]string{"a": "b"}}). + Backup(), + apiResources: []*apiResource{ + pods( + withLabel(newPod("foo", "bar"), "velero.io/exclude-from-backup", "true", "a", "b"), + withLabel(newPod("zoo", "raz"), "a", "b"), + ), + deployments( + newDeployment("foo", "bar"), + withLabel(newDeployment("zoo", "raz"), "velero.io/exclude-from-backup", "true", "a", "b"), + ), + pvs( + withLabel(newPV("bar"), "a", "b"), + withLabel(newPV("baz"), "a", "b", "velero.io/exclude-from-backup", "true"), + ), + }, + want: []string{ + "resources/pods/namespaces/zoo/raz.json", + "resources/persistentvolumes/cluster/bar.json", + }, + }, + { + name: "resources with velero.io/exclude-from-backup label specified but not 'true' are included", + backup: defaultBackup(). + Backup(), + apiResources: []*apiResource{ + pods( + withLabel(newPod("foo", "bar"), "velero.io/exclude-from-backup", "false"), + newPod("zoo", "raz"), + ), + deployments( + newDeployment("foo", "bar"), + withLabel(newDeployment("zoo", "raz"), "velero.io/exclude-from-backup", "1"), + ), + pvs( + withLabel(newPV("bar"), "a", "b"), + withLabel(newPV("baz"), "velero.io/exclude-from-backup", ""), + ), + }, + want: []string{ + "resources/pods/namespaces/foo/bar.json", + "resources/pods/namespaces/zoo/raz.json", + "resources/deployments.apps/namespaces/foo/bar.json", + "resources/deployments.apps/namespaces/zoo/raz.json", + "resources/persistentvolumes/cluster/bar.json", + "resources/persistentvolumes/cluster/baz.json", + }, + }, { name: "should include cluster-scoped resources if backing up subset of namespaces and IncludeClusterResources=true", backup: defaultBackup(). @@ -1794,12 +1869,17 @@ func newHarness(t *testing.T) *harness { } } -func withLabel(obj metav1.Object, key, val string) metav1.Object { +func withLabel(obj metav1.Object, labelPairs ...string) metav1.Object { + if len(labelPairs)%2 != 0 { + panic("withLabel requires a series of key-value pairs") + } labels := obj.GetLabels() if labels == nil { labels = make(map[string]string) } - labels[key] = val + for i := 0; i < len(labelPairs); i += 2 { + labels[labelPairs[i]] = labelPairs[i+1] + } obj.SetLabels(labels) return obj diff --git a/pkg/backup/resource_backupper.go b/pkg/backup/resource_backupper.go index 86d1ca8a4..de78a25d3 100644 --- a/pkg/backup/resource_backupper.go +++ b/pkg/backup/resource_backupper.go @@ -221,9 +221,9 @@ func (rb *defaultResourceBackupper) backupResource(group *metav1.APIResourceList continue } - var labelSelector string + labelSelector := "velero.io/exclude-from-backup!=true" if selector := rb.backupRequest.Spec.LabelSelector; selector != nil { - labelSelector = metav1.FormatLabelSelector(selector) + labelSelector = labelSelector + "," + metav1.FormatLabelSelector(selector) } log.Info("Listing items")