You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: design/namespace-label-selector-in-resource-policy_design.md
+61-28Lines changed: 61 additions & 28 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,15 +1,31 @@
1
1
# Namespace Selection by Label in Resource Policy
2
2
3
+
## Glossary & Abbreviation
4
+
5
+
**Backup Filter**: The mechanism in Velero that determines which Kubernetes resources are collected from the cluster and written into the backup archive. Backup filters currently operate on four dimensions: namespace, resource type, label, and cluster scope.
6
+
**Global Filter**: A filter that applies uniformly across all namespaces in a backup. All existing Velero backup filters are global filters.
7
+
**Namespace Label Selector Filter**: A filter that dynamically includes or excludes entire namespaces from a backup based on Kubernetes label selectors applied to namespace objects. This is the capability introduced by this design.
8
+
**Resource Policy**: An existing Velero mechanism where backup behavior rules are defined in a ConfigMap and referenced from `BackupSpec.ResourcePolicy`. Currently used for volume policies and global include/exclude policies.
9
+
3
10
## Abstract
4
11
5
-
This proposal extends Velero's `includeExcludePolicy` in the ResourcePolicy configmap to support selecting namespaces by Kubernetes label selectors.
6
-
Users can dynamically include or exclude namespaces from backups without modifying backup or schedule specs.
12
+
This proposal extends Velero's `includeExcludePolicy` in the ResourcePolicy ConfigMap to support selecting namespaces by Kubernetes label selectors.
13
+
Users can dynamically include or exclude namespaces from backups without modifying `BackupSpec` or schedule specs.
7
14
8
15
## Background
9
16
17
+
Velero's backup filter system allows users to specify which resources to include or exclude from a backup. The filters operate on four dimensions:
18
+
19
+
1.**Namespace** — `IncludedNamespaces`/`ExcludedNamespaces` select which namespaces to back up
20
+
2.**Resource Type** — `IncludedResources`/`ExcludedResources` (or the newer scoped variants `Included/ExcludedClusterScopedResources`, `Included/ExcludedNamespaceScopedResources`) select which Kubernetes resource types to back up
21
+
3.**Labels** — `LabelSelector`/`OrLabelSelectors` filter individual objects by their labels
22
+
4.**Cluster Scope** — `IncludeClusterResources` controls whether cluster-scoped resources are included
23
+
24
+
All four dimensions are applied **globally** — the same filters apply uniformly throughout the entire backup operation. There is no mechanism to dynamically resolve which namespaces to include based on namespace labels.
25
+
10
26
Users managing many clusters or dynamic namespace sets need a way to declare "back up namespaces labeled `backup=weekly`" without enumerating names.
11
-
Issue [#7492](https://github.com/vmware-tanzu/velero/issues/7492) originally proposed extending `--selector` on the Backup, but the community preferred not to overload existing filters.
12
-
The agreed direction is to model namespace selection by label as a `ResourcePolicy` capability, extending `includeExcludePolicy` rather than adding new fields to `BackupSpec`.
27
+
Issue [#7492](https://github.com/vmware-tanzu/velero/issues/7492) originally proposed extending `--selector` on the Backup, but the community preferred not to overload existing backup filters.
28
+
The agreed direction is to model namespace selection by label as a Resource Policy capability, extending `includeExcludePolicy` rather than adding new fields to `BackupSpec`.
13
29
14
30
The existing `includeExcludePolicy` already holds reusable include/exclude resource filters.
15
31
Adding namespace label selectors here is consistent with its purpose and avoids spec sprawl.
@@ -18,11 +34,12 @@ Adding namespace label selectors here is consistent with its purpose and avoids
18
34
19
35
- Allow users to specify Kubernetes label selectors in `includeExcludePolicy` to dynamically include or exclude namespaces in a backup.
20
36
21
-
## NonGoals
37
+
## Non-Goals
22
38
23
-
- Changing the behavior of `backup.spec.labelSelector` or `backup.spec.orLabelSelectors` (those continue to filter individual resources, not namespaces).
24
-
- Selecting cluster-scoped resources by label (a separate concern).
39
+
- Changing the behavior of `BackupSpec.LabelSelector` or `BackupSpec.OrLabelSelectors` (those continue to filter individual resources, not namespaces).
40
+
- Selecting cluster-scoped resources by label (a separate concern; see [Fine Grained Backup Filters](backup-filter-enhancement/fine-grained-backup-filters-design.md) for cluster-scoped resource filtering).
25
41
- Selecting individual namespaced resources by namespace label (resources must still be individually matched).
42
+
- Changing existing `BackupSpec` fields (`IncludedResources`, `LabelSelector`, etc.) or adding new CRD fields is explicitly avoided by this design.
26
43
27
44
## Use Cases
28
45
@@ -75,14 +92,16 @@ includeExcludePolicy:
75
92
76
93
## High-Level Design
77
94
78
-
Two new fields, `includedNamespacesByLabel` and `excludedNamespacesByLabel`, are added to `IncludeExcludePolicy`.
95
+
Two new fields, `includedNamespacesByLabel` and `excludedNamespacesByLabel`, are added to `IncludeExcludePolicy` in the ResourcePolicy ConfigMap.
79
96
Each field is a list of Kubernetes label selector strings (same syntax as `kubectl get ns -l`).
80
97
81
98
At backup time, after existing namespace filters are resolved, Velero evaluates each selector against the live namespace list.
82
99
The union of namespaces matched by all `includedNamespacesByLabel` selectors is added to the effective included namespace set.
83
100
Namespaces matched by any `excludedNamespacesByLabel` selector are removed from that set.
84
101
The final set is stored in `backup.status.includedNamespaces` so users can observe which namespaces were actually selected.
85
102
103
+
This design coexists with the existing `includeExcludePolicy` fields (`includedClusterScopedResources`, `excludedClusterScopedResources`, `includedNamespaceScopedResources`, `excludedNamespaceScopedResources`) and is independent of the `namespacedFilterPolicies` and `fineGrainedGlobalFilterPolicy` sections described in the [Fine Grained Backup Filters](backup-filter-enhancement/fine-grained-backup-filters-design.md) design.
104
+
86
105
## Detailed Design
87
106
88
107
### Data Structure
@@ -105,7 +124,7 @@ Each entry in `includedNamespacesByLabel` / `excludedNamespacesByLabel` is a lab
105
124
Multiple entries within the same list are combined with OR (union): a namespace matching any selector in the list is included/excluded.
106
125
Within a single selector string, comma-separated requirements are AND.
Where `resolvedExcludedByLabel` excludes take precedence over both `backup.spec.includedNamespaces` and `resolvedIncludedByLabel`.
192
-
This ensures an operator can always exclude sensitive namespaces regardless of what the backup spec says.
210
+
Where `resolvedExcludedByLabel` excludes take precedence over both `BackupSpec.IncludedNamespaces` and `resolvedIncludedByLabel`.
211
+
This ensures an operator can always exclude sensitive namespaces regardless of what the `BackupSpec` says.
193
212
194
-
`backup.spec.labelSelector`and `backup.spec.orLabelSelectors` are unaffected — they continue to select individual resources, not namespaces.
213
+
The `velero.io/exclude-from-backup=true` label always takes precedence over all filters, regardless of whether the namespace matches global or label-resolved filters.
214
+
215
+
`BackupSpec.LabelSelector`and `BackupSpec.OrLabelSelectors` are unaffected — they continue to select individual resources, not namespaces.
195
216
196
217
### Observability
197
218
198
219
The resolved namespace list from label selectors is merged into `backup.status.includedNamespaces` so users can see which namespaces were actually backed up.
199
220
200
221
### Limitations
201
222
202
-
`includedNamespacesByLabel`and `excludedNamespacesByLabel` do not interact with the "old" resource filters (`includedResources`, `excludedResources`, `includeClusterResources` in BackupSpec).
203
-
If a backup references a resource policy with `includeExcludePolicy` that contains the new fields AND has old-style resource filters in BackupSpec, the backup fails validation with a clear error — consistent with the existing behavior of `includeExcludePolicy`.
223
+
`includedNamespacesByLabel`and `excludedNamespacesByLabel` do not interact with the old-style global filters (`IncludedResources`/`ExcludedResources`/`IncludeClusterResources` in `BackupSpec`).
224
+
If a backup references a ResourcePolicy ConfigMap with `includeExcludePolicy` that contains the new fields AND has old-style resource filters in `BackupSpec`, the backup fails validation with a clear error — consistent with the existing behavior of `includeExcludePolicy`.
225
+
226
+
**Interaction with `namespacedFilterPolicies`**: If a ResourcePolicy ConfigMap contains both `includedNamespacesByLabel`/`excludedNamespacesByLabel` (from this design) and `namespacedFilterPolicies` (from the [Fine Grained Backup Filters](backup-filter-enhancement/fine-grained-backup-filters-design.md) design), the namespace label selectors determine which namespaces are included in the backup, while `namespacedFilterPolicies` determines which resources within those namespaces are collected. The two mechanisms operate at different levels and are complementary.
204
227
205
228
## Alternatives Considered
206
229
207
-
### Modify backup.spec.labelSelector to select namespaces
230
+
### Modify `BackupSpec.LabelSelector` to select namespaces
208
231
209
-
PR [#9223](https://github.com/vmware-tanzu/velero/pull/9223) proposed treating `labelSelector`-matched namespaces as implicitly included.
210
-
This was a breaking change and made `labelSelector` semantics ambiguous (resource filter vs namespace filter).
232
+
PR [#9223](https://github.com/vmware-tanzu/velero/pull/9223) proposed treating `LabelSelector`-matched namespaces as implicitly included.
233
+
This was a breaking change and made `LabelSelector` semantics ambiguous (resource filter vs namespace filter).
211
234
Closed without merge.
212
235
213
-
### New field on BackupSpec (e.g., `includedNamespacesByLabel`)
236
+
### New CRD field on `BackupSpec` (e.g., `IncludedNamespacesByLabel`)
214
237
215
-
Proposed in community meeting but rejected: the community preferred not to proliferate new fields on BackupSpec when ResourcePolicy already serves this purpose.
238
+
Proposed in community meeting but rejected: the community preferred not to proliferate new fields on `BackupSpec` when ResourcePolicy already serves this purpose. This is consistent with the approach taken by the [Fine Grained Backup Filters](backup-filter-enhancement/fine-grained-backup-filters-design.md) design, which also avoids adding new CRD fields.
216
239
217
240
### New standalone ConfigMap type
218
241
219
-
Adds unnecessary indirection without benefit over extending `includeExcludePolicy`.
242
+
Adds unnecessary indirection without benefit over extending `includeExcludePolicy` in the existing ResourcePolicy ConfigMap.
220
243
221
244
## Security Considerations
222
245
@@ -229,20 +252,30 @@ No new permissions are required by Velero itself — it already has `list` acces
229
252
## Compatibility
230
253
231
254
This is a backwards-compatible additive change.
232
-
Existing resource policy configmaps without the new fields behave identically.
233
-
Existing backups and schedules are unaffected unless they reference a configmap with the new fields.
255
+
Existing ResourcePolicy ConfigMaps without the new fields behave identically.
256
+
Existing backups and schedules are unaffected unless they reference a ConfigMap with the new fields.
234
257
235
258
`backup.status.includedNamespaces`may be populated for the first time in cases where it was previously empty; consumers of this field should handle a non-empty list.
236
259
260
+
Maintain full backward compatibility — existing backups with no `includedNamespacesByLabel`/`excludedNamespacesByLabel` behave exactly as they do today.
261
+
262
+
## User Perspective
263
+
264
+
- **For users not using namespace label selector filters**: Zero changes. All existing backups and workflows continue to work identically. The new YAML fields are optional.
265
+
- **For users adopting namespace label selector filters**: Add `includedNamespacesByLabel` and/or `excludedNamespacesByLabel` to the `includeExcludePolicy` section of the ResourcePolicy ConfigMap, and reference it via `BackupSpec.ResourcePolicy` (or the existing `--resource-policies-configmap` flag). The backup will dynamically resolve which namespaces to include/exclude based on namespace labels at backup time.
266
+
- **For users already using ResourcePolicy for volume policies or include/exclude policies**: Add the new fields to the existing `includeExcludePolicy` section in the same ConfigMap. All sections coexist.
267
+
- **Validation errors**: Reported at backup start when the ResourcePolicy ConfigMap contains invalid label selector strings. Consistent with how other validation errors are reported today.
268
+
237
269
## Implementation
238
270
239
271
1. Add `IncludedNamespacesByLabel` / `ExcludedNamespacesByLabel` fields to `IncludeExcludePolicy`.
240
-
2. Extend `Validate()` to parse and validate selector strings.
272
+
2. Extend `Validate()` to parse and validate selector strings using `k8s.io/apimachinery/pkg/labels.Parse`.
241
273
3. Implement `resolveNamespacesByLabel` helper.
242
274
4. Call resolution in `prepareBackupRequest` and merge results into the effective namespace filter.
243
-
5. Populate `backup.status.includedNamespaces` with the resolved set.
244
-
6. Add unit tests for selector parsing, resolution logic, and precedence rules.
245
-
7. Add E2E test: schedule with no `includedNamespaces`, label selector in resource policy, verify only labeled namespaces are backed up.
275
+
5. Add validation in `backup_controller.go` to ensure `includedNamespacesByLabel`/`excludedNamespacesByLabel` are not used with old-style resource filters (`IncludedResources`/`ExcludedResources`/`IncludeClusterResources`), consistent with the existing check for `includeExcludePolicy`.
276
+
6. Populate `backup.status.includedNamespaces` with the resolved set.
277
+
7. Add unit tests for selector parsing, resolution logic, and precedence rules.
278
+
8. Add E2E test: schedule with no `includedNamespaces`, label selector in resource policy, verify only labeled namespaces are backed up.
0 commit comments