Implement DeleteItemAction plugin support (#2808)

* Add DeleteItemAction struct & protobuf definition

Signed-off-by: Nolan Brubaker <brubakern@vmware.com>
This commit is contained in:
Nolan Brubaker
2020-08-18 15:16:26 -04:00
committed by GitHub
parent d1a1d063e1
commit e9ece0f7b5
22 changed files with 1119 additions and 72 deletions

View File

@@ -1,5 +1,5 @@
/*
Copyright 2017 the Velero contributors.
Copyright 2020 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.
@@ -46,6 +46,12 @@ type Manager interface {
// GetRestoreItemAction returns the restore item action plugin for name.
GetRestoreItemAction(name string) (velero.RestoreItemAction, error)
// GetDeleteItemActions returns all delete item action plugins.
GetDeleteItemActions() ([]velero.DeleteItemAction, error)
// GetDeleteItemAction returns the delete item action plugin for name.
GetDeleteItemAction(name string) (velero.DeleteItemAction, error)
// CleanupClients terminates all of the Manager's running plugin processes.
CleanupClients()
}
@@ -224,3 +230,39 @@ func (m *manager) GetRestoreItemAction(name string) (velero.RestoreItemAction, e
r := newRestartableRestoreItemAction(name, restartableProcess)
return r, nil
}
// GetDeleteItemActions returns all delete item actions as restartableDeleteItemActions.
func (m *manager) GetDeleteItemActions() ([]velero.DeleteItemAction, error) {
list := m.registry.List(framework.PluginKindDeleteItemAction)
actions := make([]velero.DeleteItemAction, 0, len(list))
for i := range list {
id := list[i]
r, err := m.GetDeleteItemAction(id.Name)
if err != nil {
return nil, err
}
actions = append(actions, r)
}
return actions, nil
}
// GetDeleteItemAction returns a restartableDeleteItemAction for name.
func (m *manager) GetDeleteItemAction(name string) (velero.DeleteItemAction, error) {
// Backwards compatibility with non-namespaced plugins, following principle of least surprise
// since DeleteItemActions were not bundled with Velero when plugins were non-namespaced.
if !strings.Contains(name, "/") {
name = "velero.io/" + name
}
restartableProcess, err := m.getRestartableProcess(framework.PluginKindDeleteItemAction, name)
if err != nil {
return nil, err
}
r := newRestartableDeleteItemAction(name, restartableProcess)
return r, nil
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2018 the Velero contributors.
Copyright 2020 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.
@@ -475,3 +475,102 @@ func TestGetRestoreItemActions(t *testing.T) {
})
}
}
func TestGetDeleteItemAction(t *testing.T) {
getPluginTest(t,
framework.PluginKindDeleteItemAction,
"velero.io/deleter",
func(m Manager, name string) (interface{}, error) {
return m.GetDeleteItemAction(name)
},
func(name string, sharedPluginProcess RestartableProcess) interface{} {
return &restartableDeleteItemAction{
key: kindAndName{kind: framework.PluginKindDeleteItemAction, name: name},
sharedPluginProcess: sharedPluginProcess,
}
},
false,
)
}
func TestGetDeleteItemActions(t *testing.T) {
tests := []struct {
name string
names []string
newRestartableProcessError error
expectedError string
}{
{
name: "No items",
names: []string{},
},
}
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 := framework.PluginKindDeleteItemAction
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 := &mockRestartableProcess{}
defer restartableProcess.AssertExpectations(t)
expected := &restartableRestoreItemAction{
key: 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)
}
deleteItemActions, err := m.GetDeleteItemActions()
if tc.newRestartableProcessError != nil {
assert.Nil(t, deleteItemActions)
assert.EqualError(t, err, "newRestartableProcess")
} else {
require.NoError(t, err)
var actual []interface{}
for i := range deleteItemActions {
actual = append(actual, deleteItemActions[i])
}
assert.Equal(t, expectedActions, actual)
}
})
}
}

View File

@@ -0,0 +1,88 @@
/*
Copyright 2020 the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package clientmgmt
import (
"github.com/pkg/errors"
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
)
// restartableDeleteItemAction is a delete item action for a given implementation (such as "pod"). It is associated with
// a restartableProcess, which may be shared and used to run multiple plugins. At the beginning of each method
// call, the restartableDeleteItemAction asks its restartableProcess to restart itself if needed (e.g. if the
// process terminated for any reason), then it proceeds with the actual call.
type restartableDeleteItemAction struct {
key kindAndName
sharedPluginProcess RestartableProcess
config map[string]string
}
// newRestartableDeleteItemAction returns a new restartableDeleteItemAction.
func newRestartableDeleteItemAction(name string, sharedPluginProcess RestartableProcess) *restartableDeleteItemAction {
r := &restartableDeleteItemAction{
key: kindAndName{kind: framework.PluginKindDeleteItemAction, name: name},
sharedPluginProcess: sharedPluginProcess,
}
return r
}
// getDeleteItemAction returns the delete item action for this restartableDeleteItemAction. It does *not* restart the
// plugin process.
func (r *restartableDeleteItemAction) getDeleteItemAction() (velero.DeleteItemAction, error) {
plugin, err := r.sharedPluginProcess.getByKindAndName(r.key)
if err != nil {
return nil, err
}
deleteItemAction, ok := plugin.(velero.DeleteItemAction)
if !ok {
return nil, errors.Errorf("%T is not a DeleteItemAction!", plugin)
}
return deleteItemAction, nil
}
// getDelegate restarts the plugin process (if needed) and returns the delete item action for this restartableDeleteItemAction.
func (r *restartableDeleteItemAction) getDelegate() (velero.DeleteItemAction, error) {
if err := r.sharedPluginProcess.resetIfNeeded(); err != nil {
return nil, err
}
return r.getDeleteItemAction()
}
// AppliesTo restarts the plugin's process if needed, then delegates the call.
func (r *restartableDeleteItemAction) AppliesTo() (velero.ResourceSelector, error) {
delegate, err := r.getDelegate()
if err != nil {
return velero.ResourceSelector{}, err
}
return delegate.AppliesTo()
}
// Execute restarts the plugin's process if needed, then delegates the call.
func (r *restartableDeleteItemAction) Execute(input *velero.DeleteItemActionExecuteInput) error {
delegate, err := r.getDelegate()
if err != nil {
return err
}
return delegate.Execute(input)
}

View File

@@ -0,0 +1,142 @@
/*
Copyright 2020 the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package clientmgmt
import (
"testing"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"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"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
"github.com/vmware-tanzu/velero/pkg/plugin/velero/mocks"
)
func TestRestartableGetDeleteItemAction(t *testing.T) {
tests := []struct {
name string
plugin interface{}
getError error
expectedError string
}{
{
name: "error getting by kind and name",
getError: errors.Errorf("get error"),
expectedError: "get error",
},
{
name: "wrong type",
plugin: 3,
expectedError: "int is not a DeleteItemAction!",
},
{
name: "happy path",
plugin: new(mocks.DeleteItemAction),
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
p := new(mockRestartableProcess)
defer p.AssertExpectations(t)
name := "pod"
key := kindAndName{kind: framework.PluginKindDeleteItemAction, name: name}
p.On("getByKindAndName", key).Return(tc.plugin, tc.getError)
r := newRestartableDeleteItemAction(name, p)
a, err := r.getDeleteItemAction()
if tc.expectedError != "" {
assert.EqualError(t, err, tc.expectedError)
return
}
require.NoError(t, err)
assert.Equal(t, tc.plugin, a)
})
}
}
func TestRestartableDeleteItemActionGetDelegate(t *testing.T) {
p := new(mockRestartableProcess)
defer p.AssertExpectations(t)
// Reset error
p.On("resetIfNeeded").Return(errors.Errorf("reset error")).Once()
name := "pod"
r := newRestartableDeleteItemAction(name, p)
a, err := r.getDelegate()
assert.Nil(t, a)
assert.EqualError(t, err, "reset error")
// Happy path
// Currently broken since this mocks out the restore item action interface
p.On("resetIfNeeded").Return(nil)
expected := new(mocks.DeleteItemAction)
key := kindAndName{kind: framework.PluginKindDeleteItemAction, name: name}
p.On("getByKindAndName", key).Return(expected, nil)
a, err = r.getDelegate()
assert.NoError(t, err)
assert.Equal(t, expected, a)
}
func TestRestartableDeleteItemActionDelegatedFunctions(t *testing.T) {
pv := &unstructured.Unstructured{
Object: map[string]interface{}{
"color": "blue",
},
}
backup := &api.Backup{}
input := &velero.DeleteItemActionExecuteInput{
Item: pv,
Backup: backup,
}
runRestartableDelegateTests(
t,
framework.PluginKindDeleteItemAction,
func(key kindAndName, p RestartableProcess) interface{} {
return &restartableDeleteItemAction{
key: key,
sharedPluginProcess: p,
}
},
func() mockable {
// Currently broken because this mocks the restore item action interface
return new(mocks.DeleteItemAction)
},
restartableDelegateTest{
function: "AppliesTo",
inputs: []interface{}{},
expectedErrorOutputs: []interface{}{velero.ResourceSelector{}, errors.Errorf("reset error")},
expectedDelegateOutputs: []interface{}{velero.ResourceSelector{IncludedNamespaces: []string{"a"}}, errors.Errorf("delegate error")},
},
restartableDelegateTest{
function: "Execute",
inputs: []interface{}{input},
expectedErrorOutputs: []interface{}{errors.Errorf("reset error")},
expectedDelegateOutputs: []interface{}{errors.Errorf("delegate error")},
},
)
}

View File

@@ -0,0 +1,44 @@
/*
Copyright 2020 the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package framework
import (
plugin "github.com/hashicorp/go-plugin"
"golang.org/x/net/context"
"google.golang.org/grpc"
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
)
// RestoreItemActionPlugin is an implementation of go-plugin's Plugin
// interface with support for gRPC for the restore/ItemAction
// interface.
type DeleteItemActionPlugin struct {
plugin.NetRPCUnsupportedPlugin
*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
}
// GRPCServer registers a DeleteItemAction gRPC server.
func (p *DeleteItemActionPlugin) GRPCServer(_ *plugin.GRPCBroker, server *grpc.Server) error {
proto.RegisterDeleteItemActionServer(server, &DeleteItemActionGRPCServer{mux: p.serverMux})
return nil
}

View File

@@ -0,0 +1,95 @@
/*
Copyright 2020 the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package framework
import (
"encoding/json"
"github.com/pkg/errors"
"golang.org/x/net/context"
"google.golang.org/grpc"
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
)
var _ velero.DeleteItemAction = &DeleteItemActionGRPCClient{}
// NewDeleteItemActionPlugin constructs a DeleteItemActionPlugin.
func NewDeleteItemActionPlugin(options ...PluginOption) *DeleteItemActionPlugin {
return &DeleteItemActionPlugin{
pluginBase: newPluginBase(options...),
}
}
// DeleteItemActionGRPCClient implements the backup/ItemAction interface and uses a
// gRPC client to make calls to the plugin server.
type DeleteItemActionGRPCClient struct {
*clientBase
grpcClient proto.DeleteItemActionClient
}
func newDeleteItemActionGRPCClient(base *clientBase, clientConn *grpc.ClientConn) interface{} {
return &DeleteItemActionGRPCClient{
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})
if err != nil {
return velero.ResourceSelector{}, fromGRPCError(err)
}
if res.ResourceSelector == nil {
return velero.ResourceSelector{}, nil
}
return velero.ResourceSelector{
IncludedNamespaces: res.ResourceSelector.IncludedNamespaces,
ExcludedNamespaces: res.ResourceSelector.ExcludedNamespaces,
IncludedResources: res.ResourceSelector.IncludedResources,
ExcludedResources: res.ResourceSelector.ExcludedResources,
LabelSelector: res.ResourceSelector.Selector,
}, nil
}
func (c *DeleteItemActionGRPCClient) Execute(input *velero.DeleteItemActionExecuteInput) error {
itemJSON, err := json.Marshal(input.Item.UnstructuredContent())
if err != nil {
return errors.WithStack(err)
}
backupJSON, err := json.Marshal(input.Backup)
if err != nil {
return errors.WithStack(err)
}
req := &proto.DeleteItemActionExecuteRequest{
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 nil
}

View File

@@ -0,0 +1,112 @@
/*
Copyright 2020 the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package framework
import (
"encoding/json"
"github.com/pkg/errors"
"golang.org/x/net/context"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
)
// 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
}
func (s *DeleteItemActionGRPCServer) getImpl(name string) (velero.DeleteItemAction, error) {
impl, err := s.mux.getHandler(name)
if err != nil {
return nil, err
}
itemAction, ok := impl.(velero.DeleteItemAction)
if !ok {
return nil, errors.Errorf("%T is not a delete item action", impl)
}
return itemAction, nil
}
func (s *DeleteItemActionGRPCServer) AppliesTo(ctx context.Context, req *proto.DeleteItemActionAppliesToRequest) (response *proto.DeleteItemActionAppliesToResponse, err error) {
defer func() {
if recoveredErr := handlePanic(recover()); recoveredErr != nil {
err = recoveredErr
}
}()
impl, err := s.getImpl(req.Plugin)
if err != nil {
return nil, newGRPCError(err)
}
resourceSelector, err := impl.AppliesTo()
if err != nil {
return nil, newGRPCError(err)
}
return &proto.DeleteItemActionAppliesToResponse{
&proto.ResourceSelector{
IncludedNamespaces: resourceSelector.IncludedNamespaces,
ExcludedNamespaces: resourceSelector.ExcludedNamespaces,
IncludedResources: resourceSelector.IncludedResources,
ExcludedResources: resourceSelector.ExcludedResources,
Selector: resourceSelector.LabelSelector,
},
}, nil
}
func (s *DeleteItemActionGRPCServer) Execute(ctx context.Context, req *proto.DeleteItemActionExecuteRequest) (_ *proto.Empty, err error) {
defer func() {
if recoveredErr := handlePanic(recover()); recoveredErr != nil {
err = recoveredErr
}
}()
impl, err := s.getImpl(req.Plugin)
if err != nil {
return nil, newGRPCError(err)
}
var (
item unstructured.Unstructured
backup api.Backup
)
if err := json.Unmarshal(req.Item, &item); err != nil {
return nil, newGRPCError(errors.WithStack(err))
}
if err = json.Unmarshal(req.Backup, &backup); err != nil {
return nil, newGRPCError(errors.WithStack(err))
}
if err := impl.Execute(&velero.DeleteItemActionExecuteInput{
Item: &item,
Backup: &backup,
}); err != nil {
return nil, newGRPCError(err)
}
return nil, nil
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2019 the Velero contributors.
Copyright 2020 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.
@@ -19,12 +19,15 @@ package framework
import (
"github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/runtime"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
)
func ExampleNewServer_volumeSnapshotter() {
NewServer(). // call the server
RegisterVolumeSnapshotter("example.io/volumesnapshotter", newVolumeSnapshotter). // register the plugin with a valid name
Serve() // serve the plugin
RegisterDeleteItemAction("example.io/delete-item-action", newDeleteItemAction).
Serve() // serve the plugin
}
func newVolumeSnapshotter(logger logrus.FieldLogger) (interface{}, error) {
@@ -91,3 +94,29 @@ func (b *VolumeSnapshotter) DeleteSnapshot(snapshotID string) error {
return nil
}
// Implement all methods for the DeleteItemAction interface
func newDeleteItemAction(logger logrus.FieldLogger) (interface{}, error) {
return DeleteItemAction{FieldLogger: logger}, nil
}
type DeleteItemAction struct {
FieldLogger logrus.FieldLogger
}
func (d *DeleteItemAction) AppliesTo() (velero.ResourceSelector, error) {
d.FieldLogger.Infof("AppliesTo called")
// ...
return velero.ResourceSelector{}, nil
}
func (d *DeleteItemAction) Execute(input *velero.DeleteItemActionExecuteInput) error {
d.FieldLogger.Infof("Execute called")
// ...
return nil
}

View File

@@ -38,6 +38,9 @@ const (
// PluginKindRestoreItemAction represents a restore item action plugin.
PluginKindRestoreItemAction PluginKind = "RestoreItemAction"
// PluginKindDeleteItemAction represents a delete item action plugin.
PluginKindDeleteItemAction PluginKind = "DeleteItemAction"
// PluginKindPluginLister represents a plugin lister plugin.
PluginKindPluginLister PluginKind = "PluginLister"
)
@@ -50,5 +53,6 @@ func AllPluginKinds() map[string]PluginKind {
allPluginKinds[PluginKindVolumeSnapshotter.String()] = PluginKindVolumeSnapshotter
allPluginKinds[PluginKindBackupItemAction.String()] = PluginKindBackupItemAction
allPluginKinds[PluginKindRestoreItemAction.String()] = PluginKindRestoreItemAction
allPluginKinds[PluginKindDeleteItemAction.String()] = PluginKindDeleteItemAction
return allPluginKinds
}

View File

@@ -67,6 +67,13 @@ type Server interface {
// RegisterRestoreItemActions registers multiple restore item actions.
RegisterRestoreItemActions(map[string]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
// RegisterDeleteItemActions registers multiple Delete item actions.
RegisterDeleteItemActions(map[string]HandlerInitializer) Server
// Server runs the plugin server.
Serve()
}
@@ -81,6 +88,7 @@ type server struct {
volumeSnapshotter *VolumeSnapshotterPlugin
objectStore *ObjectStorePlugin
restoreItemAction *RestoreItemActionPlugin
deleteItemAction *DeleteItemActionPlugin
}
// NewServer returns a new Server
@@ -96,6 +104,7 @@ func NewServer() Server {
volumeSnapshotter: NewVolumeSnapshotterPlugin(serverLogger(log)),
objectStore: NewObjectStorePlugin(serverLogger(log)),
restoreItemAction: NewRestoreItemActionPlugin(serverLogger(log)),
deleteItemAction: NewDeleteItemActionPlugin(serverLogger(log)),
}
}
@@ -156,6 +165,18 @@ func (s *server) RegisterRestoreItemActions(m map[string]HandlerInitializer) Ser
return s
}
func (s *server) RegisterDeleteItemAction(name string, initializer HandlerInitializer) Server {
s.deleteItemAction.register(name, initializer)
return s
}
func (s *server) RegisterDeleteItemActions(m map[string]HandlerInitializer) Server {
for name := range m {
s.RegisterDeleteItemAction(name, m[name])
}
return s
}
// getNames returns a list of PluginIdentifiers registered with plugin.
func getNames(command string, kind PluginKind, plugin Interface) []PluginIdentifier {
var pluginIdentifiers []PluginIdentifier

View File

@@ -6,6 +6,7 @@ Package generated is a generated protocol buffer package.
It is generated from these files:
BackupItemAction.proto
DeleteItemAction.proto
ObjectStore.proto
PluginLister.proto
RestoreItemAction.proto
@@ -17,6 +18,9 @@ It has these top-level messages:
ExecuteResponse
BackupItemActionAppliesToRequest
BackupItemActionAppliesToResponse
DeleteItemActionExecuteRequest
DeleteItemActionAppliesToRequest
DeleteItemActionAppliesToResponse
PutObjectRequest
ObjectExistsRequest
ObjectExistsResponse

View File

@@ -0,0 +1,219 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: DeleteItemAction.proto
package generated
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
type DeleteItemActionExecuteRequest struct {
Plugin string `protobuf:"bytes,1,opt,name=plugin" json:"plugin,omitempty"`
Item []byte `protobuf:"bytes,2,opt,name=item,proto3" json:"item,omitempty"`
Backup []byte `protobuf:"bytes,3,opt,name=backup,proto3" json:"backup,omitempty"`
}
func (m *DeleteItemActionExecuteRequest) Reset() { *m = DeleteItemActionExecuteRequest{} }
func (m *DeleteItemActionExecuteRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteItemActionExecuteRequest) ProtoMessage() {}
func (*DeleteItemActionExecuteRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
func (m *DeleteItemActionExecuteRequest) GetPlugin() string {
if m != nil {
return m.Plugin
}
return ""
}
func (m *DeleteItemActionExecuteRequest) GetItem() []byte {
if m != nil {
return m.Item
}
return nil
}
func (m *DeleteItemActionExecuteRequest) GetBackup() []byte {
if m != nil {
return m.Backup
}
return nil
}
type DeleteItemActionAppliesToRequest struct {
Plugin string `protobuf:"bytes,1,opt,name=plugin" json:"plugin,omitempty"`
}
func (m *DeleteItemActionAppliesToRequest) Reset() { *m = DeleteItemActionAppliesToRequest{} }
func (m *DeleteItemActionAppliesToRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteItemActionAppliesToRequest) ProtoMessage() {}
func (*DeleteItemActionAppliesToRequest) Descriptor() ([]byte, []int) {
return fileDescriptor1, []int{1}
}
func (m *DeleteItemActionAppliesToRequest) GetPlugin() string {
if m != nil {
return m.Plugin
}
return ""
}
type DeleteItemActionAppliesToResponse struct {
ResourceSelector *ResourceSelector `protobuf:"bytes,1,opt,name=ResourceSelector" json:"ResourceSelector,omitempty"`
}
func (m *DeleteItemActionAppliesToResponse) Reset() { *m = DeleteItemActionAppliesToResponse{} }
func (m *DeleteItemActionAppliesToResponse) String() string { return proto.CompactTextString(m) }
func (*DeleteItemActionAppliesToResponse) ProtoMessage() {}
func (*DeleteItemActionAppliesToResponse) Descriptor() ([]byte, []int) {
return fileDescriptor1, []int{2}
}
func (m *DeleteItemActionAppliesToResponse) GetResourceSelector() *ResourceSelector {
if m != nil {
return m.ResourceSelector
}
return nil
}
func init() {
proto.RegisterType((*DeleteItemActionExecuteRequest)(nil), "generated.DeleteItemActionExecuteRequest")
proto.RegisterType((*DeleteItemActionAppliesToRequest)(nil), "generated.DeleteItemActionAppliesToRequest")
proto.RegisterType((*DeleteItemActionAppliesToResponse)(nil), "generated.DeleteItemActionAppliesToResponse")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// Client API for DeleteItemAction service
type DeleteItemActionClient interface {
AppliesTo(ctx context.Context, in *DeleteItemActionAppliesToRequest, opts ...grpc.CallOption) (*DeleteItemActionAppliesToResponse, error)
Execute(ctx context.Context, in *DeleteItemActionExecuteRequest, opts ...grpc.CallOption) (*Empty, error)
}
type deleteItemActionClient struct {
cc *grpc.ClientConn
}
func NewDeleteItemActionClient(cc *grpc.ClientConn) DeleteItemActionClient {
return &deleteItemActionClient{cc}
}
func (c *deleteItemActionClient) AppliesTo(ctx context.Context, in *DeleteItemActionAppliesToRequest, opts ...grpc.CallOption) (*DeleteItemActionAppliesToResponse, error) {
out := new(DeleteItemActionAppliesToResponse)
err := grpc.Invoke(ctx, "/generated.DeleteItemAction/AppliesTo", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *deleteItemActionClient) Execute(ctx context.Context, in *DeleteItemActionExecuteRequest, opts ...grpc.CallOption) (*Empty, error) {
out := new(Empty)
err := grpc.Invoke(ctx, "/generated.DeleteItemAction/Execute", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for DeleteItemAction service
type DeleteItemActionServer interface {
AppliesTo(context.Context, *DeleteItemActionAppliesToRequest) (*DeleteItemActionAppliesToResponse, error)
Execute(context.Context, *DeleteItemActionExecuteRequest) (*Empty, error)
}
func RegisterDeleteItemActionServer(s *grpc.Server, srv DeleteItemActionServer) {
s.RegisterService(&_DeleteItemAction_serviceDesc, srv)
}
func _DeleteItemAction_AppliesTo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteItemActionAppliesToRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(DeleteItemActionServer).AppliesTo(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/generated.DeleteItemAction/AppliesTo",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(DeleteItemActionServer).AppliesTo(ctx, req.(*DeleteItemActionAppliesToRequest))
}
return interceptor(ctx, in, info, handler)
}
func _DeleteItemAction_Execute_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteItemActionExecuteRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(DeleteItemActionServer).Execute(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/generated.DeleteItemAction/Execute",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(DeleteItemActionServer).Execute(ctx, req.(*DeleteItemActionExecuteRequest))
}
return interceptor(ctx, in, info, handler)
}
var _DeleteItemAction_serviceDesc = grpc.ServiceDesc{
ServiceName: "generated.DeleteItemAction",
HandlerType: (*DeleteItemActionServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "AppliesTo",
Handler: _DeleteItemAction_AppliesTo_Handler,
},
{
MethodName: "Execute",
Handler: _DeleteItemAction_Execute_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "DeleteItemAction.proto",
}
func init() { proto.RegisterFile("DeleteItemAction.proto", fileDescriptor1) }
var fileDescriptor1 = []byte{
// 253 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0x41, 0x4b, 0xc3, 0x40,
0x14, 0x84, 0x89, 0x4a, 0x25, 0xcf, 0x1e, 0xc2, 0x1e, 0x4a, 0x88, 0x20, 0x31, 0xa7, 0x8a, 0x92,
0x43, 0xbd, 0x79, 0x2b, 0x58, 0xc5, 0x6b, 0xea, 0x1f, 0x48, 0x37, 0x63, 0x0d, 0x6e, 0xb2, 0xeb,
0xee, 0x5b, 0xd0, 0xbf, 0xe7, 0x2f, 0x13, 0x63, 0x28, 0x35, 0x42, 0xdb, 0xdb, 0xbe, 0xdd, 0x99,
0xf7, 0x31, 0x3b, 0x34, 0xb9, 0x87, 0x02, 0xe3, 0x89, 0xd1, 0xcc, 0x25, 0xd7, 0xba, 0xcd, 0x8d,
0xd5, 0xac, 0x45, 0xb8, 0x46, 0x0b, 0x5b, 0x32, 0xaa, 0x64, 0xbc, 0x7c, 0x2d, 0x2d, 0xaa, 0xdf,
0x87, 0xac, 0xa2, 0x8b, 0xa1, 0x65, 0xf1, 0x01, 0xe9, 0x19, 0x05, 0xde, 0x3d, 0x1c, 0x8b, 0x09,
0x8d, 0x8c, 0xf2, 0xeb, 0xba, 0x8d, 0x83, 0x34, 0x98, 0x86, 0x45, 0x3f, 0x09, 0x41, 0x27, 0x35,
0xa3, 0x89, 0x8f, 0xd2, 0x60, 0x3a, 0x2e, 0xba, 0xf3, 0x8f, 0x76, 0x55, 0xca, 0x37, 0x6f, 0xe2,
0xe3, 0xee, 0xb6, 0x9f, 0xb2, 0x3b, 0x4a, 0x87, 0x94, 0xb9, 0x31, 0xaa, 0x86, 0x7b, 0xd6, 0x7b,
0x38, 0x99, 0xa2, 0xcb, 0x1d, 0x5e, 0x67, 0x74, 0xeb, 0x20, 0x1e, 0x29, 0x2a, 0xe0, 0xb4, 0xb7,
0x12, 0x4b, 0x28, 0x48, 0xd6, 0xb6, 0x5b, 0x73, 0x36, 0x3b, 0xcf, 0x37, 0xd1, 0xf3, 0xa1, 0xa4,
0xf8, 0x67, 0x9a, 0x7d, 0x05, 0x14, 0x0d, 0x71, 0xe2, 0x85, 0xc2, 0x0d, 0x52, 0x5c, 0x6f, 0x2d,
0xdc, 0x17, 0x2a, 0xb9, 0x39, 0x4c, 0xdc, 0xa7, 0x78, 0xa0, 0xd3, 0xfe, 0xf3, 0xc5, 0xd5, 0x0e,
0xe3, 0xdf, 0x82, 0x92, 0x68, 0x4b, 0xba, 0x68, 0x0c, 0x7f, 0xae, 0x46, 0x5d, 0xb7, 0xb7, 0xdf,
0x01, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x31, 0x0b, 0xd3, 0x0e, 0x02, 0x00, 0x00,
}

View File

@@ -27,7 +27,7 @@ type PutObjectRequest struct {
func (m *PutObjectRequest) Reset() { *m = PutObjectRequest{} }
func (m *PutObjectRequest) String() string { return proto.CompactTextString(m) }
func (*PutObjectRequest) ProtoMessage() {}
func (*PutObjectRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
func (*PutObjectRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0} }
func (m *PutObjectRequest) GetPlugin() string {
if m != nil {
@@ -66,7 +66,7 @@ type ObjectExistsRequest struct {
func (m *ObjectExistsRequest) Reset() { *m = ObjectExistsRequest{} }
func (m *ObjectExistsRequest) String() string { return proto.CompactTextString(m) }
func (*ObjectExistsRequest) ProtoMessage() {}
func (*ObjectExistsRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} }
func (*ObjectExistsRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{1} }
func (m *ObjectExistsRequest) GetPlugin() string {
if m != nil {
@@ -96,7 +96,7 @@ type ObjectExistsResponse struct {
func (m *ObjectExistsResponse) Reset() { *m = ObjectExistsResponse{} }
func (m *ObjectExistsResponse) String() string { return proto.CompactTextString(m) }
func (*ObjectExistsResponse) ProtoMessage() {}
func (*ObjectExistsResponse) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{2} }
func (*ObjectExistsResponse) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{2} }
func (m *ObjectExistsResponse) GetExists() bool {
if m != nil {
@@ -114,7 +114,7 @@ type GetObjectRequest struct {
func (m *GetObjectRequest) Reset() { *m = GetObjectRequest{} }
func (m *GetObjectRequest) String() string { return proto.CompactTextString(m) }
func (*GetObjectRequest) ProtoMessage() {}
func (*GetObjectRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{3} }
func (*GetObjectRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{3} }
func (m *GetObjectRequest) GetPlugin() string {
if m != nil {
@@ -144,7 +144,7 @@ type Bytes struct {
func (m *Bytes) Reset() { *m = Bytes{} }
func (m *Bytes) String() string { return proto.CompactTextString(m) }
func (*Bytes) ProtoMessage() {}
func (*Bytes) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{4} }
func (*Bytes) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{4} }
func (m *Bytes) GetData() []byte {
if m != nil {
@@ -163,7 +163,7 @@ type ListCommonPrefixesRequest struct {
func (m *ListCommonPrefixesRequest) Reset() { *m = ListCommonPrefixesRequest{} }
func (m *ListCommonPrefixesRequest) String() string { return proto.CompactTextString(m) }
func (*ListCommonPrefixesRequest) ProtoMessage() {}
func (*ListCommonPrefixesRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{5} }
func (*ListCommonPrefixesRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{5} }
func (m *ListCommonPrefixesRequest) GetPlugin() string {
if m != nil {
@@ -200,7 +200,7 @@ type ListCommonPrefixesResponse struct {
func (m *ListCommonPrefixesResponse) Reset() { *m = ListCommonPrefixesResponse{} }
func (m *ListCommonPrefixesResponse) String() string { return proto.CompactTextString(m) }
func (*ListCommonPrefixesResponse) ProtoMessage() {}
func (*ListCommonPrefixesResponse) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{6} }
func (*ListCommonPrefixesResponse) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{6} }
func (m *ListCommonPrefixesResponse) GetPrefixes() []string {
if m != nil {
@@ -218,7 +218,7 @@ type ListObjectsRequest struct {
func (m *ListObjectsRequest) Reset() { *m = ListObjectsRequest{} }
func (m *ListObjectsRequest) String() string { return proto.CompactTextString(m) }
func (*ListObjectsRequest) ProtoMessage() {}
func (*ListObjectsRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{7} }
func (*ListObjectsRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{7} }
func (m *ListObjectsRequest) GetPlugin() string {
if m != nil {
@@ -248,7 +248,7 @@ type ListObjectsResponse struct {
func (m *ListObjectsResponse) Reset() { *m = ListObjectsResponse{} }
func (m *ListObjectsResponse) String() string { return proto.CompactTextString(m) }
func (*ListObjectsResponse) ProtoMessage() {}
func (*ListObjectsResponse) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{8} }
func (*ListObjectsResponse) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{8} }
func (m *ListObjectsResponse) GetKeys() []string {
if m != nil {
@@ -266,7 +266,7 @@ type DeleteObjectRequest struct {
func (m *DeleteObjectRequest) Reset() { *m = DeleteObjectRequest{} }
func (m *DeleteObjectRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteObjectRequest) ProtoMessage() {}
func (*DeleteObjectRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{9} }
func (*DeleteObjectRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{9} }
func (m *DeleteObjectRequest) GetPlugin() string {
if m != nil {
@@ -299,7 +299,7 @@ type CreateSignedURLRequest struct {
func (m *CreateSignedURLRequest) Reset() { *m = CreateSignedURLRequest{} }
func (m *CreateSignedURLRequest) String() string { return proto.CompactTextString(m) }
func (*CreateSignedURLRequest) ProtoMessage() {}
func (*CreateSignedURLRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{10} }
func (*CreateSignedURLRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{10} }
func (m *CreateSignedURLRequest) GetPlugin() string {
if m != nil {
@@ -336,7 +336,7 @@ type CreateSignedURLResponse struct {
func (m *CreateSignedURLResponse) Reset() { *m = CreateSignedURLResponse{} }
func (m *CreateSignedURLResponse) String() string { return proto.CompactTextString(m) }
func (*CreateSignedURLResponse) ProtoMessage() {}
func (*CreateSignedURLResponse) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{11} }
func (*CreateSignedURLResponse) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{11} }
func (m *CreateSignedURLResponse) GetUrl() string {
if m != nil {
@@ -353,7 +353,7 @@ type ObjectStoreInitRequest struct {
func (m *ObjectStoreInitRequest) Reset() { *m = ObjectStoreInitRequest{} }
func (m *ObjectStoreInitRequest) String() string { return proto.CompactTextString(m) }
func (*ObjectStoreInitRequest) ProtoMessage() {}
func (*ObjectStoreInitRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{12} }
func (*ObjectStoreInitRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{12} }
func (m *ObjectStoreInitRequest) GetPlugin() string {
if m != nil {
@@ -750,9 +750,9 @@ var _ObjectStore_serviceDesc = grpc.ServiceDesc{
Metadata: "ObjectStore.proto",
}
func init() { proto.RegisterFile("ObjectStore.proto", fileDescriptor1) }
func init() { proto.RegisterFile("ObjectStore.proto", fileDescriptor2) }
var fileDescriptor1 = []byte{
var fileDescriptor2 = []byte{
// 577 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xcd, 0x6e, 0xd3, 0x40,
0x10, 0xd6, 0xc6, 0x69, 0x54, 0x4f, 0x22, 0x61, 0xb6, 0x55, 0x30, 0x2e, 0x94, 0xb0, 0x02, 0x29,

View File

@@ -26,7 +26,7 @@ type PluginIdentifier struct {
func (m *PluginIdentifier) Reset() { *m = PluginIdentifier{} }
func (m *PluginIdentifier) String() string { return proto.CompactTextString(m) }
func (*PluginIdentifier) ProtoMessage() {}
func (*PluginIdentifier) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0} }
func (*PluginIdentifier) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{0} }
func (m *PluginIdentifier) GetCommand() string {
if m != nil {
@@ -56,7 +56,7 @@ type ListPluginsResponse struct {
func (m *ListPluginsResponse) Reset() { *m = ListPluginsResponse{} }
func (m *ListPluginsResponse) String() string { return proto.CompactTextString(m) }
func (*ListPluginsResponse) ProtoMessage() {}
func (*ListPluginsResponse) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{1} }
func (*ListPluginsResponse) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{1} }
func (m *ListPluginsResponse) GetPlugins() []*PluginIdentifier {
if m != nil {
@@ -142,9 +142,9 @@ var _PluginLister_serviceDesc = grpc.ServiceDesc{
Metadata: "PluginLister.proto",
}
func init() { proto.RegisterFile("PluginLister.proto", fileDescriptor2) }
func init() { proto.RegisterFile("PluginLister.proto", fileDescriptor3) }
var fileDescriptor2 = []byte{
var fileDescriptor3 = []byte{
// 201 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x0a, 0xc8, 0x29, 0x4d,
0xcf, 0xcc, 0xf3, 0xc9, 0x2c, 0x2e, 0x49, 0x2d, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2,

View File

@@ -28,7 +28,7 @@ func (m *RestoreItemActionExecuteRequest) Reset() { *m = RestoreItemActi
func (m *RestoreItemActionExecuteRequest) String() string { return proto.CompactTextString(m) }
func (*RestoreItemActionExecuteRequest) ProtoMessage() {}
func (*RestoreItemActionExecuteRequest) Descriptor() ([]byte, []int) {
return fileDescriptor3, []int{0}
return fileDescriptor4, []int{0}
}
func (m *RestoreItemActionExecuteRequest) GetPlugin() string {
@@ -69,7 +69,7 @@ func (m *RestoreItemActionExecuteResponse) Reset() { *m = RestoreItemAct
func (m *RestoreItemActionExecuteResponse) String() string { return proto.CompactTextString(m) }
func (*RestoreItemActionExecuteResponse) ProtoMessage() {}
func (*RestoreItemActionExecuteResponse) Descriptor() ([]byte, []int) {
return fileDescriptor3, []int{1}
return fileDescriptor4, []int{1}
}
func (m *RestoreItemActionExecuteResponse) GetItem() []byte {
@@ -101,7 +101,7 @@ func (m *RestoreItemActionAppliesToRequest) Reset() { *m = RestoreItemAc
func (m *RestoreItemActionAppliesToRequest) String() string { return proto.CompactTextString(m) }
func (*RestoreItemActionAppliesToRequest) ProtoMessage() {}
func (*RestoreItemActionAppliesToRequest) Descriptor() ([]byte, []int) {
return fileDescriptor3, []int{2}
return fileDescriptor4, []int{2}
}
func (m *RestoreItemActionAppliesToRequest) GetPlugin() string {
@@ -119,7 +119,7 @@ func (m *RestoreItemActionAppliesToResponse) Reset() { *m = RestoreItemA
func (m *RestoreItemActionAppliesToResponse) String() string { return proto.CompactTextString(m) }
func (*RestoreItemActionAppliesToResponse) ProtoMessage() {}
func (*RestoreItemActionAppliesToResponse) Descriptor() ([]byte, []int) {
return fileDescriptor3, []int{3}
return fileDescriptor4, []int{3}
}
func (m *RestoreItemActionAppliesToResponse) GetResourceSelector() *ResourceSelector {
@@ -241,9 +241,9 @@ var _RestoreItemAction_serviceDesc = grpc.ServiceDesc{
Metadata: "RestoreItemAction.proto",
}
func init() { proto.RegisterFile("RestoreItemAction.proto", fileDescriptor3) }
func init() { proto.RegisterFile("RestoreItemAction.proto", fileDescriptor4) }
var fileDescriptor3 = []byte{
var fileDescriptor4 = []byte{
// 332 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0xdd, 0x4e, 0xc2, 0x30,
0x14, 0x4e, 0x81, 0x80, 0x1c, 0x88, 0x3f, 0xbd, 0xd0, 0x06, 0x63, 0x9c, 0xbb, 0x30, 0xc4, 0x1f,

View File

@@ -18,7 +18,7 @@ type Empty struct {
func (m *Empty) Reset() { *m = Empty{} }
func (m *Empty) String() string { return proto.CompactTextString(m) }
func (*Empty) ProtoMessage() {}
func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{0} }
func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{0} }
type Stack struct {
Frames []*StackFrame `protobuf:"bytes,1,rep,name=frames" json:"frames,omitempty"`
@@ -27,7 +27,7 @@ type Stack struct {
func (m *Stack) Reset() { *m = Stack{} }
func (m *Stack) String() string { return proto.CompactTextString(m) }
func (*Stack) ProtoMessage() {}
func (*Stack) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{1} }
func (*Stack) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{1} }
func (m *Stack) GetFrames() []*StackFrame {
if m != nil {
@@ -45,7 +45,7 @@ type StackFrame struct {
func (m *StackFrame) Reset() { *m = StackFrame{} }
func (m *StackFrame) String() string { return proto.CompactTextString(m) }
func (*StackFrame) ProtoMessage() {}
func (*StackFrame) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{2} }
func (*StackFrame) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{2} }
func (m *StackFrame) GetFile() string {
if m != nil {
@@ -78,7 +78,7 @@ type ResourceIdentifier struct {
func (m *ResourceIdentifier) Reset() { *m = ResourceIdentifier{} }
func (m *ResourceIdentifier) String() string { return proto.CompactTextString(m) }
func (*ResourceIdentifier) ProtoMessage() {}
func (*ResourceIdentifier) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{3} }
func (*ResourceIdentifier) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{3} }
func (m *ResourceIdentifier) GetGroup() string {
if m != nil {
@@ -119,7 +119,7 @@ type ResourceSelector struct {
func (m *ResourceSelector) Reset() { *m = ResourceSelector{} }
func (m *ResourceSelector) String() string { return proto.CompactTextString(m) }
func (*ResourceSelector) ProtoMessage() {}
func (*ResourceSelector) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{4} }
func (*ResourceSelector) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{4} }
func (m *ResourceSelector) GetIncludedNamespaces() []string {
if m != nil {
@@ -164,9 +164,9 @@ func init() {
proto.RegisterType((*ResourceSelector)(nil), "generated.ResourceSelector")
}
func init() { proto.RegisterFile("Shared.proto", fileDescriptor4) }
func init() { proto.RegisterFile("Shared.proto", fileDescriptor5) }
var fileDescriptor4 = []byte{
var fileDescriptor5 = []byte{
// 294 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x92, 0xc1, 0x4e, 0xb5, 0x30,
0x10, 0x85, 0xc3, 0x05, 0xee, 0xff, 0x33, 0xba, 0xd0, 0x46, 0x93, 0xc6, 0xb8, 0x20, 0xac, 0x58,

View File

@@ -28,7 +28,7 @@ type CreateVolumeRequest struct {
func (m *CreateVolumeRequest) Reset() { *m = CreateVolumeRequest{} }
func (m *CreateVolumeRequest) String() string { return proto.CompactTextString(m) }
func (*CreateVolumeRequest) ProtoMessage() {}
func (*CreateVolumeRequest) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{0} }
func (*CreateVolumeRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{0} }
func (m *CreateVolumeRequest) GetPlugin() string {
if m != nil {
@@ -72,7 +72,7 @@ type CreateVolumeResponse struct {
func (m *CreateVolumeResponse) Reset() { *m = CreateVolumeResponse{} }
func (m *CreateVolumeResponse) String() string { return proto.CompactTextString(m) }
func (*CreateVolumeResponse) ProtoMessage() {}
func (*CreateVolumeResponse) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{1} }
func (*CreateVolumeResponse) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{1} }
func (m *CreateVolumeResponse) GetVolumeID() string {
if m != nil {
@@ -90,7 +90,7 @@ type GetVolumeInfoRequest struct {
func (m *GetVolumeInfoRequest) Reset() { *m = GetVolumeInfoRequest{} }
func (m *GetVolumeInfoRequest) String() string { return proto.CompactTextString(m) }
func (*GetVolumeInfoRequest) ProtoMessage() {}
func (*GetVolumeInfoRequest) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{2} }
func (*GetVolumeInfoRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{2} }
func (m *GetVolumeInfoRequest) GetPlugin() string {
if m != nil {
@@ -121,7 +121,7 @@ type GetVolumeInfoResponse struct {
func (m *GetVolumeInfoResponse) Reset() { *m = GetVolumeInfoResponse{} }
func (m *GetVolumeInfoResponse) String() string { return proto.CompactTextString(m) }
func (*GetVolumeInfoResponse) ProtoMessage() {}
func (*GetVolumeInfoResponse) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{3} }
func (*GetVolumeInfoResponse) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{3} }
func (m *GetVolumeInfoResponse) GetVolumeType() string {
if m != nil {
@@ -147,7 +147,7 @@ type CreateSnapshotRequest struct {
func (m *CreateSnapshotRequest) Reset() { *m = CreateSnapshotRequest{} }
func (m *CreateSnapshotRequest) String() string { return proto.CompactTextString(m) }
func (*CreateSnapshotRequest) ProtoMessage() {}
func (*CreateSnapshotRequest) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{4} }
func (*CreateSnapshotRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{4} }
func (m *CreateSnapshotRequest) GetPlugin() string {
if m != nil {
@@ -184,7 +184,7 @@ type CreateSnapshotResponse struct {
func (m *CreateSnapshotResponse) Reset() { *m = CreateSnapshotResponse{} }
func (m *CreateSnapshotResponse) String() string { return proto.CompactTextString(m) }
func (*CreateSnapshotResponse) ProtoMessage() {}
func (*CreateSnapshotResponse) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{5} }
func (*CreateSnapshotResponse) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{5} }
func (m *CreateSnapshotResponse) GetSnapshotID() string {
if m != nil {
@@ -201,7 +201,7 @@ type DeleteSnapshotRequest struct {
func (m *DeleteSnapshotRequest) Reset() { *m = DeleteSnapshotRequest{} }
func (m *DeleteSnapshotRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteSnapshotRequest) ProtoMessage() {}
func (*DeleteSnapshotRequest) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{6} }
func (*DeleteSnapshotRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{6} }
func (m *DeleteSnapshotRequest) GetPlugin() string {
if m != nil {
@@ -225,7 +225,7 @@ type GetVolumeIDRequest struct {
func (m *GetVolumeIDRequest) Reset() { *m = GetVolumeIDRequest{} }
func (m *GetVolumeIDRequest) String() string { return proto.CompactTextString(m) }
func (*GetVolumeIDRequest) ProtoMessage() {}
func (*GetVolumeIDRequest) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{7} }
func (*GetVolumeIDRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{7} }
func (m *GetVolumeIDRequest) GetPlugin() string {
if m != nil {
@@ -248,7 +248,7 @@ type GetVolumeIDResponse struct {
func (m *GetVolumeIDResponse) Reset() { *m = GetVolumeIDResponse{} }
func (m *GetVolumeIDResponse) String() string { return proto.CompactTextString(m) }
func (*GetVolumeIDResponse) ProtoMessage() {}
func (*GetVolumeIDResponse) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{8} }
func (*GetVolumeIDResponse) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{8} }
func (m *GetVolumeIDResponse) GetVolumeID() string {
if m != nil {
@@ -266,7 +266,7 @@ type SetVolumeIDRequest struct {
func (m *SetVolumeIDRequest) Reset() { *m = SetVolumeIDRequest{} }
func (m *SetVolumeIDRequest) String() string { return proto.CompactTextString(m) }
func (*SetVolumeIDRequest) ProtoMessage() {}
func (*SetVolumeIDRequest) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{9} }
func (*SetVolumeIDRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{9} }
func (m *SetVolumeIDRequest) GetPlugin() string {
if m != nil {
@@ -296,7 +296,7 @@ type SetVolumeIDResponse struct {
func (m *SetVolumeIDResponse) Reset() { *m = SetVolumeIDResponse{} }
func (m *SetVolumeIDResponse) String() string { return proto.CompactTextString(m) }
func (*SetVolumeIDResponse) ProtoMessage() {}
func (*SetVolumeIDResponse) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{10} }
func (*SetVolumeIDResponse) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{10} }
func (m *SetVolumeIDResponse) GetPersistentVolume() []byte {
if m != nil {
@@ -313,7 +313,7 @@ type VolumeSnapshotterInitRequest struct {
func (m *VolumeSnapshotterInitRequest) Reset() { *m = VolumeSnapshotterInitRequest{} }
func (m *VolumeSnapshotterInitRequest) String() string { return proto.CompactTextString(m) }
func (*VolumeSnapshotterInitRequest) ProtoMessage() {}
func (*VolumeSnapshotterInitRequest) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{11} }
func (*VolumeSnapshotterInitRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{11} }
func (m *VolumeSnapshotterInitRequest) GetPlugin() string {
if m != nil {
@@ -614,9 +614,9 @@ var _VolumeSnapshotter_serviceDesc = grpc.ServiceDesc{
Metadata: "VolumeSnapshotter.proto",
}
func init() { proto.RegisterFile("VolumeSnapshotter.proto", fileDescriptor5) }
func init() { proto.RegisterFile("VolumeSnapshotter.proto", fileDescriptor6) }
var fileDescriptor5 = []byte{
var fileDescriptor6 = []byte{
// 566 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xc1, 0x6e, 0xd3, 0x40,
0x10, 0xd5, 0xda, 0x6e, 0x44, 0x26, 0xa5, 0x0a, 0x9b, 0xa4, 0x58, 0x16, 0x04, 0xe3, 0x0b, 0x51,

View File

@@ -1,25 +1,10 @@
/*
Copyright 2018 the Velero contributors.
// Code generated by mockery v2.1.0. DO NOT EDIT.
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 mocks
import (
mock "github.com/stretchr/testify/mock"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
velero "github.com/vmware-tanzu/velero/pkg/plugin/velero"
)
// Manager is an autogenerated mock type for the Manager type
@@ -78,16 +63,16 @@ func (_m *Manager) GetBackupItemActions() ([]velero.BackupItemAction, error) {
return r0, r1
}
// GetVolumeSnapshotter provides a mock function with given fields: name
func (_m *Manager) GetVolumeSnapshotter(name string) (velero.VolumeSnapshotter, error) {
// GetDeleteItemAction provides a mock function with given fields: name
func (_m *Manager) GetDeleteItemAction(name string) (velero.DeleteItemAction, error) {
ret := _m.Called(name)
var r0 velero.VolumeSnapshotter
if rf, ok := ret.Get(0).(func(string) velero.VolumeSnapshotter); ok {
var r0 velero.DeleteItemAction
if rf, ok := ret.Get(0).(func(string) velero.DeleteItemAction); ok {
r0 = rf(name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(velero.VolumeSnapshotter)
r0 = ret.Get(0).(velero.DeleteItemAction)
}
}
@@ -101,6 +86,29 @@ func (_m *Manager) GetVolumeSnapshotter(name string) (velero.VolumeSnapshotter,
return r0, r1
}
// GetDeleteItemActions provides a mock function with given fields:
func (_m *Manager) GetDeleteItemActions() ([]velero.DeleteItemAction, error) {
ret := _m.Called()
var r0 []velero.DeleteItemAction
if rf, ok := ret.Get(0).(func() []velero.DeleteItemAction); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]velero.DeleteItemAction)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetObjectStore provides a mock function with given fields: name
func (_m *Manager) GetObjectStore(name string) (velero.ObjectStore, error) {
ret := _m.Called(name)
@@ -169,3 +177,26 @@ func (_m *Manager) GetRestoreItemActions() ([]velero.RestoreItemAction, error) {
return r0, r1
}
// GetVolumeSnapshotter provides a mock function with given fields: name
func (_m *Manager) GetVolumeSnapshotter(name string) (velero.VolumeSnapshotter, error) {
ret := _m.Called(name)
var r0 velero.VolumeSnapshotter
if rf, ok := ret.Get(0).(func(string) velero.VolumeSnapshotter); ok {
r0 = rf(name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(velero.VolumeSnapshotter)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}

View File

@@ -0,0 +1,23 @@
syntax = "proto3";
package generated;
import "Shared.proto";
message DeleteItemActionExecuteRequest {
string plugin = 1;
bytes item = 2;
bytes backup = 3;
}
service DeleteItemAction {
rpc AppliesTo(DeleteItemActionAppliesToRequest) returns (DeleteItemActionAppliesToResponse);
rpc Execute(DeleteItemActionExecuteRequest) returns (Empty);
}
message DeleteItemActionAppliesToRequest {
string plugin = 1;
}
message DeleteItemActionAppliesToResponse {
ResourceSelector ResourceSelector = 1;
}

View File

@@ -0,0 +1,45 @@
/*
Copyright 2020 the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package velero
import (
"k8s.io/apimachinery/pkg/runtime"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
)
// DeleteItemAction is an actor that performs an operation on an individual item being restored.
type DeleteItemAction interface {
// AppliesTo returns information about which resources this action should be invoked for.
// A DeleteItemAction's Execute function will only be invoked on items that match the returned
// selector. A zero-valued ResourceSelector matches all resources.
AppliesTo() (ResourceSelector, error)
// Execute allows the ItemAction to perform arbitrary logic with the item being deleted.
// An error should be returned if there were problems with the deletion process, but the
// overall deletion process cannot be stopped.
// Returned errors are logged.
Execute(input *DeleteItemActionExecuteInput) error
}
// DeleteItemActionExecuteInput contains the input parameters for the ItemAction's Execute function.
type DeleteItemActionExecuteInput struct {
// Item is the item taken from the pristine backed up version of resource.
Item runtime.Unstructured
// Backup is the representation of the restore resource processed by Velero.
Backup *velerov1api.Backup
}

View File

@@ -0,0 +1,48 @@
// Code generated by mockery v2.1.0. DO NOT EDIT.
package mocks
import (
mock "github.com/stretchr/testify/mock"
velero "github.com/vmware-tanzu/velero/pkg/plugin/velero"
)
// DeleteItemAction is an autogenerated mock type for the DeleteItemAction type
type DeleteItemAction struct {
mock.Mock
}
// AppliesTo provides a mock function with given fields:
func (_m *DeleteItemAction) 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: input
func (_m *DeleteItemAction) Execute(input *velero.DeleteItemActionExecuteInput) error {
ret := _m.Called(input)
var r0 error
if rf, ok := ret.Get(0).(func(*velero.DeleteItemActionExecuteInput) error); ok {
r0 = rf(input)
} else {
r0 = ret.Error(0)
}
return r0
}