mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-07-31 12:32:44 +00:00
Remove Reference of itemsnapshotter (#5997)
It will be removed as we choose to use BIAv2 for progress monitoring. Signed-off-by: Daniel Jiang <jiangd@vmware.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Remove Reference of itemsnapshotter
|
||||
+2
-13
@@ -67,9 +67,7 @@ type Backupper interface {
|
||||
// Backup takes a backup using the specification in the velerov1api.Backup and writes backup and log data
|
||||
// to the given writers.
|
||||
Backup(logger logrus.FieldLogger, backup *Request, backupFile io.Writer, actions []biav2.BackupItemAction, volumeSnapshotterGetter VolumeSnapshotterGetter) error
|
||||
BackupWithResolvers(log logrus.FieldLogger, backupRequest *Request, backupFile io.Writer,
|
||||
backupItemActionResolver framework.BackupItemActionResolverV2, itemSnapshotterResolver framework.ItemSnapshotterResolver,
|
||||
volumeSnapshotterGetter VolumeSnapshotterGetter) error
|
||||
BackupWithResolvers(log logrus.FieldLogger, backupRequest *Request, backupFile io.Writer, backupItemActionResolver framework.BackupItemActionResolverV2, volumeSnapshotterGetter VolumeSnapshotterGetter) error
|
||||
FinalizeBackup(log logrus.FieldLogger, backupRequest *Request, inBackupFile io.Reader, outBackupFile io.Writer,
|
||||
backupItemActionResolver framework.BackupItemActionResolverV2,
|
||||
asyncBIAOperations []*itemoperation.BackupOperation) error
|
||||
@@ -182,16 +180,13 @@ type VolumeSnapshotterGetter interface {
|
||||
func (kb *kubernetesBackupper) Backup(log logrus.FieldLogger, backupRequest *Request, backupFile io.Writer,
|
||||
actions []biav2.BackupItemAction, volumeSnapshotterGetter VolumeSnapshotterGetter) error {
|
||||
backupItemActions := framework.NewBackupItemActionResolverV2(actions)
|
||||
itemSnapshotters := framework.NewItemSnapshotterResolver(nil)
|
||||
return kb.BackupWithResolvers(log, backupRequest, backupFile, backupItemActions, itemSnapshotters,
|
||||
volumeSnapshotterGetter)
|
||||
return kb.BackupWithResolvers(log, backupRequest, backupFile, backupItemActions, volumeSnapshotterGetter)
|
||||
}
|
||||
|
||||
func (kb *kubernetesBackupper) BackupWithResolvers(log logrus.FieldLogger,
|
||||
backupRequest *Request,
|
||||
backupFile io.Writer,
|
||||
backupItemActionResolver framework.BackupItemActionResolverV2,
|
||||
itemSnapshotterResolver framework.ItemSnapshotterResolver,
|
||||
volumeSnapshotterGetter VolumeSnapshotterGetter) error {
|
||||
gzippedData := gzip.NewWriter(backupFile)
|
||||
defer gzippedData.Close()
|
||||
@@ -239,12 +234,6 @@ func (kb *kubernetesBackupper) BackupWithResolvers(log logrus.FieldLogger,
|
||||
return err
|
||||
}
|
||||
|
||||
backupRequest.ResolvedItemSnapshotters, err = itemSnapshotterResolver.ResolveActions(kb.discoveryHelper, log)
|
||||
if err != nil {
|
||||
log.WithError(errors.WithStack(err)).Debugf("Error from itemSnapshotterResolver.ResolveActions")
|
||||
return err
|
||||
}
|
||||
|
||||
backupRequest.BackedUpItems = map[itemKey]struct{}{}
|
||||
|
||||
podVolumeTimeout := kb.podVolumeTimeout
|
||||
|
||||
@@ -47,7 +47,6 @@ type Request struct {
|
||||
ResourceIncludesExcludes collections.IncludesExcludesInterface
|
||||
ResourceHooks []hook.ResourceHook
|
||||
ResolvedActions []framework.BackupItemResolvedActionV2
|
||||
ResolvedItemSnapshotters []framework.ItemSnapshotterResolvedAction
|
||||
VolumeSnapshots []*volume.Snapshot
|
||||
PodVolumeBackups []*velerov1api.PodVolumeBackup
|
||||
BackedUpItems map[itemKey]struct{}
|
||||
|
||||
@@ -611,11 +611,6 @@ func (b *backupReconciler) runBackup(backup *pkgbackup.Request) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
itemSnapshotters, err := pluginManager.GetItemSnapshotters()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
backupLog.Info("Setting up backup store to check for backup existence")
|
||||
backupStore, err := b.backupStoreGetter.Get(backup.StorageLocation, pluginManager, backupLog)
|
||||
if err != nil {
|
||||
@@ -633,11 +628,9 @@ func (b *backupReconciler) runBackup(backup *pkgbackup.Request) error {
|
||||
}
|
||||
|
||||
backupItemActionsResolver := framework.NewBackupItemActionResolverV2(actions)
|
||||
itemSnapshottersResolver := framework.NewItemSnapshotterResolver(itemSnapshotters)
|
||||
|
||||
var fatalErrs []error
|
||||
if err := b.backupper.BackupWithResolvers(backupLog, backup, backupFile, backupItemActionsResolver,
|
||||
itemSnapshottersResolver, pluginManager); err != nil {
|
||||
if err := b.backupper.BackupWithResolvers(backupLog, backup, backupFile, backupItemActionsResolver, pluginManager); err != nil {
|
||||
fatalErrs = append(fatalErrs, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -70,9 +70,8 @@ func (b *fakeBackupper) Backup(logger logrus.FieldLogger, backup *pkgbackup.Requ
|
||||
}
|
||||
|
||||
func (b *fakeBackupper) BackupWithResolvers(logger logrus.FieldLogger, backup *pkgbackup.Request, backupFile io.Writer,
|
||||
backupItemActionResolver framework.BackupItemActionResolverV2, itemSnapshotterResolver framework.ItemSnapshotterResolver,
|
||||
volumeSnapshotterGetter pkgbackup.VolumeSnapshotterGetter) error {
|
||||
args := b.Called(logger, backup, backupFile, backupItemActionResolver, itemSnapshotterResolver, volumeSnapshotterGetter)
|
||||
backupItemActionResolver framework.BackupItemActionResolverV2, volumeSnapshotterGetter pkgbackup.VolumeSnapshotterGetter) error {
|
||||
args := b.Called(logger, backup, backupFile, backupItemActionResolver, volumeSnapshotterGetter)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
@@ -1047,9 +1046,8 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
|
||||
pluginManager.On("GetBackupItemActionsV2").Return(nil, nil)
|
||||
pluginManager.On("CleanupClients").Return(nil)
|
||||
pluginManager.On("GetItemSnapshotters").Return(nil, nil)
|
||||
backupper.On("Backup", mock.Anything, mock.Anything, mock.Anything, []biav2.BackupItemAction(nil), pluginManager).Return(nil)
|
||||
backupper.On("BackupWithResolvers", mock.Anything, mock.Anything, mock.Anything, framework.BackupItemActionResolverV2{}, framework.ItemSnapshotterResolver{}, pluginManager).Return(nil)
|
||||
backupper.On("BackupWithResolvers", mock.Anything, mock.Anything, mock.Anything, framework.BackupItemActionResolverV2{}, pluginManager).Return(nil)
|
||||
backupStore.On("BackupExists", test.backupLocation.Spec.StorageType.ObjectStorage.Bucket, test.backup.Name).Return(test.backupExists, test.existenceCheckError)
|
||||
|
||||
// Ensure we have a CompletionTimestamp when uploading and that the backup name matches the backup in the object store.
|
||||
|
||||
@@ -431,12 +431,6 @@ func (r *restoreReconciler) runValidatedRestore(restore *api.Restore, info backu
|
||||
}
|
||||
actionsResolver := framework.NewRestoreItemActionResolverV2(actions)
|
||||
|
||||
itemSnapshotters, err := pluginManager.GetItemSnapshotters()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error getting item snapshotters")
|
||||
}
|
||||
snapshotItemResolver := framework.NewItemSnapshotterResolver(itemSnapshotters)
|
||||
|
||||
backupFile, err := downloadToTempFile(restore.Spec.BackupName, backupStore, restoreLog)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error downloading backup")
|
||||
@@ -475,8 +469,7 @@ func (r *restoreReconciler) runValidatedRestore(restore *api.Restore, info backu
|
||||
VolumeSnapshots: volumeSnapshots,
|
||||
BackupReader: backupFile,
|
||||
}
|
||||
restoreWarnings, restoreErrors := r.restorer.RestoreWithResolvers(restoreReq, actionsResolver, snapshotItemResolver,
|
||||
pluginManager)
|
||||
restoreWarnings, restoreErrors := r.restorer.RestoreWithResolvers(restoreReq, actionsResolver, pluginManager)
|
||||
|
||||
// Iterate over restore item operations and update progress.
|
||||
// Any errors on operations at this point should be added to restore errors.
|
||||
|
||||
@@ -41,7 +41,6 @@ import (
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
||||
pluginmocks "github.com/vmware-tanzu/velero/pkg/plugin/mocks"
|
||||
isv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/item_snapshotter/v1"
|
||||
riav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v2"
|
||||
pkgrestore "github.com/vmware-tanzu/velero/pkg/restore"
|
||||
velerotest "github.com/vmware-tanzu/velero/pkg/test"
|
||||
@@ -481,7 +480,6 @@ func TestRestoreReconcile(t *testing.T) {
|
||||
|
||||
if test.restore != nil {
|
||||
pluginManager.On("GetRestoreItemActionsV2").Return(nil, nil)
|
||||
pluginManager.On("GetItemSnapshotters").Return([]isv1.ItemSnapshotter{}, nil)
|
||||
pluginManager.On("CleanupClients")
|
||||
}
|
||||
|
||||
@@ -786,10 +784,9 @@ func (r *fakeRestorer) Restore(
|
||||
|
||||
func (r *fakeRestorer) RestoreWithResolvers(req *pkgrestore.Request,
|
||||
resolver framework.RestoreItemActionResolverV2,
|
||||
itemSnapshotterResolver framework.ItemSnapshotterResolver,
|
||||
volumeSnapshotterGetter pkgrestore.VolumeSnapshotterGetter,
|
||||
) (results.Result, results.Result) {
|
||||
res := r.Called(req.Log, req.Restore, req.Backup, req.BackupReader, resolver, itemSnapshotterResolver,
|
||||
res := r.Called(req.Log, req.Restore, req.Backup, req.BackupReader, resolver,
|
||||
r.kbClient, volumeSnapshotterGetter)
|
||||
|
||||
r.calledWithArg = *req.Restore
|
||||
|
||||
@@ -34,7 +34,6 @@ import (
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||
biav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v1"
|
||||
biav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
|
||||
isv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/item_snapshotter/v1"
|
||||
riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1"
|
||||
riav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v2"
|
||||
vsv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v1"
|
||||
@@ -78,12 +77,6 @@ type Manager interface {
|
||||
// GetDeleteItemAction returns the delete item action plugin for name.
|
||||
GetDeleteItemAction(name string) (velero.DeleteItemAction, error)
|
||||
|
||||
// GetItemSnapshotter returns the item snapshotter plugin for name
|
||||
GetItemSnapshotter(name string) (isv1.ItemSnapshotter, error)
|
||||
|
||||
// GetItemSnapshotters returns all item snapshotter plugins
|
||||
GetItemSnapshotters() ([]isv1.ItemSnapshotter, error)
|
||||
|
||||
// CleanupClients terminates all of the Manager's running plugin processes.
|
||||
CleanupClients()
|
||||
}
|
||||
@@ -381,37 +374,6 @@ func (m *manager) GetDeleteItemAction(name string) (velero.DeleteItemAction, err
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (m *manager) GetItemSnapshotter(name string) (isv1.ItemSnapshotter, error) {
|
||||
name = sanitizeName(name)
|
||||
|
||||
restartableProcess, err := m.getRestartableProcess(common.PluginKindItemSnapshotter, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r := NewRestartableItemSnapshotter(name, restartableProcess)
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (m *manager) GetItemSnapshotters() ([]isv1.ItemSnapshotter, error) {
|
||||
list := m.registry.List(common.PluginKindItemSnapshotter)
|
||||
|
||||
actions := make([]isv1.ItemSnapshotter, 0, len(list))
|
||||
|
||||
for i := range list {
|
||||
id := list[i]
|
||||
|
||||
r, err := m.GetItemSnapshotter(id.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
actions = append(actions, r)
|
||||
}
|
||||
|
||||
return actions, nil
|
||||
}
|
||||
|
||||
// sanitizeName adds "velero.io" to legacy plugins that weren't namespaced.
|
||||
func sanitizeName(name string) string {
|
||||
// Backwards compatibility with non-namespaced Velero plugins, following principle of least surprise
|
||||
|
||||
@@ -78,7 +78,6 @@ func (b *clientBuilder) clientConfig() *hcplugin.ClientConfig {
|
||||
string(common.PluginKindRestoreItemAction): framework.NewRestoreItemActionPlugin(common.ClientLogger(b.clientLogger)),
|
||||
string(common.PluginKindRestoreItemActionV2): riav2.NewRestoreItemActionPlugin(common.ClientLogger(b.clientLogger)),
|
||||
string(common.PluginKindDeleteItemAction): framework.NewDeleteItemActionPlugin(common.ClientLogger(b.clientLogger)),
|
||||
string(common.PluginKindItemSnapshotter): framework.NewItemSnapshotterPlugin(common.ClientLogger(b.clientLogger)),
|
||||
},
|
||||
Logger: b.pluginLogger,
|
||||
Cmd: exec.Command(b.commandName, b.commandArgs...), //nolint
|
||||
|
||||
@@ -71,7 +71,6 @@ func TestClientConfig(t *testing.T) {
|
||||
string(common.PluginKindRestoreItemAction): framework.NewRestoreItemActionPlugin(common.ClientLogger(logger)),
|
||||
string(common.PluginKindRestoreItemActionV2): riav2.NewRestoreItemActionPlugin(common.ClientLogger(logger)),
|
||||
string(common.PluginKindDeleteItemAction): framework.NewDeleteItemActionPlugin(common.ClientLogger(logger)),
|
||||
string(common.PluginKindItemSnapshotter): framework.NewItemSnapshotterPlugin(common.ClientLogger(logger)),
|
||||
},
|
||||
Logger: cb.pluginLogger,
|
||||
Cmd: exec.Command(cb.commandName, cb.commandArgs...),
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
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 clientmgmt
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/framework/common"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||
isv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/item_snapshotter/v1"
|
||||
)
|
||||
|
||||
type restartableItemSnapshotter struct {
|
||||
key process.KindAndName
|
||||
sharedPluginProcess process.RestartableProcess
|
||||
}
|
||||
|
||||
// NewRestartableItemSnapshotter returns a new restartableItemSnapshotter.
|
||||
func NewRestartableItemSnapshotter(name string, sharedPluginProcess process.RestartableProcess) *restartableItemSnapshotter {
|
||||
r := &restartableItemSnapshotter{
|
||||
key: process.KindAndName{Kind: common.PluginKindItemSnapshotter, Name: name},
|
||||
sharedPluginProcess: sharedPluginProcess,
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// getItemSnapshotter returns the item snapshotter for this restartableItemSnapshotter. It does *not* restart the
|
||||
// plugin process.
|
||||
func (r *restartableItemSnapshotter) getItemSnapshotter() (isv1.ItemSnapshotter, error) {
|
||||
plugin, err := r.sharedPluginProcess.GetByKindAndName(r.key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
itemSnapshotter, ok := plugin.(isv1.ItemSnapshotter)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("%T is not an ItemSnapshotter!", plugin)
|
||||
}
|
||||
|
||||
return itemSnapshotter, nil
|
||||
}
|
||||
|
||||
// getDelegate restarts the plugin process (if needed) and returns the item snapshotter for this restartableItemSnapshotter.
|
||||
func (r *restartableItemSnapshotter) getDelegate() (isv1.ItemSnapshotter, error) {
|
||||
if err := r.sharedPluginProcess.ResetIfNeeded(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.getItemSnapshotter()
|
||||
}
|
||||
|
||||
func (r *restartableItemSnapshotter) Init(config map[string]string) error {
|
||||
delegate, err := r.getDelegate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return delegate.Init(config)
|
||||
}
|
||||
|
||||
// AppliesTo restarts the plugin's process if needed, then delegates the call.
|
||||
func (r *restartableItemSnapshotter) AppliesTo() (velero.ResourceSelector, error) {
|
||||
delegate, err := r.getDelegate()
|
||||
if err != nil {
|
||||
return velero.ResourceSelector{}, err
|
||||
}
|
||||
|
||||
return delegate.AppliesTo()
|
||||
}
|
||||
|
||||
func (r *restartableItemSnapshotter) AlsoHandles(input *isv1.AlsoHandlesInput) ([]velero.ResourceIdentifier, error) {
|
||||
delegate, err := r.getDelegate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return delegate.AlsoHandles(input)
|
||||
}
|
||||
|
||||
func (r *restartableItemSnapshotter) SnapshotItem(ctx context.Context, input *isv1.SnapshotItemInput) (*isv1.SnapshotItemOutput, error) {
|
||||
delegate, err := r.getDelegate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return delegate.SnapshotItem(ctx, input)
|
||||
}
|
||||
|
||||
func (r *restartableItemSnapshotter) Progress(input *isv1.ProgressInput) (*isv1.ProgressOutput, error) {
|
||||
delegate, err := r.getDelegate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return delegate.Progress(input)
|
||||
}
|
||||
|
||||
func (r *restartableItemSnapshotter) DeleteSnapshot(ctx context.Context, input *isv1.DeleteSnapshotInput) error {
|
||||
delegate, err := r.getDelegate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return delegate.DeleteSnapshot(ctx, input)
|
||||
}
|
||||
|
||||
func (r *restartableItemSnapshotter) CreateItemFromSnapshot(ctx context.Context, input *isv1.CreateItemInput) (*isv1.CreateItemOutput, error) {
|
||||
delegate, err := r.getDelegate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return delegate.CreateItemFromSnapshot(ctx, input)
|
||||
}
|
||||
@@ -1,234 +0,0 @@
|
||||
/*
|
||||
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 clientmgmt
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/vmware-tanzu/velero/internal/restartabletest"
|
||||
v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero/item_snapshotter/v1/mocks"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/framework/common"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||
isv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/item_snapshotter/v1"
|
||||
)
|
||||
|
||||
func TestRestartableGetItemSnapshotter(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
plugin interface{}
|
||||
getError error
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
name: "error getting by kind and name",
|
||||
getError: errors.Errorf("get error"),
|
||||
expectedError: "get error",
|
||||
},
|
||||
{
|
||||
name: "wrong type",
|
||||
plugin: 3,
|
||||
expectedError: "int is not an ItemSnapshotter!",
|
||||
},
|
||||
{
|
||||
name: "happy path",
|
||||
plugin: new(mocks.ItemSnapshotter),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
p := new(restartabletest.MockRestartableProcess)
|
||||
defer p.AssertExpectations(t)
|
||||
|
||||
name := "pvc"
|
||||
key := process.KindAndName{Kind: common.PluginKindItemSnapshotter, Name: name}
|
||||
p.On("GetByKindAndName", key).Return(tc.plugin, tc.getError)
|
||||
|
||||
r := NewRestartableItemSnapshotter(name, p)
|
||||
a, err := r.getItemSnapshotter()
|
||||
if tc.expectedError != "" {
|
||||
assert.EqualError(t, err, tc.expectedError)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, tc.plugin, a)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRestartableItemSnapshotterGetDelegate(t *testing.T) {
|
||||
p := new(restartabletest.MockRestartableProcess)
|
||||
defer p.AssertExpectations(t)
|
||||
|
||||
// Reset error
|
||||
p.On("ResetIfNeeded").Return(errors.Errorf("reset error")).Once()
|
||||
name := "pvc"
|
||||
r := NewRestartableItemSnapshotter(name, p)
|
||||
a, err := r.getDelegate()
|
||||
assert.Nil(t, a)
|
||||
assert.EqualError(t, err, "reset error")
|
||||
|
||||
// Happy path
|
||||
p.On("ResetIfNeeded").Return(nil)
|
||||
expected := new(mocks.ItemSnapshotter)
|
||||
key := process.KindAndName{Kind: common.PluginKindItemSnapshotter, Name: name}
|
||||
p.On("GetByKindAndName", key).Return(expected, nil)
|
||||
|
||||
a, err = r.getDelegate()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expected, a)
|
||||
}
|
||||
|
||||
func TestRestartableItemSnasphotterDelegatedFunctions(t *testing.T) {
|
||||
b := new(v1.Backup)
|
||||
|
||||
pv := &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"color": "blue",
|
||||
},
|
||||
}
|
||||
|
||||
sii := &isv1.SnapshotItemInput{
|
||||
Item: pv,
|
||||
Params: nil,
|
||||
Backup: b,
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
pvToReturn := &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"color": "green",
|
||||
},
|
||||
}
|
||||
|
||||
additionalItems := []velero.ResourceIdentifier{
|
||||
{
|
||||
GroupResource: schema.GroupResource{Group: "velero.io", Resource: "backups"},
|
||||
},
|
||||
}
|
||||
|
||||
sio := &isv1.SnapshotItemOutput{
|
||||
UpdatedItem: pvToReturn,
|
||||
SnapshotID: "",
|
||||
SnapshotMetadata: nil,
|
||||
AdditionalItems: additionalItems,
|
||||
HandledItems: nil,
|
||||
}
|
||||
|
||||
cii := &isv1.CreateItemInput{
|
||||
SnapshottedItem: nil,
|
||||
SnapshotID: "",
|
||||
ItemFromBackup: nil,
|
||||
SnapshotMetadata: nil,
|
||||
Params: nil,
|
||||
Restore: nil,
|
||||
}
|
||||
|
||||
cio := &isv1.CreateItemOutput{
|
||||
UpdatedItem: nil,
|
||||
AdditionalItems: nil,
|
||||
SkipRestore: false,
|
||||
}
|
||||
|
||||
pi := &isv1.ProgressInput{
|
||||
ItemID: velero.ResourceIdentifier{},
|
||||
SnapshotID: "",
|
||||
Backup: nil,
|
||||
}
|
||||
po := &isv1.ProgressOutput{
|
||||
Phase: isv1.SnapshotPhaseInProgress,
|
||||
Err: "",
|
||||
ItemsCompleted: 0,
|
||||
ItemsToComplete: 0,
|
||||
Started: time.Time{},
|
||||
Updated: time.Time{},
|
||||
}
|
||||
dsi := &isv1.DeleteSnapshotInput{
|
||||
SnapshotID: "",
|
||||
ItemFromBackup: nil,
|
||||
SnapshotMetadata: nil,
|
||||
Params: nil,
|
||||
}
|
||||
restartabletest.RunRestartableDelegateTests(
|
||||
t,
|
||||
common.PluginKindItemSnapshotter,
|
||||
func(key process.KindAndName, p process.RestartableProcess) interface{} {
|
||||
return &restartableItemSnapshotter{
|
||||
key: key,
|
||||
sharedPluginProcess: p,
|
||||
}
|
||||
},
|
||||
func() restartabletest.Mockable {
|
||||
return new(mocks.ItemSnapshotter)
|
||||
},
|
||||
restartabletest.RestartableDelegateTest{
|
||||
Function: "Init",
|
||||
Inputs: []interface{}{map[string]string{}},
|
||||
ExpectedErrorOutputs: []interface{}{errors.Errorf("reset error")},
|
||||
ExpectedDelegateOutputs: []interface{}{errors.Errorf("delegate error")},
|
||||
},
|
||||
restartabletest.RestartableDelegateTest{
|
||||
Function: "AppliesTo",
|
||||
Inputs: []interface{}{},
|
||||
ExpectedErrorOutputs: []interface{}{velero.ResourceSelector{}, errors.Errorf("reset error")},
|
||||
ExpectedDelegateOutputs: []interface{}{velero.ResourceSelector{IncludedNamespaces: []string{"a"}}, errors.Errorf("delegate error")},
|
||||
},
|
||||
restartabletest.RestartableDelegateTest{
|
||||
Function: "AlsoHandles",
|
||||
Inputs: []interface{}{&isv1.AlsoHandlesInput{}},
|
||||
ExpectedErrorOutputs: []interface{}{[]velero.ResourceIdentifier(nil), errors.Errorf("reset error")},
|
||||
ExpectedDelegateOutputs: []interface{}{[]velero.ResourceIdentifier(nil), errors.Errorf("delegate error")},
|
||||
},
|
||||
restartabletest.RestartableDelegateTest{
|
||||
Function: "SnapshotItem",
|
||||
Inputs: []interface{}{ctx, sii},
|
||||
ExpectedErrorOutputs: []interface{}{nil, errors.Errorf("reset error")},
|
||||
ExpectedDelegateOutputs: []interface{}{sio, errors.Errorf("delegate error")},
|
||||
},
|
||||
restartabletest.RestartableDelegateTest{
|
||||
Function: "CreateItemFromSnapshot",
|
||||
Inputs: []interface{}{ctx, cii},
|
||||
ExpectedErrorOutputs: []interface{}{nil, errors.Errorf("reset error")},
|
||||
ExpectedDelegateOutputs: []interface{}{cio, errors.Errorf("delegate error")},
|
||||
},
|
||||
restartabletest.RestartableDelegateTest{
|
||||
Function: "Progress",
|
||||
Inputs: []interface{}{pi},
|
||||
ExpectedErrorOutputs: []interface{}{nil, errors.Errorf("reset error")},
|
||||
ExpectedDelegateOutputs: []interface{}{po, errors.Errorf("delegate error")},
|
||||
},
|
||||
restartabletest.RestartableDelegateTest{
|
||||
Function: "DeleteSnapshot",
|
||||
Inputs: []interface{}{ctx, dsi},
|
||||
ExpectedErrorOutputs: []interface{}{errors.Errorf("reset error")},
|
||||
ExpectedDelegateOutputs: []interface{}{errors.Errorf("delegate error")},
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -27,7 +27,6 @@ import (
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||
biav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v1"
|
||||
biav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
|
||||
isv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/item_snapshotter/v1"
|
||||
riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1"
|
||||
riav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v2"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/collections"
|
||||
@@ -141,12 +140,6 @@ func NewDeleteItemActionResolver(actions []velero.DeleteItemAction) DeleteItemAc
|
||||
}
|
||||
}
|
||||
|
||||
func NewItemSnapshotterResolver(actions []isv1.ItemSnapshotter) ItemSnapshotterResolver {
|
||||
return ItemSnapshotterResolver{
|
||||
actions: actions,
|
||||
}
|
||||
}
|
||||
|
||||
type ActionResolver interface {
|
||||
ResolveAction(helper discovery.Helper, action velero.Applicable, log logrus.FieldLogger) (ResolvedAction, error)
|
||||
}
|
||||
@@ -287,32 +280,3 @@ func (recv DeleteItemActionResolver) ResolveActions(helper discovery.Helper, log
|
||||
}
|
||||
return resolved, nil
|
||||
}
|
||||
|
||||
type ItemSnapshotterResolvedAction struct {
|
||||
isv1.ItemSnapshotter
|
||||
resolvedAction
|
||||
}
|
||||
|
||||
type ItemSnapshotterResolver struct {
|
||||
actions []isv1.ItemSnapshotter
|
||||
}
|
||||
|
||||
func (recv ItemSnapshotterResolver) ResolveActions(helper discovery.Helper, log logrus.FieldLogger) ([]ItemSnapshotterResolvedAction, error) {
|
||||
var resolved []ItemSnapshotterResolvedAction
|
||||
for _, action := range recv.actions {
|
||||
resources, namespaces, selector, err := resolveAction(helper, action)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := ItemSnapshotterResolvedAction{
|
||||
ItemSnapshotter: action,
|
||||
resolvedAction: resolvedAction{
|
||||
ResourceIncludesExcludes: resources,
|
||||
NamespaceIncludesExcludes: namespaces,
|
||||
Selector: selector,
|
||||
},
|
||||
}
|
||||
resolved = append(resolved, res)
|
||||
}
|
||||
return resolved, nil
|
||||
}
|
||||
|
||||
@@ -47,9 +47,6 @@ const (
|
||||
// PluginKindDeleteItemAction represents a delete item action plugin.
|
||||
PluginKindDeleteItemAction PluginKind = "DeleteItemAction"
|
||||
|
||||
// PluginKindItemSnapshotter represents an item snapshotter plugin
|
||||
PluginKindItemSnapshotter PluginKind = "ItemSnapshotter"
|
||||
|
||||
// PluginKindPluginLister represents a plugin lister plugin.
|
||||
PluginKindPluginLister PluginKind = "PluginLister"
|
||||
)
|
||||
@@ -73,6 +70,5 @@ func AllPluginKinds() map[string]PluginKind {
|
||||
allPluginKinds[PluginKindRestoreItemAction.String()] = PluginKindRestoreItemAction
|
||||
allPluginKinds[PluginKindRestoreItemActionV2.String()] = PluginKindRestoreItemActionV2
|
||||
allPluginKinds[PluginKindDeleteItemAction.String()] = PluginKindDeleteItemAction
|
||||
allPluginKinds[PluginKindItemSnapshotter.String()] = PluginKindItemSnapshotter
|
||||
return allPluginKinds
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
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 framework
|
||||
|
||||
import (
|
||||
plugin "github.com/hashicorp/go-plugin"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/framework/common"
|
||||
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
||||
)
|
||||
|
||||
// ItemSnapshotterPlugin is an implementation of go-plugin's Plugin
|
||||
// interface with support for gRPC for the ItemSnapshotter
|
||||
// interface.
|
||||
type ItemSnapshotterPlugin struct {
|
||||
plugin.NetRPCUnsupportedPlugin
|
||||
*common.PluginBase
|
||||
}
|
||||
|
||||
// GRPCClient returns a clientDispenser for ItemSnapshotter gRPC clients.
|
||||
func (p *ItemSnapshotterPlugin) GRPCClient(_ context.Context, _ *plugin.GRPCBroker, clientConn *grpc.ClientConn) (interface{}, error) {
|
||||
return common.NewClientDispenser(p.ClientLogger, clientConn, newItemSnapshotterGRPCClient), nil
|
||||
}
|
||||
|
||||
// GRPCServer registers an ItemSnapshotter gRPC server.
|
||||
func (p *ItemSnapshotterPlugin) GRPCServer(_ *plugin.GRPCBroker, server *grpc.Server) error {
|
||||
proto.RegisterItemSnapshotterServer(server, &ItemSnapshotterGRPCServer{mux: p.ServerMux})
|
||||
return nil
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
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 framework
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/grpc"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/framework/common"
|
||||
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||
isv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/item_snapshotter/v1"
|
||||
)
|
||||
|
||||
// NewItemSnapshotterPlugin constructs a ItemSnapshotterPlugin.
|
||||
func NewItemSnapshotterPlugin(options ...common.PluginOption) *ItemSnapshotterPlugin {
|
||||
return &ItemSnapshotterPlugin{
|
||||
PluginBase: common.NewPluginBase(options...),
|
||||
}
|
||||
}
|
||||
|
||||
func newItemSnapshotterGRPCClient(base *common.ClientBase, clientConn *grpc.ClientConn) interface{} {
|
||||
return &ItemSnapshotterGRPCClient{
|
||||
ClientBase: base,
|
||||
grpcClient: proto.NewItemSnapshotterClient(clientConn),
|
||||
}
|
||||
}
|
||||
|
||||
// ItemSnapshotterGRPCClient implements the ItemSnapshotter interface and uses a
|
||||
// gRPC client to make calls to the plugin server.
|
||||
type ItemSnapshotterGRPCClient struct {
|
||||
*common.ClientBase
|
||||
grpcClient proto.ItemSnapshotterClient
|
||||
}
|
||||
|
||||
func (recv ItemSnapshotterGRPCClient) Init(config map[string]string) error {
|
||||
req := &proto.ItemSnapshotterInitRequest{
|
||||
Plugin: recv.Plugin,
|
||||
Config: config,
|
||||
}
|
||||
|
||||
_, err := recv.grpcClient.Init(context.Background(), req)
|
||||
return err
|
||||
}
|
||||
|
||||
func (recv ItemSnapshotterGRPCClient) AppliesTo() (velero.ResourceSelector, error) {
|
||||
req := &proto.ItemSnapshotterAppliesToRequest{
|
||||
Plugin: recv.Plugin,
|
||||
}
|
||||
|
||||
res, err := recv.grpcClient.AppliesTo(context.Background(), req)
|
||||
if err != nil {
|
||||
return velero.ResourceSelector{}, common.FromGRPCError(err)
|
||||
}
|
||||
|
||||
if res.ResourceSelector == nil {
|
||||
return velero.ResourceSelector{}, nil
|
||||
}
|
||||
|
||||
return velero.ResourceSelector{
|
||||
IncludedNamespaces: res.ResourceSelector.IncludedNamespaces,
|
||||
ExcludedNamespaces: res.ResourceSelector.ExcludedNamespaces,
|
||||
IncludedResources: res.ResourceSelector.IncludedResources,
|
||||
ExcludedResources: res.ResourceSelector.ExcludedResources,
|
||||
LabelSelector: res.ResourceSelector.Selector,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (recv ItemSnapshotterGRPCClient) AlsoHandles(input *isv1.AlsoHandlesInput) ([]velero.ResourceIdentifier, error) {
|
||||
itemJSON, err := json.Marshal(input.Item.UnstructuredContent())
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
backupJSON, err := json.Marshal(input.Backup)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
req := &proto.AlsoHandlesRequest{
|
||||
Plugin: recv.Plugin,
|
||||
Item: itemJSON,
|
||||
Backup: backupJSON,
|
||||
}
|
||||
res, err := recv.grpcClient.AlsoHandles(context.Background(), req)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
handledItems := unpackResourceIdentifiers(res.HandledItems)
|
||||
|
||||
return handledItems, nil
|
||||
}
|
||||
|
||||
func (recv ItemSnapshotterGRPCClient) SnapshotItem(ctx context.Context, input *isv1.SnapshotItemInput) (*isv1.SnapshotItemOutput, error) {
|
||||
itemJSON, err := json.Marshal(input.Item.UnstructuredContent())
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
backupJSON, err := json.Marshal(input.Backup)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
req := &proto.SnapshotItemRequest{
|
||||
Plugin: recv.Plugin,
|
||||
Item: itemJSON,
|
||||
Backup: backupJSON,
|
||||
}
|
||||
res, err := recv.grpcClient.SnapshotItem(ctx, req)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
var updatedItem unstructured.Unstructured
|
||||
if err := json.Unmarshal(res.Item, &updatedItem); err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
additionalItems := unpackResourceIdentifiers(res.AdditionalItems)
|
||||
handledItems := unpackResourceIdentifiers(res.HandledItems)
|
||||
|
||||
sio := isv1.SnapshotItemOutput{
|
||||
UpdatedItem: &updatedItem,
|
||||
SnapshotID: res.SnapshotID,
|
||||
SnapshotMetadata: res.SnapshotMetadata,
|
||||
AdditionalItems: additionalItems,
|
||||
HandledItems: handledItems,
|
||||
}
|
||||
return &sio, nil
|
||||
}
|
||||
|
||||
func (recv ItemSnapshotterGRPCClient) Progress(input *isv1.ProgressInput) (*isv1.ProgressOutput, error) {
|
||||
backupJSON, err := json.Marshal(input.Backup)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
req := &proto.ProgressRequest{
|
||||
Plugin: recv.Plugin,
|
||||
ItemID: resourceIdentifierToProto(input.ItemID),
|
||||
SnapshotID: input.SnapshotID,
|
||||
Backup: backupJSON,
|
||||
}
|
||||
|
||||
res, err := recv.grpcClient.Progress(context.Background(), req)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
// Validate phase
|
||||
|
||||
phase, err := isv1.SnapshotPhaseFromString(res.Phase)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
up := isv1.ProgressOutput{
|
||||
Phase: phase,
|
||||
Err: res.Err,
|
||||
ItemsCompleted: res.ItemsCompleted,
|
||||
ItemsToComplete: res.ItemsToComplete,
|
||||
Started: time.Unix(res.Started, res.StartedNano),
|
||||
Updated: time.Unix(res.Updated, res.UpdatedNano),
|
||||
}
|
||||
return &up, nil
|
||||
}
|
||||
|
||||
func (recv ItemSnapshotterGRPCClient) DeleteSnapshot(ctx context.Context, input *isv1.DeleteSnapshotInput) error {
|
||||
req := &proto.DeleteItemSnapshotRequest{
|
||||
Plugin: recv.Plugin,
|
||||
Params: input.Params,
|
||||
SnapshotID: input.SnapshotID,
|
||||
}
|
||||
_, err := recv.grpcClient.DeleteSnapshot(ctx, req) // Returns Empty as first arg so just ignore
|
||||
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (recv ItemSnapshotterGRPCClient) CreateItemFromSnapshot(ctx context.Context, input *isv1.CreateItemInput) (*isv1.CreateItemOutput, error) {
|
||||
itemJSON, err := json.Marshal(input.SnapshottedItem.UnstructuredContent())
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
itemFromBackupJSON, err := json.Marshal(input.ItemFromBackup.UnstructuredContent())
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
restoreJSON, err := json.Marshal(input.Restore)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
req := &proto.CreateItemFromSnapshotRequest{
|
||||
Plugin: recv.Plugin,
|
||||
Item: itemJSON,
|
||||
SnapshotID: input.SnapshotID,
|
||||
ItemFromBackup: itemFromBackupJSON,
|
||||
SnapshotMetadata: input.SnapshotMetadata,
|
||||
Params: input.Params,
|
||||
Restore: restoreJSON,
|
||||
}
|
||||
|
||||
res, err := recv.grpcClient.CreateItemFromSnapshot(ctx, req)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
var updatedItem unstructured.Unstructured
|
||||
if err := json.Unmarshal(res.Item, &updatedItem); err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
additionalItems := unpackResourceIdentifiers(res.AdditionalItems)
|
||||
|
||||
cio := isv1.CreateItemOutput{
|
||||
UpdatedItem: &updatedItem,
|
||||
AdditionalItems: additionalItems,
|
||||
SkipRestore: res.SkipRestore,
|
||||
}
|
||||
return &cio, nil
|
||||
}
|
||||
@@ -1,312 +0,0 @@
|
||||
/*
|
||||
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 framework
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
isv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/item_snapshotter/v1"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/framework/common"
|
||||
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
||||
)
|
||||
|
||||
// ItemSnapshotterGRPCServer implements the proto-generated ItemSnapshotterServer interface, and accepts
|
||||
// gRPC calls and forwards them to an implementation of the pluggable interface.
|
||||
type ItemSnapshotterGRPCServer struct {
|
||||
mux *common.ServerMux
|
||||
}
|
||||
|
||||
func (recv *ItemSnapshotterGRPCServer) getImpl(name string) (isv1.ItemSnapshotter, error) {
|
||||
impl, err := recv.mux.GetHandler(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
itemAction, ok := impl.(isv1.ItemSnapshotter)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("%T is not an item snapshotter", impl)
|
||||
}
|
||||
|
||||
return itemAction, nil
|
||||
}
|
||||
|
||||
func (recv *ItemSnapshotterGRPCServer) Init(c context.Context, req *proto.ItemSnapshotterInitRequest) (response *proto.Empty, err error) {
|
||||
defer func() {
|
||||
if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil {
|
||||
err = recoveredErr
|
||||
}
|
||||
}()
|
||||
|
||||
impl, err := recv.getImpl(req.Plugin)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
err = impl.Init(req.Config)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
return &proto.Empty{}, nil
|
||||
}
|
||||
|
||||
func (recv *ItemSnapshotterGRPCServer) AppliesTo(ctx context.Context, req *proto.ItemSnapshotterAppliesToRequest) (response *proto.ItemSnapshotterAppliesToResponse, err error) {
|
||||
defer func() {
|
||||
if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil {
|
||||
err = recoveredErr
|
||||
}
|
||||
}()
|
||||
|
||||
impl, err := recv.getImpl(req.Plugin)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
resourceSelector, err := impl.AppliesTo()
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
return &proto.ItemSnapshotterAppliesToResponse{
|
||||
ResourceSelector: &proto.ResourceSelector{
|
||||
IncludedNamespaces: resourceSelector.IncludedNamespaces,
|
||||
ExcludedNamespaces: resourceSelector.ExcludedNamespaces,
|
||||
IncludedResources: resourceSelector.IncludedResources,
|
||||
ExcludedResources: resourceSelector.ExcludedResources,
|
||||
Selector: resourceSelector.LabelSelector,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (recv *ItemSnapshotterGRPCServer) AlsoHandles(ctx context.Context, req *proto.AlsoHandlesRequest) (res *proto.AlsoHandlesResponse, err error) {
|
||||
defer func() {
|
||||
if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil {
|
||||
err = recoveredErr
|
||||
}
|
||||
}()
|
||||
|
||||
impl, err := recv.getImpl(req.Plugin)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
var item unstructured.Unstructured
|
||||
var backup api.Backup
|
||||
|
||||
if err := json.Unmarshal(req.Item, &item); err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
if err := json.Unmarshal(req.Backup, &backup); err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
ahi := isv1.AlsoHandlesInput{
|
||||
Item: &item,
|
||||
Backup: &backup,
|
||||
}
|
||||
alsoHandles, err := impl.AlsoHandles(&ahi)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
res = &proto.AlsoHandlesResponse{}
|
||||
|
||||
for _, item := range alsoHandles {
|
||||
res.HandledItems = append(res.HandledItems, resourceIdentifierToProto(item))
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (recv *ItemSnapshotterGRPCServer) SnapshotItem(ctx context.Context, req *proto.SnapshotItemRequest) (res *proto.SnapshotItemResponse, err error) {
|
||||
defer func() {
|
||||
if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil {
|
||||
err = recoveredErr
|
||||
}
|
||||
}()
|
||||
|
||||
impl, err := recv.getImpl(req.Plugin)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
var item unstructured.Unstructured
|
||||
var backup api.Backup
|
||||
|
||||
if err := json.Unmarshal(req.Item, &item); err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
if err := json.Unmarshal(req.Backup, &backup); err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
sii := isv1.SnapshotItemInput{
|
||||
Item: &item,
|
||||
Params: req.Params,
|
||||
Backup: &backup,
|
||||
}
|
||||
sio, err := impl.SnapshotItem(ctx, &sii)
|
||||
|
||||
// If the plugin implementation returned a nil updatedItem (meaning no modifications), reset updatedItem to the
|
||||
// original item.
|
||||
var updatedItemJSON []byte
|
||||
if sio.UpdatedItem == nil {
|
||||
updatedItemJSON = req.Item
|
||||
} else {
|
||||
updatedItemJSON, err = json.Marshal(sio.UpdatedItem.UnstructuredContent())
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
}
|
||||
res = &proto.SnapshotItemResponse{
|
||||
Item: updatedItemJSON,
|
||||
SnapshotID: sio.SnapshotID,
|
||||
SnapshotMetadata: sio.SnapshotMetadata,
|
||||
}
|
||||
res.AdditionalItems = packResourceIdentifiers(sio.AdditionalItems)
|
||||
res.HandledItems = packResourceIdentifiers(sio.HandledItems)
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (recv *ItemSnapshotterGRPCServer) Progress(ctx context.Context, req *proto.ProgressRequest) (res *proto.ProgressResponse, err error) {
|
||||
defer func() {
|
||||
if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil {
|
||||
err = recoveredErr
|
||||
}
|
||||
}()
|
||||
impl, err := recv.getImpl(req.Plugin)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
var backup api.Backup
|
||||
|
||||
if err := json.Unmarshal(req.Backup, &backup); err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
sipi := &isv1.ProgressInput{
|
||||
ItemID: protoToResourceIdentifier(req.ItemID),
|
||||
SnapshotID: req.SnapshotID,
|
||||
Backup: &backup,
|
||||
}
|
||||
|
||||
sipo, err := impl.Progress(sipi)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
res = &proto.ProgressResponse{
|
||||
Phase: string(sipo.Phase),
|
||||
ItemsCompleted: sipo.ItemsCompleted,
|
||||
ItemsToComplete: sipo.ItemsToComplete,
|
||||
Started: sipo.Started.Unix(),
|
||||
StartedNano: sipo.Started.UnixNano(),
|
||||
Updated: sipo.Updated.Unix(),
|
||||
UpdatedNano: sipo.Updated.UnixNano(),
|
||||
Err: sipo.Err,
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (recv *ItemSnapshotterGRPCServer) DeleteSnapshot(ctx context.Context, req *proto.DeleteItemSnapshotRequest) (empty *proto.Empty, err error) {
|
||||
defer func() {
|
||||
if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil {
|
||||
err = recoveredErr
|
||||
}
|
||||
}()
|
||||
impl, err := recv.getImpl(req.Plugin)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
var itemFromBackup unstructured.Unstructured
|
||||
if err := json.Unmarshal(req.ItemFromBackup, &itemFromBackup); err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
|
||||
disi := isv1.DeleteSnapshotInput{
|
||||
SnapshotID: req.SnapshotID,
|
||||
ItemFromBackup: &itemFromBackup,
|
||||
SnapshotMetadata: req.Metadata,
|
||||
Params: req.Params,
|
||||
}
|
||||
|
||||
err = impl.DeleteSnapshot(ctx, &disi)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (recv *ItemSnapshotterGRPCServer) CreateItemFromSnapshot(ctx context.Context, req *proto.CreateItemFromSnapshotRequest) (res *proto.CreateItemFromSnapshotResponse, err error) {
|
||||
defer func() {
|
||||
if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil {
|
||||
err = recoveredErr
|
||||
}
|
||||
}()
|
||||
impl, err := recv.getImpl(req.Plugin)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
var snapshottedItem unstructured.Unstructured
|
||||
if err := json.Unmarshal(req.Item, &snapshottedItem); err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
|
||||
var itemFromBackup unstructured.Unstructured
|
||||
if err := json.Unmarshal(req.Item, &itemFromBackup); err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
|
||||
var restore api.Restore
|
||||
|
||||
if err := json.Unmarshal(req.Restore, &restore); err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
|
||||
cii := isv1.CreateItemInput{
|
||||
SnapshottedItem: &snapshottedItem,
|
||||
SnapshotID: req.SnapshotID,
|
||||
ItemFromBackup: &itemFromBackup,
|
||||
SnapshotMetadata: req.SnapshotMetadata,
|
||||
Params: req.Params,
|
||||
Restore: &restore,
|
||||
}
|
||||
|
||||
cio, err := impl.CreateItemFromSnapshot(ctx, &cii)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
var updatedItemJSON []byte
|
||||
if cio.UpdatedItem == nil {
|
||||
updatedItemJSON = req.Item
|
||||
} else {
|
||||
updatedItemJSON, err = json.Marshal(cio.UpdatedItem.UnstructuredContent())
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
}
|
||||
res = &proto.CreateItemFromSnapshotResponse{
|
||||
Item: updatedItemJSON,
|
||||
SkipRestore: cio.SkipRestore,
|
||||
}
|
||||
res.AdditionalItems = packResourceIdentifiers(cio.AdditionalItems)
|
||||
|
||||
return
|
||||
}
|
||||
@@ -30,7 +30,6 @@ func TestPluginImplementationsAreGRPCPlugins(t *testing.T) {
|
||||
new(ObjectStorePlugin),
|
||||
new(PluginListerPlugin),
|
||||
new(RestoreItemActionPlugin),
|
||||
new(ItemSnapshotterPlugin),
|
||||
}
|
||||
|
||||
for _, impl := range pluginImpls {
|
||||
|
||||
@@ -90,11 +90,6 @@ type Server interface {
|
||||
// RegisterDeleteItemActions registers multiple Delete item actions.
|
||||
RegisterDeleteItemActions(map[string]common.HandlerInitializer) Server
|
||||
|
||||
RegisterItemSnapshotter(pluginName string, initializer common.HandlerInitializer) Server
|
||||
|
||||
// RegisterItemSnapshotters registers multiple Item Snapshotters
|
||||
RegisterItemSnapshotters(map[string]common.HandlerInitializer) Server
|
||||
|
||||
// Server runs the plugin server.
|
||||
Serve()
|
||||
}
|
||||
@@ -111,7 +106,6 @@ type server struct {
|
||||
restoreItemAction *RestoreItemActionPlugin
|
||||
restoreItemActionV2 *riav2.RestoreItemActionPlugin
|
||||
deleteItemAction *DeleteItemActionPlugin
|
||||
itemSnapshotter *ItemSnapshotterPlugin
|
||||
}
|
||||
|
||||
// NewServer returns a new Server
|
||||
@@ -128,7 +122,6 @@ func NewServer() Server {
|
||||
restoreItemAction: NewRestoreItemActionPlugin(common.ServerLogger(log)),
|
||||
restoreItemActionV2: riav2.NewRestoreItemActionPlugin(common.ServerLogger(log)),
|
||||
deleteItemAction: NewDeleteItemActionPlugin(common.ServerLogger(log)),
|
||||
itemSnapshotter: NewItemSnapshotterPlugin(common.ServerLogger(log)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,17 +217,6 @@ func (s *server) RegisterDeleteItemActions(m map[string]common.HandlerInitialize
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *server) RegisterItemSnapshotter(name string, initializer common.HandlerInitializer) Server {
|
||||
s.itemSnapshotter.Register(name, initializer)
|
||||
return s
|
||||
}
|
||||
func (s *server) RegisterItemSnapshotters(m map[string]common.HandlerInitializer) Server {
|
||||
for name := range m {
|
||||
s.RegisterItemSnapshotter(name, m[name])
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// getNames returns a list of PluginIdentifiers registered with plugin.
|
||||
func getNames(command string, kind common.PluginKind, plugin Interface) []PluginIdentifier {
|
||||
var pluginIdentifiers []PluginIdentifier
|
||||
@@ -266,7 +248,6 @@ func (s *server) Serve() {
|
||||
pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindRestoreItemAction, s.restoreItemAction)...)
|
||||
pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindRestoreItemActionV2, s.restoreItemActionV2)...)
|
||||
pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindDeleteItemAction, s.deleteItemAction)...)
|
||||
pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindItemSnapshotter, s.itemSnapshotter)...)
|
||||
|
||||
pluginLister := NewPluginLister(pluginIdentifiers...)
|
||||
|
||||
@@ -281,7 +262,6 @@ func (s *server) Serve() {
|
||||
string(common.PluginKindRestoreItemAction): s.restoreItemAction,
|
||||
string(common.PluginKindRestoreItemActionV2): s.restoreItemActionV2,
|
||||
string(common.PluginKindDeleteItemAction): s.deleteItemAction,
|
||||
string(common.PluginKindItemSnapshotter): s.itemSnapshotter,
|
||||
},
|
||||
GRPCServer: plugin.DefaultGRPCServer,
|
||||
})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,8 +4,6 @@ package mocks
|
||||
|
||||
import (
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
item_snapshotterv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/item_snapshotter/v1"
|
||||
|
||||
restoreitemactionv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1"
|
||||
|
||||
restoreitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v2"
|
||||
@@ -167,52 +165,6 @@ func (_m *Manager) GetDeleteItemActions() ([]velero.DeleteItemAction, error) {
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetItemSnapshotter provides a mock function with given fields: name
|
||||
func (_m *Manager) GetItemSnapshotter(name string) (item_snapshotterv1.ItemSnapshotter, error) {
|
||||
ret := _m.Called(name)
|
||||
|
||||
var r0 item_snapshotterv1.ItemSnapshotter
|
||||
if rf, ok := ret.Get(0).(func(string) item_snapshotterv1.ItemSnapshotter); ok {
|
||||
r0 = rf(name)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(item_snapshotterv1.ItemSnapshotter)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||
r1 = rf(name)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetItemSnapshotters provides a mock function with given fields:
|
||||
func (_m *Manager) GetItemSnapshotters() ([]item_snapshotterv1.ItemSnapshotter, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 []item_snapshotterv1.ItemSnapshotter
|
||||
if rf, ok := ret.Get(0).(func() []item_snapshotterv1.ItemSnapshotter); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]item_snapshotterv1.ItemSnapshotter)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetObjectStore provides a mock function with given fields: name
|
||||
func (_m *Manager) GetObjectStore(name string) (velero.ObjectStore, error) {
|
||||
ret := _m.Called(name)
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
syntax = "proto3";
|
||||
package generated;
|
||||
option go_package = "github.com/vmware-tanzu/velero/pkg/plugin/generated";
|
||||
|
||||
import "Shared.proto";
|
||||
|
||||
message ItemSnapshotterAppliesToRequest {
|
||||
string plugin = 1;
|
||||
}
|
||||
|
||||
message ItemSnapshotterAppliesToResponse {
|
||||
ResourceSelector ResourceSelector = 1;
|
||||
}
|
||||
|
||||
message AlsoHandlesRequest {
|
||||
string plugin = 1;
|
||||
bytes item = 2;
|
||||
bytes backup = 3;
|
||||
}
|
||||
|
||||
message AlsoHandlesResponse {
|
||||
repeated ResourceIdentifier handledItems = 1;
|
||||
}
|
||||
|
||||
message SnapshotItemRequest {
|
||||
string plugin = 1;
|
||||
bytes item = 2;
|
||||
map<string, string> params = 3;
|
||||
bytes backup = 4;
|
||||
}
|
||||
|
||||
message SnapshotItemResponse {
|
||||
bytes item = 1;
|
||||
string snapshotID = 2;
|
||||
map<string, string> snapshotMetadata = 3;
|
||||
repeated ResourceIdentifier additionalItems = 4;
|
||||
repeated ResourceIdentifier handledItems = 5;
|
||||
}
|
||||
|
||||
message ProgressRequest {
|
||||
string plugin = 1;
|
||||
ResourceIdentifier itemID = 2;
|
||||
string snapshotID = 3;
|
||||
bytes backup = 4;
|
||||
}
|
||||
|
||||
message ProgressResponse {
|
||||
string phase = 1;
|
||||
int64 itemsCompleted = 2;
|
||||
int64 itemsToComplete = 3;
|
||||
int64 started = 4;
|
||||
int64 startedNano = 5;
|
||||
int64 updated = 6;
|
||||
int64 updatedNano = 7;
|
||||
string err = 8;
|
||||
}
|
||||
|
||||
message DeleteItemSnapshotRequest {
|
||||
string plugin = 1;
|
||||
string snapshotID = 2;
|
||||
bytes itemFromBackup = 3;
|
||||
map<string, string> metadata = 4;
|
||||
map<string, string> params = 5;
|
||||
}
|
||||
|
||||
message CreateItemFromSnapshotRequest {
|
||||
string plugin = 1;
|
||||
bytes item = 2;
|
||||
string snapshotID = 3;
|
||||
bytes itemFromBackup = 4;
|
||||
map<string, string> snapshotMetadata = 5;
|
||||
map<string, string> params = 6;
|
||||
bytes restore = 7;
|
||||
}
|
||||
|
||||
message CreateItemFromSnapshotResponse {
|
||||
bytes item = 1;
|
||||
repeated ResourceIdentifier additionalItems = 2;
|
||||
bool skipRestore = 3;
|
||||
}
|
||||
|
||||
message ItemSnapshotterInitRequest {
|
||||
string plugin = 1;
|
||||
map<string, string> config = 2;
|
||||
}
|
||||
|
||||
service ItemSnapshotter {
|
||||
rpc Init(ItemSnapshotterInitRequest) returns (Empty);
|
||||
rpc AppliesTo(ItemSnapshotterAppliesToRequest) returns (ItemSnapshotterAppliesToResponse);
|
||||
rpc AlsoHandles(AlsoHandlesRequest) returns (AlsoHandlesResponse);
|
||||
rpc SnapshotItem(SnapshotItemRequest) returns (SnapshotItemResponse);
|
||||
rpc Progress(ProgressRequest) returns (ProgressResponse);
|
||||
rpc DeleteSnapshot(DeleteItemSnapshotRequest) returns (Empty);
|
||||
rpc CreateItemFromSnapshot(CreateItemFromSnapshotRequest) returns (CreateItemFromSnapshotResponse);
|
||||
}
|
||||
@@ -1,196 +0,0 @@
|
||||
/*
|
||||
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 v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||
)
|
||||
|
||||
type AlsoHandlesInput struct {
|
||||
// Item is the item that will be snapshotted
|
||||
Item runtime.Unstructured
|
||||
// Backup is the representation of the backup resource being processed by Velero.
|
||||
Backup *api.Backup
|
||||
}
|
||||
|
||||
type SnapshotItemInput struct {
|
||||
// Item is the item to snapshot
|
||||
Item runtime.Unstructured
|
||||
// Params are parameters to the snapshot
|
||||
Params map[string]string
|
||||
// Backup is the representation of the backup resource being processed by Velero.
|
||||
Backup *api.Backup
|
||||
}
|
||||
|
||||
type SnapshotItemOutput struct {
|
||||
// UpdatedItem is the Item that should be included in the backup. It can optionally be modified during the Snapshot
|
||||
UpdatedItem runtime.Unstructured
|
||||
// SnapshotID identifies the snapshot that was taken
|
||||
SnapshotID string
|
||||
// SnapshotMetadata is information in addition to the SnapshotID that the
|
||||
// plugin wants to store in the backup. SnapshotMetadata will be passed
|
||||
// back in for DeleteSnapshot and CreateItemFromSnapshot
|
||||
SnapshotMetadata map[string]string
|
||||
// AdditionalItems are resources that need to be included in the backup to support this snapshhot
|
||||
AdditionalItems []velero.ResourceIdentifier
|
||||
// Items that were handled by this snapshot that should be excluded from the backup
|
||||
HandledItems []velero.ResourceIdentifier
|
||||
}
|
||||
|
||||
// ProgressInput contains the input parameters for the ItemSnapshotter's Progress function.
|
||||
type ProgressInput struct {
|
||||
// ItemID is the id of item that was stored in the backup
|
||||
ItemID velero.ResourceIdentifier
|
||||
// SnapshotID is the snapshot ID returned by ItemSnapshotter
|
||||
SnapshotID string
|
||||
// Backup is the representation of the backup resource being processed by Velero.
|
||||
Backup *api.Backup
|
||||
}
|
||||
|
||||
// SnapshotPhase is the lifecycle phase of a Velero item snapshot.
|
||||
type SnapshotPhase string
|
||||
|
||||
const (
|
||||
// SnapshotPhaseInProgress means the snapshot of the item has been taken and the point-in-time has been preserved,
|
||||
// but the snapshot is not ready for use yet
|
||||
SnapshotPhaseInProgress = SnapshotPhase("InProgress")
|
||||
|
||||
// SnapshotPhaseCompleted means the item snapshot was successfully created and can be restored from
|
||||
SnapshotPhaseCompleted = SnapshotPhase("Completed")
|
||||
|
||||
// SnapshotPhaseFailed means the item snapshot was unable to be completed
|
||||
SnapshotPhaseFailed = SnapshotPhase("Failed")
|
||||
)
|
||||
|
||||
func SnapshotPhaseFromString(phase string) (SnapshotPhase, error) {
|
||||
switch phase {
|
||||
case string(SnapshotPhaseInProgress):
|
||||
return SnapshotPhaseInProgress, nil
|
||||
case string(SnapshotPhaseCompleted):
|
||||
return SnapshotPhaseCompleted, nil
|
||||
case string(SnapshotPhaseFailed):
|
||||
return SnapshotPhaseFailed, nil
|
||||
default:
|
||||
return SnapshotPhase(""), fmt.Errorf("%s is not a valid SnapshotPhase", phase)
|
||||
}
|
||||
}
|
||||
|
||||
type ProgressOutput struct {
|
||||
// Phase of the snapshot. If the phase is SnapshotPhaseFailed, the error will be in the Err string
|
||||
Phase SnapshotPhase
|
||||
// Err is a message about the error(s) that occurred during the processing of the snapshot
|
||||
Err string
|
||||
// ItemsCompleted is the number of items that have been completed in processing of the snapshot
|
||||
// This is simply to show progress, when Phase goes to SnapshotPhaseCompleted ItemsCompleted and ItemsToComplete
|
||||
// should be the same. This could be blocks to copy, files to copy, or anything else.
|
||||
ItemsCompleted int64
|
||||
// ItemsToComplete is the number of items that need to be completed
|
||||
ItemsToComplete int64
|
||||
// Started indicates when processing on the snapshot began (usually the time the snapshot was taken)
|
||||
Started time.Time
|
||||
// Updated indicates the time the status was last updated. Time 0 (time.Unix(0, 0)) is returned if unknown.
|
||||
Updated time.Time
|
||||
}
|
||||
|
||||
type DeleteSnapshotInput struct {
|
||||
// SnapshotID is the snapshot to delete
|
||||
SnapshotID string
|
||||
// ItemFromBackup is the resource that was included in the backup
|
||||
ItemFromBackup runtime.Unstructured
|
||||
// SnapshotMetadata is the metadata that was returned when the snapshot was originally taken
|
||||
SnapshotMetadata map[string]string
|
||||
// Params are parameters to the deletion
|
||||
Params map[string]string
|
||||
}
|
||||
|
||||
type CreateItemInput struct {
|
||||
// The snapshotted item at this stage of the restore (RestoreItemActions may
|
||||
// have modified the item prior to CreateItemFromSnapshot being called)
|
||||
SnapshottedItem runtime.Unstructured
|
||||
// SnapshotID is the snapshot to create the item from
|
||||
SnapshotID string
|
||||
// ItemFromBackup is the snapshotted item that was stored in the backup
|
||||
ItemFromBackup runtime.Unstructured
|
||||
// SnapshotMetadata is the metadata that was returned when the snapshot was originally taken
|
||||
SnapshotMetadata map[string]string
|
||||
// Params are parameters to the deletion
|
||||
Params map[string]string
|
||||
// Restore is the representation of the restore resource being processed by Velero.
|
||||
Restore *api.Restore
|
||||
}
|
||||
|
||||
type CreateItemOutput struct {
|
||||
// UpdatedItem is the item being restored mutated by ItemAction.
|
||||
UpdatedItem runtime.Unstructured
|
||||
|
||||
// AdditionalItems is a list of additional related items that should
|
||||
// be restored.
|
||||
AdditionalItems []velero.ResourceIdentifier
|
||||
|
||||
// SkipRestore tells velero to stop executing further actions
|
||||
// on this item, and skip the restore step. When this field's
|
||||
// value is true, AdditionalItems will be ignored.
|
||||
SkipRestore bool
|
||||
}
|
||||
|
||||
// ItemSnapshotter handles snapshots on an individual item being backed up.
|
||||
type ItemSnapshotter interface {
|
||||
|
||||
// Init prepares the ItemSnapshotter for usage using the provided map of
|
||||
// configuration key-value pairs. It returns an error if the ItemSnapshotter
|
||||
// cannot be initialized from the provided config.
|
||||
Init(config map[string]string) error
|
||||
|
||||
// AppliesTo returns information about which resources this action should be invoked for.
|
||||
// An ItemSnapshotter's SnapshotItem method will only be invoked on items that match the returned
|
||||
// selector. A zero-valued ResourceSelector matches all resources.
|
||||
AppliesTo() (velero.ResourceSelector, error)
|
||||
|
||||
// AlsoHandles is called for each item this ItemSnapshotter should handle and returns any items
|
||||
// which will be handled by this plugin when snapshotting the item. These items will be excluded from the
|
||||
// items being backed up. AlsoHandles will be called before SnapshotItem is called. For example, a database may expose
|
||||
// a database resource that can be snapshotted. If the database uses a PVC that will be snapshotted/backed up as
|
||||
// part of the database snapshot, that PVC should be returned when AlsoHandles is invoked. This is different from
|
||||
// AdditionalItems (returned in SnapshotItemOutput and CreateItemOutput) which are specifying additional resources
|
||||
// that Velero should store in the backup or create.
|
||||
AlsoHandles(input *AlsoHandlesInput) ([]velero.ResourceIdentifier, error)
|
||||
|
||||
// SnapshotItem causes the ItemSnapshotter to snapshot the specified item. It may also
|
||||
// perform arbitrary logic with the item being backed up, including mutating the item itself prior to backup.
|
||||
// The item (unmodified or modified) should be returned, along with an optional slice of ResourceIdentifiers specifying
|
||||
// additional related items that should be backed up.
|
||||
// A caller can pass a context that includes a timeout. If the time to take the snapshot exceeds the
|
||||
// time in the context, the plugin may abort the snapshot. The context timeout does not apply to upload
|
||||
// time that occurs after SnapshotItem returns
|
||||
SnapshotItem(ctx context.Context, input *SnapshotItemInput) (*SnapshotItemOutput, error)
|
||||
|
||||
// Progress will return the progress of a snapshot that is being uploaded
|
||||
Progress(input *ProgressInput) (*ProgressOutput, error)
|
||||
|
||||
// DeleteSnapshot removes a snapshot
|
||||
DeleteSnapshot(ctx context.Context, input *DeleteSnapshotInput) error
|
||||
|
||||
// CreateItemFromSnapshot creates a new item from the snapshot
|
||||
CreateItemFromSnapshot(ctx context.Context, input *CreateItemInput) (*CreateItemOutput, error)
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
// Code generated by mockery v0.0.0-dev. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
context "context"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
velero "github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||
v1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/item_snapshotter/v1"
|
||||
)
|
||||
|
||||
// ItemSnapshotter is an autogenerated mock type for the ItemSnapshotter type
|
||||
type ItemSnapshotter struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// AlsoHandles provides a mock function with given fields: input
|
||||
func (_m *ItemSnapshotter) AlsoHandles(input *v1.AlsoHandlesInput) ([]velero.ResourceIdentifier, error) {
|
||||
ret := _m.Called(input)
|
||||
|
||||
var r0 []velero.ResourceIdentifier
|
||||
if rf, ok := ret.Get(0).(func(*v1.AlsoHandlesInput) []velero.ResourceIdentifier); ok {
|
||||
r0 = rf(input)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]velero.ResourceIdentifier)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*v1.AlsoHandlesInput) error); ok {
|
||||
r1 = rf(input)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// AppliesTo provides a mock function with given fields:
|
||||
func (_m *ItemSnapshotter) AppliesTo() (velero.ResourceSelector, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 velero.ResourceSelector
|
||||
if rf, ok := ret.Get(0).(func() velero.ResourceSelector); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(velero.ResourceSelector)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// CreateItemFromSnapshot provides a mock function with given fields: ctx, input
|
||||
func (_m *ItemSnapshotter) CreateItemFromSnapshot(ctx context.Context, input *v1.CreateItemInput) (*v1.CreateItemOutput, error) {
|
||||
ret := _m.Called(ctx, input)
|
||||
|
||||
var r0 *v1.CreateItemOutput
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v1.CreateItemInput) *v1.CreateItemOutput); ok {
|
||||
r0 = rf(ctx, input)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v1.CreateItemOutput)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v1.CreateItemInput) error); ok {
|
||||
r1 = rf(ctx, input)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// DeleteSnapshot provides a mock function with given fields: ctx, input
|
||||
func (_m *ItemSnapshotter) DeleteSnapshot(ctx context.Context, input *v1.DeleteSnapshotInput) error {
|
||||
ret := _m.Called(ctx, input)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v1.DeleteSnapshotInput) error); ok {
|
||||
r0 = rf(ctx, input)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Init provides a mock function with given fields: config
|
||||
func (_m *ItemSnapshotter) Init(config map[string]string) error {
|
||||
ret := _m.Called(config)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(map[string]string) error); ok {
|
||||
r0 = rf(config)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Progress provides a mock function with given fields: input
|
||||
func (_m *ItemSnapshotter) Progress(input *v1.ProgressInput) (*v1.ProgressOutput, error) {
|
||||
ret := _m.Called(input)
|
||||
|
||||
var r0 *v1.ProgressOutput
|
||||
if rf, ok := ret.Get(0).(func(*v1.ProgressInput) *v1.ProgressOutput); ok {
|
||||
r0 = rf(input)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v1.ProgressOutput)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*v1.ProgressInput) error); ok {
|
||||
r1 = rf(input)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SnapshotItem provides a mock function with given fields: ctx, input
|
||||
func (_m *ItemSnapshotter) SnapshotItem(ctx context.Context, input *v1.SnapshotItemInput) (*v1.SnapshotItemOutput, error) {
|
||||
ret := _m.Called(ctx, input)
|
||||
|
||||
var r0 *v1.SnapshotItemOutput
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v1.SnapshotItemInput) *v1.SnapshotItemOutput); ok {
|
||||
r0 = rf(ctx, input)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v1.SnapshotItemOutput)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v1.SnapshotItemInput) error); ok {
|
||||
r1 = rf(ctx, input)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
+1
-11
@@ -84,7 +84,6 @@ type Restorer interface {
|
||||
RestoreWithResolvers(
|
||||
req *Request,
|
||||
restoreItemActionResolver framework.RestoreItemActionResolverV2,
|
||||
itemSnapshotterResolver framework.ItemSnapshotterResolver,
|
||||
volumeSnapshotterGetter VolumeSnapshotterGetter,
|
||||
) (Result, Result)
|
||||
}
|
||||
@@ -159,14 +158,12 @@ func (kr *kubernetesRestorer) Restore(
|
||||
volumeSnapshotterGetter VolumeSnapshotterGetter,
|
||||
) (Result, Result) {
|
||||
resolver := framework.NewRestoreItemActionResolverV2(actions)
|
||||
snapshotItemResolver := framework.NewItemSnapshotterResolver(nil)
|
||||
return kr.RestoreWithResolvers(req, resolver, snapshotItemResolver, volumeSnapshotterGetter)
|
||||
return kr.RestoreWithResolvers(req, resolver, volumeSnapshotterGetter)
|
||||
}
|
||||
|
||||
func (kr *kubernetesRestorer) RestoreWithResolvers(
|
||||
req *Request,
|
||||
restoreItemActionResolver framework.RestoreItemActionResolverV2,
|
||||
itemSnapshotterResolver framework.ItemSnapshotterResolver,
|
||||
volumeSnapshotterGetter VolumeSnapshotterGetter,
|
||||
) (Result, Result) {
|
||||
// metav1.LabelSelectorAsSelector converts a nil LabelSelector to a
|
||||
@@ -222,11 +219,6 @@ func (kr *kubernetesRestorer) RestoreWithResolvers(
|
||||
return Result{}, Result{Velero: []string{err.Error()}}
|
||||
}
|
||||
|
||||
resolvedItemSnapshotterActions, err := itemSnapshotterResolver.ResolveActions(kr.discoveryHelper, kr.logger)
|
||||
if err != nil {
|
||||
return Result{}, Result{Velero: []string{err.Error()}}
|
||||
}
|
||||
|
||||
podVolumeTimeout := kr.podVolumeTimeout
|
||||
if val := req.Restore.Annotations[velerov1api.PodVolumeOperationTimeoutAnnotation]; val != "" {
|
||||
parsed, err := time.ParseDuration(val)
|
||||
@@ -291,7 +283,6 @@ func (kr *kubernetesRestorer) RestoreWithResolvers(
|
||||
fileSystem: kr.fileSystem,
|
||||
namespaceClient: kr.namespaceClient,
|
||||
restoreItemActions: resolvedActions,
|
||||
itemSnapshotterActions: resolvedItemSnapshotterActions,
|
||||
volumeSnapshotterGetter: volumeSnapshotterGetter,
|
||||
podVolumeRestorer: podVolumeRestorer,
|
||||
podVolumeErrs: make(chan error),
|
||||
@@ -335,7 +326,6 @@ type restoreContext struct {
|
||||
fileSystem filesystem.Interface
|
||||
namespaceClient corev1.NamespaceInterface
|
||||
restoreItemActions []framework.RestoreItemResolvedActionV2
|
||||
itemSnapshotterActions []framework.ItemSnapshotterResolvedAction
|
||||
volumeSnapshotterGetter VolumeSnapshotterGetter
|
||||
podVolumeRestorer podvolume.Restorer
|
||||
podVolumeWaitGroup sync.WaitGroup
|
||||
|
||||
Reference in New Issue
Block a user