diff --git a/changelogs/unreleased/8591-reasonerjt b/changelogs/unreleased/8591-reasonerjt new file mode 100644 index 000000000..05c0e20dd --- /dev/null +++ b/changelogs/unreleased/8591-reasonerjt @@ -0,0 +1 @@ +Skip patching the PV in finalization for failed operation \ No newline at end of file diff --git a/pkg/cmd/server/plugin/plugin.go b/pkg/cmd/server/plugin/plugin.go index b0f8aae3f..3fa174d81 100644 --- a/pkg/cmd/server/plugin/plugin.go +++ b/pkg/cmd/server/plugin/plugin.go @@ -21,6 +21,7 @@ import ( "github.com/spf13/cobra" apiextensions "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + "github.com/vmware-tanzu/velero/pkg/constant" "github.com/vmware-tanzu/velero/pkg/datamover" dia "github.com/vmware-tanzu/velero/internal/delete/actions/csi" @@ -162,7 +163,7 @@ func NewCommand(f client.Factory) *cobra.Command { newVolumeSnapshotClassBackupItemAction, ). RegisterRestoreItemActionV2( - "velero.io/csi-pvc-restorer", + constant.PluginCSIPVCRestoreRIA, newPvcRestoreItemAction(f), ). RegisterRestoreItemActionV2( diff --git a/pkg/constant/constant.go b/pkg/constant/constant.go index f8d5b191f..dc2c0e558 100644 --- a/pkg/constant/constant.go +++ b/pkg/constant/constant.go @@ -19,4 +19,6 @@ const ( ControllerSchedule = "schedule" ControllerServerStatusRequest = "server-status-request" ControllerRestoreFinalizer = "restore-finalizer" + + PluginCSIPVCRestoreRIA = "velero.io/csi-pvc-restorer" ) diff --git a/pkg/controller/restore_finalizer_controller.go b/pkg/controller/restore_finalizer_controller.go index d9fa5797a..2caec1788 100644 --- a/pkg/controller/restore_finalizer_controller.go +++ b/pkg/controller/restore_finalizer_controller.go @@ -22,6 +22,12 @@ import ( "sync" "time" + "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/vmware-tanzu/velero/pkg/constant" + "github.com/vmware-tanzu/velero/pkg/itemoperation" + "github.com/vmware-tanzu/velero/pkg/plugin/velero" + storagev1api "k8s.io/api/storage/v1" "github.com/pkg/errors" @@ -155,6 +161,12 @@ func (r *restoreFinalizerReconciler) Reconcile(ctx context.Context, req ctrl.Req restoredPVCList := volume.RestoredPVCFromRestoredResourceList(restoredResourceList) + restoreItemOperations, err := backupStore.GetRestoreItemOperations(restore.Name) + if err != nil { + log.WithError(err).Error("error getting itemOperationList") + return ctrl.Result{}, errors.Wrap(err, "error getting itemOperationList") + } + finalizerCtx := &finalizerContext{ logger: log, restore: restore, @@ -163,6 +175,9 @@ func (r *restoreFinalizerReconciler) Reconcile(ctx context.Context, req ctrl.Req restoredPVCList: restoredPVCList, multiHookTracker: r.multiHookTracker, resourceTimeout: r.resourceTimeout, + restoreItemOperationList: restoreItemOperationList{ + items: restoreItemOperations, + }, } warnings, errs := finalizerCtx.execute() @@ -239,16 +254,44 @@ func (r *restoreFinalizerReconciler) finishProcessing(restorePhase velerov1api.R return kubeutil.PatchResourceWithRetriesOnErrors(r.resourceTimeout, original, restore, r.Client) } +type restoreItemOperationList struct { + items []*itemoperation.RestoreOperation +} + +func (r *restoreItemOperationList) selectByResource(group, resource, ns, name string) []*itemoperation.RestoreOperation { + var res []*itemoperation.RestoreOperation + rid := velero.ResourceIdentifier{ + GroupResource: schema.GroupResource{ + Group: group, + Resource: resource, + }, + Namespace: ns, + Name: name, + } + for _, item := range r.items { + if item != nil && item.Spec.ResourceIdentifier == rid { + res = append(res, item) + } + } + return res +} + +// SelectByPVC filters the restore item operation list by PVC namespace and name. +func (r *restoreItemOperationList) SelectByPVC(ns, name string) []*itemoperation.RestoreOperation { + return r.selectByResource("", "persistentvolumeclaims", ns, name) +} + // finalizerContext includes all the dependencies required by finalization tasks and // a function execute() to orderly implement task logic. type finalizerContext struct { - logger logrus.FieldLogger - restore *velerov1api.Restore - crClient client.Client - volumeInfo []*volume.BackupVolumeInfo - restoredPVCList map[string]struct{} - multiHookTracker *hook.MultiHookTracker - resourceTimeout time.Duration + logger logrus.FieldLogger + restore *velerov1api.Restore + crClient client.Client + volumeInfo []*volume.BackupVolumeInfo + restoredPVCList map[string]struct{} + restoreItemOperationList restoreItemOperationList + multiHookTracker *hook.MultiHookTracker + resourceTimeout time.Duration } func (ctx *finalizerContext) execute() (results.Result, results.Result) { //nolint:unparam //temporarily ignore the lint report: result 0 is always nil (unparam) @@ -310,6 +353,17 @@ func (ctx *finalizerContext) patchDynamicPVWithVolumeInfo() (errs results.Result return false, err } + // Check whether the async operation to populate the PVC is successful. If it's not, will skip patching the PV, instead of waiting. + operations := ctx.restoreItemOperationList.SelectByPVC(pvc.Namespace, pvc.Name) + for _, op := range operations { + if op.Spec.RestoreItemAction == constant.PluginCSIPVCRestoreRIA && + op.Status.Phase != itemoperation.OperationPhaseCompleted { + log.Warnf("skipping PV patch, because the operation to restore the PVC is not completed, "+ + "operation: %s, phase: %s", op.Spec.OperationID, op.Status.Phase) + return true, nil + } + } + // We are handling a common but specific scenario where a PVC is in a pending state and uses a storage class with // VolumeBindingMode set to WaitForFirstConsumer. In this case, the PV patch step is skipped to avoid // failures due to the PVC not being bound, which could cause a timeout and result in a failed restore. diff --git a/pkg/controller/restore_finalizer_controller_test.go b/pkg/controller/restore_finalizer_controller_test.go index 83738feb1..518b82424 100644 --- a/pkg/controller/restore_finalizer_controller_test.go +++ b/pkg/controller/restore_finalizer_controller_test.go @@ -23,6 +23,11 @@ import ( "testing" "time" + "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/vmware-tanzu/velero/pkg/itemoperation" + "github.com/vmware-tanzu/velero/pkg/plugin/velero" + "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -145,6 +150,7 @@ func TestRestoreFinalizerReconcile(t *testing.T) { if test.restore != nil && test.restore.Namespace == velerov1api.DefaultNamespace { require.NoError(t, r.Client.Create(context.Background(), test.restore)) backupStore.On("GetRestoredResourceList", test.restore.Name).Return(map[string][]string{}, nil) + backupStore.On("GetRestoreItemOperations", test.restore.Name).Return([]*itemoperation.RestoreOperation{}, nil) } if test.backup != nil { assert.NoError(t, r.Client.Create(context.Background(), test.backup)) @@ -627,3 +633,112 @@ func Test_restoreFinalizerReconciler_finishProcessing(t *testing.T) { }) } } + +func TestRestoreOperationList(t *testing.T) { + var empty []*itemoperation.RestoreOperation + tests := []struct { + name string + items []*itemoperation.RestoreOperation + inputPVCNS string + inputPVCName string + expected []*itemoperation.RestoreOperation + }{ + { + name: "no restore operations", + items: []*itemoperation.RestoreOperation{}, + inputPVCNS: "ns-1", + inputPVCName: "pvc-1", + expected: empty, + }, + { + name: "one operation with matched info and a nil element", + items: []*itemoperation.RestoreOperation{ + nil, + { + Spec: itemoperation.RestoreOperationSpec{ + RestoreName: "restore-1", + RestoreUID: "uid-1", + RestoreItemAction: "velero.io/csi-pvc-restorer", + OperationID: "dd-abbb048d-7036-4855-bf50-ebba978b59a6.2426dd0e-b863-4222b5b2b", + ResourceIdentifier: velero.ResourceIdentifier{ + GroupResource: schema.GroupResource{ + Group: "", + Resource: "persistentvolumeclaims", + }, + Namespace: "ns-1", + Name: "pvc-1", + }, + }, + Status: itemoperation.OperationStatus{ + Phase: itemoperation.OperationPhaseCompleted, + OperationUnits: "Byte", + Description: "Completed", + }, + }, + }, + inputPVCNS: "ns-1", + inputPVCName: "pvc-1", + expected: []*itemoperation.RestoreOperation{ + { + Spec: itemoperation.RestoreOperationSpec{ + RestoreName: "restore-1", + RestoreUID: "uid-1", + RestoreItemAction: "velero.io/csi-pvc-restorer", + OperationID: "dd-abbb048d-7036-4855-bf50-ebba978b59a6.2426dd0e-b863-4222b5b2b", + ResourceIdentifier: velero.ResourceIdentifier{ + GroupResource: schema.GroupResource{ + Group: "", + Resource: "persistentvolumeclaims", + }, + Namespace: "ns-1", + Name: "pvc-1", + }, + }, + Status: itemoperation.OperationStatus{ + Phase: itemoperation.OperationPhaseCompleted, + OperationUnits: "Byte", + Description: "Completed", + }, + }, + }, + }, + { + name: "one operation with incorrect resource type", + items: []*itemoperation.RestoreOperation{ + { + Spec: itemoperation.RestoreOperationSpec{ + RestoreName: "restore-1", + RestoreUID: "uid-1", + RestoreItemAction: "velero.io/csi-pvc-restorer", + OperationID: "dd-abbb048d-7036-4855-bf50-ebba978b59a6.2426dd0e-b863-4222b5b2b", + ResourceIdentifier: velero.ResourceIdentifier{ + GroupResource: schema.GroupResource{ + Group: "", + Resource: "configmaps", + }, + Namespace: "ns-1", + Name: "pvc-1", + }, + }, + Status: itemoperation.OperationStatus{ + Phase: itemoperation.OperationPhaseCompleted, + OperationUnits: "Byte", + Description: "Completed", + }, + }, + }, + inputPVCNS: "ns-1", + inputPVCName: "pvc-1", + expected: empty, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + l := restoreItemOperationList{ + items: tt.items, + } + assert.Equal(t, tt.expected, l.SelectByPVC(tt.inputPVCNS, tt.inputPVCName)) + }) + } +} diff --git a/pkg/persistence/mocks/backup_store.go b/pkg/persistence/mocks/backup_store.go index 8abdd35bb..bd1ef5dbd 100644 --- a/pkg/persistence/mocks/backup_store.go +++ b/pkg/persistence/mocks/backup_store.go @@ -13,7 +13,7 @@ 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. */ -// Code generated by mockery v2.16.0. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks @@ -21,15 +21,17 @@ import ( io "io" mock "github.com/stretchr/testify/mock" - volumesnapshotv1 "github.com/kubernetes-csi/external-snapshotter/client/v7/apis/volumesnapshot/v1" - itemoperation "github.com/vmware-tanzu/velero/pkg/itemoperation" - "github.com/vmware-tanzu/velero/pkg/persistence" + + persistence "github.com/vmware-tanzu/velero/pkg/persistence" + + results "github.com/vmware-tanzu/velero/pkg/util/results" + v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" - "github.com/vmware-tanzu/velero/internal/volume" - "github.com/vmware-tanzu/velero/pkg/util/results" + volume "github.com/vmware-tanzu/velero/internal/volume" + volumesnapshotv1 "github.com/kubernetes-csi/external-snapshotter/client/v7/apis/volumesnapshot/v1" ) // BackupStore is an autogenerated mock type for the BackupStore type @@ -41,14 +43,21 @@ type BackupStore struct { func (_m *BackupStore) BackupExists(bucket string, backupName string) (bool, error) { ret := _m.Called(bucket, backupName) + if len(ret) == 0 { + panic("no return value specified for BackupExists") + } + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (bool, error)); ok { + return rf(bucket, backupName) + } if rf, ok := ret.Get(0).(func(string, string) bool); ok { r0 = rf(bucket, backupName) } else { r0 = ret.Get(0).(bool) } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(bucket, backupName) } else { @@ -62,6 +71,10 @@ func (_m *BackupStore) BackupExists(bucket string, backupName string) (bool, err func (_m *BackupStore) DeleteBackup(name string) error { ret := _m.Called(name) + if len(ret) == 0 { + panic("no return value specified for DeleteBackup") + } + var r0 error if rf, ok := ret.Get(0).(func(string) error); ok { r0 = rf(name) @@ -76,6 +89,10 @@ func (_m *BackupStore) DeleteBackup(name string) error { func (_m *BackupStore) DeleteRestore(name string) error { ret := _m.Called(name) + if len(ret) == 0 { + panic("no return value specified for DeleteRestore") + } + var r0 error if rf, ok := ret.Get(0).(func(string) error); ok { r0 = rf(name) @@ -90,7 +107,15 @@ func (_m *BackupStore) DeleteRestore(name string) error { func (_m *BackupStore) GetBackupContents(name string) (io.ReadCloser, error) { ret := _m.Called(name) + if len(ret) == 0 { + panic("no return value specified for GetBackupContents") + } + var r0 io.ReadCloser + var r1 error + if rf, ok := ret.Get(0).(func(string) (io.ReadCloser, error)); ok { + return rf(name) + } if rf, ok := ret.Get(0).(func(string) io.ReadCloser); ok { r0 = rf(name) } else { @@ -99,7 +124,6 @@ func (_m *BackupStore) GetBackupContents(name string) (io.ReadCloser, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(name) } else { @@ -113,7 +137,15 @@ func (_m *BackupStore) GetBackupContents(name string) (io.ReadCloser, error) { func (_m *BackupStore) GetBackupItemOperations(name string) ([]*itemoperation.BackupOperation, error) { ret := _m.Called(name) + if len(ret) == 0 { + panic("no return value specified for GetBackupItemOperations") + } + var r0 []*itemoperation.BackupOperation + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]*itemoperation.BackupOperation, error)); ok { + return rf(name) + } if rf, ok := ret.Get(0).(func(string) []*itemoperation.BackupOperation); ok { r0 = rf(name) } else { @@ -122,7 +154,6 @@ func (_m *BackupStore) GetBackupItemOperations(name string) ([]*itemoperation.Ba } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(name) } else { @@ -136,7 +167,15 @@ func (_m *BackupStore) GetBackupItemOperations(name string) ([]*itemoperation.Ba func (_m *BackupStore) GetBackupMetadata(name string) (*v1.Backup, error) { ret := _m.Called(name) + if len(ret) == 0 { + panic("no return value specified for GetBackupMetadata") + } + var r0 *v1.Backup + var r1 error + if rf, ok := ret.Get(0).(func(string) (*v1.Backup, error)); ok { + return rf(name) + } if rf, ok := ret.Get(0).(func(string) *v1.Backup); ok { r0 = rf(name) } else { @@ -145,7 +184,36 @@ func (_m *BackupStore) GetBackupMetadata(name string) (*v1.Backup, error) { } } + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(name) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBackupVolumeInfos provides a mock function with given fields: name +func (_m *BackupStore) GetBackupVolumeInfos(name string) ([]*volume.BackupVolumeInfo, error) { + ret := _m.Called(name) + + if len(ret) == 0 { + panic("no return value specified for GetBackupVolumeInfos") + } + + var r0 []*volume.BackupVolumeInfo var r1 error + if rf, ok := ret.Get(0).(func(string) ([]*volume.BackupVolumeInfo, error)); ok { + return rf(name) + } + if rf, ok := ret.Get(0).(func(string) []*volume.BackupVolumeInfo); ok { + r0 = rf(name) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*volume.BackupVolumeInfo) + } + } + if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(name) } else { @@ -159,7 +227,15 @@ func (_m *BackupStore) GetBackupMetadata(name string) (*v1.Backup, error) { func (_m *BackupStore) GetBackupVolumeSnapshots(name string) ([]*volume.Snapshot, error) { ret := _m.Called(name) + if len(ret) == 0 { + panic("no return value specified for GetBackupVolumeSnapshots") + } + var r0 []*volume.Snapshot + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]*volume.Snapshot, error)); ok { + return rf(name) + } if rf, ok := ret.Get(0).(func(string) []*volume.Snapshot); ok { r0 = rf(name) } else { @@ -168,7 +244,6 @@ func (_m *BackupStore) GetBackupVolumeSnapshots(name string) ([]*volume.Snapshot } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(name) } else { @@ -182,7 +257,15 @@ func (_m *BackupStore) GetBackupVolumeSnapshots(name string) ([]*volume.Snapshot func (_m *BackupStore) GetCSIVolumeSnapshotClasses(name string) ([]*volumesnapshotv1.VolumeSnapshotClass, error) { ret := _m.Called(name) + if len(ret) == 0 { + panic("no return value specified for GetCSIVolumeSnapshotClasses") + } + var r0 []*volumesnapshotv1.VolumeSnapshotClass + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]*volumesnapshotv1.VolumeSnapshotClass, error)); ok { + return rf(name) + } if rf, ok := ret.Get(0).(func(string) []*volumesnapshotv1.VolumeSnapshotClass); ok { r0 = rf(name) } else { @@ -191,7 +274,6 @@ func (_m *BackupStore) GetCSIVolumeSnapshotClasses(name string) ([]*volumesnapsh } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(name) } else { @@ -205,7 +287,15 @@ func (_m *BackupStore) GetCSIVolumeSnapshotClasses(name string) ([]*volumesnapsh func (_m *BackupStore) GetCSIVolumeSnapshotContents(name string) ([]*volumesnapshotv1.VolumeSnapshotContent, error) { ret := _m.Called(name) + if len(ret) == 0 { + panic("no return value specified for GetCSIVolumeSnapshotContents") + } + var r0 []*volumesnapshotv1.VolumeSnapshotContent + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]*volumesnapshotv1.VolumeSnapshotContent, error)); ok { + return rf(name) + } if rf, ok := ret.Get(0).(func(string) []*volumesnapshotv1.VolumeSnapshotContent); ok { r0 = rf(name) } else { @@ -214,7 +304,6 @@ func (_m *BackupStore) GetCSIVolumeSnapshotContents(name string) ([]*volumesnaps } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(name) } else { @@ -228,7 +317,15 @@ func (_m *BackupStore) GetCSIVolumeSnapshotContents(name string) ([]*volumesnaps func (_m *BackupStore) GetCSIVolumeSnapshots(name string) ([]*volumesnapshotv1.VolumeSnapshot, error) { ret := _m.Called(name) + if len(ret) == 0 { + panic("no return value specified for GetCSIVolumeSnapshots") + } + var r0 []*volumesnapshotv1.VolumeSnapshot + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]*volumesnapshotv1.VolumeSnapshot, error)); ok { + return rf(name) + } if rf, ok := ret.Get(0).(func(string) []*volumesnapshotv1.VolumeSnapshot); ok { r0 = rf(name) } else { @@ -237,7 +334,6 @@ func (_m *BackupStore) GetCSIVolumeSnapshots(name string) ([]*volumesnapshotv1.V } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(name) } else { @@ -251,14 +347,21 @@ func (_m *BackupStore) GetCSIVolumeSnapshots(name string) ([]*volumesnapshotv1.V func (_m *BackupStore) GetDownloadURL(target v1.DownloadTarget) (string, error) { ret := _m.Called(target) + if len(ret) == 0 { + panic("no return value specified for GetDownloadURL") + } + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(v1.DownloadTarget) (string, error)); ok { + return rf(target) + } if rf, ok := ret.Get(0).(func(v1.DownloadTarget) string); ok { r0 = rf(target) } else { r0 = ret.Get(0).(string) } - var r1 error if rf, ok := ret.Get(1).(func(v1.DownloadTarget) error); ok { r1 = rf(target) } else { @@ -272,7 +375,15 @@ func (_m *BackupStore) GetDownloadURL(target v1.DownloadTarget) (string, error) func (_m *BackupStore) GetPodVolumeBackups(name string) ([]*v1.PodVolumeBackup, error) { ret := _m.Called(name) + if len(ret) == 0 { + panic("no return value specified for GetPodVolumeBackups") + } + var r0 []*v1.PodVolumeBackup + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]*v1.PodVolumeBackup, error)); ok { + return rf(name) + } if rf, ok := ret.Get(0).(func(string) []*v1.PodVolumeBackup); ok { r0 = rf(name) } else { @@ -281,7 +392,6 @@ func (_m *BackupStore) GetPodVolumeBackups(name string) ([]*v1.PodVolumeBackup, } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(name) } else { @@ -295,7 +405,15 @@ func (_m *BackupStore) GetPodVolumeBackups(name string) ([]*v1.PodVolumeBackup, func (_m *BackupStore) GetRestoreItemOperations(name string) ([]*itemoperation.RestoreOperation, error) { ret := _m.Called(name) + if len(ret) == 0 { + panic("no return value specified for GetRestoreItemOperations") + } + var r0 []*itemoperation.RestoreOperation + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]*itemoperation.RestoreOperation, error)); ok { + return rf(name) + } if rf, ok := ret.Get(0).(func(string) []*itemoperation.RestoreOperation); ok { r0 = rf(name) } else { @@ -304,7 +422,6 @@ func (_m *BackupStore) GetRestoreItemOperations(name string) ([]*itemoperation.R } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(name) } else { @@ -314,48 +431,19 @@ func (_m *BackupStore) GetRestoreItemOperations(name string) ([]*itemoperation.R return r0, r1 } -// GetRestoreItemOperations provides a mock function with given fields: name -func (_m *BackupStore) GetBackupVolumeInfos(name string) ([]*volume.BackupVolumeInfo, error) { - ret := _m.Called(name) - - var r0 []*volume.BackupVolumeInfo - if rf, ok := ret.Get(0).(func(string) []*volume.BackupVolumeInfo); ok { - r0 = rf(name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*volume.BackupVolumeInfo) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PutBackupVolumeInfos provides a mock function with given fields: name, volumeInfo -func (_m *BackupStore) PutBackupVolumeInfos(name string, volumeInfo io.Reader) error { - ret := _m.Called(name, volumeInfo) - - var r0 error - if rf, ok := ret.Get(0).(func(string, io.Reader) error); ok { - r0 = rf(name, volumeInfo) - } else { - r0 = ret.Error(0) - } - - return r0 -} - // GetRestoreResults provides a mock function with given fields: name func (_m *BackupStore) GetRestoreResults(name string) (map[string]results.Result, error) { ret := _m.Called(name) - r0 := make(map[string]results.Result) + if len(ret) == 0 { + panic("no return value specified for GetRestoreResults") + } + + var r0 map[string]results.Result + var r1 error + if rf, ok := ret.Get(0).(func(string) (map[string]results.Result, error)); ok { + return rf(name) + } if rf, ok := ret.Get(0).(func(string) map[string]results.Result); ok { r0 = rf(name) } else { @@ -364,7 +452,6 @@ func (_m *BackupStore) GetRestoreResults(name string) (map[string]results.Result } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(name) } else { @@ -378,7 +465,15 @@ func (_m *BackupStore) GetRestoreResults(name string) (map[string]results.Result func (_m *BackupStore) GetRestoredResourceList(name string) (map[string][]string, error) { ret := _m.Called(name) - r0 := make(map[string][]string) + if len(ret) == 0 { + panic("no return value specified for GetRestoredResourceList") + } + + var r0 map[string][]string + var r1 error + if rf, ok := ret.Get(0).(func(string) (map[string][]string, error)); ok { + return rf(name) + } if rf, ok := ret.Get(0).(func(string) map[string][]string); ok { r0 = rf(name) } else { @@ -387,7 +482,6 @@ func (_m *BackupStore) GetRestoredResourceList(name string) (map[string][]string } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(name) } else { @@ -401,6 +495,10 @@ func (_m *BackupStore) GetRestoredResourceList(name string) (map[string][]string func (_m *BackupStore) IsValid() error { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for IsValid") + } + var r0 error if rf, ok := ret.Get(0).(func() error); ok { r0 = rf() @@ -415,7 +513,15 @@ func (_m *BackupStore) IsValid() error { func (_m *BackupStore) ListBackups() ([]string, error) { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for ListBackups") + } + var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func() ([]string, error)); ok { + return rf() + } if rf, ok := ret.Get(0).(func() []string); ok { r0 = rf() } else { @@ -424,7 +530,6 @@ func (_m *BackupStore) ListBackups() ([]string, error) { } } - var r1 error if rf, ok := ret.Get(1).(func() error); ok { r1 = rf() } else { @@ -438,6 +543,10 @@ func (_m *BackupStore) ListBackups() ([]string, error) { func (_m *BackupStore) PutBackup(info persistence.BackupInfo) error { ret := _m.Called(info) + if len(ret) == 0 { + panic("no return value specified for PutBackup") + } + var r0 error if rf, ok := ret.Get(0).(func(persistence.BackupInfo) error); ok { r0 = rf(info) @@ -452,6 +561,10 @@ func (_m *BackupStore) PutBackup(info persistence.BackupInfo) error { func (_m *BackupStore) PutBackupContents(backup string, backupContents io.Reader) error { ret := _m.Called(backup, backupContents) + if len(ret) == 0 { + panic("no return value specified for PutBackupContents") + } + var r0 error if rf, ok := ret.Get(0).(func(string, io.Reader) error); ok { r0 = rf(backup, backupContents) @@ -466,6 +579,10 @@ func (_m *BackupStore) PutBackupContents(backup string, backupContents io.Reader func (_m *BackupStore) PutBackupItemOperations(backup string, backupItemOperations io.Reader) error { ret := _m.Called(backup, backupItemOperations) + if len(ret) == 0 { + panic("no return value specified for PutBackupItemOperations") + } + var r0 error if rf, ok := ret.Get(0).(func(string, io.Reader) error); ok { r0 = rf(backup, backupItemOperations) @@ -480,6 +597,10 @@ func (_m *BackupStore) PutBackupItemOperations(backup string, backupItemOperatio func (_m *BackupStore) PutBackupMetadata(backup string, backupMetadata io.Reader) error { ret := _m.Called(backup, backupMetadata) + if len(ret) == 0 { + panic("no return value specified for PutBackupMetadata") + } + var r0 error if rf, ok := ret.Get(0).(func(string, io.Reader) error); ok { r0 = rf(backup, backupMetadata) @@ -490,10 +611,32 @@ func (_m *BackupStore) PutBackupMetadata(backup string, backupMetadata io.Reader return r0 } +// PutBackupVolumeInfos provides a mock function with given fields: name, volumeInfo +func (_m *BackupStore) PutBackupVolumeInfos(name string, volumeInfo io.Reader) error { + ret := _m.Called(name, volumeInfo) + + if len(ret) == 0 { + panic("no return value specified for PutBackupVolumeInfos") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string, io.Reader) error); ok { + r0 = rf(name, volumeInfo) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // PutRestoreItemOperations provides a mock function with given fields: restore, restoreItemOperations func (_m *BackupStore) PutRestoreItemOperations(restore string, restoreItemOperations io.Reader) error { ret := _m.Called(restore, restoreItemOperations) + if len(ret) == 0 { + panic("no return value specified for PutRestoreItemOperations") + } + var r0 error if rf, ok := ret.Get(0).(func(string, io.Reader) error); ok { r0 = rf(restore, restoreItemOperations) @@ -508,6 +651,10 @@ func (_m *BackupStore) PutRestoreItemOperations(restore string, restoreItemOpera func (_m *BackupStore) PutRestoreLog(backup string, restore string, log io.Reader) error { ret := _m.Called(backup, restore, log) + if len(ret) == 0 { + panic("no return value specified for PutRestoreLog") + } + var r0 error if rf, ok := ret.Get(0).(func(string, string, io.Reader) error); ok { r0 = rf(backup, restore, log) @@ -518,13 +665,17 @@ func (_m *BackupStore) PutRestoreLog(backup string, restore string, log io.Reade return r0 } -// PutRestoreResults provides a mock function with given fields: backup, restore, results -func (_m *BackupStore) PutRestoreResults(backup string, restore string, results io.Reader) error { - ret := _m.Called(backup, restore, results) +// PutRestoreResults provides a mock function with given fields: backup, restore, _a2 +func (_m *BackupStore) PutRestoreResults(backup string, restore string, _a2 io.Reader) error { + ret := _m.Called(backup, restore, _a2) + + if len(ret) == 0 { + panic("no return value specified for PutRestoreResults") + } var r0 error if rf, ok := ret.Get(0).(func(string, string, io.Reader) error); ok { - r0 = rf(backup, restore, results) + r0 = rf(backup, restore, _a2) } else { r0 = ret.Error(0) } @@ -532,13 +683,17 @@ func (_m *BackupStore) PutRestoreResults(backup string, restore string, results return r0 } -// PutRestoredResourceList provides a mock function with given fields: restore, results -func (_m *BackupStore) PutRestoredResourceList(restore string, results io.Reader) error { - ret := _m.Called(restore, results) +// PutRestoreVolumeInfo provides a mock function with given fields: restore, volumeInfo +func (_m *BackupStore) PutRestoreVolumeInfo(restore string, volumeInfo io.Reader) error { + ret := _m.Called(restore, volumeInfo) + + if len(ret) == 0 { + panic("no return value specified for PutRestoreVolumeInfo") + } var r0 error if rf, ok := ret.Get(0).(func(string, io.Reader) error); ok { - r0 = rf(restore, results) + r0 = rf(restore, volumeInfo) } else { r0 = ret.Error(0) } @@ -546,26 +701,30 @@ func (_m *BackupStore) PutRestoredResourceList(restore string, results io.Reader return r0 } -// PutRestoreVolumeInfo provides a mock function with given fields: restore, results -func (_m *BackupStore) PutRestoreVolumeInfo(restore string, results io.Reader) error { - ret := _m.Called(restore, results) +// PutRestoredResourceList provides a mock function with given fields: restore, _a1 +func (_m *BackupStore) PutRestoredResourceList(restore string, _a1 io.Reader) error { + ret := _m.Called(restore, _a1) + + if len(ret) == 0 { + panic("no return value specified for PutRestoredResourceList") + } var r0 error if rf, ok := ret.Get(0).(func(string, io.Reader) error); ok { - r0 = rf(restore, results) + r0 = rf(restore, _a1) } else { r0 = ret.Error(0) } return r0 } -type mockConstructorTestingTNewBackupStore interface { - mock.TestingT - Cleanup(func()) -} // NewBackupStore creates a new instance of BackupStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewBackupStore(t mockConstructorTestingTNewBackupStore) *BackupStore { +// The first argument is typically a *testing.T value. +func NewBackupStore(t interface { + mock.TestingT + Cleanup(func()) +}) *BackupStore { mock := &BackupStore{} mock.Mock.Test(t)