From 2be71e3c3b113d56156f7b0e05ce2aaaf1638bbf Mon Sep 17 00:00:00 2001 From: Shubham Pampattiwar Date: Tue, 28 Jul 2026 10:58:05 -0700 Subject: [PATCH] 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 --- examples/default-resource-modifier-cni.yaml | 18 ++++++++ pkg/cmd/util/output/restore_describer.go | 4 ++ pkg/controller/restore_controller.go | 2 + pkg/install/deployment_test.go | 4 ++ .../docs/main/customize-installation.md | 2 + .../docs/main/restore-resource-modifiers.md | 45 ++++++++++++++++++- 6 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 examples/default-resource-modifier-cni.yaml diff --git a/examples/default-resource-modifier-cni.yaml b/examples/default-resource-modifier-cni.yaml new file mode 100644 index 000000000..352180f5a --- /dev/null +++ b/examples/default-resource-modifier-cni.yaml @@ -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 diff --git a/pkg/cmd/util/output/restore_describer.go b/pkg/cmd/util/output/restore_describer.go index c33da9f69..e94b2dedd 100644 --- a/pkg/cmd/util/output/restore_describer.go +++ b/pkg/cmd/util/output/restore_describer.go @@ -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) diff --git a/pkg/controller/restore_controller.go b/pkg/controller/restore_controller.go index daf5cbf0c..a7f0f7429 100644 --- a/pkg/controller/restore_controller.go +++ b/pkg/controller/restore_controller.go @@ -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) diff --git a/pkg/install/deployment_test.go b/pkg/install/deployment_test.go index 0cfcb65dd..6e9ff6ec5 100644 --- a/pkg/install/deployment_test.go +++ b/pkg/install/deployment_test.go @@ -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{ diff --git a/site/content/docs/main/customize-installation.md b/site/content/docs/main/customize-installation.md index e42d6a3f8..e9561eea9 100644 --- a/site/content/docs/main/customize-installation.md +++ b/site/content/docs/main/customize-installation.md @@ -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 diff --git a/site/content/docs/main/restore-resource-modifiers.md b/site/content/docs/main/restore-resource-modifiers.md index 0c1f2f217..39248ad30 100644 --- a/site/content/docs/main/restore-resource-modifiers.md +++ b/site/content/docs/main/restore-resource-modifiers.md @@ -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. \ No newline at end of file +- 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. \ No newline at end of file