mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-09-27 02:14:47 +00:00
Dedup the entries in backuprequest.spec.excludeNamespaces (#10562)
Run the E2E test on kind / setup-test-matrix (push) Failing after 4s
e2e-test-kind.yaml / extract (push) Failing after 8s
Run the E2E test on kind / get-go-version (push) Failing after 9s
Run the E2E test on kind / build (push) Skipped
Run the E2E test on kind / run-e2e-test (push) Skipped
push.yml / extract (push) Failing after 5s
Scorecard supply-chain security / Scorecard analysis (push) Skipped
Main CI / get-go-version (push) Failing after 6s
Main CI / Build (push) Skipped
Run the E2E test on kind / setup-test-matrix (push) Failing after 4s
e2e-test-kind.yaml / extract (push) Failing after 8s
Run the E2E test on kind / get-go-version (push) Failing after 9s
Run the E2E test on kind / build (push) Skipped
Run the E2E test on kind / run-e2e-test (push) Skipped
push.yml / extract (push) Failing after 5s
Scorecard supply-chain security / Scorecard analysis (push) Skipped
Main CI / get-go-version (push) Failing after 6s
Main CI / Build (push) Skipped
This commit fixes the issue that when a namespace with label velero.io/exclude-from-backup: "true" is added to the exludeNamespaces of a backup CR. There will be duplicated entries of the namespace in the spec of the backup. Signed-off-by: Daniel Jiang <daniel.jiang@broadcom.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Dedup the entries in backuprequest.spec.excludeNamespaces
|
||||
@@ -544,6 +544,10 @@ func (b *backupReconciler) prepareBackupRequest(ctx context.Context, backup *vel
|
||||
request.Status.ValidationErrors = append(request.Status.ValidationErrors, fmt.Sprintf("error getting namespace list: %v", err))
|
||||
}
|
||||
|
||||
if len(request.Spec.ExcludedNamespaces) > 0 {
|
||||
request.Spec.ExcludedNamespaces = sets.NewString(request.Spec.ExcludedNamespaces...).List()
|
||||
}
|
||||
|
||||
// validate whether Included/Excluded resources and IncludedClusterResource are mixed with
|
||||
// Included/Excluded cluster-scoped/namespace-scoped resources.
|
||||
if oldAndNewFilterParametersUsedTogether(request.Spec) {
|
||||
|
||||
@@ -2901,3 +2901,120 @@ func TestPrepareBackupRequest_FilterPoliciesWithNewFilters(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrepareBackupRequest_DeduplicateExcludedNamespaces(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
specExcluded []string
|
||||
clusterNamespaces []*corev1api.Namespace
|
||||
expectedExcluded []string
|
||||
}{
|
||||
{
|
||||
name: "duplicates in spec.excludedNamespaces are de-duped",
|
||||
specExcluded: []string{"ns-1", "ns-2", "ns-1", "ns-2", "ns-3"},
|
||||
clusterNamespaces: []*corev1api.Namespace{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "ns-4",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedExcluded: []string{"ns-1", "ns-2", "ns-3"},
|
||||
},
|
||||
{
|
||||
name: "labeled namespaces overlapping with spec.excludedNamespaces are de-duped",
|
||||
specExcluded: []string{"ns-1", "ns-2"},
|
||||
clusterNamespaces: []*corev1api.Namespace{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "ns-2",
|
||||
Labels: map[string]string{
|
||||
velerov1api.ExcludeFromBackupLabel: "true",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "ns-3",
|
||||
Labels: map[string]string{
|
||||
velerov1api.ExcludeFromBackupLabel: "true",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "ns-4",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedExcluded: []string{"ns-1", "ns-2", "ns-3"},
|
||||
},
|
||||
{
|
||||
name: "empty spec.excludedNamespaces with labeled namespaces",
|
||||
specExcluded: nil,
|
||||
clusterNamespaces: []*corev1api.Namespace{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "ns-1",
|
||||
Labels: map[string]string{
|
||||
velerov1api.ExcludeFromBackupLabel: "true",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "ns-2",
|
||||
Labels: map[string]string{
|
||||
velerov1api.ExcludeFromBackupLabel: "true",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedExcluded: []string{"ns-1", "ns-2"},
|
||||
},
|
||||
{
|
||||
name: "empty spec.excludedNamespaces with no labeled namespaces remains empty",
|
||||
specExcluded: nil,
|
||||
clusterNamespaces: nil,
|
||||
expectedExcluded: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
formatFlag := logging.FormatText
|
||||
logger := logging.DefaultLogger(logrus.DebugLevel, formatFlag)
|
||||
|
||||
backupLocation := builder.ForBackupStorageLocation(velerov1api.DefaultNamespace, "loc-1").
|
||||
Phase(velerov1api.BackupStorageLocationPhaseAvailable).Result()
|
||||
|
||||
var objects []runtime.Object
|
||||
objects = append(objects, backupLocation)
|
||||
for _, ns := range tt.clusterNamespaces {
|
||||
objects = append(objects, ns)
|
||||
}
|
||||
|
||||
fakeClient := velerotest.NewFakeControllerRuntimeClient(t, objects...)
|
||||
apiServer := velerotest.NewAPIServer(t)
|
||||
discoveryHelper, err := discovery.NewHelper(apiServer.DiscoveryClient, logger)
|
||||
require.NoError(t, err)
|
||||
|
||||
c := &backupReconciler{
|
||||
logger: logger,
|
||||
discoveryHelper: discoveryHelper,
|
||||
kbClient: fakeClient,
|
||||
clock: &clock.RealClock{},
|
||||
formatFlag: formatFlag,
|
||||
}
|
||||
|
||||
backup := defaultBackup().StorageLocation("loc-1").Result()
|
||||
backup.Spec.ExcludedNamespaces = tt.specExcluded
|
||||
|
||||
res := c.prepareBackupRequest(t.Context(), backup, logger)
|
||||
defer res.WorkerPool.Stop()
|
||||
|
||||
assert.Empty(t, res.Status.ValidationErrors)
|
||||
assert.Equal(t, tt.expectedExcluded, res.Spec.ExcludedNamespaces)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user