Merge pull request #8591 from reasonerjt/finalize-async-op

Skip patching the PV in finalization for failed operation
pull/8602/head
lyndon-li 2025-01-10 14:02:42 +08:00 committed by GitHub
commit 42d2e9bfc4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 415 additions and 83 deletions

View File

@ -0,0 +1 @@
Skip patching the PV in finalization for failed operation

View File

@ -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(

View File

@ -19,4 +19,6 @@ const (
ControllerSchedule = "schedule"
ControllerServerStatusRequest = "server-status-request"
ControllerRestoreFinalizer = "restore-finalizer"
PluginCSIPVCRestoreRIA = "velero.io/csi-pvc-restorer"
)

View File

@ -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.

View File

@ -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))
})
}
}

View File

@ -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)