Skip to content

Commit 107ec98

Browse files
kaovilaiclaude
andcommitted
Align terminology with Fine Grained Backup Filters design (PR #9783)
- Add Glossary & Abbreviation section matching PR #9783 style - Use consistent BackupSpec.Field notation throughout - Capitalize ConfigMap consistently - Add cross-references to Fine Grained Backup Filters design - Add User Perspective section - Document velero.io/exclude-from-backup=true precedence - Document interaction with namespacedFilterPolicies - Expand Background with four-dimension filter model from PR #9783 - Non Goals -> Non-Goals Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
1 parent dd541ab commit 107ec98

1 file changed

Lines changed: 61 additions & 28 deletions

File tree

design/namespace-label-selector-in-resource-policy_design.md

Lines changed: 61 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,31 @@
11
# Namespace Selection by Label in Resource Policy
22

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+
310
## Abstract
411

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.
714

815
## Background
916

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+
1026
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`.
1329

1430
The existing `includeExcludePolicy` already holds reusable include/exclude resource filters.
1531
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
1834

1935
- Allow users to specify Kubernetes label selectors in `includeExcludePolicy` to dynamically include or exclude namespaces in a backup.
2036

21-
## Non Goals
37+
## Non-Goals
2238

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).
2541
- 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.
2643

2744
## Use Cases
2845

@@ -75,14 +92,16 @@ includeExcludePolicy:
7592

7693
## High-Level Design
7794

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.
7996
Each field is a list of Kubernetes label selector strings (same syntax as `kubectl get ns -l`).
8097

8198
At backup time, after existing namespace filters are resolved, Velero evaluates each selector against the live namespace list.
8299
The union of namespaces matched by all `includedNamespacesByLabel` selectors is added to the effective included namespace set.
83100
Namespaces matched by any `excludedNamespacesByLabel` selector are removed from that set.
84101
The final set is stored in `backup.status.includedNamespaces` so users can observe which namespaces were actually selected.
85102

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+
86105
## Detailed Design
87106

88107
### Data Structure
@@ -105,7 +124,7 @@ Each entry in `includedNamespacesByLabel` / `excludedNamespacesByLabel` is a lab
105124
Multiple entries within the same list are combined with OR (union): a namespace matching any selector in the list is included/excluded.
106125
Within a single selector string, comma-separated requirements are AND.
107126

108-
Example YAML in ConfigMap:
127+
Example YAML in ResourcePolicy ConfigMap:
109128

110129
```yaml
111130
version: v1
@@ -182,41 +201,45 @@ func resolveNamespacesByLabel(
182201
Final effective namespace set:
183202

184203
```
185-
effective = (backup.spec.includedNamespaces
204+
effective = (BackupSpec.IncludedNamespaces
186205
∪ resolvedIncludedByLabel)
187-
backup.spec.excludedNamespaces
206+
BackupSpec.ExcludedNamespaces
188207
− resolvedExcludedByLabel
189208
```
190209

191-
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.
193212

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.
195216

196217
### Observability
197218

198219
The resolved namespace list from label selectors is merged into `backup.status.includedNamespaces` so users can see which namespaces were actually backed up.
199220

200221
### Limitations
201222

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.
204227

205228
## Alternatives Considered
206229

207-
### Modify backup.spec.labelSelector to select namespaces
230+
### Modify `BackupSpec.LabelSelector` to select namespaces
208231

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).
211234
Closed without merge.
212235

213-
### New field on BackupSpec (e.g., `includedNamespacesByLabel`)
236+
### New CRD field on `BackupSpec` (e.g., `IncludedNamespacesByLabel`)
214237

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.
216239

217240
### New standalone ConfigMap type
218241

219-
Adds unnecessary indirection without benefit over extending `includeExcludePolicy`.
242+
Adds unnecessary indirection without benefit over extending `includeExcludePolicy` in the existing ResourcePolicy ConfigMap.
220243

221244
## Security Considerations
222245

@@ -229,20 +252,30 @@ No new permissions are required by Velero itself — it already has `list` acces
229252
## Compatibility
230253

231254
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.
234257

235258
`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.
236259

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+
237269
## Implementation
238270

239271
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`.
241273
3. Implement `resolveNamespacesByLabel` helper.
242274
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.
246279

247280
## Open Issues
248281

0 commit comments

Comments
 (0)