Add docs, example ConfigMap, describer, and review fixes

- Add Default Resource Modifiers section to restore-resource-modifiers.md
- Add --default-resource-modifier-configmap to customize-installation.md
- Add examples/default-resource-modifier-cni.yaml with CNI annotation
  stripping rules for OVN-K and Multus
- Update restore describer to show SkipDefaultResourceModifier when set
- Log warning when ResourceModifier Kind is not ConfigMap instead of
  silently doing nothing
- Add deployment_test.go coverage for the new server flag

Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
This commit is contained in:
Shubham Pampattiwar
2026-08-03 13:19:48 -07:00
parent a6f800c591
commit 2be71e3c3b
6 changed files with 74 additions and 1 deletions
@@ -0,0 +1,18 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: default-restore-resource-modifiers
namespace: velero
data:
resource-modifiers.yaml: |
version: v1
resourceModifierRules:
- conditions:
groupResource: pods
mergePatches:
- patchData: |
metadata:
annotations:
k8s.ovn.org/pod-networks: null
k8s.v1.cni.cncf.io/network-status: null
k8s.v1.cni.cncf.io/networks-status: null
+4
View File
@@ -219,6 +219,10 @@ func DescribeRestore(
DescribeResourceModifier(d, restore.Spec.ResourceModifier)
}
if boolptr.IsSetToTrue(restore.Spec.SkipDefaultResourceModifier) {
d.Printf("Skip Default Resource Modifier:\ttrue\n")
}
if restore.Spec.ResourcePolicy != nil {
d.Println()
DescribeResourcePolicies(d, restore.Spec.ResourcePolicy)
+2
View File
@@ -441,6 +441,8 @@ func (r *restoreReconciler) validateAndComplete(ctx context.Context, restore *ap
if resourceModifiers == nil && len(restore.Status.ValidationErrors) > 0 {
return backupInfo{}, nil, nil
}
} else {
r.logger.Warnf("Unsupported resource modifier kind %q, only %q is supported", restore.Spec.ResourceModifier.Kind, resourcemodifiers.ConfigmapRefType)
}
} else if r.defaultResourceModifierConfigMap != "" && !boolptr.IsSetToTrue(restore.Spec.SkipDefaultResourceModifier) {
resourceModifiers = r.loadResourceModifierConfigMap(ctx, restore, r.defaultResourceModifierConfigMap, true)
+4
View File
@@ -109,6 +109,10 @@ func TestDeployment(t *testing.T) {
assert.Len(t, deploy.Spec.Template.Spec.Containers[0].Args, 2)
assert.Equal(t, "--repo-maintenance-job-configmap=test-repo-maintenance-config", deploy.Spec.Template.Spec.Containers[0].Args[1])
deploy = Deployment("velero", WithDefaultResourceModifierConfigMap("default-restore-modifiers"))
assert.Len(t, deploy.Spec.Template.Spec.Containers[0].Args, 2)
assert.Equal(t, "--default-resource-modifier-configmap=default-restore-modifiers", deploy.Spec.Template.Spec.Containers[0].Args[1])
assert.Equal(t, &corev1api.Affinity{
NodeAffinity: &corev1api.NodeAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: &corev1api.NodeSelector{
@@ -501,6 +501,7 @@ By far, `velero install` supports the following parameters to specify the extern
* --backup-repository-configmap: [backup repository configuration document][15]
* --node-agent-configmap: [node-agent concurrency configuration document][16], and there are some other documents specify other parts of node-agent-config.
* --repo-maintenance-job-configmap: [repository maintenance configuration document][17]
* --default-resource-modifier-configmap: [default restore resource modifier document][18]. When set, the referenced ConfigMap's resource modifier rules apply automatically to all restores that don't specify a per-restore modifier.
From v1.17, Velero adds verification for the ConfigMaps in CLI and server side, which means `velero install` CLI will fail and velero server and node-agent pod will exit if the specified ConfigMaps don't exist or are invalid.
@@ -539,3 +540,4 @@ The new workflow is:
[15]: backup-repository-configuration.md
[16]: node-agent-concurrency.md
[17]: repository-maintenance.md
[18]: restore-resource-modifiers.md#default-resource-modifiers
@@ -184,4 +184,47 @@ resourceModifierRules:
### Wildcard Support for GroupResource
The user can specify a wildcard for groupResource in the conditions' struct. This will allow the user to apply the patches for all the resources of a particular group or all resources in all groups. For example, `*.apps` will apply to all the resources in the `apps` group, `*` will apply to all the resources in core group, `*.*` will apply to all the resources in all groups.
- If both `*.groupName` and `namespaces` are specified, the patches will be applied to all the namespaced resources in this group in the specified namespaces and all the cluster resources in this group.
- If both `*.groupName` and `namespaces` are specified, the patches will be applied to all the namespaced resources in this group in the specified namespaces and all the cluster resources in this group.
## Default Resource Modifiers
Velero supports a server-level default resource modifier that applies automatically to all restores without requiring per-restore configuration.
This is useful for common transformations like stripping stale CNI annotations that can break workloads after restore.
### Configuration
1. Create a ConfigMap in the Velero namespace with your default resource modifier rules:
```bash
kubectl apply -f examples/default-resource-modifier-cni.yaml
```
2. Configure the Velero server to use it, either during install:
```bash
velero install --default-resource-modifier-configmap=default-restore-resource-modifiers ...
```
Or by editing an existing deployment:
```bash
kubectl -n velero edit deploy velero
# Add to the server args: --default-resource-modifier-configmap=default-restore-resource-modifiers
```
### Precedence
When a per-restore modifier is specified via `--resource-modifier-configmap`, it takes exclusive precedence and the default is not applied.
### Opt-out
To skip the default modifier for a specific restore without specifying a per-restore modifier:
```bash
velero restore create --from-backup my-backup --skip-default-resource-modifier
```
### Error Handling
If the default ConfigMap is missing or contains invalid data, Velero logs a warning and proceeds with the restore.
Per-restore modifier errors remain fatal and cause the restore to fail validation.