mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-01-05 21:14:56 +00:00
plugin/framework refactoring for BackupItemAction v1
Refactors the framework package to implement the plugin versioning changes needed for BIA v1 and overall package refactoring to support plugin versions in different packages. This should be all that's needed to move on to v2 for BackupItemAction. The remaining plugin types still need similar refactoring to what's being done here for BIA before attempting a v2 implementation. Signed-off-by: Scott Seago <sseago@redhat.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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...),
|
||||
|
||||
@@ -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...),
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
}}
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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 ""
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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 {
|
||||
@@ -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
|
||||
}
|
||||
@@ -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:
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package framework
|
||||
package common
|
||||
|
||||
import (
|
||||
"strings"
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 <DNS subdomain>/<non-empty name>.
|
||||
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 <DNS subdomain>/<non-empty name>.
|
||||
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 <DNS subdomain>/<non-empty name>.
|
||||
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 <DNS subdomain>/<non-empty name>.
|
||||
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 <DNS subdomain>/<non-empty name>.
|
||||
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,
|
||||
})
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by mockery v1.0.0. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
velero "github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||
|
||||
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
)
|
||||
|
||||
// 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 *BackupItemAction) AppliesTo() (velero.ResourceSelector, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 velero.ResourceSelector
|
||||
if rf, ok := ret.Get(0).(func() velero.ResourceSelector); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(velero.ResourceSelector)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// 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, *velerov1.Backup) runtime.Unstructured); ok {
|
||||
r0 = rf(item, backup)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(runtime.Unstructured)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 []velero.ResourceIdentifier
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(2).(func(runtime.Unstructured, *velerov1.Backup) error); ok {
|
||||
r2 = rf(item, backup)
|
||||
} else {
|
||||
r2 = ret.Error(2)
|
||||
}
|
||||
|
||||
return r0, r1, r2
|
||||
}
|
||||
Reference in New Issue
Block a user