Skip to content

Commit

Permalink
RestoreItemAction v2 API implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Scott Seago <[email protected]>
  • Loading branch information
sseago committed Nov 8, 2022
1 parent fd02297 commit c629079
Show file tree
Hide file tree
Showing 23 changed files with 2,645 additions and 78 deletions.
1 change: 1 addition & 0 deletions changelogs/unreleased/5569-sseago
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
RestoreItemAction v2 API implementation
4 changes: 2 additions & 2 deletions pkg/controller/restore_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -472,11 +472,11 @@ func (c *restoreController) runValidatedRestore(restore *api.Restore, info backu
pluginManager := c.newPluginManager(restoreLog)
defer pluginManager.CleanupClients()

actions, err := pluginManager.GetRestoreItemActions()
actions, err := pluginManager.GetRestoreItemActionsV2()
if err != nil {
return errors.Wrap(err, "error getting restore item actions")
}
actionsResolver := framework.NewRestoreItemActionResolver(actions)
actionsResolver := framework.NewRestoreItemActionResolverV2(actions)

itemSnapshotters, err := pluginManager.GetItemSnapshotters()
if err != nil {
Expand Down
8 changes: 4 additions & 4 deletions pkg/controller/restore_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
pluginmocks "github.com/vmware-tanzu/velero/pkg/plugin/mocks"
isv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/item_snapshotter/v1"
riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1"
riav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v2"
pkgrestore "github.com/vmware-tanzu/velero/pkg/restore"
velerotest "github.com/vmware-tanzu/velero/pkg/test"
"github.com/vmware-tanzu/velero/pkg/util/logging"
Expand Down Expand Up @@ -556,7 +556,7 @@ func TestProcessQueueItem(t *testing.T) {
}

if test.restore != nil {
pluginManager.On("GetRestoreItemActions").Return(nil, nil)
pluginManager.On("GetRestoreItemActionsV2").Return(nil, nil)
pluginManager.On("GetItemSnapshotters").Return([]isv1.ItemSnapshotter{}, nil)
pluginManager.On("CleanupClients")
}
Expand Down Expand Up @@ -861,7 +861,7 @@ type fakeRestorer struct {

func (r *fakeRestorer) Restore(
info pkgrestore.Request,
actions []riav1.RestoreItemAction,
actions []riav2.RestoreItemAction,
snapshotLocationLister listers.VolumeSnapshotLocationLister,
volumeSnapshotterGetter pkgrestore.VolumeSnapshotterGetter,
) (pkgrestore.Result, pkgrestore.Result) {
Expand All @@ -873,7 +873,7 @@ func (r *fakeRestorer) Restore(
}

func (r *fakeRestorer) RestoreWithResolvers(req pkgrestore.Request,
resolver framework.RestoreItemActionResolver,
resolver framework.RestoreItemActionResolverV2,
itemSnapshotterResolver framework.ItemSnapshotterResolver,
snapshotLocationLister listers.VolumeSnapshotLocationLister,
volumeSnapshotterGetter pkgrestore.VolumeSnapshotterGetter,
Expand Down
46 changes: 46 additions & 0 deletions pkg/plugin/clientmgmt/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@ import (
biav2cli "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/backupitemaction/v2"
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process"
riav1cli "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/restoreitemaction/v1"
riav2cli "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/restoreitemaction/v2"
vsv1cli "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/volumesnapshotter/v1"
"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"
biav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
isv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/item_snapshotter/v1"
riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1"
riav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v2"
vsv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v1"
)

Expand Down Expand Up @@ -64,6 +66,12 @@ type Manager interface {
// GetRestoreItemAction returns the restore item action plugin for name.
GetRestoreItemAction(name string) (riav1.RestoreItemAction, error)

// GetRestoreItemActionsV2 returns all v2 restore item action plugins.
GetRestoreItemActionsV2() ([]riav2.RestoreItemAction, error)

// GetRestoreItemActionV2 returns the restore item action plugin for name.
GetRestoreItemActionV2(name string) (riav2.RestoreItemAction, error)

// GetDeleteItemActions returns all delete item action plugins.
GetDeleteItemActions() ([]velero.DeleteItemAction, error)

Expand Down Expand Up @@ -302,6 +310,44 @@ func (m *manager) GetRestoreItemAction(name string) (riav1.RestoreItemAction, er
return nil, fmt.Errorf("unable to get valid RestoreItemAction for %q", name)
}

// GetRestoreItemActionsV2 returns all v2 restore item actions as restartableRestoreItemActions.
func (m *manager) GetRestoreItemActionsV2() ([]riav2.RestoreItemAction, error) {
list := m.registry.List(common.PluginKindRestoreItemActionV2)

actions := make([]riav2.RestoreItemAction, 0, len(list))

for i := range list {
id := list[i]

r, err := m.GetRestoreItemActionV2(id.Name)
if err != nil {
return nil, err
}

actions = append(actions, r)
}

return actions, nil
}

// GetRestoreItemActionV2 returns a v2 restartableRestoreItemAction for name.
func (m *manager) GetRestoreItemActionV2(name string) (riav2.RestoreItemAction, error) {
name = sanitizeName(name)

for _, adaptedRestoreItemAction := range riav2cli.AdaptedRestoreItemActions() {
restartableProcess, err := m.getRestartableProcess(adaptedRestoreItemAction.Kind, name)
// Check if plugin was not found
if errors.As(err, &pluginNotFoundErrType) {
continue
}
if err != nil {
return nil, err
}
return adaptedRestoreItemAction.GetRestartable(name, restartableProcess), nil
}
return nil, fmt.Errorf("unable to get valid RestoreItemActionV2 for %q", name)
}

// GetDeleteItemActions returns all delete item actions as restartableDeleteItemActions.
func (m *manager) GetDeleteItemActions() ([]velero.DeleteItemAction, error) {
list := m.registry.List(common.PluginKindDeleteItemAction)
Expand Down
110 changes: 110 additions & 0 deletions pkg/plugin/clientmgmt/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
biav2cli "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/backupitemaction/v2"
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process"
riav1cli "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/restoreitemaction/v1"
riav2cli "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/restoreitemaction/v2"
vsv1cli "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/volumesnapshotter/v1"
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
"github.com/vmware-tanzu/velero/pkg/plugin/framework/common"
Expand Down Expand Up @@ -238,6 +239,23 @@ func TestGetRestoreItemAction(t *testing.T) {
)
}

func TestGetRestoreItemActionV2(t *testing.T) {
getPluginTest(t,
common.PluginKindRestoreItemActionV2,
"velero.io/pod",
func(m Manager, name string) (interface{}, error) {
return m.GetRestoreItemActionV2(name)
},
func(name string, sharedPluginProcess process.RestartableProcess) interface{} {
return &riav2cli.RestartableRestoreItemAction{
Key: process.KindAndName{Kind: common.PluginKindRestoreItemActionV2, Name: name},
SharedPluginProcess: sharedPluginProcess,
}
},
false,
)
}

func getPluginTest(
t *testing.T,
kind common.PluginKind,
Expand Down Expand Up @@ -565,6 +583,98 @@ func TestGetRestoreItemActions(t *testing.T) {
}
}

func TestGetRestoreItemActionsV2(t *testing.T) {
tests := []struct {
name string
names []string
newRestartableProcessError error
expectedError string
}{
{
name: "No items",
names: []string{},
},
{
name: "Error getting restartable process",
names: []string{"velero.io/a", "velero.io/b", "velero.io/c"},
newRestartableProcessError: errors.Errorf("NewRestartableProcess"),
expectedError: "NewRestartableProcess",
},
{
name: "Happy path",
names: []string{"velero.io/a", "velero.io/b", "velero.io/c"},
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
logger := test.NewLogger()
logLevel := logrus.InfoLevel

registry := &mockRegistry{}
defer registry.AssertExpectations(t)

m := NewManager(logger, logLevel, registry).(*manager)
factory := &mockRestartableProcessFactory{}
defer factory.AssertExpectations(t)
m.restartableProcessFactory = factory

pluginKind := common.PluginKindRestoreItemActionV2
var pluginIDs []framework.PluginIdentifier
for i := range tc.names {
pluginID := framework.PluginIdentifier{
Command: "/command",
Kind: pluginKind,
Name: tc.names[i],
}
pluginIDs = append(pluginIDs, pluginID)
}
registry.On("List", pluginKind).Return(pluginIDs)

var expectedActions []interface{}
for i := range pluginIDs {
pluginID := pluginIDs[i]
pluginName := pluginID.Name

registry.On("Get", pluginKind, pluginName).Return(pluginID, nil)

restartableProcess := &restartabletest.MockRestartableProcess{}
defer restartableProcess.AssertExpectations(t)

expected := &riav2cli.RestartableRestoreItemAction{
Key: process.KindAndName{Kind: pluginKind, Name: pluginName},
SharedPluginProcess: restartableProcess,
}

if tc.newRestartableProcessError != nil {
// Test 1: error getting restartable process
factory.On("NewRestartableProcess", pluginID.Command, logger, logLevel).Return(nil, errors.Errorf("NewRestartableProcess")).Once()
break
}

// Test 2: happy path
if i == 0 {
factory.On("NewRestartableProcess", pluginID.Command, logger, logLevel).Return(restartableProcess, nil).Once()
}

expectedActions = append(expectedActions, expected)
}

restoreItemActions, err := m.GetRestoreItemActionsV2()
if tc.newRestartableProcessError != nil {
assert.Nil(t, restoreItemActions)
assert.EqualError(t, err, "NewRestartableProcess")
} else {
require.NoError(t, err)
var actual []interface{}
for i := range restoreItemActions {
actual = append(actual, restoreItemActions[i])
}
assert.Equal(t, expectedActions, actual)
}
})
}
}

func TestGetDeleteItemAction(t *testing.T) {
getPluginTest(t,
common.PluginKindDeleteItemAction,
Expand Down
18 changes: 10 additions & 8 deletions pkg/plugin/clientmgmt/process/client_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
biav2 "github.com/vmware-tanzu/velero/pkg/plugin/framework/backupitemaction/v2"
"github.com/vmware-tanzu/velero/pkg/plugin/framework/common"
riav2 "github.com/vmware-tanzu/velero/pkg/plugin/framework/restoreitemaction/v2"
)

// clientBuilder builds go-plugin Clients.
Expand Down Expand Up @@ -69,14 +70,15 @@ func (b *clientBuilder) clientConfig() *hcplugin.ClientConfig {
HandshakeConfig: framework.Handshake(),
AllowedProtocols: []hcplugin.Protocol{hcplugin.ProtocolGRPC},
Plugins: map[string]hcplugin.Plugin{
string(common.PluginKindBackupItemAction): framework.NewBackupItemActionPlugin(common.ClientLogger(b.clientLogger)),
string(common.PluginKindBackupItemActionV2): biav2.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)),
string(common.PluginKindBackupItemAction): framework.NewBackupItemActionPlugin(common.ClientLogger(b.clientLogger)),
string(common.PluginKindBackupItemActionV2): biav2.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.PluginKindRestoreItemActionV2): riav2.NewRestoreItemActionPlugin(common.ClientLogger(b.clientLogger)),
string(common.PluginKindDeleteItemAction): framework.NewDeleteItemActionPlugin(common.ClientLogger(b.clientLogger)),
string(common.PluginKindItemSnapshotter): framework.NewItemSnapshotterPlugin(common.ClientLogger(b.clientLogger)),
},
Logger: b.pluginLogger,
Cmd: exec.Command(b.commandName, b.commandArgs...), //nolint
Expand Down
18 changes: 10 additions & 8 deletions pkg/plugin/clientmgmt/process/client_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
biav2 "github.com/vmware-tanzu/velero/pkg/plugin/framework/backupitemaction/v2"
"github.com/vmware-tanzu/velero/pkg/plugin/framework/common"
riav2 "github.com/vmware-tanzu/velero/pkg/plugin/framework/restoreitemaction/v2"
"github.com/vmware-tanzu/velero/pkg/test"
)

Expand Down Expand Up @@ -62,14 +63,15 @@ func TestClientConfig(t *testing.T) {
HandshakeConfig: framework.Handshake(),
AllowedProtocols: []hcplugin.Protocol{hcplugin.ProtocolGRPC},
Plugins: map[string]hcplugin.Plugin{
string(common.PluginKindBackupItemAction): framework.NewBackupItemActionPlugin(common.ClientLogger(logger)),
string(common.PluginKindBackupItemActionV2): biav2.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)),
string(common.PluginKindBackupItemAction): framework.NewBackupItemActionPlugin(common.ClientLogger(logger)),
string(common.PluginKindBackupItemActionV2): biav2.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.PluginKindRestoreItemActionV2): riav2.NewRestoreItemActionPlugin(common.ClientLogger(logger)),
string(common.PluginKindDeleteItemAction): framework.NewDeleteItemActionPlugin(common.ClientLogger(logger)),
string(common.PluginKindItemSnapshotter): framework.NewItemSnapshotterPlugin(common.ClientLogger(logger)),
},
Logger: cb.pluginLogger,
Cmd: exec.Command(cb.commandName, cb.commandArgs...),
Expand Down
Loading

0 comments on commit c629079

Please sign in to comment.