diff --git a/changelogs/unreleased/6968-blackpiglet b/changelogs/unreleased/6968-blackpiglet new file mode 100644 index 000000000..9a3461f24 --- /dev/null +++ b/changelogs/unreleased/6968-blackpiglet @@ -0,0 +1 @@ +Check whether the action is a CSI action and whether CSI feature is enabled, before executing the action. \ No newline at end of file diff --git a/internal/delete/delete_item_action_handler.go b/internal/delete/delete_item_action_handler.go index d85df8a6a..ba242c0ca 100644 --- a/internal/delete/delete_item_action_handler.go +++ b/internal/delete/delete_item_action_handler.go @@ -119,6 +119,7 @@ func InvokeDeleteActions(ctx *Context) error { if !action.Selector.Matches(labels.Set(obj.GetLabels())) { continue } + err = action.DeleteItemAction.Execute(&velero.DeleteItemActionExecuteInput{ Item: obj, Backup: ctx.Backup, diff --git a/pkg/backup/backup_test.go b/pkg/backup/backup_test.go index c0642f818..e9c15dbc4 100644 --- a/pkg/backup/backup_test.go +++ b/pkg/backup/backup_test.go @@ -46,6 +46,7 @@ import ( "github.com/vmware-tanzu/velero/pkg/builder" "github.com/vmware-tanzu/velero/pkg/client" "github.com/vmware-tanzu/velero/pkg/discovery" + "github.com/vmware-tanzu/velero/pkg/features" "github.com/vmware-tanzu/velero/pkg/itemoperation" "github.com/vmware-tanzu/velero/pkg/kuberesource" "github.com/vmware-tanzu/velero/pkg/plugin/velero" @@ -1379,6 +1380,12 @@ func TestBackupItemActionsForSkippedPV(t *testing.T) { expectNotSkippedPVs: []string{"pv-1"}, }, } + // Enable CSI feature before running the test, because Velero will check whether + // CSI feature is enabled before executing CSI plugin actions. + features.NewFeatureFlagSet("EnableCSI") + defer func() { + features.NewFeatureFlagSet("") + }() for _, tc := range tests { t.Run(tc.name, func(tt *testing.T) { var ( diff --git a/pkg/backup/item_backupper.go b/pkg/backup/item_backupper.go index ddee9a0cb..61f6834d6 100644 --- a/pkg/backup/item_backupper.go +++ b/pkg/backup/item_backupper.go @@ -52,6 +52,7 @@ import ( vsv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v1" "github.com/vmware-tanzu/velero/pkg/podvolume" "github.com/vmware-tanzu/velero/pkg/util/boolptr" + csiutil "github.com/vmware-tanzu/velero/pkg/util/csi" pdvolumeutil "github.com/vmware-tanzu/velero/pkg/util/podvolume" "github.com/vmware-tanzu/velero/pkg/volume" ) @@ -361,6 +362,14 @@ func (ib *itemBackupper) executeActions( ib.trackSkippedPV(obj, groupResource, "", "skipped due to resource policy ", log) continue } + + // If the EnableCSI feature is not enabled, but the executing action is from CSI plugin, skip the action. + if csiutil.ShouldSkipAction(actionName) { + log.Infof("Skip action %s for resource %s:%s/%s, because the CSI feature is not enabled. Feature setting is %s.", + actionName, groupResource.String(), metadata.GetNamespace(), metadata.GetName(), features.Serialize()) + continue + } + updatedItem, additionalItemIdentifiers, operationID, postOperationItems, err := action.Execute(obj, ib.backupRequest.Backup) if err != nil { return nil, itemFiles, errors.Wrapf(err, "error executing custom action (groupResource=%s, namespace=%s, name=%s)", groupResource.String(), namespace, name) @@ -652,6 +661,7 @@ func (ib *itemBackupper) getMatchAction(obj runtime.Unstructured, groupResource } return ib.backupRequest.ResPolicies.GetMatchAction(pv) } + return nil, nil } diff --git a/pkg/cmd/server/server.go b/pkg/cmd/server/server.go index bde964aad..749520666 100644 --- a/pkg/cmd/server/server.go +++ b/pkg/cmd/server/server.go @@ -73,6 +73,7 @@ import ( "github.com/vmware-tanzu/velero/pkg/persistence" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/podexec" "github.com/vmware-tanzu/velero/pkg/podvolume" "github.com/vmware-tanzu/velero/pkg/repository" @@ -309,6 +310,13 @@ func newServer(f client.Factory, config serverConfig, logger *logrus.Logger) (*s return nil, err } + if !features.IsEnabled(velerov1api.CSIFeatureFlag) { + _, err = pluginRegistry.Get(common.PluginKindBackupItemActionV2, "velero.io/csi-pvc-backupper") + if err == nil { + logger.Warn("CSI plugins are registered, but the EnableCSI feature is not enabled.") + } + } + // cancelFunc is not deferred here because if it was, then ctx would immediately // be canceled once this function exited, making it useless to any informers using later. // That, in turn, causes the velero server to halt when the first informer tries to use it. diff --git a/pkg/restore/restore.go b/pkg/restore/restore.go index 835553330..bc7a97a08 100644 --- a/pkg/restore/restore.go +++ b/pkg/restore/restore.go @@ -68,6 +68,7 @@ import ( "github.com/vmware-tanzu/velero/pkg/podvolume" "github.com/vmware-tanzu/velero/pkg/util/boolptr" "github.com/vmware-tanzu/velero/pkg/util/collections" + csiutil "github.com/vmware-tanzu/velero/pkg/util/csi" "github.com/vmware-tanzu/velero/pkg/util/filesystem" "github.com/vmware-tanzu/velero/pkg/util/kube" "github.com/vmware-tanzu/velero/pkg/util/results" @@ -1337,6 +1338,13 @@ func (ctx *restoreContext) restoreItem(obj *unstructured.Unstructured, groupReso continue } + // If the EnableCSI feature is not enabled, but the executing action is from CSI plugin, skip the action. + if csiutil.ShouldSkipAction(action.Name()) { + ctx.log.Infof("Skip action %s for resource %s:%s/%s, because the CSI feature is not enabled. Feature setting is %s.", + action.Name(), groupResource.String(), obj.GetNamespace(), obj.GetName(), features.Serialize()) + continue + } + ctx.log.Infof("Executing item action for %v", &groupResource) executeOutput, err := action.RestoreItemAction.Execute(&velero.RestoreItemActionExecuteInput{ Item: obj, diff --git a/pkg/util/csi/util.go b/pkg/util/csi/util.go new file mode 100644 index 000000000..bcc424d1b --- /dev/null +++ b/pkg/util/csi/util.go @@ -0,0 +1,32 @@ +/* +Copyright The Velero Contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package csi + +import ( + "strings" + + velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" + "github.com/vmware-tanzu/velero/pkg/features" +) + +const ( + csiPluginNamePrefix = "velero.io/csi-" +) + +func ShouldSkipAction(actionName string) bool { + return !features.IsEnabled(velerov1api.CSIFeatureFlag) && strings.Contains(actionName, csiPluginNamePrefix) +} diff --git a/pkg/util/csi/util_test.go b/pkg/util/csi/util_test.go new file mode 100644 index 000000000..a9b0a37aa --- /dev/null +++ b/pkg/util/csi/util_test.go @@ -0,0 +1,36 @@ +/* +Copyright The Velero Contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package csi + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/vmware-tanzu/velero/pkg/features" +) + +func TestCSIFeatureNotEnabledAndPluginIsFromCSI(t *testing.T) { + + features.NewFeatureFlagSet("EnableCSI") + require.False(t, ShouldSkipAction("abc")) + require.False(t, ShouldSkipAction("velero.io/csi-pvc-backupper")) + + features.NewFeatureFlagSet("") + require.True(t, ShouldSkipAction("velero.io/csi-pvc-backupper")) + require.False(t, ShouldSkipAction("abc")) +}