diff --git a/internal/delete/delete_item_action_handler.go b/internal/delete/delete_item_action_handler.go index b08c8e024e..bdcf511b24 100644 --- a/internal/delete/delete_item_action_handler.go +++ b/internal/delete/delete_item_action_handler.go @@ -48,7 +48,7 @@ type Context struct { func InvokeDeleteActions(ctx *Context) error { var err error resolver := framework.NewDeleteItemActionResolver(ctx.Actions) - ctx.resolvedActions, err = resolver.ResolveActions(ctx.DiscoveryHelper) + ctx.resolvedActions, err = resolver.ResolveActions(ctx.DiscoveryHelper, ctx.Log) // No actions installed and no error means we don't have to continue; // just do the backup deletion without worrying about plugins. if len(ctx.resolvedActions) == 0 && err == nil { diff --git a/internal/velero/serverstatusrequest.go b/internal/velero/serverstatusrequest.go index a220c5c19e..c9c8acc0a5 100644 --- a/internal/velero/serverstatusrequest.go +++ b/internal/velero/serverstatusrequest.go @@ -19,17 +19,18 @@ package velero import ( velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" ) type PluginLister interface { // List returns all PluginIdentifiers for kind. - List(kind framework.PluginKind) []framework.PluginIdentifier + List(kind common.PluginKind) []framework.PluginIdentifier } // GetInstalledPluginInfo returns a list of installed plugins func GetInstalledPluginInfo(pluginLister PluginLister) []velerov1api.PluginInfo { var plugins []velerov1api.PluginInfo - for _, v := range framework.AllPluginKinds() { + for _, v := range common.AllPluginKinds() { list := pluginLister.List(v) for _, plugin := range list { pluginInfo := velerov1api.PluginInfo{ diff --git a/pkg/backup/backup.go b/pkg/backup/backup.go index c613cba521..c8795ce4b9 100644 --- a/pkg/backup/backup.go +++ b/pkg/backup/backup.go @@ -211,13 +211,13 @@ func (kb *kubernetesBackupper) BackupWithResolvers(log logrus.FieldLogger, return err } - backupRequest.ResolvedActions, err = backupItemActionResolver.ResolveActions(kb.discoveryHelper) + backupRequest.ResolvedActions, err = backupItemActionResolver.ResolveActions(kb.discoveryHelper, log) if err != nil { log.WithError(errors.WithStack(err)).Debugf("Error from backupItemActionResolver.ResolveActions") return err } - backupRequest.ResolvedItemSnapshotters, err = itemSnapshotterResolver.ResolveActions(kb.discoveryHelper) + backupRequest.ResolvedItemSnapshotters, err = itemSnapshotterResolver.ResolveActions(kb.discoveryHelper, log) if err != nil { log.WithError(errors.WithStack(err)).Debugf("Error from itemSnapshotterResolver.ResolveActions") return err diff --git a/pkg/cmd/server/plugin/plugin.go b/pkg/cmd/server/plugin/plugin.go index 5dec03856b..64dbe4572a 100644 --- a/pkg/cmd/server/plugin/plugin.go +++ b/pkg/cmd/server/plugin/plugin.go @@ -28,6 +28,7 @@ import ( "github.com/vmware-tanzu/velero/pkg/client" velerodiscovery "github.com/vmware-tanzu/velero/pkg/discovery" veleroplugin "github.com/vmware-tanzu/velero/pkg/plugin/framework" + plugincommon "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/restore" ) @@ -76,7 +77,7 @@ func newPodBackupItemAction(logger logrus.FieldLogger) (interface{}, error) { return backup.NewPodAction(logger), nil } -func newServiceAccountBackupItemAction(f client.Factory) veleroplugin.HandlerInitializer { +func newServiceAccountBackupItemAction(f client.Factory) plugincommon.HandlerInitializer { return func(logger logrus.FieldLogger) (interface{}, error) { // TODO(ncdc): consider a k8s style WantsKubernetesClientSet initialization approach clientset, err := f.KubeClient() @@ -101,7 +102,7 @@ func newServiceAccountBackupItemAction(f client.Factory) veleroplugin.HandlerIni } } -func newRemapCRDVersionAction(f client.Factory) veleroplugin.HandlerInitializer { +func newRemapCRDVersionAction(f client.Factory) plugincommon.HandlerInitializer { return func(logger logrus.FieldLogger) (interface{}, error) { config, err := f.ClientConfig() if err != nil { @@ -138,7 +139,7 @@ func newInitRestoreHookPodAction(logger logrus.FieldLogger) (interface{}, error) return restore.NewInitRestoreHookPodAction(logger), nil } -func newResticRestoreItemAction(f client.Factory) veleroplugin.HandlerInitializer { +func newResticRestoreItemAction(f client.Factory) plugincommon.HandlerInitializer { return func(logger logrus.FieldLogger) (interface{}, error) { client, err := f.KubeClient() if err != nil { @@ -174,7 +175,7 @@ func newCRDV1PreserveUnknownFieldsItemAction(logger logrus.FieldLogger) (interfa return restore.NewCRDV1PreserveUnknownFieldsAction(logger), nil } -func newChangeStorageClassRestoreItemAction(f client.Factory) veleroplugin.HandlerInitializer { +func newChangeStorageClassRestoreItemAction(f client.Factory) plugincommon.HandlerInitializer { return func(logger logrus.FieldLogger) (interface{}, error) { client, err := f.KubeClient() if err != nil { @@ -197,7 +198,7 @@ func newClusterRoleBindingItemAction(logger logrus.FieldLogger) (interface{}, er return restore.NewClusterRoleBindingAction(logger), nil } -func newChangePVCNodeSelectorItemAction(f client.Factory) veleroplugin.HandlerInitializer { +func newChangePVCNodeSelectorItemAction(f client.Factory) plugincommon.HandlerInitializer { return func(logger logrus.FieldLogger) (interface{}, error) { client, err := f.KubeClient() if err != nil { diff --git a/pkg/controller/server_status_request_controller.go b/pkg/controller/server_status_request_controller.go index 6d76576834..50ae606276 100644 --- a/pkg/controller/server_status_request_controller.go +++ b/pkg/controller/server_status_request_controller.go @@ -33,6 +33,7 @@ import ( velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/buildinfo" "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" ) const ( @@ -42,7 +43,7 @@ const ( type PluginLister interface { // List returns all PluginIdentifiers for kind. - List(kind framework.PluginKind) []framework.PluginIdentifier + List(kind common.PluginKind) []framework.PluginIdentifier } // serverStatusRequestReconciler reconciles a ServerStatusRequest object diff --git a/pkg/controller/server_status_request_controller_test.go b/pkg/controller/server_status_request_controller_test.go index c968a60180..f86ed49523 100644 --- a/pkg/controller/server_status_request_controller_test.go +++ b/pkg/controller/server_status_request_controller_test.go @@ -36,6 +36,7 @@ import ( "github.com/vmware-tanzu/velero/pkg/builder" "github.com/vmware-tanzu/velero/pkg/buildinfo" "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" velerotest "github.com/vmware-tanzu/velero/pkg/test" ) @@ -247,7 +248,7 @@ type fakePluginLister struct { plugins []framework.PluginIdentifier } -func (l *fakePluginLister) List(kind framework.PluginKind) []framework.PluginIdentifier { +func (l *fakePluginLister) List(kind common.PluginKind) []framework.PluginIdentifier { var plugins []framework.PluginIdentifier for _, plugin := range l.plugins { if plugin.Kind == kind { diff --git a/pkg/plugin/clientmgmt/backupitemaction/v1/restartable_backup_item_action.go b/pkg/plugin/clientmgmt/backupitemaction/v1/restartable_backup_item_action.go index 3317be280b..6cbca3f525 100644 --- a/pkg/plugin/clientmgmt/backupitemaction/v1/restartable_backup_item_action.go +++ b/pkg/plugin/clientmgmt/backupitemaction/v1/restartable_backup_item_action.go @@ -22,14 +22,14 @@ import ( api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/plugin/velero" biav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v1" ) // AdaptedBackupItemAction is a backup item action adapted to the v1 BackupItemAction API type AdaptedBackupItemAction struct { - Kind framework.PluginKind + Kind common.PluginKind // Get returns a restartable BackupItemAction for the given name and process, wrapping if necessary GetRestartable func(name string, restartableProcess process.RestartableProcess) biav1.BackupItemAction @@ -38,7 +38,7 @@ type AdaptedBackupItemAction struct { func AdaptedBackupItemActions() []AdaptedBackupItemAction { return []AdaptedBackupItemAction{ { - Kind: framework.PluginKindBackupItemAction, + Kind: common.PluginKindBackupItemAction, GetRestartable: func(name string, restartableProcess process.RestartableProcess) biav1.BackupItemAction { return NewRestartableBackupItemAction(name, restartableProcess) }, @@ -58,7 +58,7 @@ type RestartableBackupItemAction struct { // NewRestartableBackupItemAction returns a new RestartableBackupItemAction. func NewRestartableBackupItemAction(name string, sharedPluginProcess process.RestartableProcess) *RestartableBackupItemAction { r := &RestartableBackupItemAction{ - Key: process.KindAndName{Kind: framework.PluginKindBackupItemAction, Name: name}, + Key: process.KindAndName{Kind: common.PluginKindBackupItemAction, Name: name}, SharedPluginProcess: sharedPluginProcess, } return r diff --git a/pkg/plugin/clientmgmt/backupitemaction/v1/restartable_backup_item_action_test.go b/pkg/plugin/clientmgmt/backupitemaction/v1/restartable_backup_item_action_test.go index 947a0f1505..d20b150d96 100644 --- a/pkg/plugin/clientmgmt/backupitemaction/v1/restartable_backup_item_action_test.go +++ b/pkg/plugin/clientmgmt/backupitemaction/v1/restartable_backup_item_action_test.go @@ -26,10 +26,10 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" - "github.com/vmware-tanzu/velero/pkg/backup/mocks" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/plugin/velero" + mocks "github.com/vmware-tanzu/velero/pkg/plugin/velero/mocks/backupitemaction/v1" ) func TestRestartableGetBackupItemAction(t *testing.T) { @@ -51,7 +51,7 @@ func TestRestartableGetBackupItemAction(t *testing.T) { }, { name: "happy path", - plugin: new(mocks.ItemAction), + plugin: new(mocks.BackupItemAction), }, } @@ -61,7 +61,7 @@ func TestRestartableGetBackupItemAction(t *testing.T) { defer p.AssertExpectations(t) name := "pod" - key := process.KindAndName{Kind: framework.PluginKindBackupItemAction, Name: name} + key := process.KindAndName{Kind: common.PluginKindBackupItemAction, Name: name} p.On("GetByKindAndName", key).Return(tc.plugin, tc.getError) r := NewRestartableBackupItemAction(name, p) @@ -91,8 +91,8 @@ func TestRestartableBackupItemActionGetDelegate(t *testing.T) { // Happy path p.On("ResetIfNeeded").Return(nil) - expected := new(mocks.ItemAction) - key := process.KindAndName{Kind: framework.PluginKindBackupItemAction, Name: name} + expected := new(mocks.BackupItemAction) + key := process.KindAndName{Kind: common.PluginKindBackupItemAction, Name: name} p.On("GetByKindAndName", key).Return(expected, nil) a, err = r.getDelegate() @@ -123,7 +123,7 @@ func TestRestartableBackupItemActionDelegatedFunctions(t *testing.T) { runRestartableDelegateTests( t, - framework.PluginKindBackupItemAction, + common.PluginKindBackupItemAction, func(key process.KindAndName, p process.RestartableProcess) interface{} { return &RestartableBackupItemAction{ Key: key, @@ -131,7 +131,7 @@ func TestRestartableBackupItemActionDelegatedFunctions(t *testing.T) { } }, func() mockable { - return new(mocks.ItemAction) + return new(mocks.BackupItemAction) }, restartableDelegateTest{ function: "AppliesTo", diff --git a/pkg/plugin/clientmgmt/backupitemaction/v1/shared_test.go b/pkg/plugin/clientmgmt/backupitemaction/v1/shared_test.go index a612c764cb..6745b8fa0b 100644 --- a/pkg/plugin/clientmgmt/backupitemaction/v1/shared_test.go +++ b/pkg/plugin/clientmgmt/backupitemaction/v1/shared_test.go @@ -25,7 +25,7 @@ import ( "github.com/stretchr/testify/require" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" ) type mockRestartableProcess struct { @@ -70,7 +70,7 @@ type mockable interface { func runRestartableDelegateTests( t *testing.T, - kind framework.PluginKind, + kind common.PluginKind, newRestartable func(key process.KindAndName, p process.RestartableProcess) interface{}, newMock func() mockable, tests ...restartableDelegateTest, diff --git a/pkg/plugin/clientmgmt/manager.go b/pkg/plugin/clientmgmt/manager.go index e2b55951c7..292e8e9c2b 100644 --- a/pkg/plugin/clientmgmt/manager.go +++ b/pkg/plugin/clientmgmt/manager.go @@ -26,7 +26,7 @@ import ( biav1cli "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/backupitemaction/v1" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/plugin/velero" biav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v1" isv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/item_snapshotter/v1" @@ -68,6 +68,9 @@ type Manager interface { CleanupClients() } +// Used checking for adapted plugin versions +var pluginNotFoundErrType = &process.PluginNotFoundError{} + // manager implements Manager. type manager struct { logger logrus.FieldLogger @@ -106,7 +109,7 @@ func (m *manager) CleanupClients() { // getRestartableProcess returns a restartableProcess for a plugin identified by kind and name, creating a // restartableProcess if it is the first time it has been requested. -func (m *manager) getRestartableProcess(kind framework.PluginKind, name string) (process.RestartableProcess, error) { +func (m *manager) getRestartableProcess(kind common.PluginKind, name string) (process.RestartableProcess, error) { m.lock.Lock() defer m.lock.Unlock() @@ -145,7 +148,7 @@ func (m *manager) getRestartableProcess(kind framework.PluginKind, name string) func (m *manager) GetObjectStore(name string) (velero.ObjectStore, error) { name = sanitizeName(name) - restartableProcess, err := m.getRestartableProcess(framework.PluginKindObjectStore, name) + restartableProcess, err := m.getRestartableProcess(common.PluginKindObjectStore, name) if err != nil { return nil, err } @@ -159,7 +162,7 @@ func (m *manager) GetObjectStore(name string) (velero.ObjectStore, error) { func (m *manager) GetVolumeSnapshotter(name string) (velero.VolumeSnapshotter, error) { name = sanitizeName(name) - restartableProcess, err := m.getRestartableProcess(framework.PluginKindVolumeSnapshotter, name) + restartableProcess, err := m.getRestartableProcess(common.PluginKindVolumeSnapshotter, name) if err != nil { return nil, err } @@ -171,7 +174,7 @@ func (m *manager) GetVolumeSnapshotter(name string) (velero.VolumeSnapshotter, e // GetBackupItemActions returns all backup item actions as restartableBackupItemActions. func (m *manager) GetBackupItemActions() ([]biav1.BackupItemAction, error) { - list := m.registry.List(framework.PluginKindBackupItemAction) + list := m.registry.List(common.PluginKindBackupItemAction) actions := make([]biav1.BackupItemAction, 0, len(list)) @@ -196,7 +199,7 @@ func (m *manager) GetBackupItemAction(name string) (biav1.BackupItemAction, erro for _, adaptedBackupItemAction := range biav1cli.AdaptedBackupItemActions() { restartableProcess, err := m.getRestartableProcess(adaptedBackupItemAction.Kind, name) // Check if plugin was not found - if errors.Is(err, &process.PluginNotFoundError{}) { + if errors.As(err, &pluginNotFoundErrType) { continue } if err != nil { @@ -209,7 +212,7 @@ func (m *manager) GetBackupItemAction(name string) (biav1.BackupItemAction, erro // GetRestoreItemActions returns all restore item actions as restartableRestoreItemActions. func (m *manager) GetRestoreItemActions() ([]velero.RestoreItemAction, error) { - list := m.registry.List(framework.PluginKindRestoreItemAction) + list := m.registry.List(common.PluginKindRestoreItemAction) actions := make([]velero.RestoreItemAction, 0, len(list)) @@ -231,7 +234,7 @@ func (m *manager) GetRestoreItemActions() ([]velero.RestoreItemAction, error) { func (m *manager) GetRestoreItemAction(name string) (velero.RestoreItemAction, error) { name = sanitizeName(name) - restartableProcess, err := m.getRestartableProcess(framework.PluginKindRestoreItemAction, name) + restartableProcess, err := m.getRestartableProcess(common.PluginKindRestoreItemAction, name) if err != nil { return nil, err } @@ -242,7 +245,7 @@ func (m *manager) GetRestoreItemAction(name string) (velero.RestoreItemAction, e // GetDeleteItemActions returns all delete item actions as restartableDeleteItemActions. func (m *manager) GetDeleteItemActions() ([]velero.DeleteItemAction, error) { - list := m.registry.List(framework.PluginKindDeleteItemAction) + list := m.registry.List(common.PluginKindDeleteItemAction) actions := make([]velero.DeleteItemAction, 0, len(list)) @@ -264,7 +267,7 @@ func (m *manager) GetDeleteItemActions() ([]velero.DeleteItemAction, error) { func (m *manager) GetDeleteItemAction(name string) (velero.DeleteItemAction, error) { name = sanitizeName(name) - restartableProcess, err := m.getRestartableProcess(framework.PluginKindDeleteItemAction, name) + restartableProcess, err := m.getRestartableProcess(common.PluginKindDeleteItemAction, name) if err != nil { return nil, err } @@ -276,7 +279,7 @@ func (m *manager) GetDeleteItemAction(name string) (velero.DeleteItemAction, err func (m *manager) GetItemSnapshotter(name string) (isv1.ItemSnapshotter, error) { name = sanitizeName(name) - restartableProcess, err := m.getRestartableProcess(framework.PluginKindItemSnapshotter, name) + restartableProcess, err := m.getRestartableProcess(common.PluginKindItemSnapshotter, name) if err != nil { return nil, err } @@ -286,7 +289,7 @@ func (m *manager) GetItemSnapshotter(name string) (isv1.ItemSnapshotter, error) } func (m *manager) GetItemSnapshotters() ([]isv1.ItemSnapshotter, error) { - list := m.registry.List(framework.PluginKindItemSnapshotter) + list := m.registry.List(common.PluginKindItemSnapshotter) actions := make([]isv1.ItemSnapshotter, 0, len(list)) diff --git a/pkg/plugin/clientmgmt/manager_test.go b/pkg/plugin/clientmgmt/manager_test.go index 64b8bf4eda..b5b54b3f49 100644 --- a/pkg/plugin/clientmgmt/manager_test.go +++ b/pkg/plugin/clientmgmt/manager_test.go @@ -29,6 +29,7 @@ import ( biav1cli "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/backupitemaction/v1" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process" "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/test" ) @@ -41,12 +42,12 @@ func (r *mockRegistry) DiscoverPlugins() error { return args.Error(0) } -func (r *mockRegistry) List(kind framework.PluginKind) []framework.PluginIdentifier { +func (r *mockRegistry) List(kind common.PluginKind) []framework.PluginIdentifier { args := r.Called(kind) return args.Get(0).([]framework.PluginIdentifier) } -func (r *mockRegistry) Get(kind framework.PluginKind, name string) (framework.PluginIdentifier, error) { +func (r *mockRegistry) Get(kind common.PluginKind, name string) (framework.PluginIdentifier, error) { args := r.Called(kind, name) var id framework.PluginIdentifier if args.Get(0) != nil { @@ -123,7 +124,7 @@ func TestGetRestartableProcess(t *testing.T) { m.restartableProcessFactory = factory // Test 1: registry error - pluginKind := framework.PluginKindBackupItemAction + pluginKind := common.PluginKindBackupItemAction pluginName := "pod" registry.On("Get", pluginKind, pluginName).Return(nil, errors.Errorf("registry")).Once() rp, err := m.getRestartableProcess(pluginKind, pluginName) @@ -177,14 +178,14 @@ func TestCleanupClients(t *testing.T) { func TestGetObjectStore(t *testing.T) { getPluginTest(t, - framework.PluginKindObjectStore, + common.PluginKindObjectStore, "velero.io/aws", func(m Manager, name string) (interface{}, error) { return m.GetObjectStore(name) }, func(name string, sharedPluginProcess process.RestartableProcess) interface{} { return &restartableObjectStore{ - key: process.KindAndName{Kind: framework.PluginKindObjectStore, Name: name}, + key: process.KindAndName{Kind: common.PluginKindObjectStore, Name: name}, sharedPluginProcess: sharedPluginProcess, } }, @@ -194,14 +195,14 @@ func TestGetObjectStore(t *testing.T) { func TestGetVolumeSnapshotter(t *testing.T) { getPluginTest(t, - framework.PluginKindVolumeSnapshotter, + common.PluginKindVolumeSnapshotter, "velero.io/aws", func(m Manager, name string) (interface{}, error) { return m.GetVolumeSnapshotter(name) }, func(name string, sharedPluginProcess process.RestartableProcess) interface{} { return &restartableVolumeSnapshotter{ - key: process.KindAndName{Kind: framework.PluginKindVolumeSnapshotter, Name: name}, + key: process.KindAndName{Kind: common.PluginKindVolumeSnapshotter, Name: name}, sharedPluginProcess: sharedPluginProcess, } }, @@ -211,14 +212,14 @@ func TestGetVolumeSnapshotter(t *testing.T) { func TestGetBackupItemAction(t *testing.T) { getPluginTest(t, - framework.PluginKindBackupItemAction, + common.PluginKindBackupItemAction, "velero.io/pod", func(m Manager, name string) (interface{}, error) { return m.GetBackupItemAction(name) }, func(name string, sharedPluginProcess process.RestartableProcess) interface{} { return &biav1cli.RestartableBackupItemAction{ - Key: process.KindAndName{Kind: framework.PluginKindBackupItemAction, Name: name}, + Key: process.KindAndName{Kind: common.PluginKindBackupItemAction, Name: name}, SharedPluginProcess: sharedPluginProcess, } }, @@ -228,14 +229,14 @@ func TestGetBackupItemAction(t *testing.T) { func TestGetRestoreItemAction(t *testing.T) { getPluginTest(t, - framework.PluginKindRestoreItemAction, + common.PluginKindRestoreItemAction, "velero.io/pod", func(m Manager, name string) (interface{}, error) { return m.GetRestoreItemAction(name) }, func(name string, sharedPluginProcess process.RestartableProcess) interface{} { return &restartableRestoreItemAction{ - key: process.KindAndName{Kind: framework.PluginKindRestoreItemAction, Name: name}, + key: process.KindAndName{Kind: common.PluginKindRestoreItemAction, Name: name}, sharedPluginProcess: sharedPluginProcess, } }, @@ -245,7 +246,7 @@ func TestGetRestoreItemAction(t *testing.T) { func getPluginTest( t *testing.T, - kind framework.PluginKind, + kind common.PluginKind, name string, getPluginFunc func(m Manager, name string) (interface{}, error), expectedResultFunc func(name string, sharedPluginProcess process.RestartableProcess) interface{}, @@ -329,7 +330,7 @@ func TestGetBackupItemActions(t *testing.T) { defer factory.AssertExpectations(t) m.restartableProcessFactory = factory - pluginKind := framework.PluginKindBackupItemAction + pluginKind := common.PluginKindBackupItemAction var pluginIDs []framework.PluginIdentifier for i := range tc.names { pluginID := framework.PluginIdentifier{ @@ -421,7 +422,7 @@ func TestGetRestoreItemActions(t *testing.T) { defer factory.AssertExpectations(t) m.restartableProcessFactory = factory - pluginKind := framework.PluginKindRestoreItemAction + pluginKind := common.PluginKindRestoreItemAction var pluginIDs []framework.PluginIdentifier for i := range tc.names { pluginID := framework.PluginIdentifier{ @@ -480,14 +481,14 @@ func TestGetRestoreItemActions(t *testing.T) { func TestGetDeleteItemAction(t *testing.T) { getPluginTest(t, - framework.PluginKindDeleteItemAction, + common.PluginKindDeleteItemAction, "velero.io/deleter", func(m Manager, name string) (interface{}, error) { return m.GetDeleteItemAction(name) }, func(name string, sharedPluginProcess process.RestartableProcess) interface{} { return &restartableDeleteItemAction{ - key: process.KindAndName{Kind: framework.PluginKindDeleteItemAction, Name: name}, + key: process.KindAndName{Kind: common.PluginKindDeleteItemAction, Name: name}, sharedPluginProcess: sharedPluginProcess, } }, @@ -520,7 +521,7 @@ func TestGetDeleteItemActions(t *testing.T) { defer factory.AssertExpectations(t) m.restartableProcessFactory = factory - pluginKind := framework.PluginKindDeleteItemAction + pluginKind := common.PluginKindDeleteItemAction var pluginIDs []framework.PluginIdentifier for i := range tc.names { pluginID := framework.PluginIdentifier{ diff --git a/pkg/plugin/clientmgmt/process/client_builder.go b/pkg/plugin/clientmgmt/process/client_builder.go index 0d3948807e..4b6c27731f 100644 --- a/pkg/plugin/clientmgmt/process/client_builder.go +++ b/pkg/plugin/clientmgmt/process/client_builder.go @@ -27,6 +27,7 @@ import ( "github.com/vmware-tanzu/velero/pkg/features" "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" ) // clientBuilder builds go-plugin Clients. @@ -67,13 +68,13 @@ func (b *clientBuilder) clientConfig() *hcplugin.ClientConfig { HandshakeConfig: framework.Handshake(), AllowedProtocols: []hcplugin.Protocol{hcplugin.ProtocolGRPC}, Plugins: map[string]hcplugin.Plugin{ - string(framework.PluginKindBackupItemAction): framework.NewBackupItemActionPlugin(framework.ClientLogger(b.clientLogger)), - string(framework.PluginKindVolumeSnapshotter): framework.NewVolumeSnapshotterPlugin(framework.ClientLogger(b.clientLogger)), - string(framework.PluginKindObjectStore): framework.NewObjectStorePlugin(framework.ClientLogger(b.clientLogger)), - string(framework.PluginKindPluginLister): &framework.PluginListerPlugin{}, - string(framework.PluginKindRestoreItemAction): framework.NewRestoreItemActionPlugin(framework.ClientLogger(b.clientLogger)), - string(framework.PluginKindDeleteItemAction): framework.NewDeleteItemActionPlugin(framework.ClientLogger(b.clientLogger)), - string(framework.PluginKindItemSnapshotter): framework.NewItemSnapshotterPlugin(framework.ClientLogger(b.clientLogger)), + string(common.PluginKindBackupItemAction): framework.NewBackupItemActionPlugin(common.ClientLogger(b.clientLogger)), + string(common.PluginKindVolumeSnapshotter): framework.NewVolumeSnapshotterPlugin(common.ClientLogger(b.clientLogger)), + string(common.PluginKindObjectStore): framework.NewObjectStorePlugin(common.ClientLogger(b.clientLogger)), + string(common.PluginKindPluginLister): &framework.PluginListerPlugin{}, + string(common.PluginKindRestoreItemAction): framework.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...), diff --git a/pkg/plugin/clientmgmt/process/client_builder_test.go b/pkg/plugin/clientmgmt/process/client_builder_test.go index 1b9c77145d..2a3f6df615 100644 --- a/pkg/plugin/clientmgmt/process/client_builder_test.go +++ b/pkg/plugin/clientmgmt/process/client_builder_test.go @@ -27,6 +27,7 @@ import ( "github.com/vmware-tanzu/velero/pkg/features" "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/test" ) @@ -60,13 +61,13 @@ func TestClientConfig(t *testing.T) { HandshakeConfig: framework.Handshake(), AllowedProtocols: []hcplugin.Protocol{hcplugin.ProtocolGRPC}, Plugins: map[string]hcplugin.Plugin{ - string(framework.PluginKindBackupItemAction): framework.NewBackupItemActionPlugin(framework.ClientLogger(logger)), - string(framework.PluginKindVolumeSnapshotter): framework.NewVolumeSnapshotterPlugin(framework.ClientLogger(logger)), - string(framework.PluginKindObjectStore): framework.NewObjectStorePlugin(framework.ClientLogger(logger)), - string(framework.PluginKindPluginLister): &framework.PluginListerPlugin{}, - string(framework.PluginKindRestoreItemAction): framework.NewRestoreItemActionPlugin(framework.ClientLogger(logger)), - string(framework.PluginKindDeleteItemAction): framework.NewDeleteItemActionPlugin(framework.ClientLogger(logger)), - string(framework.PluginKindItemSnapshotter): framework.NewItemSnapshotterPlugin(framework.ClientLogger(logger)), + string(common.PluginKindBackupItemAction): framework.NewBackupItemActionPlugin(common.ClientLogger(logger)), + string(common.PluginKindVolumeSnapshotter): framework.NewVolumeSnapshotterPlugin(common.ClientLogger(logger)), + string(common.PluginKindObjectStore): framework.NewObjectStorePlugin(common.ClientLogger(logger)), + string(common.PluginKindPluginLister): &framework.PluginListerPlugin{}, + string(common.PluginKindRestoreItemAction): framework.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...), diff --git a/pkg/plugin/clientmgmt/process/process.go b/pkg/plugin/clientmgmt/process/process.go index 66033768d8..b6be276871 100644 --- a/pkg/plugin/clientmgmt/process/process.go +++ b/pkg/plugin/clientmgmt/process/process.go @@ -23,7 +23,7 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" ) type ProcessFactory interface { @@ -132,7 +132,7 @@ func (r *process) dispense(key KindAndName) (interface{}, error) { } // Currently all plugins except for PluginLister dispense clientDispenser instances. - if clientDispenser, ok := dispensed.(framework.ClientDispenser); ok { + if clientDispenser, ok := dispensed.(common.ClientDispenser); ok { if key.Name == "" { return nil, errors.Errorf("%s plugin requested but name is missing", key.Kind.String()) } diff --git a/pkg/plugin/clientmgmt/process/process_test.go b/pkg/plugin/clientmgmt/process/process_test.go index a44254dbd0..ce7c7c07b9 100644 --- a/pkg/plugin/clientmgmt/process/process_test.go +++ b/pkg/plugin/clientmgmt/process/process_test.go @@ -24,6 +24,7 @@ import ( "github.com/stretchr/testify/require" "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" ) type mockClientProtocol struct { @@ -96,7 +97,7 @@ func TestDispense(t *testing.T) { key := KindAndName{} if tc.clientDispenser { - key.Kind = framework.PluginKindObjectStore + key.Kind = common.PluginKindObjectStore protocolClient.On("Dispense", key.Kind.String()).Return(clientDispenser, tc.dispenseError) if !tc.missingKeyName { @@ -105,7 +106,7 @@ func TestDispense(t *testing.T) { clientDispenser.On("ClientFor", key.Name).Return(client) } } else { - key.Kind = framework.PluginKindPluginLister + key.Kind = common.PluginKindPluginLister client = &framework.PluginListerGRPCClient{} protocolClient.On("Dispense", key.Kind.String()).Return(client, tc.dispenseError) } diff --git a/pkg/plugin/clientmgmt/process/registry.go b/pkg/plugin/clientmgmt/process/registry.go index 2e51ea2a2b..11a6bf43ed 100644 --- a/pkg/plugin/clientmgmt/process/registry.go +++ b/pkg/plugin/clientmgmt/process/registry.go @@ -25,6 +25,7 @@ import ( "github.com/sirupsen/logrus" "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/util/filesystem" ) @@ -33,14 +34,14 @@ type Registry interface { // DiscoverPlugins discovers all available plugins. DiscoverPlugins() error // List returns all PluginIdentifiers for kind. - List(kind framework.PluginKind) []framework.PluginIdentifier + List(kind common.PluginKind) []framework.PluginIdentifier // Get returns the PluginIdentifier for kind and name. - Get(kind framework.PluginKind, name string) (framework.PluginIdentifier, error) + Get(kind common.PluginKind, name string) (framework.PluginIdentifier, error) } // KindAndName is a convenience struct that combines a PluginKind and a name. type KindAndName struct { - Kind framework.PluginKind + Kind common.PluginKind Name string } @@ -54,7 +55,7 @@ type registry struct { processFactory ProcessFactory fs filesystem.Interface pluginsByID map[KindAndName]framework.PluginIdentifier - pluginsByKind map[framework.PluginKind][]framework.PluginIdentifier + pluginsByKind map[common.PluginKind][]framework.PluginIdentifier } // NewRegistry returns a new registry. @@ -67,7 +68,7 @@ func NewRegistry(dir string, logger logrus.FieldLogger, logLevel logrus.Level) R processFactory: newProcessFactory(), fs: filesystem.NewFileSystem(), pluginsByID: make(map[KindAndName]framework.PluginIdentifier), - pluginsByKind: make(map[framework.PluginKind][]framework.PluginIdentifier), + pluginsByKind: make(map[common.PluginKind][]framework.PluginIdentifier), } } @@ -110,13 +111,13 @@ func (r *registry) discoverPlugins(commands []string) error { // List returns info about all plugin binaries that implement the given // PluginKind. -func (r *registry) List(kind framework.PluginKind) []framework.PluginIdentifier { +func (r *registry) List(kind common.PluginKind) []framework.PluginIdentifier { return r.pluginsByKind[kind] } // Get returns info about a plugin with the given name and kind, or an // error if one cannot be found. -func (r *registry) Get(kind framework.PluginKind, name string) (framework.PluginIdentifier, error) { +func (r *registry) Get(kind common.PluginKind, name string) (framework.PluginIdentifier, error) { p, found := r.pluginsByID[KindAndName{Kind: kind, Name: name}] if !found { return framework.PluginIdentifier{}, newPluginNotFoundError(kind, name) @@ -182,7 +183,7 @@ func (r *registry) listPlugins(command string) ([]framework.PluginIdentifier, er } defer process.kill() - plugin, err := process.dispense(KindAndName{Kind: framework.PluginKindPluginLister}) + plugin, err := process.dispense(KindAndName{Kind: common.PluginKindPluginLister}) if err != nil { return nil, err } @@ -203,24 +204,33 @@ func (r *registry) register(id framework.PluginIdentifier) error { } // no need to pass list of existing plugins since the check if this exists was done above - if err := framework.ValidatePluginName(id.Name, nil); err != nil { + if err := common.ValidatePluginName(id.Name, nil); err != nil { return errors.Errorf("invalid plugin name %q: %s", id.Name, err) } r.pluginsByID[key] = id r.pluginsByKind[id.Kind] = append(r.pluginsByKind[id.Kind], id) + // if id.Kind is adaptable to newer plugin versions, list it under the other versions as well + // If BackupItemAction is adaptable to BackupItemActionV2, then it would be listed under both + // kinds + if kinds, ok := common.PluginKindsAdaptableTo[id.Kind]; ok { + for _, kind := range kinds { + r.pluginsByKind[kind] = append(r.pluginsByKind[kind], id) + } + } + return nil } // pluginNotFoundError indicates a plugin could not be located for kind and name. type PluginNotFoundError struct { - kind framework.PluginKind + kind common.PluginKind name string } // newPluginNotFoundError returns a new pluginNotFoundError for kind and name. -func newPluginNotFoundError(kind framework.PluginKind, name string) *PluginNotFoundError { +func newPluginNotFoundError(kind common.PluginKind, name string) *PluginNotFoundError { return &PluginNotFoundError{ kind: kind, name: name, diff --git a/pkg/plugin/clientmgmt/restartable_delegate_test.go b/pkg/plugin/clientmgmt/restartable_delegate_test.go index c71d3e2769..a69f2e05d4 100644 --- a/pkg/plugin/clientmgmt/restartable_delegate_test.go +++ b/pkg/plugin/clientmgmt/restartable_delegate_test.go @@ -25,7 +25,7 @@ import ( "github.com/stretchr/testify/require" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" ) type restartableDelegateTest struct { @@ -43,7 +43,7 @@ type mockable interface { func runRestartableDelegateTests( t *testing.T, - kind framework.PluginKind, + kind common.PluginKind, newRestartable func(key process.KindAndName, p process.RestartableProcess) interface{}, newMock func() mockable, tests ...restartableDelegateTest, diff --git a/pkg/plugin/clientmgmt/restartable_delete_item_action.go b/pkg/plugin/clientmgmt/restartable_delete_item_action.go index 977203aae6..ead2b9b09f 100644 --- a/pkg/plugin/clientmgmt/restartable_delete_item_action.go +++ b/pkg/plugin/clientmgmt/restartable_delete_item_action.go @@ -20,7 +20,7 @@ import ( "github.com/pkg/errors" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/plugin/velero" ) @@ -37,7 +37,7 @@ type restartableDeleteItemAction struct { // NewRestartableDeleteItemAction returns a new restartableDeleteItemAction. func NewRestartableDeleteItemAction(name string, sharedPluginProcess process.RestartableProcess) *restartableDeleteItemAction { r := &restartableDeleteItemAction{ - key: process.KindAndName{Kind: framework.PluginKindDeleteItemAction, Name: name}, + key: process.KindAndName{Kind: common.PluginKindDeleteItemAction, Name: name}, sharedPluginProcess: sharedPluginProcess, } return r diff --git a/pkg/plugin/clientmgmt/restartable_delete_item_action_test.go b/pkg/plugin/clientmgmt/restartable_delete_item_action_test.go index 65fb9646ca..bd5d734a45 100644 --- a/pkg/plugin/clientmgmt/restartable_delete_item_action_test.go +++ b/pkg/plugin/clientmgmt/restartable_delete_item_action_test.go @@ -26,7 +26,7 @@ import ( api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/plugin/velero" "github.com/vmware-tanzu/velero/pkg/plugin/velero/mocks" ) @@ -60,7 +60,7 @@ func TestRestartableGetDeleteItemAction(t *testing.T) { defer p.AssertExpectations(t) name := "pod" - key := process.KindAndName{Kind: framework.PluginKindDeleteItemAction, Name: name} + key := process.KindAndName{Kind: common.PluginKindDeleteItemAction, Name: name} p.On("GetByKindAndName", key).Return(tc.plugin, tc.getError) r := NewRestartableDeleteItemAction(name, p) @@ -92,7 +92,7 @@ func TestRestartableDeleteItemActionGetDelegate(t *testing.T) { // Currently broken since this mocks out the restore item action interface p.On("ResetIfNeeded").Return(nil) expected := new(mocks.DeleteItemAction) - key := process.KindAndName{Kind: framework.PluginKindDeleteItemAction, Name: name} + key := process.KindAndName{Kind: common.PluginKindDeleteItemAction, Name: name} p.On("GetByKindAndName", key).Return(expected, nil) a, err = r.getDelegate() @@ -116,7 +116,7 @@ func TestRestartableDeleteItemActionDelegatedFunctions(t *testing.T) { runRestartableDelegateTests( t, - framework.PluginKindDeleteItemAction, + common.PluginKindDeleteItemAction, func(key process.KindAndName, p process.RestartableProcess) interface{} { return &restartableDeleteItemAction{ key: key, diff --git a/pkg/plugin/clientmgmt/restartable_item_snapshotter.go b/pkg/plugin/clientmgmt/restartable_item_snapshotter.go index d2743789ac..204d6ca229 100644 --- a/pkg/plugin/clientmgmt/restartable_item_snapshotter.go +++ b/pkg/plugin/clientmgmt/restartable_item_snapshotter.go @@ -22,7 +22,7 @@ import ( "github.com/pkg/errors" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "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" ) @@ -35,7 +35,7 @@ type restartableItemSnapshotter struct { // NewRestartableItemSnapshotter returns a new restartableItemSnapshotter. func NewRestartableItemSnapshotter(name string, sharedPluginProcess process.RestartableProcess) *restartableItemSnapshotter { r := &restartableItemSnapshotter{ - key: process.KindAndName{Kind: framework.PluginKindItemSnapshotter, Name: name}, + key: process.KindAndName{Kind: common.PluginKindItemSnapshotter, Name: name}, sharedPluginProcess: sharedPluginProcess, } return r diff --git a/pkg/plugin/clientmgmt/restartable_item_snapshotter_test.go b/pkg/plugin/clientmgmt/restartable_item_snapshotter_test.go index 70d4a934ac..5aeca0551d 100644 --- a/pkg/plugin/clientmgmt/restartable_item_snapshotter_test.go +++ b/pkg/plugin/clientmgmt/restartable_item_snapshotter_test.go @@ -31,7 +31,7 @@ import ( "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" + "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" ) @@ -65,7 +65,7 @@ func TestRestartableGetItemSnapshotter(t *testing.T) { defer p.AssertExpectations(t) name := "pvc" - key := process.KindAndName{Kind: framework.PluginKindItemSnapshotter, Name: name} + key := process.KindAndName{Kind: common.PluginKindItemSnapshotter, Name: name} p.On("GetByKindAndName", key).Return(tc.plugin, tc.getError) r := NewRestartableItemSnapshotter(name, p) @@ -96,7 +96,7 @@ func TestRestartableItemSnapshotterGetDelegate(t *testing.T) { // Happy path p.On("ResetIfNeeded").Return(nil) expected := new(mocks.ItemSnapshotter) - key := process.KindAndName{Kind: framework.PluginKindItemSnapshotter, Name: name} + key := process.KindAndName{Kind: common.PluginKindItemSnapshotter, Name: name} p.On("GetByKindAndName", key).Return(expected, nil) a, err = r.getDelegate() @@ -177,7 +177,7 @@ func TestRestartableItemSnasphotterDelegatedFunctions(t *testing.T) { } runRestartableDelegateTests( t, - framework.PluginKindItemSnapshotter, + common.PluginKindItemSnapshotter, func(key process.KindAndName, p process.RestartableProcess) interface{} { return &restartableItemSnapshotter{ key: key, diff --git a/pkg/plugin/clientmgmt/restartable_object_store.go b/pkg/plugin/clientmgmt/restartable_object_store.go index 5be1113408..a3552bd0ab 100644 --- a/pkg/plugin/clientmgmt/restartable_object_store.go +++ b/pkg/plugin/clientmgmt/restartable_object_store.go @@ -23,7 +23,7 @@ import ( "github.com/pkg/errors" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/plugin/velero" ) @@ -41,7 +41,7 @@ type restartableObjectStore struct { // NewRestartableObjectStore returns a new restartableObjectStore. func NewRestartableObjectStore(name string, sharedPluginProcess process.RestartableProcess) *restartableObjectStore { - key := process.KindAndName{Kind: framework.PluginKindObjectStore, Name: name} + key := process.KindAndName{Kind: common.PluginKindObjectStore, Name: name} r := &restartableObjectStore{ key: key, sharedPluginProcess: sharedPluginProcess, diff --git a/pkg/plugin/clientmgmt/restartable_object_store_test.go b/pkg/plugin/clientmgmt/restartable_object_store_test.go index b4e94fccc6..47699c50bc 100644 --- a/pkg/plugin/clientmgmt/restartable_object_store_test.go +++ b/pkg/plugin/clientmgmt/restartable_object_store_test.go @@ -27,7 +27,7 @@ import ( "github.com/stretchr/testify/require" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" providermocks "github.com/vmware-tanzu/velero/pkg/plugin/velero/mocks" ) @@ -61,7 +61,7 @@ func TestRestartableGetObjectStore(t *testing.T) { defer p.AssertExpectations(t) name := "aws" - key := process.KindAndName{Kind: framework.PluginKindObjectStore, Name: name} + key := process.KindAndName{Kind: common.PluginKindObjectStore, Name: name} p.On("GetByKindAndName", key).Return(tc.plugin, tc.getError) r := &restartableObjectStore{ @@ -86,7 +86,7 @@ func TestRestartableObjectStoreReinitialize(t *testing.T) { defer p.AssertExpectations(t) name := "aws" - key := process.KindAndName{Kind: framework.PluginKindObjectStore, Name: name} + key := process.KindAndName{Kind: common.PluginKindObjectStore, Name: name} r := &restartableObjectStore{ key: key, sharedPluginProcess: p, @@ -119,7 +119,7 @@ func TestRestartableObjectStoreGetDelegate(t *testing.T) { // Reset error p.On("ResetIfNeeded").Return(errors.Errorf("reset error")).Once() name := "aws" - key := process.KindAndName{Kind: framework.PluginKindObjectStore, Name: name} + key := process.KindAndName{Kind: common.PluginKindObjectStore, Name: name} r := &restartableObjectStore{ key: key, sharedPluginProcess: p, @@ -147,7 +147,7 @@ func TestRestartableObjectStoreInit(t *testing.T) { // getObjectStore error name := "aws" - key := process.KindAndName{Kind: framework.PluginKindObjectStore, Name: name} + key := process.KindAndName{Kind: common.PluginKindObjectStore, Name: name} r := &restartableObjectStore{ key: key, sharedPluginProcess: p, @@ -187,7 +187,7 @@ func TestRestartableObjectStoreInit(t *testing.T) { func TestRestartableObjectStoreDelegatedFunctions(t *testing.T) { runRestartableDelegateTests( t, - framework.PluginKindObjectStore, + common.PluginKindObjectStore, func(key process.KindAndName, p process.RestartableProcess) interface{} { return &restartableObjectStore{ key: key, diff --git a/pkg/plugin/clientmgmt/restartable_restore_item_action.go b/pkg/plugin/clientmgmt/restartable_restore_item_action.go index c4e6911b41..fdd266d0bf 100644 --- a/pkg/plugin/clientmgmt/restartable_restore_item_action.go +++ b/pkg/plugin/clientmgmt/restartable_restore_item_action.go @@ -20,7 +20,7 @@ import ( "github.com/pkg/errors" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/plugin/velero" ) @@ -37,7 +37,7 @@ type restartableRestoreItemAction struct { // NewRestartableRestoreItemAction returns a new RestartableRestoreItemAction. func NewRestartableRestoreItemAction(name string, sharedPluginProcess process.RestartableProcess) *restartableRestoreItemAction { r := &restartableRestoreItemAction{ - key: process.KindAndName{Kind: framework.PluginKindRestoreItemAction, Name: name}, + key: process.KindAndName{Kind: common.PluginKindRestoreItemAction, Name: name}, sharedPluginProcess: sharedPluginProcess, } return r diff --git a/pkg/plugin/clientmgmt/restartable_restore_item_action_test.go b/pkg/plugin/clientmgmt/restartable_restore_item_action_test.go index 3d4fd52e99..b91d08bfa6 100644 --- a/pkg/plugin/clientmgmt/restartable_restore_item_action_test.go +++ b/pkg/plugin/clientmgmt/restartable_restore_item_action_test.go @@ -26,7 +26,7 @@ import ( v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/plugin/velero" "github.com/vmware-tanzu/velero/pkg/restore/mocks" ) @@ -60,7 +60,7 @@ func TestRestartableGetRestoreItemAction(t *testing.T) { defer p.AssertExpectations(t) name := "pod" - key := process.KindAndName{Kind: framework.PluginKindRestoreItemAction, Name: name} + key := process.KindAndName{Kind: common.PluginKindRestoreItemAction, Name: name} p.On("GetByKindAndName", key).Return(tc.plugin, tc.getError) r := NewRestartableRestoreItemAction(name, p) @@ -91,7 +91,7 @@ func TestRestartableRestoreItemActionGetDelegate(t *testing.T) { // Happy path p.On("ResetIfNeeded").Return(nil) expected := new(mocks.ItemAction) - key := process.KindAndName{Kind: framework.PluginKindRestoreItemAction, Name: name} + key := process.KindAndName{Kind: common.PluginKindRestoreItemAction, Name: name} p.On("GetByKindAndName", key).Return(expected, nil) a, err = r.getDelegate() @@ -122,7 +122,7 @@ func TestRestartableRestoreItemActionDelegatedFunctions(t *testing.T) { runRestartableDelegateTests( t, - framework.PluginKindRestoreItemAction, + common.PluginKindRestoreItemAction, func(key process.KindAndName, p process.RestartableProcess) interface{} { return &restartableRestoreItemAction{ key: key, diff --git a/pkg/plugin/clientmgmt/restartable_volume_snapshotter.go b/pkg/plugin/clientmgmt/restartable_volume_snapshotter.go index f8a1a66b02..1252306ea3 100644 --- a/pkg/plugin/clientmgmt/restartable_volume_snapshotter.go +++ b/pkg/plugin/clientmgmt/restartable_volume_snapshotter.go @@ -21,7 +21,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/plugin/velero" ) @@ -35,9 +35,9 @@ type restartableVolumeSnapshotter struct { config map[string]string } -// NewRestartableVolumeSnapshotter returns a new RestartableVolumeSnapshotter. +// NewRestartableVolumeSnapshotter returns a new restartableVolumeSnapshotter. func NewRestartableVolumeSnapshotter(name string, sharedPluginProcess process.RestartableProcess) *restartableVolumeSnapshotter { - key := process.KindAndName{Kind: framework.PluginKindVolumeSnapshotter, Name: name} + key := process.KindAndName{Kind: common.PluginKindVolumeSnapshotter, Name: name} r := &restartableVolumeSnapshotter{ key: key, sharedPluginProcess: sharedPluginProcess, diff --git a/pkg/plugin/clientmgmt/restartable_volume_snapshotter_test.go b/pkg/plugin/clientmgmt/restartable_volume_snapshotter_test.go index 8d198ec96d..4f8c06f8c6 100644 --- a/pkg/plugin/clientmgmt/restartable_volume_snapshotter_test.go +++ b/pkg/plugin/clientmgmt/restartable_volume_snapshotter_test.go @@ -26,7 +26,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" providermocks "github.com/vmware-tanzu/velero/pkg/plugin/velero/mocks" ) @@ -60,7 +60,7 @@ func TestRestartableGetVolumeSnapshotter(t *testing.T) { defer p.AssertExpectations(t) name := "aws" - key := process.KindAndName{Kind: framework.PluginKindVolumeSnapshotter, Name: name} + key := process.KindAndName{Kind: common.PluginKindVolumeSnapshotter, Name: name} p.On("GetByKindAndName", key).Return(tc.plugin, tc.getError) r := &restartableVolumeSnapshotter{ @@ -85,7 +85,7 @@ func TestRestartableVolumeSnapshotterReinitialize(t *testing.T) { defer p.AssertExpectations(t) name := "aws" - key := process.KindAndName{Kind: framework.PluginKindVolumeSnapshotter, Name: name} + key := process.KindAndName{Kind: common.PluginKindVolumeSnapshotter, Name: name} r := &restartableVolumeSnapshotter{ key: key, sharedPluginProcess: p, @@ -118,7 +118,7 @@ func TestRestartableVolumeSnapshotterGetDelegate(t *testing.T) { // Reset error p.On("ResetIfNeeded").Return(errors.Errorf("reset error")).Once() name := "aws" - key := process.KindAndName{Kind: framework.PluginKindVolumeSnapshotter, Name: name} + key := process.KindAndName{Kind: common.PluginKindVolumeSnapshotter, Name: name} r := &restartableVolumeSnapshotter{ key: key, sharedPluginProcess: p, @@ -146,7 +146,7 @@ func TestRestartableVolumeSnapshotterInit(t *testing.T) { // getVolumeSnapshottererror name := "aws" - key := process.KindAndName{Kind: framework.PluginKindVolumeSnapshotter, Name: name} + key := process.KindAndName{Kind: common.PluginKindVolumeSnapshotter, Name: name} r := &restartableVolumeSnapshotter{ key: key, sharedPluginProcess: p, @@ -198,7 +198,7 @@ func TestRestartableVolumeSnapshotterDelegatedFunctions(t *testing.T) { runRestartableDelegateTests( t, - framework.PluginKindVolumeSnapshotter, + common.PluginKindVolumeSnapshotter, func(key process.KindAndName, p process.RestartableProcess) interface{} { return &restartableVolumeSnapshotter{ key: key, diff --git a/pkg/plugin/framework/action_resolver.go b/pkg/plugin/framework/action_resolver.go index 345061aacb..b1d692fd36 100644 --- a/pkg/plugin/framework/action_resolver.go +++ b/pkg/plugin/framework/action_resolver.go @@ -127,14 +127,14 @@ func NewItemSnapshotterResolver(actions []isv1.ItemSnapshotter) ItemSnapshotterR } type ActionResolver interface { - ResolveAction(helper discovery.Helper, action velero.Applicable) (ResolvedAction, error) + ResolveAction(helper discovery.Helper, action velero.Applicable, log logrus.FieldLogger) (ResolvedAction, error) } type BackupItemActionResolver struct { actions []biav1.BackupItemAction } -func (recv BackupItemActionResolver) ResolveActions(helper discovery.Helper) ([]BackupItemResolvedAction, error) { +func (recv BackupItemActionResolver) ResolveActions(helper discovery.Helper, log logrus.FieldLogger) ([]BackupItemResolvedAction, error) { var resolved []BackupItemResolvedAction for _, action := range recv.actions { resources, namespaces, selector, err := resolveAction(helper, action) @@ -163,7 +163,7 @@ type RestoreItemActionResolver struct { actions []velero.RestoreItemAction } -func (recv RestoreItemActionResolver) ResolveActions(helper discovery.Helper) ([]RestoreItemResolvedAction, error) { +func (recv RestoreItemActionResolver) ResolveActions(helper discovery.Helper, log logrus.FieldLogger) ([]RestoreItemResolvedAction, error) { var resolved []RestoreItemResolvedAction for _, action := range recv.actions { resources, namespaces, selector, err := resolveAction(helper, action) @@ -192,7 +192,7 @@ type DeleteItemActionResolver struct { actions []velero.DeleteItemAction } -func (recv DeleteItemActionResolver) ResolveActions(helper discovery.Helper) ([]DeleteItemResolvedAction, error) { +func (recv DeleteItemActionResolver) ResolveActions(helper discovery.Helper, log logrus.FieldLogger) ([]DeleteItemResolvedAction, error) { var resolved []DeleteItemResolvedAction for _, action := range recv.actions { resources, namespaces, selector, err := resolveAction(helper, action) @@ -221,7 +221,7 @@ type ItemSnapshotterResolver struct { actions []isv1.ItemSnapshotter } -func (recv ItemSnapshotterResolver) ResolveActions(helper discovery.Helper) ([]ItemSnapshotterResolvedAction, error) { +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) diff --git a/pkg/plugin/framework/backup_item_action.go b/pkg/plugin/framework/backup_item_action.go index 8780c78264..8f6bc7554a 100644 --- a/pkg/plugin/framework/backup_item_action.go +++ b/pkg/plugin/framework/backup_item_action.go @@ -21,6 +21,7 @@ import ( "golang.org/x/net/context" "google.golang.org/grpc" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" protobiav1 "github.com/vmware-tanzu/velero/pkg/plugin/generated" ) @@ -29,16 +30,16 @@ import ( // interface. type BackupItemActionPlugin struct { plugin.NetRPCUnsupportedPlugin - *pluginBase + *common.PluginBase } // GRPCClient returns a clientDispenser for BackupItemAction gRPC clients. func (p *BackupItemActionPlugin) GRPCClient(_ context.Context, _ *plugin.GRPCBroker, clientConn *grpc.ClientConn) (interface{}, error) { - return newClientDispenser(p.clientLogger, clientConn, newBackupItemActionGRPCClient), nil + return common.NewClientDispenser(p.ClientLogger, clientConn, newBackupItemActionGRPCClient), nil } // GRPCServer registers a BackupItemAction gRPC server. func (p *BackupItemActionPlugin) GRPCServer(_ *plugin.GRPCBroker, server *grpc.Server) error { - protobiav1.RegisterBackupItemActionServer(server, &BackupItemActionGRPCServer{mux: p.serverMux}) + protobiav1.RegisterBackupItemActionServer(server, &BackupItemActionGRPCServer{mux: p.ServerMux}) return nil } diff --git a/pkg/plugin/framework/backup_item_action_client.go b/pkg/plugin/framework/backup_item_action_client.go index 4756ab3920..50101975f9 100644 --- a/pkg/plugin/framework/backup_item_action_client.go +++ b/pkg/plugin/framework/backup_item_action_client.go @@ -27,39 +27,40 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" protobiav1 "github.com/vmware-tanzu/velero/pkg/plugin/generated" "github.com/vmware-tanzu/velero/pkg/plugin/velero" ) // NewBackupItemActionPlugin constructs a BackupItemActionPlugin. -func NewBackupItemActionPlugin(options ...PluginOption) *BackupItemActionPlugin { +func NewBackupItemActionPlugin(options ...common.PluginOption) *BackupItemActionPlugin { return &BackupItemActionPlugin{ - pluginBase: newPluginBase(options...), + PluginBase: common.NewPluginBase(options...), } } // BackupItemActionGRPCClient implements the backup/ItemAction interface and uses a // gRPC client to make calls to the plugin server. type BackupItemActionGRPCClient struct { - *clientBase + *common.ClientBase grpcClient protobiav1.BackupItemActionClient } -func newBackupItemActionGRPCClient(base *clientBase, clientConn *grpc.ClientConn) interface{} { +func newBackupItemActionGRPCClient(base *common.ClientBase, clientConn *grpc.ClientConn) interface{} { return &BackupItemActionGRPCClient{ - clientBase: base, + ClientBase: base, grpcClient: protobiav1.NewBackupItemActionClient(clientConn), } } func (c *BackupItemActionGRPCClient) AppliesTo() (velero.ResourceSelector, error) { req := &protobiav1.BackupItemActionAppliesToRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, } res, err := c.grpcClient.AppliesTo(context.Background(), req) if err != nil { - return velero.ResourceSelector{}, fromGRPCError(err) + return velero.ResourceSelector{}, common.FromGRPCError(err) } if res.ResourceSelector == nil { @@ -87,14 +88,14 @@ func (c *BackupItemActionGRPCClient) Execute(item runtime.Unstructured, backup * } req := &protobiav1.ExecuteRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, Item: itemJSON, Backup: backupJSON, } res, err := c.grpcClient.Execute(context.Background(), req) if err != nil { - return nil, nil, fromGRPCError(err) + return nil, nil, common.FromGRPCError(err) } var updatedItem unstructured.Unstructured diff --git a/pkg/plugin/framework/backup_item_action_server.go b/pkg/plugin/framework/backup_item_action_server.go index fec8f07008..bde6c2148a 100644 --- a/pkg/plugin/framework/backup_item_action_server.go +++ b/pkg/plugin/framework/backup_item_action_server.go @@ -24,6 +24,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" proto "github.com/vmware-tanzu/velero/pkg/plugin/generated" protobiav1 "github.com/vmware-tanzu/velero/pkg/plugin/generated" "github.com/vmware-tanzu/velero/pkg/plugin/velero" @@ -33,11 +34,11 @@ import ( // BackupItemActionGRPCServer implements the proto-generated BackupItemAction interface, and accepts // gRPC calls and forwards them to an implementation of the pluggable interface. type BackupItemActionGRPCServer struct { - mux *serverMux + mux *common.ServerMux } func (s *BackupItemActionGRPCServer) getImpl(name string) (biav1.BackupItemAction, error) { - impl, err := s.mux.getHandler(name) + impl, err := s.mux.GetHandler(name) if err != nil { return nil, err } @@ -54,19 +55,19 @@ func (s *BackupItemActionGRPCServer) AppliesTo( ctx context.Context, req *protobiav1.BackupItemActionAppliesToRequest) ( response *protobiav1.BackupItemActionAppliesToResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } resourceSelector, err := impl.AppliesTo() if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &protobiav1.BackupItemActionAppliesToResponse{ @@ -83,29 +84,29 @@ func (s *BackupItemActionGRPCServer) AppliesTo( func (s *BackupItemActionGRPCServer) Execute( ctx context.Context, req *protobiav1.ExecuteRequest) (response *protobiav1.ExecuteResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } var item unstructured.Unstructured var backup api.Backup if err := json.Unmarshal(req.Item, &item); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } if err := json.Unmarshal(req.Backup, &backup); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } updatedItem, additionalItems, err := impl.Execute(&item, &backup) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } // If the plugin implementation returned a nil updatedItem (meaning no modifications), reset updatedItem to the @@ -116,7 +117,7 @@ func (s *BackupItemActionGRPCServer) Execute( } else { updatedItemJSON, err = json.Marshal(updatedItem.UnstructuredContent()) if err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } } diff --git a/pkg/plugin/framework/backup_item_action_test.go b/pkg/plugin/framework/backup_item_action_test.go index 32d7ea5515..a88aaf853b 100644 --- a/pkg/plugin/framework/backup_item_action_test.go +++ b/pkg/plugin/framework/backup_item_action_test.go @@ -29,10 +29,11 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" - "github.com/vmware-tanzu/velero/pkg/backup/mocks" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" proto "github.com/vmware-tanzu/velero/pkg/plugin/generated" protobiav1 "github.com/vmware-tanzu/velero/pkg/plugin/generated" "github.com/vmware-tanzu/velero/pkg/plugin/velero" + mocks "github.com/vmware-tanzu/velero/pkg/plugin/velero/mocks/backupitemaction/v1" velerotest "github.com/vmware-tanzu/velero/pkg/test" ) @@ -147,16 +148,16 @@ func TestBackupItemActionGRPCServerExecute(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - itemAction := &mocks.ItemAction{} + itemAction := &mocks.BackupItemAction{} defer itemAction.AssertExpectations(t) if !test.skipMock { itemAction.On("Execute", &validItemObject, &validBackupObject).Return(test.implUpdatedItem, test.implAdditionalItems, test.implError) } - s := &BackupItemActionGRPCServer{mux: &serverMux{ - serverLog: velerotest.NewLogger(), - handlers: map[string]interface{}{ + s := &BackupItemActionGRPCServer{mux: &common.ServerMux{ + ServerLog: velerotest.NewLogger(), + Handlers: map[string]interface{}{ "xyz": itemAction, }, }} diff --git a/pkg/plugin/framework/client_dispenser.go b/pkg/plugin/framework/common/client_dispenser.go similarity index 86% rename from pkg/plugin/framework/client_dispenser.go rename to pkg/plugin/framework/common/client_dispenser.go index 83e934d725..1abb11c2df 100644 --- a/pkg/plugin/framework/client_dispenser.go +++ b/pkg/plugin/framework/common/client_dispenser.go @@ -14,17 +14,17 @@ See the License for the specific language governing permissions and limitations under the License. */ -package framework +package common import ( "github.com/sirupsen/logrus" "google.golang.org/grpc" ) -// clientBase implements client and contains shared fields common to all clients. -type clientBase struct { - plugin string - logger logrus.FieldLogger +// ClientBase implements client and contains shared fields common to all clients. +type ClientBase struct { + Plugin string + Logger logrus.FieldLogger } type ClientDispenser interface { @@ -44,10 +44,10 @@ type clientDispenser struct { clients map[string]interface{} } -type clientInitFunc func(base *clientBase, clientConn *grpc.ClientConn) interface{} +type clientInitFunc func(base *ClientBase, clientConn *grpc.ClientConn) interface{} // newClientDispenser creates a new clientDispenser. -func newClientDispenser(logger logrus.FieldLogger, clientConn *grpc.ClientConn, initFunc clientInitFunc) *clientDispenser { +func NewClientDispenser(logger logrus.FieldLogger, clientConn *grpc.ClientConn, initFunc clientInitFunc) *clientDispenser { return &clientDispenser{ clientConn: clientConn, logger: logger, @@ -63,9 +63,9 @@ func (cd *clientDispenser) ClientFor(name string) interface{} { return client } - base := &clientBase{ - plugin: name, - logger: cd.logger, + base := &ClientBase{ + Plugin: name, + Logger: cd.logger, } // Initialize the plugin (e.g. newBackupItemActionGRPCClient()) client := cd.initFunc(base, cd.clientConn) diff --git a/pkg/plugin/framework/client_dispenser_test.go b/pkg/plugin/framework/common/client_dispenser_test.go similarity index 83% rename from pkg/plugin/framework/client_dispenser_test.go rename to pkg/plugin/framework/common/client_dispenser_test.go index 9ec5266691..bd1461658a 100644 --- a/pkg/plugin/framework/client_dispenser_test.go +++ b/pkg/plugin/framework/common/client_dispenser_test.go @@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -package framework +package common import ( "testing" @@ -26,7 +26,7 @@ import ( ) type fakeClient struct { - base *clientBase + base *ClientBase clientConn *grpc.ClientConn } @@ -36,11 +36,11 @@ func TestNewClientDispenser(t *testing.T) { clientConn := new(grpc.ClientConn) c := 3 - initFunc := func(base *clientBase, clientConn *grpc.ClientConn) interface{} { + initFunc := func(base *ClientBase, clientConn *grpc.ClientConn) interface{} { return c } - cd := newClientDispenser(logger, clientConn, initFunc) + cd := NewClientDispenser(logger, clientConn, initFunc) assert.Equal(t, clientConn, cd.clientConn) assert.NotNil(t, cd.clients) assert.Empty(t, cd.clients) @@ -52,23 +52,23 @@ func TestClientFor(t *testing.T) { c := new(fakeClient) count := 0 - initFunc := func(base *clientBase, clientConn *grpc.ClientConn) interface{} { + initFunc := func(base *ClientBase, clientConn *grpc.ClientConn) interface{} { c.base = base c.clientConn = clientConn count++ return c } - cd := newClientDispenser(logger, clientConn, initFunc) + cd := NewClientDispenser(logger, clientConn, initFunc) actual := cd.ClientFor("pod") require.IsType(t, &fakeClient{}, actual) typed := actual.(*fakeClient) assert.Equal(t, 1, count) assert.Equal(t, &typed, &c) - expectedBase := &clientBase{ - plugin: "pod", - logger: logger, + expectedBase := &ClientBase{ + Plugin: "pod", + Logger: logger, } assert.Equal(t, expectedBase, typed.base) assert.Equal(t, clientConn, typed.clientConn) diff --git a/pkg/plugin/framework/client_errors.go b/pkg/plugin/framework/common/client_errors.go similarity index 84% rename from pkg/plugin/framework/client_errors.go rename to pkg/plugin/framework/common/client_errors.go index adad199dbe..377851aa8f 100644 --- a/pkg/plugin/framework/client_errors.go +++ b/pkg/plugin/framework/common/client_errors.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package framework +package common import ( "google.golang.org/grpc/status" @@ -22,7 +22,7 @@ import ( proto "github.com/vmware-tanzu/velero/pkg/plugin/generated" ) -// fromGRPCError takes a gRPC status error, extracts a stack trace +// FromGRPCError takes a gRPC status error, extracts a stack trace // from the details if it exists, and returns an error that can // provide information about where it was created. // @@ -30,7 +30,7 @@ import ( // all errors returned from the plugin server before they're passed back to // the rest of the Velero codebase. This will enable them to display location // information when they're logged. -func fromGRPCError(err error) error { +func FromGRPCError(err error) error { statusErr, ok := status.FromError(err) if !ok { return statusErr.Err() @@ -39,7 +39,7 @@ func fromGRPCError(err error) error { for _, detail := range statusErr.Details() { switch t := detail.(type) { case *proto.Stack: - return &protoStackError{ + return &ProtoStackError{ error: err, stack: t, } @@ -49,12 +49,12 @@ func fromGRPCError(err error) error { return err } -type protoStackError struct { +type ProtoStackError struct { error stack *proto.Stack } -func (e *protoStackError) File() string { +func (e *ProtoStackError) File() string { if e.stack == nil || len(e.stack.Frames) < 1 { return "" } @@ -62,7 +62,7 @@ func (e *protoStackError) File() string { return e.stack.Frames[0].File } -func (e *protoStackError) Line() int32 { +func (e *ProtoStackError) Line() int32 { if e.stack == nil || len(e.stack.Frames) < 1 { return 0 } @@ -70,7 +70,7 @@ func (e *protoStackError) Line() int32 { return e.stack.Frames[0].Line } -func (e *protoStackError) Function() string { +func (e *ProtoStackError) Function() string { if e.stack == nil || len(e.stack.Frames) < 1 { return "" } diff --git a/pkg/plugin/framework/handle_panic.go b/pkg/plugin/framework/common/handle_panic.go similarity index 84% rename from pkg/plugin/framework/handle_panic.go rename to pkg/plugin/framework/common/handle_panic.go index 4ea0ec2b52..e4324898dd 100644 --- a/pkg/plugin/framework/handle_panic.go +++ b/pkg/plugin/framework/common/handle_panic.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package framework +package common import ( "runtime/debug" @@ -23,8 +23,8 @@ import ( "google.golang.org/grpc/codes" ) -// handlePanic is a panic handler for the server half of velero plugins. -func handlePanic(p interface{}) error { +// HandlePanic is a panic handler for the server half of velero plugins. +func HandlePanic(p interface{}) error { if p == nil { return nil } @@ -37,7 +37,7 @@ func handlePanic(p interface{}) error { if panicErr, ok := p.(error); !ok { err = errors.Errorf("plugin panicked: %v", p) } else { - if _, ok := panicErr.(stackTracer); ok { + if _, ok := panicErr.(StackTracer); ok { err = panicErr } else { errWithStacktrace := errors.Errorf("%v, stack trace: %s", panicErr, debug.Stack()) @@ -45,5 +45,5 @@ func handlePanic(p interface{}) error { } } - return newGRPCErrorWithCode(err, codes.Aborted) + return NewGRPCErrorWithCode(err, codes.Aborted) } diff --git a/pkg/plugin/framework/plugin_base.go b/pkg/plugin/framework/common/plugin_base.go similarity index 65% rename from pkg/plugin/framework/plugin_base.go rename to pkg/plugin/framework/common/plugin_base.go index 4a97fa47b9..12e444b749 100644 --- a/pkg/plugin/framework/plugin_base.go +++ b/pkg/plugin/framework/common/plugin_base.go @@ -14,35 +14,35 @@ See the License for the specific language governing permissions and limitations under the License. */ -package framework +package common import ( "github.com/sirupsen/logrus" ) -type pluginBase struct { - clientLogger logrus.FieldLogger - *serverMux +type PluginBase struct { + ClientLogger logrus.FieldLogger + *ServerMux } -func newPluginBase(options ...PluginOption) *pluginBase { - base := new(pluginBase) +func NewPluginBase(options ...PluginOption) *PluginBase { + base := new(PluginBase) for _, option := range options { option(base) } return base } -type PluginOption func(base *pluginBase) +type PluginOption func(base *PluginBase) func ClientLogger(logger logrus.FieldLogger) PluginOption { - return func(base *pluginBase) { - base.clientLogger = logger + return func(base *PluginBase) { + base.ClientLogger = logger } } -func serverLogger(logger logrus.FieldLogger) PluginOption { - return func(base *pluginBase) { - base.serverMux = newServerMux(logger) +func ServerLogger(logger logrus.FieldLogger) PluginOption { + return func(base *PluginBase) { + base.ServerMux = NewServerMux(logger) } } diff --git a/pkg/plugin/framework/plugin_base_test.go b/pkg/plugin/framework/common/plugin_base_test.go similarity index 84% rename from pkg/plugin/framework/plugin_base_test.go rename to pkg/plugin/framework/common/plugin_base_test.go index 3d25732586..04e066d0c6 100644 --- a/pkg/plugin/framework/plugin_base_test.go +++ b/pkg/plugin/framework/common/plugin_base_test.go @@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -package framework +package common import ( "testing" @@ -24,17 +24,17 @@ import ( ) func TestClientLogger(t *testing.T) { - base := &pluginBase{} + base := &PluginBase{} logger := test.NewLogger() f := ClientLogger(logger) f(base) - assert.Equal(t, logger, base.clientLogger) + assert.Equal(t, logger, base.ClientLogger) } func TestServerLogger(t *testing.T) { - base := &pluginBase{} + base := &PluginBase{} logger := test.NewLogger() - f := serverLogger(logger) + f := ServerLogger(logger) f(base) - assert.Equal(t, newServerMux(logger), base.serverMux) + assert.Equal(t, NewServerMux(logger), base.ServerMux) } diff --git a/pkg/plugin/framework/plugin_kinds.go b/pkg/plugin/framework/common/plugin_kinds.go similarity index 89% rename from pkg/plugin/framework/plugin_kinds.go rename to pkg/plugin/framework/common/plugin_kinds.go index f48f7f4983..2e0119e2fd 100644 --- a/pkg/plugin/framework/plugin_kinds.go +++ b/pkg/plugin/framework/common/plugin_kinds.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package framework +package common // PluginKind is a type alias for a string that describes // the kind of a Velero-supported plugin. @@ -48,6 +48,11 @@ const ( PluginKindPluginLister PluginKind = "PluginLister" ) +// If there are plugin kinds that are adaptable to newer API versions, list them here. +// The older (adaptable) version is the key, and the value is the full list of newer +// plugin kinds that are capable of adapting it. +var PluginKindsAdaptableTo = map[PluginKind][]PluginKind{} + // AllPluginKinds contains all the valid plugin kinds that Velero supports, excluding PluginLister because that is not a // kind that a developer would ever need to implement (it's handled by Velero and the Velero plugin library code). func AllPluginKinds() map[string]PluginKind { diff --git a/pkg/plugin/framework/server_errors.go b/pkg/plugin/framework/common/server_errors.go similarity index 78% rename from pkg/plugin/framework/server_errors.go rename to pkg/plugin/framework/common/server_errors.go index 55f8859fde..7763d4e9ec 100644 --- a/pkg/plugin/framework/server_errors.go +++ b/pkg/plugin/framework/common/server_errors.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package framework +package common import ( goproto "github.com/golang/protobuf/proto" @@ -26,13 +26,13 @@ import ( "github.com/vmware-tanzu/velero/pkg/util/logging" ) -// newGRPCErrorWithCode wraps err in a gRPC status error with the error's stack trace +// NewGRPCErrorWithCode wraps err in a gRPC status error with the error's stack trace // included in the details if it exists. This provides an easy way to send // stack traces from plugin servers across the wire to the plugin client. // // This function should be used in the internal plugin server code to wrap // all errors before they're returned. -func newGRPCErrorWithCode(err error, code codes.Code, details ...goproto.Message) error { +func NewGRPCErrorWithCode(err error, code codes.Code, details ...goproto.Message) error { // if it's already a gRPC status error, use it; otherwise, create a new one statusErr, ok := status.FromError(err) if !ok { @@ -40,7 +40,7 @@ func newGRPCErrorWithCode(err error, code codes.Code, details ...goproto.Message } // get a Stack for the error and add it to details - if stack := errorStack(err); stack != nil { + if stack := ErrorStack(err); stack != nil { details = append(details, stack) } @@ -52,16 +52,16 @@ func newGRPCErrorWithCode(err error, code codes.Code, details ...goproto.Message return statusErr.Err() } -// newGRPCError is a convenience function for creating a new gRPC error +// NewGRPCError is a convenience function for creating a new gRPC error // with code = codes.Unknown -func newGRPCError(err error, details ...goproto.Message) error { - return newGRPCErrorWithCode(err, codes.Unknown, details...) +func NewGRPCError(err error, details ...goproto.Message) error { + return NewGRPCErrorWithCode(err, codes.Unknown, details...) } -// errorStack gets a stack trace, if it exists, from the provided error, and +// ErrorStack gets a stack trace, if it exists, from the provided error, and // returns it as a *proto.Stack. -func errorStack(err error) *proto.Stack { - stackTracer, ok := err.(stackTracer) +func ErrorStack(err error) *proto.Stack { + stackTracer, ok := err.(StackTracer) if !ok { return nil } @@ -80,6 +80,6 @@ func errorStack(err error) *proto.Stack { return stackTrace } -type stackTracer interface { +type StackTracer interface { StackTrace() errors.StackTrace } diff --git a/pkg/plugin/framework/server_mux.go b/pkg/plugin/framework/common/server_mux.go similarity index 78% rename from pkg/plugin/framework/server_mux.go rename to pkg/plugin/framework/common/server_mux.go index 4babea3841..960975c7e6 100644 --- a/pkg/plugin/framework/server_mux.go +++ b/pkg/plugin/framework/common/server_mux.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package framework +package common import ( "strings" @@ -29,42 +29,42 @@ import ( // (ObjectStore, VolumeSnapshotter, BackupItemAction, RestoreItemAction). type HandlerInitializer func(logger logrus.FieldLogger) (interface{}, error) -// serverMux manages multiple implementations of a single plugin kind, such as pod and pvc BackupItemActions. -type serverMux struct { +// ServerMux manages multiple implementations of a single plugin kind, such as pod and pvc BackupItemActions. +type ServerMux struct { kind PluginKind initializers map[string]HandlerInitializer - handlers map[string]interface{} - serverLog logrus.FieldLogger + Handlers map[string]interface{} + ServerLog logrus.FieldLogger } -// newServerMux returns a new serverMux. -func newServerMux(logger logrus.FieldLogger) *serverMux { - return &serverMux{ +// NewServerMux returns a new ServerMux. +func NewServerMux(logger logrus.FieldLogger) *ServerMux { + return &ServerMux{ initializers: make(map[string]HandlerInitializer), - handlers: make(map[string]interface{}), - serverLog: logger, + Handlers: make(map[string]interface{}), + ServerLog: logger, } } // register validates the plugin name and registers the // initializer for the given name. -func (m *serverMux) register(name string, f HandlerInitializer) { - if err := ValidatePluginName(name, m.names()); err != nil { - m.serverLog.Errorf("invalid plugin name %q: %s", name, err) +func (m *ServerMux) Register(name string, f HandlerInitializer) { + if err := ValidatePluginName(name, m.Names()); err != nil { + m.ServerLog.Errorf("invalid plugin name %q: %s", name, err) return } m.initializers[name] = f } // names returns a list of all registered implementations. -func (m *serverMux) names() []string { +func (m *ServerMux) Names() []string { return sets.StringKeySet(m.initializers).List() } -// getHandler returns the instance for a plugin with the given name. If an instance has already been initialized, +// GetHandler returns the instance for a plugin with the given name. If an instance has already been initialized, // that is returned. Otherwise, the instance is initialized by calling its initialization function. -func (m *serverMux) getHandler(name string) (interface{}, error) { - if instance, found := m.handlers[name]; found { +func (m *ServerMux) GetHandler(name string) (interface{}, error) { + if instance, found := m.Handlers[name]; found { return instance, nil } @@ -73,14 +73,14 @@ func (m *serverMux) getHandler(name string) (interface{}, error) { return nil, errors.Errorf("%v plugin: %s was not found or has an invalid name format", m.kind, name) } - instance, err := initializer(m.serverLog) + instance, err := initializer(m.ServerLog) if err != nil { return nil, err } - m.handlers[name] = instance + m.Handlers[name] = instance - return m.handlers[name], nil + return m.Handlers[name], nil } // ValidatePluginName checks if the given name: diff --git a/pkg/plugin/framework/server_mux_test.go b/pkg/plugin/framework/common/server_mux_test.go similarity index 99% rename from pkg/plugin/framework/server_mux_test.go rename to pkg/plugin/framework/common/server_mux_test.go index 1a9be9a68b..1e84555f3a 100644 --- a/pkg/plugin/framework/server_mux_test.go +++ b/pkg/plugin/framework/common/server_mux_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package framework +package common import ( "strings" diff --git a/pkg/plugin/framework/delete_item_action.go b/pkg/plugin/framework/delete_item_action.go index fc9be502c7..7d70938ca7 100644 --- a/pkg/plugin/framework/delete_item_action.go +++ b/pkg/plugin/framework/delete_item_action.go @@ -21,6 +21,7 @@ import ( "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" ) @@ -29,16 +30,16 @@ import ( // interface. type DeleteItemActionPlugin struct { plugin.NetRPCUnsupportedPlugin - *pluginBase + *common.PluginBase } // GRPCClient returns a RestoreItemAction gRPC client. func (p *DeleteItemActionPlugin) GRPCClient(_ context.Context, _ *plugin.GRPCBroker, clientConn *grpc.ClientConn) (interface{}, error) { - return newClientDispenser(p.clientLogger, clientConn, newDeleteItemActionGRPCClient), nil + return common.NewClientDispenser(p.ClientLogger, clientConn, newDeleteItemActionGRPCClient), nil } // GRPCServer registers a DeleteItemAction gRPC server. func (p *DeleteItemActionPlugin) GRPCServer(_ *plugin.GRPCBroker, server *grpc.Server) error { - proto.RegisterDeleteItemActionServer(server, &DeleteItemActionGRPCServer{mux: p.serverMux}) + proto.RegisterDeleteItemActionServer(server, &DeleteItemActionGRPCServer{mux: p.ServerMux}) return nil } diff --git a/pkg/plugin/framework/delete_item_action_client.go b/pkg/plugin/framework/delete_item_action_client.go index e9adae6d01..4988d5f085 100644 --- a/pkg/plugin/framework/delete_item_action_client.go +++ b/pkg/plugin/framework/delete_item_action_client.go @@ -23,6 +23,7 @@ import ( "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" "github.com/vmware-tanzu/velero/pkg/plugin/velero" ) @@ -30,30 +31,30 @@ import ( var _ velero.DeleteItemAction = &DeleteItemActionGRPCClient{} // NewDeleteItemActionPlugin constructs a DeleteItemActionPlugin. -func NewDeleteItemActionPlugin(options ...PluginOption) *DeleteItemActionPlugin { +func NewDeleteItemActionPlugin(options ...common.PluginOption) *DeleteItemActionPlugin { return &DeleteItemActionPlugin{ - pluginBase: newPluginBase(options...), + PluginBase: common.NewPluginBase(options...), } } // DeleteItemActionGRPCClient implements the backup/ItemAction interface and uses a // gRPC client to make calls to the plugin server. type DeleteItemActionGRPCClient struct { - *clientBase + *common.ClientBase grpcClient proto.DeleteItemActionClient } -func newDeleteItemActionGRPCClient(base *clientBase, clientConn *grpc.ClientConn) interface{} { +func newDeleteItemActionGRPCClient(base *common.ClientBase, clientConn *grpc.ClientConn) interface{} { return &DeleteItemActionGRPCClient{ - clientBase: base, + ClientBase: base, grpcClient: proto.NewDeleteItemActionClient(clientConn), } } func (c *DeleteItemActionGRPCClient) AppliesTo() (velero.ResourceSelector, error) { - res, err := c.grpcClient.AppliesTo(context.Background(), &proto.DeleteItemActionAppliesToRequest{Plugin: c.plugin}) + res, err := c.grpcClient.AppliesTo(context.Background(), &proto.DeleteItemActionAppliesToRequest{Plugin: c.Plugin}) if err != nil { - return velero.ResourceSelector{}, fromGRPCError(err) + return velero.ResourceSelector{}, common.FromGRPCError(err) } if res.ResourceSelector == nil { @@ -81,14 +82,14 @@ func (c *DeleteItemActionGRPCClient) Execute(input *velero.DeleteItemActionExecu } req := &proto.DeleteItemActionExecuteRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, Item: itemJSON, Backup: backupJSON, } // First return item is just an empty struct no matter what. if _, err = c.grpcClient.Execute(context.Background(), req); err != nil { - return fromGRPCError(err) + return common.FromGRPCError(err) } return nil diff --git a/pkg/plugin/framework/delete_item_action_server.go b/pkg/plugin/framework/delete_item_action_server.go index d9d3a7dc70..e298969d13 100644 --- a/pkg/plugin/framework/delete_item_action_server.go +++ b/pkg/plugin/framework/delete_item_action_server.go @@ -24,6 +24,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" + "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" ) @@ -31,11 +32,11 @@ import ( // DeleteItemActionGRPCServer implements the proto-generated DeleteItemActionServer interface, and accepts // gRPC calls and forwards them to an implementation of the pluggable interface. type DeleteItemActionGRPCServer struct { - mux *serverMux + mux *common.ServerMux } func (s *DeleteItemActionGRPCServer) getImpl(name string) (velero.DeleteItemAction, error) { - impl, err := s.mux.getHandler(name) + impl, err := s.mux.GetHandler(name) if err != nil { return nil, err } @@ -50,19 +51,19 @@ func (s *DeleteItemActionGRPCServer) getImpl(name string) (velero.DeleteItemActi func (s *DeleteItemActionGRPCServer) AppliesTo(ctx context.Context, req *proto.DeleteItemActionAppliesToRequest) (response *proto.DeleteItemActionAppliesToResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } resourceSelector, err := impl.AppliesTo() if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &proto.DeleteItemActionAppliesToResponse{ @@ -78,14 +79,14 @@ func (s *DeleteItemActionGRPCServer) AppliesTo(ctx context.Context, req *proto.D func (s *DeleteItemActionGRPCServer) Execute(ctx context.Context, req *proto.DeleteItemActionExecuteRequest) (_ *proto.Empty, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } var ( @@ -94,18 +95,18 @@ func (s *DeleteItemActionGRPCServer) Execute(ctx context.Context, req *proto.Del ) if err := json.Unmarshal(req.Item, &item); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } if err = json.Unmarshal(req.Backup, &backup); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } if err := impl.Execute(&velero.DeleteItemActionExecuteInput{ Item: &item, Backup: &backup, }); err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &proto.Empty{}, nil diff --git a/pkg/plugin/framework/interface.go b/pkg/plugin/framework/interface.go index 1394e8e826..4eeb3049b5 100644 --- a/pkg/plugin/framework/interface.go +++ b/pkg/plugin/framework/interface.go @@ -24,5 +24,5 @@ type Interface interface { // names returns a list of all the registered implementations for this plugin (such as "pod" and "pvc" for // BackupItemAction). - names() []string + Names() []string } diff --git a/pkg/plugin/framework/item_snapshotter.go b/pkg/plugin/framework/item_snapshotter.go index 6e6f91439f..f9af50e68c 100644 --- a/pkg/plugin/framework/item_snapshotter.go +++ b/pkg/plugin/framework/item_snapshotter.go @@ -21,6 +21,7 @@ import ( "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" ) @@ -29,16 +30,16 @@ import ( // interface. type ItemSnapshotterPlugin struct { plugin.NetRPCUnsupportedPlugin - *pluginBase + *common.PluginBase } // GRPCClient returns a clientDispenser for ItemSnapshotter gRPC clients. func (p *ItemSnapshotterPlugin) GRPCClient(_ context.Context, _ *plugin.GRPCBroker, clientConn *grpc.ClientConn) (interface{}, error) { - return newClientDispenser(p.clientLogger, clientConn, newItemSnapshotterGRPCClient), nil + 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}) + proto.RegisterItemSnapshotterServer(server, &ItemSnapshotterGRPCServer{mux: p.ServerMux}) return nil } diff --git a/pkg/plugin/framework/item_snapshotter_client.go b/pkg/plugin/framework/item_snapshotter_client.go index 23786046a3..323c3541b3 100644 --- a/pkg/plugin/framework/item_snapshotter_client.go +++ b/pkg/plugin/framework/item_snapshotter_client.go @@ -25,21 +25,22 @@ import ( "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 ...PluginOption) *ItemSnapshotterPlugin { +func NewItemSnapshotterPlugin(options ...common.PluginOption) *ItemSnapshotterPlugin { return &ItemSnapshotterPlugin{ - pluginBase: newPluginBase(options...), + PluginBase: common.NewPluginBase(options...), } } -func newItemSnapshotterGRPCClient(base *clientBase, clientConn *grpc.ClientConn) interface{} { +func newItemSnapshotterGRPCClient(base *common.ClientBase, clientConn *grpc.ClientConn) interface{} { return &ItemSnapshotterGRPCClient{ - clientBase: base, + ClientBase: base, grpcClient: proto.NewItemSnapshotterClient(clientConn), } } @@ -47,13 +48,13 @@ func newItemSnapshotterGRPCClient(base *clientBase, clientConn *grpc.ClientConn) // ItemSnapshotterGRPCClient implements the ItemSnapshotter interface and uses a // gRPC client to make calls to the plugin server. type ItemSnapshotterGRPCClient struct { - *clientBase + *common.ClientBase grpcClient proto.ItemSnapshotterClient } func (recv ItemSnapshotterGRPCClient) Init(config map[string]string) error { req := &proto.ItemSnapshotterInitRequest{ - Plugin: recv.plugin, + Plugin: recv.Plugin, Config: config, } @@ -63,12 +64,12 @@ func (recv ItemSnapshotterGRPCClient) Init(config map[string]string) error { func (recv ItemSnapshotterGRPCClient) AppliesTo() (velero.ResourceSelector, error) { req := &proto.ItemSnapshotterAppliesToRequest{ - Plugin: recv.plugin, + Plugin: recv.Plugin, } res, err := recv.grpcClient.AppliesTo(context.Background(), req) if err != nil { - return velero.ResourceSelector{}, fromGRPCError(err) + return velero.ResourceSelector{}, common.FromGRPCError(err) } if res.ResourceSelector == nil { @@ -95,7 +96,7 @@ func (recv ItemSnapshotterGRPCClient) AlsoHandles(input *isv1.AlsoHandlesInput) return nil, errors.WithStack(err) } req := &proto.AlsoHandlesRequest{ - Plugin: recv.plugin, + Plugin: recv.Plugin, Item: itemJSON, Backup: backupJSON, } @@ -120,7 +121,7 @@ func (recv ItemSnapshotterGRPCClient) SnapshotItem(ctx context.Context, input *i return nil, errors.WithStack(err) } req := &proto.SnapshotItemRequest{ - Plugin: recv.plugin, + Plugin: recv.Plugin, Item: itemJSON, Backup: backupJSON, } @@ -152,7 +153,7 @@ func (recv ItemSnapshotterGRPCClient) Progress(input *isv1.ProgressInput) (*isv1 return nil, errors.WithStack(err) } req := &proto.ProgressRequest{ - Plugin: recv.plugin, + Plugin: recv.Plugin, ItemID: resourceIdentifierToProto(input.ItemID), SnapshotID: input.SnapshotID, Backup: backupJSON, @@ -183,7 +184,7 @@ func (recv ItemSnapshotterGRPCClient) Progress(input *isv1.ProgressInput) (*isv1 func (recv ItemSnapshotterGRPCClient) DeleteSnapshot(ctx context.Context, input *isv1.DeleteSnapshotInput) error { req := &proto.DeleteItemSnapshotRequest{ - Plugin: recv.plugin, + Plugin: recv.Plugin, Params: input.Params, SnapshotID: input.SnapshotID, } @@ -209,7 +210,7 @@ func (recv ItemSnapshotterGRPCClient) CreateItemFromSnapshot(ctx context.Context return nil, errors.WithStack(err) } req := &proto.CreateItemFromSnapshotRequest{ - Plugin: recv.plugin, + Plugin: recv.Plugin, Item: itemJSON, SnapshotID: input.SnapshotID, ItemFromBackup: itemFromBackupJSON, diff --git a/pkg/plugin/framework/item_snapshotter_server.go b/pkg/plugin/framework/item_snapshotter_server.go index d746947577..21ab92110f 100644 --- a/pkg/plugin/framework/item_snapshotter_server.go +++ b/pkg/plugin/framework/item_snapshotter_server.go @@ -27,17 +27,18 @@ import ( "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 *serverMux + mux *common.ServerMux } func (recv *ItemSnapshotterGRPCServer) getImpl(name string) (isv1.ItemSnapshotter, error) { - impl, err := recv.mux.getHandler(name) + impl, err := recv.mux.GetHandler(name) if err != nil { return nil, err } @@ -52,19 +53,19 @@ func (recv *ItemSnapshotterGRPCServer) getImpl(name string) (isv1.ItemSnapshotte func (recv *ItemSnapshotterGRPCServer) Init(c context.Context, req *proto.ItemSnapshotterInitRequest) (response *proto.Empty, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := recv.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } err = impl.Init(req.Config) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &proto.Empty{}, nil @@ -72,19 +73,19 @@ func (recv *ItemSnapshotterGRPCServer) Init(c context.Context, req *proto.ItemSn func (recv *ItemSnapshotterGRPCServer) AppliesTo(ctx context.Context, req *proto.ItemSnapshotterAppliesToRequest) (response *proto.ItemSnapshotterAppliesToResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := recv.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } resourceSelector, err := impl.AppliesTo() if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &proto.ItemSnapshotterAppliesToResponse{ @@ -100,23 +101,23 @@ func (recv *ItemSnapshotterGRPCServer) AppliesTo(ctx context.Context, req *proto func (recv *ItemSnapshotterGRPCServer) AlsoHandles(ctx context.Context, req *proto.AlsoHandlesRequest) (res *proto.AlsoHandlesResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := recv.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } var item unstructured.Unstructured var backup api.Backup if err := json.Unmarshal(req.Item, &item); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } if err := json.Unmarshal(req.Backup, &backup); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } ahi := isv1.AlsoHandlesInput{ Item: &item, @@ -124,7 +125,7 @@ func (recv *ItemSnapshotterGRPCServer) AlsoHandles(ctx context.Context, req *pro } alsoHandles, err := impl.AlsoHandles(&ahi) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } res = &proto.AlsoHandlesResponse{} @@ -136,23 +137,23 @@ func (recv *ItemSnapshotterGRPCServer) AlsoHandles(ctx context.Context, req *pro func (recv *ItemSnapshotterGRPCServer) SnapshotItem(ctx context.Context, req *proto.SnapshotItemRequest) (res *proto.SnapshotItemResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := recv.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } var item unstructured.Unstructured var backup api.Backup if err := json.Unmarshal(req.Item, &item); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } if err := json.Unmarshal(req.Backup, &backup); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } sii := isv1.SnapshotItemInput{ Item: &item, @@ -169,7 +170,7 @@ func (recv *ItemSnapshotterGRPCServer) SnapshotItem(ctx context.Context, req *pr } else { updatedItemJSON, err = json.Marshal(sio.UpdatedItem.UnstructuredContent()) if err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } } res = &proto.SnapshotItemResponse{ @@ -184,18 +185,18 @@ func (recv *ItemSnapshotterGRPCServer) SnapshotItem(ctx context.Context, req *pr func (recv *ItemSnapshotterGRPCServer) Progress(ctx context.Context, req *proto.ProgressRequest) (res *proto.ProgressResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := recv.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } var backup api.Backup if err := json.Unmarshal(req.Backup, &backup); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } sipi := &isv1.ProgressInput{ ItemID: protoToResourceIdentifier(req.ItemID), @@ -205,7 +206,7 @@ func (recv *ItemSnapshotterGRPCServer) Progress(ctx context.Context, req *proto. sipo, err := impl.Progress(sipi) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } res = &proto.ProgressResponse{ @@ -223,18 +224,18 @@ func (recv *ItemSnapshotterGRPCServer) Progress(ctx context.Context, req *proto. func (recv *ItemSnapshotterGRPCServer) DeleteSnapshot(ctx context.Context, req *proto.DeleteItemSnapshotRequest) (empty *proto.Empty, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := recv.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } var itemFromBackup unstructured.Unstructured if err := json.Unmarshal(req.ItemFromBackup, &itemFromBackup); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } disi := isv1.DeleteSnapshotInput{ @@ -246,36 +247,36 @@ func (recv *ItemSnapshotterGRPCServer) DeleteSnapshot(ctx context.Context, req * err = impl.DeleteSnapshot(ctx, &disi) if err != nil { - return nil, newGRPCError(err) + 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 := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := recv.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } var snapshottedItem unstructured.Unstructured if err := json.Unmarshal(req.Item, &snapshottedItem); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } var itemFromBackup unstructured.Unstructured if err := json.Unmarshal(req.Item, &itemFromBackup); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } var restore api.Restore if err := json.Unmarshal(req.Restore, &restore); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } cii := isv1.CreateItemInput{ @@ -289,7 +290,7 @@ func (recv *ItemSnapshotterGRPCServer) CreateItemFromSnapshot(ctx context.Contex cio, err := impl.CreateItemFromSnapshot(ctx, &cii) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } var updatedItemJSON []byte @@ -298,7 +299,7 @@ func (recv *ItemSnapshotterGRPCServer) CreateItemFromSnapshot(ctx context.Contex } else { updatedItemJSON, err = json.Marshal(cio.UpdatedItem.UnstructuredContent()) if err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } } res = &proto.CreateItemFromSnapshotResponse{ diff --git a/pkg/plugin/framework/object_store.go b/pkg/plugin/framework/object_store.go index bd7a90cf3c..ddf7414218 100644 --- a/pkg/plugin/framework/object_store.go +++ b/pkg/plugin/framework/object_store.go @@ -21,6 +21,7 @@ import ( "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" ) @@ -29,17 +30,17 @@ import ( // interface. type ObjectStorePlugin struct { plugin.NetRPCUnsupportedPlugin - *pluginBase + *common.PluginBase } // GRPCClient returns an ObjectStore gRPC client. func (p *ObjectStorePlugin) GRPCClient(_ context.Context, _ *plugin.GRPCBroker, clientConn *grpc.ClientConn) (interface{}, error) { - return newClientDispenser(p.clientLogger, clientConn, newObjectStoreGRPCClient), nil + return common.NewClientDispenser(p.ClientLogger, clientConn, newObjectStoreGRPCClient), nil } // GRPCServer registers an ObjectStore gRPC server. func (p *ObjectStorePlugin) GRPCServer(_ *plugin.GRPCBroker, server *grpc.Server) error { - proto.RegisterObjectStoreServer(server, &ObjectStoreGRPCServer{mux: p.serverMux}) + proto.RegisterObjectStoreServer(server, &ObjectStoreGRPCServer{mux: p.ServerMux}) return nil } diff --git a/pkg/plugin/framework/object_store_client.go b/pkg/plugin/framework/object_store_client.go index 8442749076..7f40921c2a 100644 --- a/pkg/plugin/framework/object_store_client.go +++ b/pkg/plugin/framework/object_store_client.go @@ -24,28 +24,29 @@ import ( "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" ) const byteChunkSize = 16384 // NewObjectStorePlugin construct an ObjectStorePlugin. -func NewObjectStorePlugin(options ...PluginOption) *ObjectStorePlugin { +func NewObjectStorePlugin(options ...common.PluginOption) *ObjectStorePlugin { return &ObjectStorePlugin{ - pluginBase: newPluginBase(options...), + PluginBase: common.NewPluginBase(options...), } } // ObjectStoreGRPCClient implements the ObjectStore interface and uses a // gRPC client to make calls to the plugin server. type ObjectStoreGRPCClient struct { - *clientBase + *common.ClientBase grpcClient proto.ObjectStoreClient } -func newObjectStoreGRPCClient(base *clientBase, clientConn *grpc.ClientConn) interface{} { +func newObjectStoreGRPCClient(base *common.ClientBase, clientConn *grpc.ClientConn) interface{} { return &ObjectStoreGRPCClient{ - clientBase: base, + ClientBase: base, grpcClient: proto.NewObjectStoreClient(clientConn), } } @@ -55,12 +56,12 @@ func newObjectStoreGRPCClient(base *clientBase, clientConn *grpc.ClientConn) int // cannot be initialized from the provided config. func (c *ObjectStoreGRPCClient) Init(config map[string]string) error { req := &proto.ObjectStoreInitRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, Config: config, } if _, err := c.grpcClient.Init(context.Background(), req); err != nil { - return fromGRPCError(err) + return common.FromGRPCError(err) } return nil @@ -71,7 +72,7 @@ func (c *ObjectStoreGRPCClient) Init(config map[string]string) error { func (c *ObjectStoreGRPCClient) PutObject(bucket, key string, body io.Reader) error { stream, err := c.grpcClient.PutObject(context.Background()) if err != nil { - return fromGRPCError(err) + return common.FromGRPCError(err) } // read from the provider io.Reader into chunks, and send each one over @@ -81,7 +82,7 @@ func (c *ObjectStoreGRPCClient) PutObject(bucket, key string, body io.Reader) er n, err := body.Read(chunk) if err == io.EOF { if _, resErr := stream.CloseAndRecv(); resErr != nil { - return fromGRPCError(resErr) + return common.FromGRPCError(resErr) } return nil } @@ -90,8 +91,8 @@ func (c *ObjectStoreGRPCClient) PutObject(bucket, key string, body io.Reader) er return errors.WithStack(err) } - if err := stream.Send(&proto.PutObjectRequest{Plugin: c.plugin, Bucket: bucket, Key: key, Body: chunk[0:n]}); err != nil { - return fromGRPCError(err) + if err := stream.Send(&proto.PutObjectRequest{Plugin: c.Plugin, Bucket: bucket, Key: key, Body: chunk[0:n]}); err != nil { + return common.FromGRPCError(err) } } } @@ -99,7 +100,7 @@ func (c *ObjectStoreGRPCClient) PutObject(bucket, key string, body io.Reader) er // ObjectExists checks if there is an object with the given key in the object storage bucket. func (c *ObjectStoreGRPCClient) ObjectExists(bucket, key string) (bool, error) { req := &proto.ObjectExistsRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, Bucket: bucket, Key: key, } @@ -116,14 +117,14 @@ func (c *ObjectStoreGRPCClient) ObjectExists(bucket, key string) (bool, error) { // bucket in object storage. func (c *ObjectStoreGRPCClient) GetObject(bucket, key string) (io.ReadCloser, error) { req := &proto.GetObjectRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, Bucket: bucket, Key: key, } stream, err := c.grpcClient.GetObject(context.Background(), req) if err != nil { - return nil, fromGRPCError(err) + return nil, common.FromGRPCError(err) } receive := func() ([]byte, error) { @@ -135,7 +136,7 @@ func (c *ObjectStoreGRPCClient) GetObject(bucket, key string) (io.ReadCloser, er return nil, err } if err != nil { - return nil, fromGRPCError(err) + return nil, common.FromGRPCError(err) } return data.Data, nil @@ -143,7 +144,7 @@ func (c *ObjectStoreGRPCClient) GetObject(bucket, key string) (io.ReadCloser, er close := func() error { if err := stream.CloseSend(); err != nil { - return fromGRPCError(err) + return common.FromGRPCError(err) } return nil } @@ -156,7 +157,7 @@ func (c *ObjectStoreGRPCClient) GetObject(bucket, key string) (io.ReadCloser, er // often used to simulate a directory hierarchy in object storage). func (c *ObjectStoreGRPCClient) ListCommonPrefixes(bucket, prefix, delimiter string) ([]string, error) { req := &proto.ListCommonPrefixesRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, Bucket: bucket, Prefix: prefix, Delimiter: delimiter, @@ -164,7 +165,7 @@ func (c *ObjectStoreGRPCClient) ListCommonPrefixes(bucket, prefix, delimiter str res, err := c.grpcClient.ListCommonPrefixes(context.Background(), req) if err != nil { - return nil, fromGRPCError(err) + return nil, common.FromGRPCError(err) } return res.Prefixes, nil @@ -173,14 +174,14 @@ func (c *ObjectStoreGRPCClient) ListCommonPrefixes(bucket, prefix, delimiter str // ListObjects gets a list of all objects in bucket that have the same prefix. func (c *ObjectStoreGRPCClient) ListObjects(bucket, prefix string) ([]string, error) { req := &proto.ListObjectsRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, Bucket: bucket, Prefix: prefix, } res, err := c.grpcClient.ListObjects(context.Background(), req) if err != nil { - return nil, fromGRPCError(err) + return nil, common.FromGRPCError(err) } return res.Keys, nil @@ -190,13 +191,13 @@ func (c *ObjectStoreGRPCClient) ListObjects(bucket, prefix string) ([]string, er // bucket. func (c *ObjectStoreGRPCClient) DeleteObject(bucket, key string) error { req := &proto.DeleteObjectRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, Bucket: bucket, Key: key, } if _, err := c.grpcClient.DeleteObject(context.Background(), req); err != nil { - return fromGRPCError(err) + return common.FromGRPCError(err) } return nil @@ -205,7 +206,7 @@ func (c *ObjectStoreGRPCClient) DeleteObject(bucket, key string) error { // CreateSignedURL creates a pre-signed URL for the given bucket and key that expires after ttl. func (c *ObjectStoreGRPCClient) CreateSignedURL(bucket, key string, ttl time.Duration) (string, error) { req := &proto.CreateSignedURLRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, Bucket: bucket, Key: key, Ttl: int64(ttl), @@ -213,7 +214,7 @@ func (c *ObjectStoreGRPCClient) CreateSignedURL(bucket, key string, ttl time.Dur res, err := c.grpcClient.CreateSignedURL(context.Background(), req) if err != nil { - return "", fromGRPCError(err) + return "", common.FromGRPCError(err) } return res.Url, nil diff --git a/pkg/plugin/framework/object_store_server.go b/pkg/plugin/framework/object_store_server.go index b2f2359ce5..2d3ef3658b 100644 --- a/pkg/plugin/framework/object_store_server.go +++ b/pkg/plugin/framework/object_store_server.go @@ -23,6 +23,7 @@ import ( "github.com/pkg/errors" "golang.org/x/net/context" + "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" ) @@ -30,11 +31,11 @@ import ( // ObjectStoreGRPCServer implements the proto-generated ObjectStoreServer interface, and accepts // gRPC calls and forwards them to an implementation of the pluggable interface. type ObjectStoreGRPCServer struct { - mux *serverMux + mux *common.ServerMux } func (s *ObjectStoreGRPCServer) getImpl(name string) (velero.ObjectStore, error) { - impl, err := s.mux.getHandler(name) + impl, err := s.mux.GetHandler(name) if err != nil { return nil, err } @@ -52,18 +53,18 @@ func (s *ObjectStoreGRPCServer) getImpl(name string) (velero.ObjectStore, error) // cannot be initialized from the provided config. func (s *ObjectStoreGRPCServer) Init(ctx context.Context, req *proto.ObjectStoreInitRequest) (response *proto.Empty, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } if err := impl.Init(req.Config); err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &proto.Empty{}, nil @@ -73,7 +74,7 @@ func (s *ObjectStoreGRPCServer) Init(ctx context.Context, req *proto.ObjectStore // object storage bucket with the given key. func (s *ObjectStoreGRPCServer) PutObject(stream proto.ObjectStore_PutObjectServer) (err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() @@ -82,12 +83,12 @@ func (s *ObjectStoreGRPCServer) PutObject(stream proto.ObjectStore_PutObjectServ // in our receive method, we'll use `first` on the first call firstChunk, err := stream.Recv() if err != nil { - return newGRPCError(errors.WithStack(err)) + return common.NewGRPCError(errors.WithStack(err)) } impl, err := s.getImpl(firstChunk.Plugin) if err != nil { - return newGRPCError(err) + return common.NewGRPCError(err) } bucket := firstChunk.Bucket @@ -118,11 +119,11 @@ func (s *ObjectStoreGRPCServer) PutObject(stream proto.ObjectStore_PutObjectServ } if err := impl.PutObject(bucket, key, &StreamReadCloser{receive: receive, close: close}); err != nil { - return newGRPCError(err) + return common.NewGRPCError(err) } if err := stream.SendAndClose(&proto.Empty{}); err != nil { - return newGRPCError(errors.WithStack(err)) + return common.NewGRPCError(errors.WithStack(err)) } return nil @@ -131,19 +132,19 @@ func (s *ObjectStoreGRPCServer) PutObject(stream proto.ObjectStore_PutObjectServ // ObjectExists checks if there is an object with the given key in the object storage bucket. func (s *ObjectStoreGRPCServer) ObjectExists(ctx context.Context, req *proto.ObjectExistsRequest) (response *proto.ObjectExistsResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } exists, err := impl.ObjectExists(req.Bucket, req.Key) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &proto.ObjectExistsResponse{Exists: exists}, nil @@ -153,19 +154,19 @@ func (s *ObjectStoreGRPCServer) ObjectExists(ctx context.Context, req *proto.Obj // bucket in object storage. func (s *ObjectStoreGRPCServer) GetObject(req *proto.GetObjectRequest, stream proto.ObjectStore_GetObjectServer) (err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return newGRPCError(err) + return common.NewGRPCError(err) } rdr, err := impl.GetObject(req.Bucket, req.Key) if err != nil { - return newGRPCError(err) + return common.NewGRPCError(err) } defer rdr.Close() @@ -173,14 +174,14 @@ func (s *ObjectStoreGRPCServer) GetObject(req *proto.GetObjectRequest, stream pr for { n, err := rdr.Read(chunk) if err != nil && err != io.EOF { - return newGRPCError(errors.WithStack(err)) + return common.NewGRPCError(errors.WithStack(err)) } if n == 0 { return nil } if err := stream.Send(&proto.Bytes{Data: chunk[0:n]}); err != nil { - return newGRPCError(errors.WithStack(err)) + return common.NewGRPCError(errors.WithStack(err)) } } } @@ -190,19 +191,19 @@ func (s *ObjectStoreGRPCServer) GetObject(req *proto.GetObjectRequest, stream pr // (this is often used to simulate a directory hierarchy in object storage). func (s *ObjectStoreGRPCServer) ListCommonPrefixes(ctx context.Context, req *proto.ListCommonPrefixesRequest) (response *proto.ListCommonPrefixesResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } prefixes, err := impl.ListCommonPrefixes(req.Bucket, req.Prefix, req.Delimiter) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &proto.ListCommonPrefixesResponse{Prefixes: prefixes}, nil @@ -211,19 +212,19 @@ func (s *ObjectStoreGRPCServer) ListCommonPrefixes(ctx context.Context, req *pro // ListObjects gets a list of all objects in bucket that have the same prefix. func (s *ObjectStoreGRPCServer) ListObjects(ctx context.Context, req *proto.ListObjectsRequest) (response *proto.ListObjectsResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } keys, err := impl.ListObjects(req.Bucket, req.Prefix) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &proto.ListObjectsResponse{Keys: keys}, nil @@ -233,18 +234,18 @@ func (s *ObjectStoreGRPCServer) ListObjects(ctx context.Context, req *proto.List // bucket. func (s *ObjectStoreGRPCServer) DeleteObject(ctx context.Context, req *proto.DeleteObjectRequest) (response *proto.Empty, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } if err := impl.DeleteObject(req.Bucket, req.Key); err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &proto.Empty{}, nil @@ -253,19 +254,19 @@ func (s *ObjectStoreGRPCServer) DeleteObject(ctx context.Context, req *proto.Del // CreateSignedURL creates a pre-signed URL for the given bucket and key that expires after ttl. func (s *ObjectStoreGRPCServer) CreateSignedURL(ctx context.Context, req *proto.CreateSignedURLRequest) (response *proto.CreateSignedURLResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } url, err := impl.CreateSignedURL(req.Bucket, req.Key, time.Duration(req.Ttl)) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &proto.CreateSignedURLResponse{Url: url}, nil diff --git a/pkg/plugin/framework/plugin_lister.go b/pkg/plugin/framework/plugin_lister.go index aed7de77d4..e658ae8a21 100644 --- a/pkg/plugin/framework/plugin_lister.go +++ b/pkg/plugin/framework/plugin_lister.go @@ -22,13 +22,14 @@ import ( "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" ) // PluginIdentifier uniquely identifies a plugin by command, kind, and name. type PluginIdentifier struct { Command string - Kind PluginKind + Kind common.PluginKind Name string } @@ -87,13 +88,13 @@ func (c *PluginListerGRPCClient) ListPlugins() ([]PluginIdentifier, error) { ret := make([]PluginIdentifier, len(resp.Plugins)) for i, id := range resp.Plugins { - if _, ok := AllPluginKinds()[id.Kind]; !ok { + if _, ok := common.AllPluginKinds()[id.Kind]; !ok { return nil, errors.Errorf("invalid plugin kind: %s", id.Kind) } ret[i] = PluginIdentifier{ Command: id.Command, - Kind: PluginKind(id.Kind), + Kind: common.PluginKind(id.Kind), Name: id.Name, } } @@ -126,7 +127,7 @@ func (s *PluginListerGRPCServer) ListPlugins(ctx context.Context, req *proto.Emp plugins := make([]*proto.PluginIdentifier, len(list)) for i, id := range list { - if _, ok := AllPluginKinds()[id.Kind.String()]; !ok { + if _, ok := common.AllPluginKinds()[id.Kind.String()]; !ok { return nil, errors.Errorf("invalid plugin kind: %s", id.Kind) } diff --git a/pkg/plugin/framework/restore_item_action.go b/pkg/plugin/framework/restore_item_action.go index 255c67ae88..b5a3d41c16 100644 --- a/pkg/plugin/framework/restore_item_action.go +++ b/pkg/plugin/framework/restore_item_action.go @@ -21,6 +21,7 @@ import ( "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" ) @@ -29,16 +30,16 @@ import ( // interface. type RestoreItemActionPlugin struct { plugin.NetRPCUnsupportedPlugin - *pluginBase + *common.PluginBase } // GRPCClient returns a RestoreItemAction gRPC client. func (p *RestoreItemActionPlugin) GRPCClient(_ context.Context, _ *plugin.GRPCBroker, clientConn *grpc.ClientConn) (interface{}, error) { - return newClientDispenser(p.clientLogger, clientConn, newRestoreItemActionGRPCClient), nil + return common.NewClientDispenser(p.ClientLogger, clientConn, newRestoreItemActionGRPCClient), nil } // GRPCServer registers a RestoreItemAction gRPC server. func (p *RestoreItemActionPlugin) GRPCServer(_ *plugin.GRPCBroker, server *grpc.Server) error { - proto.RegisterRestoreItemActionServer(server, &RestoreItemActionGRPCServer{mux: p.serverMux}) + proto.RegisterRestoreItemActionServer(server, &RestoreItemActionGRPCServer{mux: p.ServerMux}) return nil } diff --git a/pkg/plugin/framework/restore_item_action_client.go b/pkg/plugin/framework/restore_item_action_client.go index 33d7fff3ae..03907f390b 100644 --- a/pkg/plugin/framework/restore_item_action_client.go +++ b/pkg/plugin/framework/restore_item_action_client.go @@ -25,6 +25,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" + "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" ) @@ -32,30 +33,30 @@ import ( var _ velero.RestoreItemAction = &RestoreItemActionGRPCClient{} // NewRestoreItemActionPlugin constructs a RestoreItemActionPlugin. -func NewRestoreItemActionPlugin(options ...PluginOption) *RestoreItemActionPlugin { +func NewRestoreItemActionPlugin(options ...common.PluginOption) *RestoreItemActionPlugin { return &RestoreItemActionPlugin{ - pluginBase: newPluginBase(options...), + PluginBase: common.NewPluginBase(options...), } } // RestoreItemActionGRPCClient implements the backup/ItemAction interface and uses a // gRPC client to make calls to the plugin server. type RestoreItemActionGRPCClient struct { - *clientBase + *common.ClientBase grpcClient proto.RestoreItemActionClient } -func newRestoreItemActionGRPCClient(base *clientBase, clientConn *grpc.ClientConn) interface{} { +func newRestoreItemActionGRPCClient(base *common.ClientBase, clientConn *grpc.ClientConn) interface{} { return &RestoreItemActionGRPCClient{ - clientBase: base, + ClientBase: base, grpcClient: proto.NewRestoreItemActionClient(clientConn), } } func (c *RestoreItemActionGRPCClient) AppliesTo() (velero.ResourceSelector, error) { - res, err := c.grpcClient.AppliesTo(context.Background(), &proto.RestoreItemActionAppliesToRequest{Plugin: c.plugin}) + res, err := c.grpcClient.AppliesTo(context.Background(), &proto.RestoreItemActionAppliesToRequest{Plugin: c.Plugin}) if err != nil { - return velero.ResourceSelector{}, fromGRPCError(err) + return velero.ResourceSelector{}, common.FromGRPCError(err) } if res.ResourceSelector == nil { @@ -88,7 +89,7 @@ func (c *RestoreItemActionGRPCClient) Execute(input *velero.RestoreItemActionExe } req := &proto.RestoreItemActionExecuteRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, Item: itemJSON, ItemFromBackup: itemFromBackupJSON, Restore: restoreJSON, @@ -96,7 +97,7 @@ func (c *RestoreItemActionGRPCClient) Execute(input *velero.RestoreItemActionExe res, err := c.grpcClient.Execute(context.Background(), req) if err != nil { - return nil, fromGRPCError(err) + return nil, common.FromGRPCError(err) } var updatedItem unstructured.Unstructured diff --git a/pkg/plugin/framework/restore_item_action_server.go b/pkg/plugin/framework/restore_item_action_server.go index ae5affb151..5b45f4e91f 100644 --- a/pkg/plugin/framework/restore_item_action_server.go +++ b/pkg/plugin/framework/restore_item_action_server.go @@ -24,6 +24,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" + "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" ) @@ -31,11 +32,11 @@ import ( // RestoreItemActionGRPCServer implements the proto-generated RestoreItemActionServer interface, and accepts // gRPC calls and forwards them to an implementation of the pluggable interface. type RestoreItemActionGRPCServer struct { - mux *serverMux + mux *common.ServerMux } func (s *RestoreItemActionGRPCServer) getImpl(name string) (velero.RestoreItemAction, error) { - impl, err := s.mux.getHandler(name) + impl, err := s.mux.GetHandler(name) if err != nil { return nil, err } @@ -50,19 +51,19 @@ func (s *RestoreItemActionGRPCServer) getImpl(name string) (velero.RestoreItemAc func (s *RestoreItemActionGRPCServer) AppliesTo(ctx context.Context, req *proto.RestoreItemActionAppliesToRequest) (response *proto.RestoreItemActionAppliesToResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } resourceSelector, err := impl.AppliesTo() if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &proto.RestoreItemActionAppliesToResponse{ @@ -78,14 +79,14 @@ func (s *RestoreItemActionGRPCServer) AppliesTo(ctx context.Context, req *proto. func (s *RestoreItemActionGRPCServer) Execute(ctx context.Context, req *proto.RestoreItemActionExecuteRequest) (response *proto.RestoreItemActionExecuteResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } var ( @@ -95,15 +96,15 @@ func (s *RestoreItemActionGRPCServer) Execute(ctx context.Context, req *proto.Re ) if err := json.Unmarshal(req.Item, &item); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } if err := json.Unmarshal(req.ItemFromBackup, &itemFromBackup); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } if err := json.Unmarshal(req.Restore, &restoreObj); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } executeOutput, err := impl.Execute(&velero.RestoreItemActionExecuteInput{ @@ -112,7 +113,7 @@ func (s *RestoreItemActionGRPCServer) Execute(ctx context.Context, req *proto.Re Restore: &restoreObj, }) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } // If the plugin implementation returned a nil updateItem (meaning no modifications), reset updatedItem to the @@ -123,7 +124,7 @@ func (s *RestoreItemActionGRPCServer) Execute(ctx context.Context, req *proto.Re } else { updatedItemJSON, err = json.Marshal(executeOutput.UpdatedItem.UnstructuredContent()) if err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } } diff --git a/pkg/plugin/framework/server.go b/pkg/plugin/framework/server.go index b25ef341de..20c5e48e00 100644 --- a/pkg/plugin/framework/server.go +++ b/pkg/plugin/framework/server.go @@ -25,6 +25,7 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/pflag" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/util/logging" ) @@ -40,43 +41,43 @@ type Server interface { // RegisterBackupItemAction registers a backup item action. Accepted format // for the plugin name is /. - RegisterBackupItemAction(pluginName string, initializer HandlerInitializer) Server + RegisterBackupItemAction(pluginName string, initializer common.HandlerInitializer) Server // RegisterBackupItemActions registers multiple backup item actions. - RegisterBackupItemActions(map[string]HandlerInitializer) Server + RegisterBackupItemActions(map[string]common.HandlerInitializer) Server // RegisterVolumeSnapshotter registers a volume snapshotter. Accepted format // for the plugin name is /. - RegisterVolumeSnapshotter(pluginName string, initializer HandlerInitializer) Server + RegisterVolumeSnapshotter(pluginName string, initializer common.HandlerInitializer) Server // RegisterVolumeSnapshotters registers multiple volume snapshotters. - RegisterVolumeSnapshotters(map[string]HandlerInitializer) Server + RegisterVolumeSnapshotters(map[string]common.HandlerInitializer) Server // RegisterObjectStore registers an object store. Accepted format // for the plugin name is /. - RegisterObjectStore(pluginName string, initializer HandlerInitializer) Server + RegisterObjectStore(pluginName string, initializer common.HandlerInitializer) Server // RegisterObjectStores registers multiple object stores. - RegisterObjectStores(map[string]HandlerInitializer) Server + RegisterObjectStores(map[string]common.HandlerInitializer) Server // RegisterRestoreItemAction registers a restore item action. Accepted format // for the plugin name is /. - RegisterRestoreItemAction(pluginName string, initializer HandlerInitializer) Server + RegisterRestoreItemAction(pluginName string, initializer common.HandlerInitializer) Server // RegisterRestoreItemActions registers multiple restore item actions. - RegisterRestoreItemActions(map[string]HandlerInitializer) Server + RegisterRestoreItemActions(map[string]common.HandlerInitializer) Server // RegisterDeleteItemAction registers a delete item action. Accepted format // for the plugin name is /. - RegisterDeleteItemAction(pluginName string, initializer HandlerInitializer) Server + RegisterDeleteItemAction(pluginName string, initializer common.HandlerInitializer) Server // RegisterDeleteItemActions registers multiple Delete item actions. - RegisterDeleteItemActions(map[string]HandlerInitializer) Server + RegisterDeleteItemActions(map[string]common.HandlerInitializer) Server - RegisterItemSnapshotter(pluginName string, initializer HandlerInitializer) Server + RegisterItemSnapshotter(pluginName string, initializer common.HandlerInitializer) Server // RegisterItemSnapshotters registers multiple Item Snapshotters - RegisterItemSnapshotters(map[string]HandlerInitializer) Server + RegisterItemSnapshotters(map[string]common.HandlerInitializer) Server // Server runs the plugin server. Serve() @@ -102,12 +103,12 @@ func NewServer() Server { return &server{ log: log, logLevelFlag: logging.LogLevelFlag(log.Level), - backupItemAction: NewBackupItemActionPlugin(serverLogger(log)), - volumeSnapshotter: NewVolumeSnapshotterPlugin(serverLogger(log)), - objectStore: NewObjectStorePlugin(serverLogger(log)), - restoreItemAction: NewRestoreItemActionPlugin(serverLogger(log)), - deleteItemAction: NewDeleteItemActionPlugin(serverLogger(log)), - itemSnapshotter: NewItemSnapshotterPlugin(serverLogger(log)), + backupItemAction: NewBackupItemActionPlugin(common.ServerLogger(log)), + volumeSnapshotter: NewVolumeSnapshotterPlugin(common.ServerLogger(log)), + objectStore: NewObjectStorePlugin(common.ServerLogger(log)), + restoreItemAction: NewRestoreItemActionPlugin(common.ServerLogger(log)), + deleteItemAction: NewDeleteItemActionPlugin(common.ServerLogger(log)), + itemSnapshotter: NewItemSnapshotterPlugin(common.ServerLogger(log)), } } @@ -119,71 +120,71 @@ func (s *server) BindFlags(flags *pflag.FlagSet) Server { return s } -func (s *server) RegisterBackupItemAction(name string, initializer HandlerInitializer) Server { - s.backupItemAction.register(name, initializer) +func (s *server) RegisterBackupItemAction(name string, initializer common.HandlerInitializer) Server { + s.backupItemAction.Register(name, initializer) return s } -func (s *server) RegisterBackupItemActions(m map[string]HandlerInitializer) Server { +func (s *server) RegisterBackupItemActions(m map[string]common.HandlerInitializer) Server { for name := range m { s.RegisterBackupItemAction(name, m[name]) } return s } -func (s *server) RegisterVolumeSnapshotter(name string, initializer HandlerInitializer) Server { - s.volumeSnapshotter.register(name, initializer) +func (s *server) RegisterVolumeSnapshotter(name string, initializer common.HandlerInitializer) Server { + s.volumeSnapshotter.Register(name, initializer) return s } -func (s *server) RegisterVolumeSnapshotters(m map[string]HandlerInitializer) Server { +func (s *server) RegisterVolumeSnapshotters(m map[string]common.HandlerInitializer) Server { for name := range m { s.RegisterVolumeSnapshotter(name, m[name]) } return s } -func (s *server) RegisterObjectStore(name string, initializer HandlerInitializer) Server { - s.objectStore.register(name, initializer) +func (s *server) RegisterObjectStore(name string, initializer common.HandlerInitializer) Server { + s.objectStore.Register(name, initializer) return s } -func (s *server) RegisterObjectStores(m map[string]HandlerInitializer) Server { +func (s *server) RegisterObjectStores(m map[string]common.HandlerInitializer) Server { for name := range m { s.RegisterObjectStore(name, m[name]) } return s } -func (s *server) RegisterRestoreItemAction(name string, initializer HandlerInitializer) Server { - s.restoreItemAction.register(name, initializer) +func (s *server) RegisterRestoreItemAction(name string, initializer common.HandlerInitializer) Server { + s.restoreItemAction.Register(name, initializer) return s } -func (s *server) RegisterRestoreItemActions(m map[string]HandlerInitializer) Server { +func (s *server) RegisterRestoreItemActions(m map[string]common.HandlerInitializer) Server { for name := range m { s.RegisterRestoreItemAction(name, m[name]) } return s } -func (s *server) RegisterDeleteItemAction(name string, initializer HandlerInitializer) Server { - s.deleteItemAction.register(name, initializer) +func (s *server) RegisterDeleteItemAction(name string, initializer common.HandlerInitializer) Server { + s.deleteItemAction.Register(name, initializer) return s } -func (s *server) RegisterDeleteItemActions(m map[string]HandlerInitializer) Server { +func (s *server) RegisterDeleteItemActions(m map[string]common.HandlerInitializer) Server { for name := range m { s.RegisterDeleteItemAction(name, m[name]) } return s } -func (s *server) RegisterItemSnapshotter(name string, initializer HandlerInitializer) Server { - s.itemSnapshotter.register(name, initializer) +func (s *server) RegisterItemSnapshotter(name string, initializer common.HandlerInitializer) Server { + s.itemSnapshotter.Register(name, initializer) return s } -func (s *server) RegisterItemSnapshotters(m map[string]HandlerInitializer) Server { +func (s *server) RegisterItemSnapshotters(m map[string]common.HandlerInitializer) Server { for name := range m { s.RegisterItemSnapshotter(name, m[name]) } @@ -191,10 +192,10 @@ func (s *server) RegisterItemSnapshotters(m map[string]HandlerInitializer) Serve } // getNames returns a list of PluginIdentifiers registered with plugin. -func getNames(command string, kind PluginKind, plugin Interface) []PluginIdentifier { +func getNames(command string, kind common.PluginKind, plugin Interface) []PluginIdentifier { var pluginIdentifiers []PluginIdentifier - for _, name := range plugin.names() { + for _, name := range plugin.Names() { id := PluginIdentifier{Command: command, Kind: kind, Name: name} pluginIdentifiers = append(pluginIdentifiers, id) } @@ -214,25 +215,25 @@ func (s *server) Serve() { command := os.Args[0] var pluginIdentifiers []PluginIdentifier - pluginIdentifiers = append(pluginIdentifiers, getNames(command, PluginKindBackupItemAction, s.backupItemAction)...) - pluginIdentifiers = append(pluginIdentifiers, getNames(command, PluginKindVolumeSnapshotter, s.volumeSnapshotter)...) - pluginIdentifiers = append(pluginIdentifiers, getNames(command, PluginKindObjectStore, s.objectStore)...) - pluginIdentifiers = append(pluginIdentifiers, getNames(command, PluginKindRestoreItemAction, s.restoreItemAction)...) - pluginIdentifiers = append(pluginIdentifiers, getNames(command, PluginKindDeleteItemAction, s.deleteItemAction)...) - pluginIdentifiers = append(pluginIdentifiers, getNames(command, PluginKindItemSnapshotter, s.itemSnapshotter)...) + pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindBackupItemAction, s.backupItemAction)...) + pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindVolumeSnapshotter, s.volumeSnapshotter)...) + pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindObjectStore, s.objectStore)...) + pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindRestoreItemAction, s.restoreItemAction)...) + pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindDeleteItemAction, s.deleteItemAction)...) + pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindItemSnapshotter, s.itemSnapshotter)...) pluginLister := NewPluginLister(pluginIdentifiers...) plugin.Serve(&plugin.ServeConfig{ HandshakeConfig: Handshake(), Plugins: map[string]plugin.Plugin{ - string(PluginKindBackupItemAction): s.backupItemAction, - string(PluginKindVolumeSnapshotter): s.volumeSnapshotter, - string(PluginKindObjectStore): s.objectStore, - string(PluginKindPluginLister): NewPluginListerPlugin(pluginLister), - string(PluginKindRestoreItemAction): s.restoreItemAction, - string(PluginKindDeleteItemAction): s.deleteItemAction, - string(PluginKindItemSnapshotter): s.itemSnapshotter, + string(common.PluginKindBackupItemAction): s.backupItemAction, + string(common.PluginKindVolumeSnapshotter): s.volumeSnapshotter, + string(common.PluginKindObjectStore): s.objectStore, + string(common.PluginKindPluginLister): NewPluginListerPlugin(pluginLister), + string(common.PluginKindRestoreItemAction): s.restoreItemAction, + string(common.PluginKindDeleteItemAction): s.deleteItemAction, + string(common.PluginKindItemSnapshotter): s.itemSnapshotter, }, GRPCServer: plugin.DefaultGRPCServer, }) diff --git a/pkg/plugin/framework/volume_snapshotter.go b/pkg/plugin/framework/volume_snapshotter.go index 50602b2c05..566fc1eb72 100644 --- a/pkg/plugin/framework/volume_snapshotter.go +++ b/pkg/plugin/framework/volume_snapshotter.go @@ -21,6 +21,7 @@ import ( "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" ) @@ -29,16 +30,16 @@ import ( // interface. type VolumeSnapshotterPlugin struct { plugin.NetRPCUnsupportedPlugin - *pluginBase + *common.PluginBase } // GRPCClient returns a VolumeSnapshotter gRPC client. func (p *VolumeSnapshotterPlugin) GRPCClient(_ context.Context, _ *plugin.GRPCBroker, clientConn *grpc.ClientConn) (interface{}, error) { - return newClientDispenser(p.clientLogger, clientConn, newVolumeSnapshotterGRPCClient), nil + return common.NewClientDispenser(p.ClientLogger, clientConn, newVolumeSnapshotterGRPCClient), nil } // GRPCServer registers a VolumeSnapshotter gRPC server. func (p *VolumeSnapshotterPlugin) GRPCServer(_ *plugin.GRPCBroker, server *grpc.Server) error { - proto.RegisterVolumeSnapshotterServer(server, &VolumeSnapshotterGRPCServer{mux: p.serverMux}) + proto.RegisterVolumeSnapshotterServer(server, &VolumeSnapshotterGRPCServer{mux: p.ServerMux}) return nil } diff --git a/pkg/plugin/framework/volume_snapshotter_client.go b/pkg/plugin/framework/volume_snapshotter_client.go index 53ac58d25b..a359046177 100644 --- a/pkg/plugin/framework/volume_snapshotter_client.go +++ b/pkg/plugin/framework/volume_snapshotter_client.go @@ -25,26 +25,27 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" proto "github.com/vmware-tanzu/velero/pkg/plugin/generated" ) // NewVolumeSnapshotterPlugin constructs a VolumeSnapshotterPlugin. -func NewVolumeSnapshotterPlugin(options ...PluginOption) *VolumeSnapshotterPlugin { +func NewVolumeSnapshotterPlugin(options ...common.PluginOption) *VolumeSnapshotterPlugin { return &VolumeSnapshotterPlugin{ - pluginBase: newPluginBase(options...), + PluginBase: common.NewPluginBase(options...), } } // VolumeSnapshotterGRPCClient implements the cloudprovider.VolumeSnapshotter interface and uses a // gRPC client to make calls to the plugin server. type VolumeSnapshotterGRPCClient struct { - *clientBase + *common.ClientBase grpcClient proto.VolumeSnapshotterClient } -func newVolumeSnapshotterGRPCClient(base *clientBase, clientConn *grpc.ClientConn) interface{} { +func newVolumeSnapshotterGRPCClient(base *common.ClientBase, clientConn *grpc.ClientConn) interface{} { return &VolumeSnapshotterGRPCClient{ - clientBase: base, + ClientBase: base, grpcClient: proto.NewVolumeSnapshotterClient(clientConn), } } @@ -54,12 +55,12 @@ func newVolumeSnapshotterGRPCClient(base *clientBase, clientConn *grpc.ClientCon // cannot be initialized from the provided config. func (c *VolumeSnapshotterGRPCClient) Init(config map[string]string) error { req := &proto.VolumeSnapshotterInitRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, Config: config, } if _, err := c.grpcClient.Init(context.Background(), req); err != nil { - return fromGRPCError(err) + return common.FromGRPCError(err) } return nil @@ -69,7 +70,7 @@ func (c *VolumeSnapshotterGRPCClient) Init(config map[string]string) error { // and with the specified type and IOPS (if using provisioned IOPS). func (c *VolumeSnapshotterGRPCClient) CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ string, iops *int64) (string, error) { req := &proto.CreateVolumeRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, SnapshotID: snapshotID, VolumeType: volumeType, VolumeAZ: volumeAZ, @@ -83,7 +84,7 @@ func (c *VolumeSnapshotterGRPCClient) CreateVolumeFromSnapshot(snapshotID, volum res, err := c.grpcClient.CreateVolumeFromSnapshot(context.Background(), req) if err != nil { - return "", fromGRPCError(err) + return "", common.FromGRPCError(err) } return res.VolumeID, nil @@ -93,14 +94,14 @@ func (c *VolumeSnapshotterGRPCClient) CreateVolumeFromSnapshot(snapshotID, volum // volume. func (c *VolumeSnapshotterGRPCClient) GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, error) { req := &proto.GetVolumeInfoRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, VolumeID: volumeID, VolumeAZ: volumeAZ, } res, err := c.grpcClient.GetVolumeInfo(context.Background(), req) if err != nil { - return "", nil, fromGRPCError(err) + return "", nil, common.FromGRPCError(err) } var iops *int64 @@ -115,7 +116,7 @@ func (c *VolumeSnapshotterGRPCClient) GetVolumeInfo(volumeID, volumeAZ string) ( // set of tags to the snapshot. func (c *VolumeSnapshotterGRPCClient) CreateSnapshot(volumeID, volumeAZ string, tags map[string]string) (string, error) { req := &proto.CreateSnapshotRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, VolumeID: volumeID, VolumeAZ: volumeAZ, Tags: tags, @@ -123,7 +124,7 @@ func (c *VolumeSnapshotterGRPCClient) CreateSnapshot(volumeID, volumeAZ string, res, err := c.grpcClient.CreateSnapshot(context.Background(), req) if err != nil { - return "", fromGRPCError(err) + return "", common.FromGRPCError(err) } return res.SnapshotID, nil @@ -132,12 +133,12 @@ func (c *VolumeSnapshotterGRPCClient) CreateSnapshot(volumeID, volumeAZ string, // DeleteSnapshot deletes the specified volume snapshot. func (c *VolumeSnapshotterGRPCClient) DeleteSnapshot(snapshotID string) error { req := &proto.DeleteSnapshotRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, SnapshotID: snapshotID, } if _, err := c.grpcClient.DeleteSnapshot(context.Background(), req); err != nil { - return fromGRPCError(err) + return common.FromGRPCError(err) } return nil @@ -150,13 +151,13 @@ func (c *VolumeSnapshotterGRPCClient) GetVolumeID(pv runtime.Unstructured) (stri } req := &proto.GetVolumeIDRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, PersistentVolume: encodedPV, } resp, err := c.grpcClient.GetVolumeID(context.Background(), req) if err != nil { - return "", fromGRPCError(err) + return "", common.FromGRPCError(err) } return resp.VolumeID, nil @@ -169,14 +170,14 @@ func (c *VolumeSnapshotterGRPCClient) SetVolumeID(pv runtime.Unstructured, volum } req := &proto.SetVolumeIDRequest{ - Plugin: c.plugin, + Plugin: c.Plugin, PersistentVolume: encodedPV, VolumeID: volumeID, } resp, err := c.grpcClient.SetVolumeID(context.Background(), req) if err != nil { - return nil, fromGRPCError(err) + return nil, common.FromGRPCError(err) } var updatedPV unstructured.Unstructured diff --git a/pkg/plugin/framework/volume_snapshotter_server.go b/pkg/plugin/framework/volume_snapshotter_server.go index bde371c93f..e0073db9aa 100644 --- a/pkg/plugin/framework/volume_snapshotter_server.go +++ b/pkg/plugin/framework/volume_snapshotter_server.go @@ -23,6 +23,7 @@ import ( "golang.org/x/net/context" "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" ) @@ -30,11 +31,11 @@ import ( // VolumeSnapshotterGRPCServer implements the proto-generated VolumeSnapshotterServer interface, and accepts // gRPC calls and forwards them to an implementation of the pluggable interface. type VolumeSnapshotterGRPCServer struct { - mux *serverMux + mux *common.ServerMux } func (s *VolumeSnapshotterGRPCServer) getImpl(name string) (velero.VolumeSnapshotter, error) { - impl, err := s.mux.getHandler(name) + impl, err := s.mux.GetHandler(name) if err != nil { return nil, err } @@ -52,18 +53,18 @@ func (s *VolumeSnapshotterGRPCServer) getImpl(name string) (velero.VolumeSnapsho // cannot be initialized from the provided config. func (s *VolumeSnapshotterGRPCServer) Init(ctx context.Context, req *proto.VolumeSnapshotterInitRequest) (response *proto.Empty, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } if err := impl.Init(req.Config); err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &proto.Empty{}, nil @@ -73,14 +74,14 @@ func (s *VolumeSnapshotterGRPCServer) Init(ctx context.Context, req *proto.Volum // and with the specified type and IOPS (if using provisioned IOPS). func (s *VolumeSnapshotterGRPCServer) CreateVolumeFromSnapshot(ctx context.Context, req *proto.CreateVolumeRequest) (response *proto.CreateVolumeResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } snapshotID := req.SnapshotID @@ -94,7 +95,7 @@ func (s *VolumeSnapshotterGRPCServer) CreateVolumeFromSnapshot(ctx context.Conte volumeID, err := impl.CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ, iops) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &proto.CreateVolumeResponse{VolumeID: volumeID}, nil @@ -104,19 +105,19 @@ func (s *VolumeSnapshotterGRPCServer) CreateVolumeFromSnapshot(ctx context.Conte // volume. func (s *VolumeSnapshotterGRPCServer) GetVolumeInfo(ctx context.Context, req *proto.GetVolumeInfoRequest) (response *proto.GetVolumeInfoResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } volumeType, iops, err := impl.GetVolumeInfo(req.VolumeID, req.VolumeAZ) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } res := &proto.GetVolumeInfoResponse{ @@ -134,19 +135,19 @@ func (s *VolumeSnapshotterGRPCServer) GetVolumeInfo(ctx context.Context, req *pr // set of tags to the snapshot. func (s *VolumeSnapshotterGRPCServer) CreateSnapshot(ctx context.Context, req *proto.CreateSnapshotRequest) (response *proto.CreateSnapshotResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } snapshotID, err := impl.CreateSnapshot(req.VolumeID, req.VolumeAZ, req.Tags) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &proto.CreateSnapshotResponse{SnapshotID: snapshotID}, nil @@ -155,18 +156,18 @@ func (s *VolumeSnapshotterGRPCServer) CreateSnapshot(ctx context.Context, req *p // DeleteSnapshot deletes the specified volume snapshot. func (s *VolumeSnapshotterGRPCServer) DeleteSnapshot(ctx context.Context, req *proto.DeleteSnapshotRequest) (response *proto.Empty, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } if err := impl.DeleteSnapshot(req.SnapshotID); err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &proto.Empty{}, nil @@ -174,25 +175,25 @@ func (s *VolumeSnapshotterGRPCServer) DeleteSnapshot(ctx context.Context, req *p func (s *VolumeSnapshotterGRPCServer) GetVolumeID(ctx context.Context, req *proto.GetVolumeIDRequest) (response *proto.GetVolumeIDResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } var pv unstructured.Unstructured if err := json.Unmarshal(req.PersistentVolume, &pv); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } volumeID, err := impl.GetVolumeID(&pv) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &proto.GetVolumeIDResponse{VolumeID: volumeID}, nil @@ -200,29 +201,29 @@ func (s *VolumeSnapshotterGRPCServer) GetVolumeID(ctx context.Context, req *prot func (s *VolumeSnapshotterGRPCServer) SetVolumeID(ctx context.Context, req *proto.SetVolumeIDRequest) (response *proto.SetVolumeIDResponse, err error) { defer func() { - if recoveredErr := handlePanic(recover()); recoveredErr != nil { + if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil { err = recoveredErr } }() impl, err := s.getImpl(req.Plugin) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } var pv unstructured.Unstructured if err := json.Unmarshal(req.PersistentVolume, &pv); err != nil { - return nil, newGRPCError(errors.WithStack(err)) + return nil, common.NewGRPCError(errors.WithStack(err)) } updatedPV, err := impl.SetVolumeID(&pv, req.VolumeID) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } updatedPVBytes, err := json.Marshal(updatedPV.UnstructuredContent()) if err != nil { - return nil, newGRPCError(err) + return nil, common.NewGRPCError(err) } return &proto.SetVolumeIDResponse{PersistentVolume: updatedPVBytes}, nil diff --git a/pkg/backup/mocks/item_action.go b/pkg/plugin/velero/mocks/backupitemaction/v1/BackupItemAction.go similarity index 58% rename from pkg/backup/mocks/item_action.go rename to pkg/plugin/velero/mocks/backupitemaction/v1/BackupItemAction.go index 5d4bd8db55..cfca2ef6d2 100644 --- a/pkg/backup/mocks/item_action.go +++ b/pkg/plugin/velero/mocks/backupitemaction/v1/BackupItemAction.go @@ -1,5 +1,5 @@ /* -Copyright 2018 the Velero contributors. +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. @@ -14,23 +14,25 @@ See the License for the specific language governing permissions and limitations under the License. */ // Code generated by mockery v1.0.0. DO NOT EDIT. -package mocks + +package v1 import ( mock "github.com/stretchr/testify/mock" runtime "k8s.io/apimachinery/pkg/runtime" - v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" - "github.com/vmware-tanzu/velero/pkg/plugin/velero" + velero "github.com/vmware-tanzu/velero/pkg/plugin/velero" + + velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" ) -// ItemAction is an autogenerated mock type for the ItemAction type -type ItemAction struct { +// BackupItemAction is an autogenerated mock type for the BackupItemAction type +type BackupItemAction struct { mock.Mock } // AppliesTo provides a mock function with given fields: -func (_m *ItemAction) AppliesTo() (velero.ResourceSelector, error) { +func (_m *BackupItemAction) AppliesTo() (velero.ResourceSelector, error) { ret := _m.Called() var r0 velero.ResourceSelector @@ -50,13 +52,13 @@ func (_m *ItemAction) AppliesTo() (velero.ResourceSelector, error) { return r0, r1 } -// Execute provides a mock function with given fields: item, _a1 -func (_m *ItemAction) Execute(item runtime.Unstructured, _a1 *v1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) { - ret := _m.Called(item, _a1) +// Execute provides a mock function with given fields: item, backup +func (_m *BackupItemAction) Execute(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) { + ret := _m.Called(item, backup) var r0 runtime.Unstructured - if rf, ok := ret.Get(0).(func(runtime.Unstructured, *v1.Backup) runtime.Unstructured); ok { - r0 = rf(item, _a1) + if rf, ok := ret.Get(0).(func(runtime.Unstructured, *velerov1.Backup) runtime.Unstructured); ok { + r0 = rf(item, backup) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(runtime.Unstructured) @@ -64,8 +66,8 @@ func (_m *ItemAction) Execute(item runtime.Unstructured, _a1 *v1.Backup) (runtim } var r1 []velero.ResourceIdentifier - if rf, ok := ret.Get(1).(func(runtime.Unstructured, *v1.Backup) []velero.ResourceIdentifier); ok { - r1 = rf(item, _a1) + if rf, ok := ret.Get(1).(func(runtime.Unstructured, *velerov1.Backup) []velero.ResourceIdentifier); ok { + r1 = rf(item, backup) } else { if ret.Get(1) != nil { r1 = ret.Get(1).([]velero.ResourceIdentifier) @@ -73,8 +75,8 @@ func (_m *ItemAction) Execute(item runtime.Unstructured, _a1 *v1.Backup) (runtim } var r2 error - if rf, ok := ret.Get(2).(func(runtime.Unstructured, *v1.Backup) error); ok { - r2 = rf(item, _a1) + if rf, ok := ret.Get(2).(func(runtime.Unstructured, *velerov1.Backup) error); ok { + r2 = rf(item, backup) } else { r2 = ret.Error(2) } diff --git a/pkg/restore/change_pvc_node_selector.go b/pkg/restore/change_pvc_node_selector.go index b4d947c21f..d281d318f7 100644 --- a/pkg/restore/change_pvc_node_selector.go +++ b/pkg/restore/change_pvc_node_selector.go @@ -26,7 +26,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" corev1client "k8s.io/client-go/kubernetes/typed/core/v1" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/plugin/velero" ) @@ -130,7 +130,7 @@ func (p *ChangePVCNodeSelectorAction) Execute(input *velero.RestoreItemActionExe func getNewNodeFromConfigMap(client corev1client.ConfigMapInterface, node string) (string, error) { // fetch node mapping from configMap - config, err := getPluginConfig(framework.PluginKindRestoreItemAction, "velero.io/change-pvc-node-selector", client) + config, err := getPluginConfig(common.PluginKindRestoreItemAction, "velero.io/change-pvc-node-selector", client) if err != nil { return "", err } diff --git a/pkg/restore/change_storageclass_action.go b/pkg/restore/change_storageclass_action.go index 577ab28ec2..a02b7c484e 100644 --- a/pkg/restore/change_storageclass_action.go +++ b/pkg/restore/change_storageclass_action.go @@ -29,7 +29,7 @@ import ( corev1client "k8s.io/client-go/kubernetes/typed/core/v1" storagev1client "k8s.io/client-go/kubernetes/typed/storage/v1" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/plugin/velero" ) @@ -69,7 +69,7 @@ func (a *ChangeStorageClassAction) Execute(input *velero.RestoreItemActionExecut defer a.logger.Info("Done executing ChangeStorageClassAction") a.logger.Debug("Getting plugin config") - config, err := getPluginConfig(framework.PluginKindRestoreItemAction, "velero.io/change-storage-class", a.configMapClient) + config, err := getPluginConfig(common.PluginKindRestoreItemAction, "velero.io/change-storage-class", a.configMapClient) if err != nil { return nil, err } diff --git a/pkg/restore/restic_restore_action.go b/pkg/restore/restic_restore_action.go index 586dbf7852..f2d8df9a1d 100644 --- a/pkg/restore/restic_restore_action.go +++ b/pkg/restore/restic_restore_action.go @@ -34,7 +34,7 @@ import ( "github.com/vmware-tanzu/velero/pkg/builder" velerov1client "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1" "github.com/vmware-tanzu/velero/pkg/label" - "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/plugin/velero" "github.com/vmware-tanzu/velero/pkg/podvolume" "github.com/vmware-tanzu/velero/pkg/util/kube" @@ -107,7 +107,7 @@ func (a *ResticRestoreAction) Execute(input *velero.RestoreItemActionExecuteInpu // TODO we might want/need to get plugin config at the top of this method at some point; for now, wait // until we know we're doing a restore before getting config. log.Debugf("Getting plugin config") - config, err := getPluginConfig(framework.PluginKindRestoreItemAction, "velero.io/restic", a.client) + config, err := getPluginConfig(common.PluginKindRestoreItemAction, "velero.io/restic", a.client) if err != nil { return nil, err } @@ -261,7 +261,7 @@ func getSecurityContext(log logrus.FieldLogger, config *corev1.ConfigMap) (strin // TODO eventually this can move to pkg/plugin/framework since it'll be used across multiple // plugins. -func getPluginConfig(kind framework.PluginKind, name string, client corev1client.ConfigMapInterface) (*corev1.ConfigMap, error) { +func getPluginConfig(kind common.PluginKind, name string, client corev1client.ConfigMapInterface) (*corev1.ConfigMap, error) { opts := metav1.ListOptions{ // velero.io/plugin-config: true // velero.io/restic: RestoreItemAction diff --git a/pkg/restore/restore.go b/pkg/restore/restore.go index 11008b55e8..c9ba6291a2 100644 --- a/pkg/restore/restore.go +++ b/pkg/restore/restore.go @@ -222,12 +222,12 @@ func (kr *kubernetesRestorer) RestoreWithResolvers( Includes(req.Restore.Spec.IncludedNamespaces...). Excludes(req.Restore.Spec.ExcludedNamespaces...) - resolvedActions, err := restoreItemActionResolver.ResolveActions(kr.discoveryHelper) + resolvedActions, err := restoreItemActionResolver.ResolveActions(kr.discoveryHelper, kr.logger) if err != nil { return Result{}, Result{Velero: []string{err.Error()}} } - resolvedItemSnapshotterActions, err := itemSnapshotterResolver.ResolveActions(kr.discoveryHelper) + resolvedItemSnapshotterActions, err := itemSnapshotterResolver.ResolveActions(kr.discoveryHelper, kr.logger) if err != nil { return Result{}, Result{Velero: []string{err.Error()}} }