mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-04-24 17:50:34 +00:00
Enhance wildcard namespace support design document
- Expanded the design to include detailed implementation steps for wildcard expansion in both backup and restore operations. - Added new status fields to the backup and restore CRDs to track expanded wildcard namespaces. - Clarified the approach to ensure backward compatibility with existing `*` behavior. - Addressed limitations and provided insights on restore operations handling wildcard-expanded backups. This update aims to provide a comprehensive and clear framework for implementing wildcard namespace support in Velero. Signed-off-by: Joseph <jvaikath@redhat.com>
This commit is contained in:
@@ -3,9 +3,9 @@
|
||||
|
||||
## Abstract
|
||||
|
||||
Velero currently does not support wildcard characters in namespace specifications, requiring all namespaces to be specified as string literals. The only exception is the standalone `*` character, which includes all namespaces and ignores excludes.
|
||||
Velero currently does not support wildcard characters in namespace specifications, requiring all namespaces to be specified as string literals. The only exception is the standalone "*" character, which includes all namespaces and ignores excludes.
|
||||
|
||||
This document details the approach to implementing wildcard namespace support for `--include-namespaces` and `--exclude-namespaces` flags, while preserving the existing `*` behavior for backward compatibility.
|
||||
This document details the approach to implementing wildcard namespace support for `--include-namespaces` and `--exclude-namespaces` flags, while preserving the existing "*" behavior for backward compatibility.
|
||||
|
||||
## Background
|
||||
|
||||
@@ -13,17 +13,19 @@ This feature was requested in Issue [#1874](https://github.com/vmware-tanzu/vele
|
||||
|
||||
## Goals
|
||||
|
||||
- Add support for wildcard patterns in `--include-namespaces` and `--exclude-namespaces` flags
|
||||
- Ensure legacy `*` behavior remains unchanged for backward compatibility
|
||||
- Add support for wildcard patterns in `--include-namespaces` and `--exclude-namespaces` flags for both backup and restore
|
||||
- Ensure legacy "*" behavior remains unchanged for backward compatibility
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Completely rethinking the way `*` is treated and allowing it to work with wildcard excludes
|
||||
- Completely rethinking the way "*" is treated and allowing it to work with wildcard excludes
|
||||
- Supporting complex regex patterns beyond basic glob patterns
|
||||
|
||||
|
||||
## High-Level Design
|
||||
|
||||
## Backup
|
||||
|
||||
The wildcard expansion implementation focuses on two key functions in `pkg/backup/item_collector.go`:
|
||||
|
||||
- [`collectNamespaces`](https://github.com/vmware-tanzu/velero/blob/1535afb45e33a3d3820088e4189800a21ba55293/pkg/backup/item_collector.go#L742) - Retrieves all active namespaces and processes include/exclude filters
|
||||
@@ -37,32 +39,52 @@ The `collectNamespaces` function is the ideal integration point because it:
|
||||
|
||||
This approach ensures wildcard namespaces are handled consistently with the existing "*" behavior, bypassing individual namespace existence checks.
|
||||
|
||||
## Restore
|
||||
|
||||
The wildcard expansion implementation for restore operations focuses on the main execution flow in `pkg/restore/restore.go`:
|
||||
|
||||
- [`execute`](https://github.com/vmware-tanzu/velero/blob/main/pkg/restore/restore.go#L430) - Main restore execution that parses backup contents and processes namespace filters
|
||||
- [`extractNamespacesFromBackup`](https://github.com/vmware-tanzu/velero/blob/main/pkg/restore/restore.go#L2407) - Extracts available namespaces from backup tar contents
|
||||
|
||||
The `execute` function is the ideal integration point because it:
|
||||
- Already parses the backup tar file to understand available resources
|
||||
- Processes the user-specified namespace filters for the restore operation
|
||||
- Can expand wildcard patterns against namespaces that actually exist in the backup
|
||||
- Stores the resolved namespaces in new restore status fields for visibility
|
||||
|
||||
This approach ensures wildcard namespaces in restore operations are based on actual backup contents rather than original backup specifications, providing safety and consistency regardless of how the backup was created.
|
||||
|
||||
## Detailed Design
|
||||
|
||||
The implementation involves four main components that can be developed incrementally:
|
||||
|
||||
### Add new status fields to the backup CRD to store expanded wildcard namespaces
|
||||
### Add new status fields to the backup and restore CRDs to store expanded wildcard namespaces
|
||||
|
||||
```go
|
||||
// BackupStatus captures the current status of a Velero backup.
|
||||
type BackupStatus struct {
|
||||
// ... existing fields ...
|
||||
|
||||
// ExpandedIncludedNamespaces records the expanded include wildcard namespaces
|
||||
// IncludeWildcardMatches records the expanded include wildcard namespaces
|
||||
// +optional
|
||||
// +nullable
|
||||
ExpandedIncludedNamespaces []string `json:"expandedIncludedNamespaces,omitempty"`
|
||||
IncludeWildcardMatches []string `json:"includeWildcardMatches,omitempty"`
|
||||
|
||||
// ExpandedExcludedNamespaces records the expanded exclude wildcard namespaces
|
||||
// ExcludeWildcardMatches records the expanded exclude wildcard namespaces
|
||||
// +optional
|
||||
// +nullable
|
||||
ExpandedExcludedNamespaces []string `json:"expandedExcludedNamespaces,omitempty"`
|
||||
ExcludeWildcardMatches []string `json:"excludeWildcardMatches,omitempty"`
|
||||
|
||||
// WildcardResult records the final namespaces after applying wildcard include/exclude logic
|
||||
// +optional
|
||||
// +nullable
|
||||
WildcardResult []string `json:"wildcardResult,omitempty"`
|
||||
|
||||
// ... other fields ...
|
||||
}
|
||||
```
|
||||
|
||||
**Implementation**: Added status fields `ExpandedIncludedNamespaces` and `ExpandedExcludedNamespaces` to `pkg/apis/velero/v1/backup_types.go` to track the resolved namespace lists after wildcard expansion.
|
||||
**Implementation**: Added status fields `IncludeWildcardMatches`, `ExcludeWildcardMatches`, and `WildcardResult` to `pkg/apis/velero/v1/backup_types.go` and `pkg/apis/velero/v1/restore_types.go` to track the resolved namespace lists after wildcard expansion.
|
||||
|
||||
### Create a util package for wildcard expansion
|
||||
|
||||
@@ -84,6 +106,8 @@ type BackupStatus struct {
|
||||
|
||||
### If required, expand wildcards and replace the request's includes and excludes with expanded namespaces
|
||||
|
||||
### Backup:
|
||||
|
||||
**Implementation**: In `pkg/backup/item_collector.go`:
|
||||
|
||||
```go
|
||||
@@ -102,17 +126,55 @@ The expansion occurs when collecting namespaces, after retrieving all active nam
|
||||
|
||||
**Performance Improvement**: As part of this implementation, active namespaces are stored in a hashset rather than being iterated for each resolved/literal namespace check. This eliminates a [nested loop anti-pattern](https://github.com/vmware-tanzu/velero/blob/1535afb45e33a3d3820088e4189800a21ba55293/pkg/backup/item_collector.go#L767) and improves performance.
|
||||
|
||||
### Restore
|
||||
|
||||
**Implementation**: In `pkg/restore/restore.go`:
|
||||
|
||||
```go
|
||||
// Lines 478-509: Wildcard expansion in restore context
|
||||
if wildcard.ShouldExpandWildcards(ctx.restore.Spec.IncludedNamespaces, ctx.restore.Spec.ExcludedNamespaces) {
|
||||
availableNamespaces := extractNamespacesFromBackup(backupResources)
|
||||
expandedIncludes, expandedExcludes, err := wildcard.ExpandWildcards(
|
||||
availableNamespaces,
|
||||
ctx.restore.Spec.IncludedNamespaces,
|
||||
ctx.restore.Spec.ExcludedNamespaces,
|
||||
)
|
||||
// Update restore context with expanded patterns
|
||||
ctx.namespaceIncludesExcludes = collections.NewIncludesExcludes().
|
||||
Includes(expandedIncludes...).
|
||||
Excludes(expandedExcludes...)
|
||||
}
|
||||
```
|
||||
|
||||
The restore expansion occurs after parsing the backup tar contents, using `extractNamespacesFromBackup` to determine which namespaces are actually available for restoration. This ensures wildcard patterns are applied against materialized backup contents rather than original backup specifications.
|
||||
|
||||
|
||||
|
||||
### Populate the expanded namespace status field with the namespaces
|
||||
|
||||
#### Backup Status Fields
|
||||
|
||||
**Implementation**: In `expandNamespaceWildcards` function (line 889-891):
|
||||
|
||||
```go
|
||||
// Record the expanded wildcard includes/excludes in the request status
|
||||
r.backupRequest.Status.ExpandedIncludedNamespaces = expandedIncludes
|
||||
r.backupRequest.Status.ExpandedExcludedNamespaces = expandedExcludes
|
||||
r.backupRequest.Status.IncludeWildcardMatches = expandedIncludes
|
||||
r.backupRequest.Status.ExcludeWildcardMatches = expandedExcludes
|
||||
r.backupRequest.Status.WildcardResult = wildcardResult
|
||||
```
|
||||
|
||||
The status fields are populated immediately after successful wildcard expansion, providing visibility into which namespaces were actually matched by the wildcard patterns.
|
||||
#### Restore Status Fields
|
||||
|
||||
**Implementation**: In `pkg/restore/restore.go` (lines 499-502):
|
||||
|
||||
```go
|
||||
// Record the expanded wildcard includes/excludes in the restore status
|
||||
ctx.restore.Status.IncludeWildcardMatches = expandedIncludes
|
||||
ctx.restore.Status.ExcludeWildcardMatches = expandedExcludes
|
||||
ctx.restore.Status.WildcardResult = wildcardResult
|
||||
```
|
||||
|
||||
The status fields are populated immediately after successful wildcard expansion, providing visibility into which namespaces were actually matched by the wildcard patterns and the final list of namespaces that will be processed.
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
@@ -141,14 +203,14 @@ This feature does not introduce any security vulnerabilities as it only affects
|
||||
### Backward Compatibility
|
||||
|
||||
The implementation maintains full backward compatibility with existing behavior:
|
||||
- The standalone `*` character continues to work as before (include all namespaces, ignore excludes)
|
||||
- The standalone "*" character continues to work as before (include all namespaces, ignore excludes)
|
||||
- Existing backup configurations remain unaffected
|
||||
|
||||
### Known Limitations
|
||||
|
||||
1. **Mixed `*` and wildcard usage**: When using the standalone `*` in includes, the legacy implementation takes precedence and wildcard expansion is skipped. This means you cannot combine "*" (all namespaces) in includes with wildcard patterns in excludes.
|
||||
1. **Mixed "*" and wildcard usage**: When using the standalone "*" in includes, the legacy implementation takes precedence and wildcard expansion is skipped. This means you cannot combine "*" (all namespaces) in includes with wildcard patterns in excludes.
|
||||
|
||||
2. **Selective exclusion limitation**: The current design does not support selective pattern-based exclusion when including all namespaces via `*`.
|
||||
2. **Selective exclusion limitation**: The current design does not support selective pattern-based exclusion when including all namespaces via "*".
|
||||
|
||||
## Implementation
|
||||
|
||||
@@ -161,4 +223,6 @@ The implementation follows the detailed design outlined above, with the followin
|
||||
|
||||
## Open Issues
|
||||
|
||||
**Restore Integration**: Currently investigating how restore operations should handle wildcard-expanded backups. The proposed approach is to apply wildcard patterns against the expanded namespace list stored in the backup's status fields, ensuring consistency between backup and restore operations.
|
||||
**Restore Integration**: Restore operations are completely decoupled from backup wildcard specifications and work safely with wildcard-created backups. The restore process reads the actual tar file contents to determine available namespaces, not the original backup spec. Since the tar file contains real, materialized namespaces (e.g., `test01`, `test02`) rather than wildcard patterns (e.g., `test*`), restore operations work with concrete namespace names.
|
||||
|
||||
When wildcard patterns are specified in restore operations, they are expanded against the namespaces that actually exist in the backup tar file. This ensures that restore wildcard expansion is based on what was actually backed up, not what was originally intended to be backed up.
|
||||
|
||||
Reference in New Issue
Block a user