Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restore Item Action v2 API implementation #5569

Merged
merged 1 commit into from
Jan 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -474,11 +474,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