mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-07-27 02:23:29 +00:00
Prioritize exact namespace match in restore (#10033)
Run the E2E test on kind / get-go-version (push) Failing after 1m12s
Run the E2E test on kind / build (push) Has been skipped
Run the E2E test on kind / setup-test-matrix (push) Successful in 4s
Run the E2E test on kind / run-e2e-test (push) Has been skipped
Main CI / get-go-version (push) Successful in 12s
Main CI / Build (push) Failing after 26s
Run the E2E test on kind / get-go-version (push) Failing after 1m12s
Run the E2E test on kind / build (push) Has been skipped
Run the E2E test on kind / setup-test-matrix (push) Successful in 4s
Run the E2E test on kind / run-e2e-test (push) Has been skipped
Main CI / get-go-version (push) Successful in 12s
Main CI / Build (push) Failing after 26s
* Prioritize exact namespace match in restore Align restore pipeline with backup pipeline by evaluating exact namespace matches before glob patterns in namespacedFilterPolicies. This ensures specific overrides always win regardless of list order. Signed-off-by: Adam Zhang <adam.zhang@broadcom.com> * improve test cases add test cases for exact listed first, and excat listed last to ensure the behavior that the order does not matter for exact listed namespace, the rule will be always honored. Signed-off-by: Adam Zhang <adam.zhang@broadcom.com> --------- Signed-off-by: Adam Zhang <adam.zhang@broadcom.com>
This commit is contained in:
+10
-6
@@ -478,7 +478,15 @@ func (ctx *restoreContext) getNamespaceFilter(namespace string) *resolvedNamespa
|
||||
return filter
|
||||
}
|
||||
|
||||
// 2. Walk patterns in definition order (first-match semantics)
|
||||
// 2. Check for exact match first (O(1) map lookup)
|
||||
// This ensures exact namespace matches take precedence over globs,
|
||||
// regardless of where they are listed in the configuration.
|
||||
if filter, ok := ctx.namespacedFilterMap[namespace]; ok {
|
||||
ctx.namespaceFilterCache[namespace] = filter
|
||||
return filter
|
||||
}
|
||||
|
||||
// 3. Walk patterns in definition order using pre-compiled globs
|
||||
// Note: namespaceFilterCache is mutated below without synchronization. This is safe
|
||||
// today because resource collection runs sequentially. If the restore loop is
|
||||
// parallelized in the future, these map writes will need a lock to prevent data races.
|
||||
@@ -489,14 +497,10 @@ func (ctx *restoreContext) getNamespaceFilter(namespace string) *resolvedNamespa
|
||||
ctx.namespaceFilterCache[namespace] = filter
|
||||
return filter
|
||||
}
|
||||
} else if p.pattern == namespace {
|
||||
filter := ctx.namespacedFilterMap[p.pattern]
|
||||
ctx.namespaceFilterCache[namespace] = filter
|
||||
return filter
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Cache the miss so we don't re-evaluate failed matches
|
||||
// 4. Cache the miss so we don't re-evaluate failed matches
|
||||
ctx.namespaceFilterCache[namespace] = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ namespacedFilterPolicies:
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "namespaced filter policy with glob namespace match and first-match semantics",
|
||||
name: "namespaced filter policy with exact match priority over glob (glob listed first)",
|
||||
restore: defaultRestore().Result(),
|
||||
backup: defaultBackup().Result(),
|
||||
policyYAML: `version: v1
|
||||
@@ -94,7 +94,43 @@ namespacedFilterPolicies:
|
||||
test.Pods(),
|
||||
},
|
||||
want: map[*test.APIResource][]string{
|
||||
test.Pods(): {"ns-1/pod-1", "ns-2/pod-1"},
|
||||
test.Pods(): {"ns-1/pod-2", "ns-2/pod-1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "namespaced filter policy with exact match priority over glob (exact listed first)",
|
||||
restore: defaultRestore().Result(),
|
||||
backup: defaultBackup().Result(),
|
||||
policyYAML: `version: v1
|
||||
namespacedFilterPolicies:
|
||||
- namespaces:
|
||||
- ns-1
|
||||
resourceFilters:
|
||||
- kinds:
|
||||
- pods
|
||||
names:
|
||||
- pod-2
|
||||
- namespaces:
|
||||
- ns-*
|
||||
resourceFilters:
|
||||
- kinds:
|
||||
- pods
|
||||
names:
|
||||
- pod-1
|
||||
`,
|
||||
tarball: test.NewTarWriter(t).
|
||||
AddItems("pods",
|
||||
builder.ForPod("ns-1", "pod-1").Result(),
|
||||
builder.ForPod("ns-1", "pod-2").Result(),
|
||||
builder.ForPod("ns-2", "pod-1").Result(),
|
||||
builder.ForPod("ns-2", "pod-2").Result(),
|
||||
).
|
||||
Done(),
|
||||
apiResources: []*test.APIResource{
|
||||
test.Pods(),
|
||||
},
|
||||
want: map[*test.APIResource][]string{
|
||||
test.Pods(): {"ns-1/pod-2", "ns-2/pod-1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user