mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-01-07 13:55:20 +00:00
Add include/exclude policy to resources policy
fixes #8610 This commit extends the resources policy, such that user can define resource include exclude filters in the policy and reuse it in different backups. Signed-off-by: Daniel Jiang <daniel.jiang@broadcom.com>
This commit is contained in:
@@ -43,7 +43,6 @@ import (
|
||||
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/vmware-tanzu/velero/internal/hook"
|
||||
"github.com/vmware-tanzu/velero/internal/resourcepolicies"
|
||||
"github.com/vmware-tanzu/velero/internal/volume"
|
||||
"github.com/vmware-tanzu/velero/internal/volumehelper"
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
@@ -270,13 +269,17 @@ func (kb *kubernetesBackupper) BackupWithResolvers(
|
||||
backupRequest.Spec.IncludeClusterResources,
|
||||
*backupRequest.NamespaceIncludesExcludes)
|
||||
} else {
|
||||
backupRequest.ResourceIncludesExcludes = collections.GetScopeResourceIncludesExcludes(kb.discoveryHelper, log,
|
||||
srie := collections.GetScopeResourceIncludesExcludes(kb.discoveryHelper, log,
|
||||
backupRequest.Spec.IncludedNamespaceScopedResources,
|
||||
backupRequest.Spec.ExcludedNamespaceScopedResources,
|
||||
backupRequest.Spec.IncludedClusterScopedResources,
|
||||
backupRequest.Spec.ExcludedClusterScopedResources,
|
||||
*backupRequest.NamespaceIncludesExcludes,
|
||||
)
|
||||
if backupRequest.ResPolicies != nil {
|
||||
srie.CombineWithPolicy(backupRequest.ResPolicies.GetIncludeExcludePolicy())
|
||||
}
|
||||
backupRequest.ResourceIncludesExcludes = srie
|
||||
}
|
||||
|
||||
log.Infof("Backing up all volumes using pod volume backup: %t", boolptr.IsSetToTrue(backupRequest.Backup.Spec.DefaultVolumesToFsBackup))
|
||||
@@ -355,11 +358,6 @@ func (kb *kubernetesBackupper) BackupWithResolvers(
|
||||
}
|
||||
backupRequest.Status.Progress = &velerov1api.BackupProgress{TotalItems: len(items)}
|
||||
|
||||
var resourcePolicy *resourcepolicies.Policies
|
||||
if backupRequest.ResPolicies != nil {
|
||||
resourcePolicy = backupRequest.ResPolicies
|
||||
}
|
||||
|
||||
itemBackupper := &itemBackupper{
|
||||
backupRequest: backupRequest,
|
||||
tarWriter: tw,
|
||||
@@ -374,7 +372,7 @@ func (kb *kubernetesBackupper) BackupWithResolvers(
|
||||
},
|
||||
hookTracker: hook.NewHookTracker(),
|
||||
volumeHelperImpl: volumehelper.NewVolumeHelperImpl(
|
||||
resourcePolicy,
|
||||
backupRequest.ResPolicies,
|
||||
backupRequest.Spec.SnapshotVolumes,
|
||||
log,
|
||||
kb.kbClient,
|
||||
|
||||
@@ -235,9 +235,10 @@ Hooks: <none>
|
||||
Excluded: <none>
|
||||
|
||||
Resources:
|
||||
Included: *
|
||||
Excluded: <none>
|
||||
Cluster-scoped: auto
|
||||
Included cluster-scoped: <none>
|
||||
Excluded cluster-scoped: <none>
|
||||
Included namespace-scoped: *
|
||||
Excluded namespace-scoped: <none>
|
||||
|
||||
Label selector: <none>
|
||||
|
||||
@@ -292,9 +293,10 @@ OrderedResources:
|
||||
Excluded: <none>
|
||||
|
||||
Resources:
|
||||
Included: *
|
||||
Excluded: <none>
|
||||
Cluster-scoped: auto
|
||||
Included cluster-scoped: <none>
|
||||
Excluded cluster-scoped: <none>
|
||||
Included namespace-scoped: *
|
||||
Excluded namespace-scoped: <none>
|
||||
|
||||
Label selector: <none>
|
||||
|
||||
@@ -325,9 +327,10 @@ Hooks: <none>
|
||||
Excluded: <none>
|
||||
|
||||
Resources:
|
||||
Included: *
|
||||
Excluded: <none>
|
||||
Cluster-scoped: auto
|
||||
Included cluster-scoped: <none>
|
||||
Excluded cluster-scoped: <none>
|
||||
Included namespace-scoped: *
|
||||
Excluded namespace-scoped: <none>
|
||||
|
||||
Label selector: <none>
|
||||
|
||||
|
||||
@@ -32,9 +32,10 @@ Backup Template:
|
||||
Excluded: <none>
|
||||
|
||||
Resources:
|
||||
Included: *
|
||||
Excluded: <none>
|
||||
Cluster-scoped: auto
|
||||
Included cluster-scoped: <none>
|
||||
Excluded cluster-scoped: <none>
|
||||
Included namespace-scoped: *
|
||||
Excluded namespace-scoped: <none>
|
||||
|
||||
Label selector: <none>
|
||||
|
||||
@@ -81,9 +82,10 @@ Backup Template:
|
||||
Excluded: <none>
|
||||
|
||||
Resources:
|
||||
Included: *
|
||||
Excluded: <none>
|
||||
Cluster-scoped: auto
|
||||
Included cluster-scoped: <none>
|
||||
Excluded cluster-scoped: <none>
|
||||
Included namespace-scoped: *
|
||||
Excluded namespace-scoped: <none>
|
||||
|
||||
Label selector: <none>
|
||||
|
||||
@@ -127,9 +129,10 @@ Backup Template:
|
||||
Excluded: <none>
|
||||
|
||||
Resources:
|
||||
Included: *
|
||||
Excluded: <none>
|
||||
Cluster-scoped: auto
|
||||
Included cluster-scoped: <none>
|
||||
Excluded cluster-scoped: <none>
|
||||
Included namespace-scoped: *
|
||||
Excluded namespace-scoped: <none>
|
||||
|
||||
Label selector: <none>
|
||||
|
||||
@@ -174,9 +177,10 @@ Backup Template:
|
||||
Excluded: <none>
|
||||
|
||||
Resources:
|
||||
Included: *
|
||||
Excluded: <none>
|
||||
Cluster-scoped: auto
|
||||
Included cluster-scoped: <none>
|
||||
Excluded cluster-scoped: <none>
|
||||
Included namespace-scoped: *
|
||||
Excluded namespace-scoped: <none>
|
||||
|
||||
Label selector: <none>
|
||||
|
||||
|
||||
@@ -558,8 +558,11 @@ func (b *backupReconciler) prepareBackupRequest(backup *velerov1api.Backup, logg
|
||||
if err != nil {
|
||||
request.Status.ValidationErrors = append(request.Status.ValidationErrors, err.Error())
|
||||
}
|
||||
if resourcePolicies != nil && resourcePolicies.GetIncludeExcludePolicy() != nil && collections.UseOldResourceFilters(request.Spec) {
|
||||
request.Status.ValidationErrors = append(request.Status.ValidationErrors, "include-resources, exclude-resources and include-cluster-resources are old filter parameters.\n"+
|
||||
"They cannot be used with include-exclude policies.")
|
||||
}
|
||||
request.ResPolicies = resourcePolicies
|
||||
|
||||
return request
|
||||
}
|
||||
|
||||
@@ -812,7 +815,6 @@ func (b *backupReconciler) runBackup(backup *pkgbackup.Request) error {
|
||||
fatalErrs = append(fatalErrs, errs...)
|
||||
}
|
||||
}
|
||||
|
||||
b.logger.WithField(constant.ControllerBackup, kubeutil.NamespaceAndName(backup)).Infof("Initial backup processing complete, moving to %s", backup.Status.Phase)
|
||||
|
||||
// if we return a non-nil error, the calling function will update
|
||||
|
||||
@@ -702,10 +702,11 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedResources: append(autoExcludeNamespaceScopedResources, autoExcludeClusterScopedResources...),
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
ExcludedNamespaceScopedResources: autoExcludeNamespaceScopedResources,
|
||||
},
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFinalizing,
|
||||
@@ -740,10 +741,11 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: "alt-loc",
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedResources: append(autoExcludeNamespaceScopedResources, autoExcludeClusterScopedResources...),
|
||||
StorageLocation: "alt-loc",
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
ExcludedNamespaceScopedResources: autoExcludeNamespaceScopedResources,
|
||||
},
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFinalizing,
|
||||
@@ -782,10 +784,11 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: "read-write",
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedResources: append(autoExcludeNamespaceScopedResources, autoExcludeClusterScopedResources...),
|
||||
StorageLocation: "read-write",
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
ExcludedNamespaceScopedResources: autoExcludeNamespaceScopedResources,
|
||||
},
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFinalizing,
|
||||
@@ -820,11 +823,12 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
TTL: metav1.Duration{Duration: 10 * time.Minute},
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedResources: append(autoExcludeNamespaceScopedResources, autoExcludeClusterScopedResources...),
|
||||
TTL: metav1.Duration{Duration: 10 * time.Minute},
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
ExcludedNamespaceScopedResources: autoExcludeNamespaceScopedResources,
|
||||
},
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFinalizing,
|
||||
@@ -860,10 +864,11 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedResources: append(autoExcludeNamespaceScopedResources, autoExcludeClusterScopedResources...),
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
ExcludedNamespaceScopedResources: autoExcludeNamespaceScopedResources,
|
||||
},
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFinalizing,
|
||||
@@ -900,10 +905,11 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedResources: append(autoExcludeNamespaceScopedResources, autoExcludeClusterScopedResources...),
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
ExcludedNamespaceScopedResources: autoExcludeNamespaceScopedResources,
|
||||
},
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFinalizing,
|
||||
@@ -940,10 +946,11 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedResources: append(autoExcludeNamespaceScopedResources, autoExcludeClusterScopedResources...),
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
ExcludedNamespaceScopedResources: autoExcludeNamespaceScopedResources,
|
||||
},
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFinalizing,
|
||||
@@ -980,10 +987,11 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedResources: append(autoExcludeNamespaceScopedResources, autoExcludeClusterScopedResources...),
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
ExcludedNamespaceScopedResources: autoExcludeNamespaceScopedResources,
|
||||
},
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFinalizing,
|
||||
@@ -1020,10 +1028,11 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedResources: append(autoExcludeNamespaceScopedResources, autoExcludeClusterScopedResources...),
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
ExcludedNamespaceScopedResources: autoExcludeNamespaceScopedResources,
|
||||
},
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFinalizing,
|
||||
@@ -1061,10 +1070,11 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedResources: append(autoExcludeNamespaceScopedResources, autoExcludeClusterScopedResources...),
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
ExcludedNamespaceScopedResources: autoExcludeNamespaceScopedResources,
|
||||
},
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFailed,
|
||||
@@ -1102,10 +1112,11 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedResources: append(autoExcludeNamespaceScopedResources, autoExcludeClusterScopedResources...),
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
ExcludedNamespaceScopedResources: autoExcludeNamespaceScopedResources,
|
||||
},
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFailed,
|
||||
@@ -1143,10 +1154,11 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.True(),
|
||||
ExcludedResources: append(autoExcludeNamespaceScopedResources, autoExcludeClusterScopedResources...),
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.True(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
ExcludedNamespaceScopedResources: autoExcludeNamespaceScopedResources,
|
||||
},
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFinalizing,
|
||||
@@ -1185,10 +1197,11 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedResources: append(autoExcludeNamespaceScopedResources, autoExcludeClusterScopedResources...),
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
ExcludedNamespaceScopedResources: autoExcludeNamespaceScopedResources,
|
||||
},
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFinalizing,
|
||||
@@ -1227,10 +1240,11 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedResources: append(autoExcludeNamespaceScopedResources, autoExcludeClusterScopedResources...),
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
ExcludedNamespaceScopedResources: autoExcludeNamespaceScopedResources,
|
||||
},
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFinalizing,
|
||||
@@ -1269,10 +1283,11 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.True(),
|
||||
ExcludedResources: append(autoExcludeNamespaceScopedResources, autoExcludeClusterScopedResources...),
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.True(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
ExcludedNamespaceScopedResources: autoExcludeNamespaceScopedResources,
|
||||
},
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFinalizing,
|
||||
@@ -1312,10 +1327,11 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedResources: append(autoExcludeNamespaceScopedResources, autoExcludeClusterScopedResources...),
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
ExcludedNamespaceScopedResources: autoExcludeNamespaceScopedResources,
|
||||
},
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFinalizing,
|
||||
@@ -1354,10 +1370,11 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.True(),
|
||||
ExcludedResources: append(autoExcludeNamespaceScopedResources, autoExcludeClusterScopedResources...),
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.True(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
ExcludedNamespaceScopedResources: autoExcludeNamespaceScopedResources,
|
||||
},
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFinalizing,
|
||||
|
||||
@@ -19,6 +19,8 @@ package collections
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/vmware-tanzu/velero/internal/resourcepolicies"
|
||||
|
||||
"github.com/gobwas/glob"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -105,14 +107,63 @@ func (ie *IncludesExcludes) ShouldInclude(s string) bool {
|
||||
return ie.includes.Len() == 0 || ie.includes.Has("*") || ie.includes.match(s)
|
||||
}
|
||||
|
||||
// IncludesString returns a string containing all of the includes, separated by commas, or * if the
|
||||
// list is empty.
|
||||
func (ie *IncludesExcludes) IncludesString() string {
|
||||
return asString(ie.GetIncludes(), "*")
|
||||
}
|
||||
|
||||
// ExcludesString returns a string containing all of the excludes, separated by commas, or <none> if the
|
||||
// list is empty.
|
||||
func (ie *IncludesExcludes) ExcludesString() string {
|
||||
return asString(ie.GetExcludes(), "<none>")
|
||||
}
|
||||
|
||||
// IncludeEverything returns true if the includes list is empty or '*'
|
||||
// and the excludes list is empty, or false otherwise.
|
||||
func (ie *IncludesExcludes) IncludeEverything() bool {
|
||||
return ie.excludes.Len() == 0 && (ie.includes.Len() == 0 || (ie.includes.Len() == 1 && ie.includes.Has("*")))
|
||||
}
|
||||
|
||||
// GetResourceIncludesExcludes takes the lists of resources to include and exclude, uses the
|
||||
// discovery helper to resolve them to fully-qualified group-resource names, and returns an
|
||||
// IncludesExcludes list.
|
||||
func GetResourceIncludesExcludes(helper discovery.Helper, includes, excludes []string) *IncludesExcludes {
|
||||
resources := generateIncludesExcludes(
|
||||
includes,
|
||||
excludes,
|
||||
func(item string) string {
|
||||
gvr, _, err := helper.ResourceFor(schema.ParseGroupResource(item).WithVersion(""))
|
||||
if err != nil {
|
||||
// If we can't resolve it, return it as-is. This prevents the generated
|
||||
// includes-excludes list from including *everything*, if none of the includes
|
||||
// can be resolved. ref. https://github.com/vmware-tanzu/velero/issues/2461
|
||||
return item
|
||||
}
|
||||
|
||||
gr := gvr.GroupResource()
|
||||
return gr.String()
|
||||
},
|
||||
)
|
||||
|
||||
return resources
|
||||
}
|
||||
|
||||
func asString(in []string, empty string) string {
|
||||
if len(in) == 0 {
|
||||
return empty
|
||||
}
|
||||
return strings.Join(in, ", ")
|
||||
}
|
||||
|
||||
// IncludesExcludesInterface is used as polymorphic IncludesExcludes for Global and scope
|
||||
// resources Include/Exclude.
|
||||
type IncludesExcludesInterface interface {
|
||||
// Check whether the type name passed in by parameter should be included.
|
||||
// ShouldInclude checks whether the type name passed in by parameter should be included.
|
||||
// typeName should be k8s.io/apimachinery/pkg/runtime/schema GroupResource's String() result.
|
||||
ShouldInclude(typeName string) bool
|
||||
|
||||
// Check whether the type name passed in by parameter should be excluded.
|
||||
// ShouldExclude checks whether the type name passed in by parameter should be excluded.
|
||||
// typeName should be k8s.io/apimachinery/pkg/runtime/schema GroupResource's String() result.
|
||||
ShouldExclude(typeName string) bool
|
||||
}
|
||||
@@ -188,6 +239,20 @@ func (ie *GlobalIncludesExcludes) ShouldExclude(typeName string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func GetGlobalResourceIncludesExcludes(helper discovery.Helper, logger logrus.FieldLogger, includes, excludes []string, includeClusterResources *bool, nsIncludesExcludes IncludesExcludes) *GlobalIncludesExcludes {
|
||||
ret := &GlobalIncludesExcludes{
|
||||
resourceFilter: *GetResourceIncludesExcludes(helper, includes, excludes),
|
||||
includeClusterResources: includeClusterResources,
|
||||
namespaceFilter: nsIncludesExcludes,
|
||||
helper: helper,
|
||||
logger: logger,
|
||||
}
|
||||
|
||||
logger.Infof("Including resources: %s", ret.resourceFilter.IncludesString())
|
||||
logger.Infof("Excluding resources: %s", ret.resourceFilter.ExcludesString())
|
||||
return ret
|
||||
}
|
||||
|
||||
type ScopeIncludesExcludes struct {
|
||||
namespaceScopedResourceFilter IncludesExcludes // namespace-scoped resource filter
|
||||
clusterScopedResourceFilter IncludesExcludes // cluster-scoped resource filter
|
||||
@@ -259,29 +324,64 @@ func (ie *ScopeIncludesExcludes) ShouldExclude(typeName string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IncludesString returns a string containing all of the includes, separated by commas, or * if the
|
||||
// list is empty.
|
||||
func (ie *IncludesExcludes) IncludesString() string {
|
||||
return asString(ie.GetIncludes(), "*")
|
||||
}
|
||||
|
||||
// ExcludesString returns a string containing all of the excludes, separated by commas, or <none> if the
|
||||
// list is empty.
|
||||
func (ie *IncludesExcludes) ExcludesString() string {
|
||||
return asString(ie.GetExcludes(), "<none>")
|
||||
}
|
||||
|
||||
func asString(in []string, empty string) string {
|
||||
if len(in) == 0 {
|
||||
return empty
|
||||
func (ie *ScopeIncludesExcludes) CombineWithPolicy(policy *resourcepolicies.IncludeExcludePolicy) {
|
||||
if policy == nil {
|
||||
return
|
||||
}
|
||||
return strings.Join(in, ", ")
|
||||
}
|
||||
|
||||
// IncludeEverything returns true if the includes list is empty or '*'
|
||||
// and the excludes list is empty, or false otherwise.
|
||||
func (ie *IncludesExcludes) IncludeEverything() bool {
|
||||
return ie.excludes.Len() == 0 && (ie.includes.Len() == 0 || (ie.includes.Len() == 1 && ie.includes.Has("*")))
|
||||
mapFunc := scopeResourceMapFunc(ie.helper)
|
||||
for _, item := range policy.ExcludedNamespaceScopedResources {
|
||||
resolvedItem := mapFunc(item, true)
|
||||
if resolvedItem == "" {
|
||||
continue
|
||||
}
|
||||
// The existing includeExcludes in the struct has higher priority, therefore, we should only add the item to the filter
|
||||
// when the struct does not include this item and this item is not yet in the excludes filter.
|
||||
if !ie.namespaceScopedResourceFilter.includes.match(resolvedItem) &&
|
||||
!ie.namespaceScopedResourceFilter.excludes.match(resolvedItem) {
|
||||
ie.namespaceScopedResourceFilter.Excludes(resolvedItem)
|
||||
}
|
||||
}
|
||||
for _, item := range policy.IncludedNamespaceScopedResources {
|
||||
resolvedItem := mapFunc(item, true)
|
||||
if resolvedItem == "" {
|
||||
continue
|
||||
}
|
||||
// The existing includeExcludes in the struct has higher priority, therefore, we should only add the item to the filter
|
||||
// when the struct does not exclude this item and this item is not yet in the includes filter.
|
||||
if !ie.namespaceScopedResourceFilter.includes.match(resolvedItem) &&
|
||||
!ie.namespaceScopedResourceFilter.excludes.match(resolvedItem) {
|
||||
ie.namespaceScopedResourceFilter.Includes(resolvedItem)
|
||||
}
|
||||
}
|
||||
for _, item := range policy.ExcludedClusterScopedResources {
|
||||
resolvedItem := mapFunc(item, false)
|
||||
if resolvedItem == "" {
|
||||
continue
|
||||
}
|
||||
if !ie.clusterScopedResourceFilter.includes.match(resolvedItem) &&
|
||||
!ie.clusterScopedResourceFilter.excludes.match(resolvedItem) {
|
||||
// The existing includeExcludes in the struct has higher priority, therefore, we should only add the item to the filter
|
||||
// when the struct does not exclude this item and this item is not yet in the includes filter.
|
||||
ie.clusterScopedResourceFilter.Excludes(resolvedItem)
|
||||
}
|
||||
}
|
||||
for _, item := range policy.IncludedClusterScopedResources {
|
||||
resolvedItem := mapFunc(item, false)
|
||||
if resolvedItem == "" {
|
||||
continue
|
||||
}
|
||||
if !ie.clusterScopedResourceFilter.includes.match(resolvedItem) &&
|
||||
!ie.clusterScopedResourceFilter.excludes.match(resolvedItem) {
|
||||
// The existing includeExcludes in the struct has higher priority, therefore, we should only add the item to the filter
|
||||
// when the struct does not exclude this item and this item is not yet in the includes filter.
|
||||
ie.clusterScopedResourceFilter.Includes(resolvedItem)
|
||||
}
|
||||
}
|
||||
ie.logger.Infof("Scoped resource includes/excludes after combining with resource policy")
|
||||
ie.logger.Infof("Including namespace-scoped resources: %s", ie.namespaceScopedResourceFilter.IncludesString())
|
||||
ie.logger.Infof("Excluding namespace-scoped resources: %s", ie.namespaceScopedResourceFilter.ExcludesString())
|
||||
ie.logger.Infof("Including cluster-scoped resources: %s", ie.clusterScopedResourceFilter.GetIncludes())
|
||||
ie.logger.Infof("Excluding cluster-scoped resources: %s", ie.clusterScopedResourceFilter.ExcludesString())
|
||||
}
|
||||
|
||||
func newScopeIncludesExcludes(nsIncludesExcludes IncludesExcludes, helper discovery.Helper, logger logrus.FieldLogger) *ScopeIncludesExcludes {
|
||||
@@ -302,6 +402,43 @@ func newScopeIncludesExcludes(nsIncludesExcludes IncludesExcludes, helper discov
|
||||
return ret
|
||||
}
|
||||
|
||||
// GetScopeResourceIncludesExcludes function is similar with GetResourceIncludesExcludes,
|
||||
// but it's used for scoped Includes/Excludes, and can handle both cluster-scoped and namespace-scoped resources.
|
||||
func GetScopeResourceIncludesExcludes(helper discovery.Helper, logger logrus.FieldLogger, namespaceIncludes, namespaceExcludes, clusterIncludes, clusterExcludes []string, nsIncludesExcludes IncludesExcludes) *ScopeIncludesExcludes {
|
||||
ret := generateScopedIncludesExcludes(
|
||||
namespaceIncludes,
|
||||
namespaceExcludes,
|
||||
clusterIncludes,
|
||||
clusterExcludes,
|
||||
scopeResourceMapFunc(helper),
|
||||
nsIncludesExcludes,
|
||||
helper,
|
||||
logger,
|
||||
)
|
||||
logger.Infof("Scoped resource includes/excludes after initialization")
|
||||
logger.Infof("Including namespace-scoped resources: %s", ret.namespaceScopedResourceFilter.IncludesString())
|
||||
logger.Infof("Excluding namespace-scoped resources: %s", ret.namespaceScopedResourceFilter.ExcludesString())
|
||||
logger.Infof("Including cluster-scoped resources: %s", ret.clusterScopedResourceFilter.GetIncludes())
|
||||
logger.Infof("Excluding cluster-scoped resources: %s", ret.clusterScopedResourceFilter.ExcludesString())
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func scopeResourceMapFunc(helper discovery.Helper) func(string, bool) string {
|
||||
return func(item string, namespaced bool) string {
|
||||
gvr, resource, err := helper.ResourceFor(schema.ParseGroupResource(item).WithVersion(""))
|
||||
if err != nil {
|
||||
return item
|
||||
}
|
||||
if resource.Namespaced != namespaced {
|
||||
return ""
|
||||
}
|
||||
|
||||
gr := gvr.GroupResource()
|
||||
return gr.String()
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateIncludesExcludes checks provided lists of included and excluded
|
||||
// items to ensure they are a valid set of IncludesExcludes data.
|
||||
func ValidateIncludesExcludes(includesList, excludesList []string) []error {
|
||||
@@ -470,97 +607,16 @@ func generateFilter(filter globStringSet, resources []string, mapFunc func(strin
|
||||
}
|
||||
}
|
||||
|
||||
// GetResourceIncludesExcludes takes the lists of resources to include and exclude, uses the
|
||||
// discovery helper to resolve them to fully-qualified group-resource names, and returns an
|
||||
// IncludesExcludes list.
|
||||
func GetResourceIncludesExcludes(helper discovery.Helper, includes, excludes []string) *IncludesExcludes {
|
||||
resources := generateIncludesExcludes(
|
||||
includes,
|
||||
excludes,
|
||||
func(item string) string {
|
||||
gvr, _, err := helper.ResourceFor(schema.ParseGroupResource(item).WithVersion(""))
|
||||
if err != nil {
|
||||
// If we can't resolve it, return it as-is. This prevents the generated
|
||||
// includes-excludes list from including *everything*, if none of the includes
|
||||
// can be resolved. ref. https://github.com/vmware-tanzu/velero/issues/2461
|
||||
return item
|
||||
}
|
||||
|
||||
gr := gvr.GroupResource()
|
||||
return gr.String()
|
||||
},
|
||||
)
|
||||
|
||||
return resources
|
||||
}
|
||||
|
||||
func GetGlobalResourceIncludesExcludes(helper discovery.Helper, logger logrus.FieldLogger, includes, excludes []string, includeClusterResources *bool, nsIncludesExcludes IncludesExcludes) *GlobalIncludesExcludes {
|
||||
ret := &GlobalIncludesExcludes{
|
||||
resourceFilter: *GetResourceIncludesExcludes(helper, includes, excludes),
|
||||
includeClusterResources: includeClusterResources,
|
||||
namespaceFilter: nsIncludesExcludes,
|
||||
helper: helper,
|
||||
logger: logger,
|
||||
}
|
||||
|
||||
logger.Infof("Including resources: %s", ret.resourceFilter.IncludesString())
|
||||
logger.Infof("Excluding resources: %s", ret.resourceFilter.ExcludesString())
|
||||
return ret
|
||||
}
|
||||
|
||||
// GetScopeResourceIncludesExcludes function is similar with GetResourceIncludesExcludes,
|
||||
// but it's used for scoped Includes/Excludes, and can handle both cluster-scoped and namespace-scoped resources.
|
||||
func GetScopeResourceIncludesExcludes(helper discovery.Helper, logger logrus.FieldLogger, namespaceIncludes, namespaceExcludes, clusterIncludes, clusterExcludes []string, nsIncludesExcludes IncludesExcludes) *ScopeIncludesExcludes {
|
||||
ret := generateScopedIncludesExcludes(
|
||||
namespaceIncludes,
|
||||
namespaceExcludes,
|
||||
clusterIncludes,
|
||||
clusterExcludes,
|
||||
func(item string, namespaced bool) string {
|
||||
gvr, resource, err := helper.ResourceFor(schema.ParseGroupResource(item).WithVersion(""))
|
||||
if err != nil {
|
||||
return item
|
||||
}
|
||||
if resource.Namespaced != namespaced {
|
||||
return ""
|
||||
}
|
||||
|
||||
gr := gvr.GroupResource()
|
||||
return gr.String()
|
||||
},
|
||||
nsIncludesExcludes,
|
||||
helper,
|
||||
logger,
|
||||
)
|
||||
logger.Infof("Including namespace-scoped resources: %s", ret.namespaceScopedResourceFilter.IncludesString())
|
||||
logger.Infof("Excluding namespace-scoped resources: %s", ret.namespaceScopedResourceFilter.ExcludesString())
|
||||
logger.Infof("Including cluster-scoped resources: %s", ret.clusterScopedResourceFilter.GetIncludes())
|
||||
logger.Infof("Excluding cluster-scoped resources: %s", ret.clusterScopedResourceFilter.ExcludesString())
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// UseOldResourceFilters checks whether to use old resource filters (IncludeClusterResources,
|
||||
// IncludedResources and ExcludedResources), depending the backup's filters setting.
|
||||
// New filters are IncludedClusterScopedResources, ExcludedClusterScopedResources,
|
||||
// IncludedNamespaceScopedResources and ExcludedNamespaceScopedResources.
|
||||
// If all resource filters are none, it is treated as using new parameter filters.
|
||||
func UseOldResourceFilters(backupSpec velerov1api.BackupSpec) bool {
|
||||
// If all resource filters are none, it is treated as using old parameter filters.
|
||||
if backupSpec.IncludeClusterResources == nil &&
|
||||
len(backupSpec.IncludedResources) == 0 &&
|
||||
len(backupSpec.ExcludedResources) == 0 &&
|
||||
len(backupSpec.IncludedClusterScopedResources) == 0 &&
|
||||
len(backupSpec.ExcludedClusterScopedResources) == 0 &&
|
||||
len(backupSpec.IncludedNamespaceScopedResources) == 0 &&
|
||||
len(backupSpec.ExcludedNamespaceScopedResources) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
if backupSpec.IncludeClusterResources != nil ||
|
||||
len(backupSpec.IncludedResources) > 0 ||
|
||||
len(backupSpec.ExcludedResources) > 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ package collections
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/vmware-tanzu/velero/internal/resourcepolicies"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -741,6 +743,100 @@ func TestGetScopedResourceIncludesExcludes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestScopeIncludesExcludes_CombineWithPolicy(t *testing.T) {
|
||||
apiResources := []*test.APIResource{test.Deployments(), test.Pods(), test.ConfigMaps(), test.Secrets(), test.PVs(), test.CRDs(), test.ServiceAccounts()}
|
||||
tests := []struct {
|
||||
name string
|
||||
namespaceScopedIncludes []string
|
||||
namespaceScopedExcludes []string
|
||||
clusterScopedIncludes []string
|
||||
clusterScopedExcludes []string
|
||||
policy *resourcepolicies.IncludeExcludePolicy
|
||||
verify func(sie ScopeIncludesExcludes) bool
|
||||
}{
|
||||
{
|
||||
name: "When policy is nil, the original includes excludes filters should not change",
|
||||
namespaceScopedIncludes: []string{"deployments", "pods"},
|
||||
namespaceScopedExcludes: []string{"configmaps"},
|
||||
clusterScopedIncludes: []string{"persistentvolumes"},
|
||||
clusterScopedExcludes: []string{"crds"},
|
||||
policy: nil,
|
||||
verify: func(sie ScopeIncludesExcludes) bool {
|
||||
return sie.clusterScopedResourceFilter.ShouldInclude("persistentvolumes") &&
|
||||
!sie.clusterScopedResourceFilter.ShouldInclude("crds") &&
|
||||
sie.namespaceScopedResourceFilter.ShouldInclude("deployments") &&
|
||||
!sie.namespaceScopedResourceFilter.ShouldInclude("configmaps")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "policy includes excludes should be merged to the original includes excludes when there's no conflict",
|
||||
namespaceScopedIncludes: []string{"pods"},
|
||||
namespaceScopedExcludes: []string{"configmaps"},
|
||||
clusterScopedIncludes: []string{},
|
||||
clusterScopedExcludes: []string{"crds"},
|
||||
policy: &resourcepolicies.IncludeExcludePolicy{
|
||||
IncludedNamespaceScopedResources: []string{"deployments"},
|
||||
ExcludedNamespaceScopedResources: []string{"secrets"},
|
||||
IncludedClusterScopedResources: []string{"persistentvolumes"},
|
||||
ExcludedClusterScopedResources: []string{},
|
||||
},
|
||||
verify: func(sie ScopeIncludesExcludes) bool {
|
||||
return sie.clusterScopedResourceFilter.ShouldInclude("persistentvolumes") &&
|
||||
!sie.clusterScopedResourceFilter.ShouldInclude("crds") &&
|
||||
sie.namespaceScopedResourceFilter.ShouldInclude("deployments") &&
|
||||
!sie.namespaceScopedResourceFilter.ShouldInclude("configmaps") &&
|
||||
!sie.namespaceScopedResourceFilter.ShouldInclude("secrets")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "when there are conflicts, the existing includes excludes filters have higher priorities",
|
||||
namespaceScopedIncludes: []string{"pods", "deployments"},
|
||||
namespaceScopedExcludes: []string{"configmaps"},
|
||||
clusterScopedIncludes: []string{"crds"},
|
||||
clusterScopedExcludes: []string{"persistentvolumes"},
|
||||
policy: &resourcepolicies.IncludeExcludePolicy{
|
||||
IncludedNamespaceScopedResources: []string{"configmaps"},
|
||||
ExcludedNamespaceScopedResources: []string{"pods", "secrets"},
|
||||
IncludedClusterScopedResources: []string{"persistentvolumes"},
|
||||
ExcludedClusterScopedResources: []string{"crds"},
|
||||
},
|
||||
verify: func(sie ScopeIncludesExcludes) bool {
|
||||
return sie.clusterScopedResourceFilter.ShouldInclude("crds") &&
|
||||
!sie.clusterScopedResourceFilter.ShouldInclude("persistentvolumes") &&
|
||||
sie.namespaceScopedResourceFilter.ShouldInclude("pods") &&
|
||||
!sie.namespaceScopedResourceFilter.ShouldInclude("configmaps") &&
|
||||
!sie.namespaceScopedResourceFilter.ShouldInclude("secrets")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "verify the case when there's '*' in the original include filter",
|
||||
namespaceScopedIncludes: []string{"*"},
|
||||
namespaceScopedExcludes: []string{},
|
||||
clusterScopedIncludes: []string{},
|
||||
clusterScopedExcludes: []string{},
|
||||
policy: &resourcepolicies.IncludeExcludePolicy{
|
||||
IncludedNamespaceScopedResources: []string{"deployments", "pods"},
|
||||
ExcludedNamespaceScopedResources: []string{"configmaps", "secrets"},
|
||||
IncludedClusterScopedResources: []string{},
|
||||
ExcludedClusterScopedResources: []string{},
|
||||
},
|
||||
verify: func(sie ScopeIncludesExcludes) bool {
|
||||
return sie.namespaceScopedResourceFilter.ShouldInclude("configmaps") &&
|
||||
sie.namespaceScopedResourceFilter.ShouldInclude("secrets")
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
logger := logrus.StandardLogger()
|
||||
discoveryHelper := setupDiscoveryClientWithResources(apiResources)
|
||||
sie := GetScopeResourceIncludesExcludes(discoveryHelper, logger, tc.namespaceScopedIncludes, tc.namespaceScopedExcludes, tc.clusterScopedIncludes, tc.clusterScopedExcludes, *NewIncludesExcludes())
|
||||
sie.CombineWithPolicy(tc.policy)
|
||||
assert.True(t, tc.verify(*sie))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUseOldResourceFilters(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -748,9 +844,9 @@ func TestUseOldResourceFilters(t *testing.T) {
|
||||
useOldResourceFilters bool
|
||||
}{
|
||||
{
|
||||
name: "backup with no filters should use old filters",
|
||||
name: "backup with no filters should use new filters",
|
||||
backup: *defaultBackup().Result(),
|
||||
useOldResourceFilters: true,
|
||||
useOldResourceFilters: false,
|
||||
},
|
||||
{
|
||||
name: "backup with only old filters should use old filters",
|
||||
|
||||
Reference in New Issue
Block a user