BackupItemAction v2 API implementation

Signed-off-by: Scott Seago <sseago@redhat.com>
pull/5442/head
Scott Seago 2022-09-01 14:36:35 -04:00
parent ffc9845fb9
commit 9a54142257
31 changed files with 2694 additions and 151 deletions

View File

@ -0,0 +1 @@
BackupItemAction v2 API implementation

View File

@ -69,8 +69,8 @@ One new shared message type will be added, as this will also be needed for v2 Re
message OperationProgress {
bool completed = 1;
string err = 2;
int64 completed = 3;
int64 total = 4;
int64 nCompleted = 3;
int64 nTotal = 4;
string operationUnits = 5;
string description = 6;
google.protobuf.Timestamp started = 7;

View File

@ -48,6 +48,10 @@ RUN apt-get update && apt-get install -y unzip
RUN wget --quiet https://github.com/protocolbuffers/protobuf/releases/download/v3.14.0/protoc-3.14.0-linux-x86_64.zip && \
unzip protoc-3.14.0-linux-x86_64.zip && \
mv bin/protoc /usr/bin/protoc && \
mv include/google /usr/include && \
chmod a+x /usr/include/google && \
chmod a+x /usr/include/google/protobuf && \
chmod a+r -R /usr/include/google && \
chmod +x /usr/bin/protoc
RUN go install github.com/golang/protobuf/protoc-gen-go@v1.4.3

View File

@ -19,6 +19,6 @@ HACK_DIR=$(dirname "${BASH_SOURCE}")
echo "Updating plugin proto"
echo protoc --version
protoc pkg/plugin/proto/*.proto --go_out=plugins=grpc:pkg/plugin/generated/ --go_opt=module=github.com/vmware-tanzu/velero/pkg/plugin/generated -I pkg/plugin/proto/
protoc pkg/plugin/proto/*.proto pkg/plugin/proto/*/*/*.proto --go_out=plugins=grpc:pkg/plugin/generated/ --go_opt=module=github.com/vmware-tanzu/velero/pkg/plugin/generated -I pkg/plugin/proto/ -I /usr/include
echo "Updating plugin proto - done!"

View File

@ -44,7 +44,7 @@ import (
velerov1client "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1"
"github.com/vmware-tanzu/velero/pkg/kuberesource"
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
biav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v1"
biav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
vsv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v1"
"github.com/vmware-tanzu/velero/pkg/podexec"
"github.com/vmware-tanzu/velero/pkg/podvolume"
@ -63,9 +63,9 @@ const BackupFormatVersion = "1.1.0"
type Backupper interface {
// Backup takes a backup using the specification in the velerov1api.Backup and writes backup and log data
// to the given writers.
Backup(logger logrus.FieldLogger, backup *Request, backupFile io.Writer, actions []biav1.BackupItemAction, volumeSnapshotterGetter VolumeSnapshotterGetter) error
Backup(logger logrus.FieldLogger, backup *Request, backupFile io.Writer, actions []biav2.BackupItemAction, volumeSnapshotterGetter VolumeSnapshotterGetter) error
BackupWithResolvers(log logrus.FieldLogger, backupRequest *Request, backupFile io.Writer,
backupItemActionResolver framework.BackupItemActionResolver, itemSnapshotterResolver framework.ItemSnapshotterResolver,
backupItemActionResolver framework.BackupItemActionResolverV2, itemSnapshotterResolver framework.ItemSnapshotterResolver,
volumeSnapshotterGetter VolumeSnapshotterGetter) error
}
@ -174,8 +174,8 @@ type VolumeSnapshotterGetter interface {
// back up individual resources that don't prevent the backup from continuing to be processed) are logged
// to the backup log.
func (kb *kubernetesBackupper) Backup(log logrus.FieldLogger, backupRequest *Request, backupFile io.Writer,
actions []biav1.BackupItemAction, volumeSnapshotterGetter VolumeSnapshotterGetter) error {
backupItemActions := framework.NewBackupItemActionResolver(actions)
actions []biav2.BackupItemAction, volumeSnapshotterGetter VolumeSnapshotterGetter) error {
backupItemActions := framework.NewBackupItemActionResolverV2(actions)
itemSnapshotters := framework.NewItemSnapshotterResolver(nil)
return kb.BackupWithResolvers(log, backupRequest, backupFile, backupItemActions, itemSnapshotters,
volumeSnapshotterGetter)
@ -184,7 +184,7 @@ func (kb *kubernetesBackupper) Backup(log logrus.FieldLogger, backupRequest *Req
func (kb *kubernetesBackupper) BackupWithResolvers(log logrus.FieldLogger,
backupRequest *Request,
backupFile io.Writer,
backupItemActionResolver framework.BackupItemActionResolver,
backupItemActionResolver framework.BackupItemActionResolverV2,
itemSnapshotterResolver framework.ItemSnapshotterResolver,
volumeSnapshotterGetter VolumeSnapshotterGetter) error {
gzippedData := gzip.NewWriter(backupFile)

View File

@ -47,7 +47,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/discovery"
"github.com/vmware-tanzu/velero/pkg/kuberesource"
"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"
vsv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v1"
"github.com/vmware-tanzu/velero/pkg/podvolume"
"github.com/vmware-tanzu/velero/pkg/test"
@ -1139,23 +1139,32 @@ type recordResourcesAction struct {
ids []string
backups []velerov1.Backup
additionalItems []velero.ResourceIdentifier
operationID string
}
func (a *recordResourcesAction) Execute(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
func (a *recordResourcesAction) Execute(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
metadata, err := meta.Accessor(item)
if err != nil {
return item, a.additionalItems, err
return item, a.additionalItems, a.operationID, err
}
a.ids = append(a.ids, kubeutil.NamespaceAndName(metadata))
a.backups = append(a.backups, *backup)
return item, a.additionalItems, nil
return item, a.additionalItems, a.operationID, nil
}
func (a *recordResourcesAction) AppliesTo() (velero.ResourceSelector, error) {
return a.selector, nil
}
func (a *recordResourcesAction) Progress(operationID string, backup *velerov1.Backup) (velero.OperationProgress, error) {
return velero.OperationProgress{}, nil
}
func (a *recordResourcesAction) Cancel(operationID string, backup *velerov1.Backup) error {
return nil
}
func (a *recordResourcesAction) ForResource(resource string) *recordResourcesAction {
a.selector.IncludedResources = append(a.selector.IncludedResources, resource)
return a
@ -1362,7 +1371,7 @@ func TestBackupActionsRunForCorrectItems(t *testing.T) {
h.addItems(t, resource)
}
actions := []biav1.BackupItemAction{}
actions := []biav2.BackupItemAction{}
for action := range tc.actions {
actions = append(actions, action)
}
@ -1388,7 +1397,7 @@ func TestBackupWithInvalidActions(t *testing.T) {
name string
backup *velerov1.Backup
apiResources []*test.APIResource
actions []biav1.BackupItemAction
actions []biav2.BackupItemAction
}{
{
name: "action with invalid label selector results in an error",
@ -1404,7 +1413,7 @@ func TestBackupWithInvalidActions(t *testing.T) {
builder.ForPersistentVolume("baz").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
new(recordResourcesAction).ForLabelSelector("=invalid-selector"),
},
},
@ -1422,7 +1431,7 @@ func TestBackupWithInvalidActions(t *testing.T) {
builder.ForPersistentVolume("baz").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
&appliesToErrorAction{},
},
},
@ -1453,7 +1462,15 @@ func (a *appliesToErrorAction) AppliesTo() (velero.ResourceSelector, error) {
return velero.ResourceSelector{}, errors.New("error calling AppliesTo")
}
func (a *appliesToErrorAction) Execute(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
func (a *appliesToErrorAction) Execute(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
panic("not implemented")
}
func (a *appliesToErrorAction) Progress(operationID string, backup *velerov1.Backup) (velero.OperationProgress, error) {
panic("not implemented")
}
func (a *appliesToErrorAction) Cancel(operationID string, backup *velerov1.Backup) error {
panic("not implemented")
}
@ -1466,16 +1483,16 @@ func TestBackupActionModifications(t *testing.T) {
// method modifies the item being passed in by calling the 'modify' function on it.
modifyingActionGetter := func(modify func(*unstructured.Unstructured)) *pluggableAction {
return &pluggableAction{
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
obj, ok := item.(*unstructured.Unstructured)
if !ok {
return nil, nil, errors.Errorf("unexpected type %T", item)
return nil, nil, "", errors.Errorf("unexpected type %T", item)
}
res := obj.DeepCopy()
modify(res)
return res, nil, nil
return res, nil, "", nil
},
}
}
@ -1484,7 +1501,7 @@ func TestBackupActionModifications(t *testing.T) {
name string
backup *velerov1.Backup
apiResources []*test.APIResource
actions []biav1.BackupItemAction
actions []biav2.BackupItemAction
want map[string]unstructuredObject
}{
{
@ -1495,7 +1512,7 @@ func TestBackupActionModifications(t *testing.T) {
builder.ForPod("ns-1", "pod-1").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
modifyingActionGetter(func(item *unstructured.Unstructured) {
item.SetLabels(map[string]string{"updated": "true"})
}),
@ -1512,7 +1529,7 @@ func TestBackupActionModifications(t *testing.T) {
builder.ForPod("ns-1", "pod-1").ObjectMeta(builder.WithLabels("should-be-removed", "true")).Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
modifyingActionGetter(func(item *unstructured.Unstructured) {
item.SetLabels(nil)
}),
@ -1529,7 +1546,7 @@ func TestBackupActionModifications(t *testing.T) {
builder.ForPod("ns-1", "pod-1").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
modifyingActionGetter(func(item *unstructured.Unstructured) {
item.Object["spec"].(map[string]interface{})["nodeName"] = "foo"
}),
@ -1547,7 +1564,7 @@ func TestBackupActionModifications(t *testing.T) {
builder.ForPod("ns-1", "pod-1").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
modifyingActionGetter(func(item *unstructured.Unstructured) {
item.SetName(item.GetName() + "-updated")
item.SetNamespace(item.GetNamespace() + "-updated")
@ -1588,7 +1605,7 @@ func TestBackupActionAdditionalItems(t *testing.T) {
name string
backup *velerov1.Backup
apiResources []*test.APIResource
actions []biav1.BackupItemAction
actions []biav2.BackupItemAction
want []string
}{
{
@ -1601,16 +1618,16 @@ func TestBackupActionAdditionalItems(t *testing.T) {
builder.ForPod("ns-3", "pod-3").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
&pluggableAction{
selector: velero.ResourceSelector{IncludedNamespaces: []string{"ns-1"}},
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
additionalItems := []velero.ResourceIdentifier{
{GroupResource: kuberesource.Pods, Namespace: "ns-2", Name: "pod-2"},
{GroupResource: kuberesource.Pods, Namespace: "ns-3", Name: "pod-3"},
}
return item, additionalItems, nil
return item, additionalItems, "", nil
},
},
},
@ -1633,15 +1650,15 @@ func TestBackupActionAdditionalItems(t *testing.T) {
builder.ForPod("ns-3", "pod-3").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
&pluggableAction{
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
additionalItems := []velero.ResourceIdentifier{
{GroupResource: kuberesource.Pods, Namespace: "ns-2", Name: "pod-2"},
{GroupResource: kuberesource.Pods, Namespace: "ns-3", Name: "pod-3"},
}
return item, additionalItems, nil
return item, additionalItems, "", nil
},
},
},
@ -1663,15 +1680,15 @@ func TestBackupActionAdditionalItems(t *testing.T) {
builder.ForPersistentVolume("pv-2").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
&pluggableAction{
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
additionalItems := []velero.ResourceIdentifier{
{GroupResource: kuberesource.PersistentVolumes, Name: "pv-1"},
{GroupResource: kuberesource.PersistentVolumes, Name: "pv-2"},
}
return item, additionalItems, nil
return item, additionalItems, "", nil
},
},
},
@ -1696,15 +1713,15 @@ func TestBackupActionAdditionalItems(t *testing.T) {
builder.ForPersistentVolume("pv-2").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
&pluggableAction{
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
additionalItems := []velero.ResourceIdentifier{
{GroupResource: kuberesource.PersistentVolumes, Name: "pv-1"},
{GroupResource: kuberesource.PersistentVolumes, Name: "pv-2"},
}
return item, additionalItems, nil
return item, additionalItems, "", nil
},
},
},
@ -1726,15 +1743,15 @@ func TestBackupActionAdditionalItems(t *testing.T) {
builder.ForPersistentVolume("pv-2").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
&pluggableAction{
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
additionalItems := []velero.ResourceIdentifier{
{GroupResource: kuberesource.PersistentVolumes, Name: "pv-1"},
{GroupResource: kuberesource.PersistentVolumes, Name: "pv-2"},
}
return item, additionalItems, nil
return item, additionalItems, "", nil
},
},
},
@ -1757,15 +1774,15 @@ func TestBackupActionAdditionalItems(t *testing.T) {
builder.ForPersistentVolume("pv-2").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
&pluggableAction{
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
additionalItems := []velero.ResourceIdentifier{
{GroupResource: kuberesource.PersistentVolumes, Name: "pv-1"},
{GroupResource: kuberesource.PersistentVolumes, Name: "pv-2"},
}
return item, additionalItems, nil
return item, additionalItems, "", nil
},
},
},
@ -1787,16 +1804,16 @@ func TestBackupActionAdditionalItems(t *testing.T) {
builder.ForPod("ns-3", "pod-3").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
&pluggableAction{
selector: velero.ResourceSelector{IncludedNamespaces: []string{"ns-1"}},
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
additionalItems := []velero.ResourceIdentifier{
{GroupResource: kuberesource.Pods, Namespace: "ns-4", Name: "pod-4"},
{GroupResource: kuberesource.Pods, Namespace: "ns-5", Name: "pod-5"},
}
return item, additionalItems, nil
return item, additionalItems, "", nil
},
},
},
@ -2727,12 +2744,12 @@ func TestBackupWithPodVolume(t *testing.T) {
// function body at runtime.
type pluggableAction struct {
selector velero.ResourceSelector
executeFunc func(runtime.Unstructured, *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error)
executeFunc func(runtime.Unstructured, *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error)
}
func (a *pluggableAction) Execute(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
func (a *pluggableAction) Execute(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
if a.executeFunc == nil {
return item, nil, nil
return item, nil, "", nil
}
return a.executeFunc(item, backup)
@ -2742,6 +2759,14 @@ func (a *pluggableAction) AppliesTo() (velero.ResourceSelector, error) {
return a.selector, nil
}
func (a *pluggableAction) Progress(operationID string, backup *velerov1.Backup) (velero.OperationProgress, error) {
return velero.OperationProgress{}, nil
}
func (a *pluggableAction) Cancel(operationID string, backup *velerov1.Backup) error {
return nil
}
type harness struct {
*test.APIServer
backupper *kubernetesBackupper

View File

@ -320,7 +320,9 @@ func (ib *itemBackupper) executeActions(
}
log.Info("Executing custom action")
updatedItem, additionalItemIdentifiers, err := action.Execute(obj, ib.backupRequest.Backup)
// Note: we're ignoring the operationID returned from Execute for now, it will be used
// with the async plugin action implementation
updatedItem, additionalItemIdentifiers, _, err := action.Execute(obj, ib.backupRequest.Backup)
if err != nil {
return nil, errors.Wrapf(err, "error executing custom action (groupResource=%s, namespace=%s, name=%s)", groupResource.String(), namespace, name)
}

View File

@ -45,7 +45,7 @@ type Request struct {
NamespaceIncludesExcludes *collections.IncludesExcludes
ResourceIncludesExcludes *collections.IncludesExcludes
ResourceHooks []hook.ResourceHook
ResolvedActions []framework.BackupItemResolvedAction
ResolvedActions []framework.BackupItemResolvedActionV2
ResolvedItemSnapshotters []framework.ItemSnapshotterResolvedAction
VolumeSnapshots []*volume.Snapshot
PodVolumeBackups []*velerov1api.PodVolumeBackup

View File

@ -620,7 +620,7 @@ func (c *backupController) runBackup(backup *pkgbackup.Request) error {
defer pluginManager.CleanupClients()
backupLog.Info("Getting backup item actions")
actions, err := pluginManager.GetBackupItemActions()
actions, err := pluginManager.GetBackupItemActionsV2()
if err != nil {
return err
}
@ -645,7 +645,7 @@ func (c *backupController) runBackup(backup *pkgbackup.Request) error {
return errors.Errorf("backup already exists in object storage")
}
backupItemActionsResolver := framework.NewBackupItemActionResolver(actions)
backupItemActionsResolver := framework.NewBackupItemActionResolverV2(actions)
itemSnapshottersResolver := framework.NewItemSnapshotterResolver(itemSnapshotters)
var fatalErrs []error

View File

@ -53,7 +53,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt"
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
pluginmocks "github.com/vmware-tanzu/velero/pkg/plugin/mocks"
biav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v1"
biav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
velerotest "github.com/vmware-tanzu/velero/pkg/test"
"github.com/vmware-tanzu/velero/pkg/util/boolptr"
"github.com/vmware-tanzu/velero/pkg/util/logging"
@ -63,13 +63,13 @@ type fakeBackupper struct {
mock.Mock
}
func (b *fakeBackupper) Backup(logger logrus.FieldLogger, backup *pkgbackup.Request, backupFile io.Writer, actions []biav1.BackupItemAction, volumeSnapshotterGetter pkgbackup.VolumeSnapshotterGetter) error {
func (b *fakeBackupper) Backup(logger logrus.FieldLogger, backup *pkgbackup.Request, backupFile io.Writer, actions []biav2.BackupItemAction, volumeSnapshotterGetter pkgbackup.VolumeSnapshotterGetter) error {
args := b.Called(logger, backup, backupFile, actions, volumeSnapshotterGetter)
return args.Error(0)
}
func (b *fakeBackupper) BackupWithResolvers(logger logrus.FieldLogger, backup *pkgbackup.Request, backupFile io.Writer,
backupItemActionResolver framework.BackupItemActionResolver, itemSnapshotterResolver framework.ItemSnapshotterResolver,
backupItemActionResolver framework.BackupItemActionResolverV2, itemSnapshotterResolver framework.ItemSnapshotterResolver,
volumeSnapshotterGetter pkgbackup.VolumeSnapshotterGetter) error {
args := b.Called(logger, backup, backupFile, backupItemActionResolver, itemSnapshotterResolver, volumeSnapshotterGetter)
return args.Error(0)
@ -1070,11 +1070,11 @@ func TestProcessBackupCompletions(t *testing.T) {
formatFlag: formatFlag,
}
pluginManager.On("GetBackupItemActions").Return(nil, nil)
pluginManager.On("GetBackupItemActionsV2").Return(nil, nil)
pluginManager.On("CleanupClients").Return(nil)
pluginManager.On("GetItemSnapshotters").Return(nil, nil)
backupper.On("Backup", mock.Anything, mock.Anything, mock.Anything, []biav1.BackupItemAction(nil), pluginManager).Return(nil)
backupper.On("BackupWithResolvers", mock.Anything, mock.Anything, mock.Anything, framework.BackupItemActionResolver{}, framework.ItemSnapshotterResolver{}, pluginManager).Return(nil)
backupper.On("Backup", mock.Anything, mock.Anything, mock.Anything, []biav2.BackupItemAction(nil), pluginManager).Return(nil)
backupper.On("BackupWithResolvers", mock.Anything, mock.Anything, mock.Anything, framework.BackupItemActionResolverV2{}, framework.ItemSnapshotterResolver{}, pluginManager).Return(nil)
backupStore.On("BackupExists", test.backupLocation.Spec.StorageType.ObjectStorage.Bucket, test.backup.Name).Return(test.backupExists, test.existenceCheckError)
// Ensure we have a CompletionTimestamp when uploading and that the backup name matches the backup in the object store.

View File

@ -0,0 +1,171 @@
/*
Copyright 2018 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 v2
import (
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/runtime"
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
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/common"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
biav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
)
// AdaptedBackupItemAction is a v1 BackupItemAction adapted to implement the v2 API
type AdaptedBackupItemAction struct {
Kind common.PluginKind
// Get returns a restartable BackupItemAction for the given name and process, wrapping if necessary
GetRestartable func(name string, restartableProcess process.RestartableProcess) biav2.BackupItemAction
}
func AdaptedBackupItemActions() []AdaptedBackupItemAction {
return []AdaptedBackupItemAction{
{
Kind: common.PluginKindBackupItemActionV2,
GetRestartable: func(name string, restartableProcess process.RestartableProcess) biav2.BackupItemAction {
return NewRestartableBackupItemAction(name, restartableProcess)
},
},
{
Kind: common.PluginKindBackupItemAction,
GetRestartable: func(name string, restartableProcess process.RestartableProcess) biav2.BackupItemAction {
return NewAdaptedV1RestartableBackupItemAction(biav1cli.NewRestartableBackupItemAction(name, restartableProcess))
},
},
}
}
// restartableBackupItemAction is a backup 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 restartableBackupItemAction 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 RestartableBackupItemAction struct {
Key process.KindAndName
SharedPluginProcess process.RestartableProcess
}
// NewRestartableBackupItemAction returns a new RestartableBackupItemAction.
func NewRestartableBackupItemAction(name string, sharedPluginProcess process.RestartableProcess) *RestartableBackupItemAction {
r := &RestartableBackupItemAction{
Key: process.KindAndName{Kind: common.PluginKindBackupItemActionV2, Name: name},
SharedPluginProcess: sharedPluginProcess,
}
return r
}
// getBackupItemAction returns the backup item action for this restartableBackupItemAction. It does *not* restart the
// plugin process.
func (r *RestartableBackupItemAction) getBackupItemAction() (biav2.BackupItemAction, error) {
plugin, err := r.SharedPluginProcess.GetByKindAndName(r.Key)
if err != nil {
return nil, err
}
backupItemAction, ok := plugin.(biav2.BackupItemAction)
if !ok {
return nil, errors.Errorf("%T (returned for %v) is not a BackupItemActionV2!", plugin, r.Key)
}
return backupItemAction, nil
}
// getDelegate restarts the plugin process (if needed) and returns the backup item action for this restartableBackupItemAction.
func (r *RestartableBackupItemAction) getDelegate() (biav2.BackupItemAction, error) {
if err := r.SharedPluginProcess.ResetIfNeeded(); err != nil {
return nil, err
}
return r.getBackupItemAction()
}
// AppliesTo restarts the plugin's process if needed, then delegates the call.
func (r *RestartableBackupItemAction) 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 *RestartableBackupItemAction) Execute(item runtime.Unstructured, backup *api.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
delegate, err := r.getDelegate()
if err != nil {
return nil, nil, "", err
}
return delegate.Execute(item, backup)
}
// Progress restarts the plugin's process if needed, then delegates the call.
func (r *RestartableBackupItemAction) Progress(operationID string, backup *api.Backup) (velero.OperationProgress, error) {
delegate, err := r.getDelegate()
if err != nil {
return velero.OperationProgress{}, err
}
return delegate.Progress(operationID, backup)
}
// Cancel restarts the plugin's process if needed, then delegates the call.
func (r *RestartableBackupItemAction) Cancel(operationID string, backup *api.Backup) error {
delegate, err := r.getDelegate()
if err != nil {
return err
}
return delegate.Cancel(operationID, backup)
}
type AdaptedV1RestartableBackupItemAction struct {
V1Restartable *biav1cli.RestartableBackupItemAction
}
// NewAdaptedV1RestartableBackupItemAction returns a new v1 RestartableBackupItemAction adapted to v2
func NewAdaptedV1RestartableBackupItemAction(v1Restartable *biav1cli.RestartableBackupItemAction) *AdaptedV1RestartableBackupItemAction {
r := &AdaptedV1RestartableBackupItemAction{
V1Restartable: v1Restartable,
}
return r
}
// AppliesTo delegates to the v1 AppliesTo call.
func (r *AdaptedV1RestartableBackupItemAction) AppliesTo() (velero.ResourceSelector, error) {
return r.V1Restartable.AppliesTo()
}
// Execute delegates to the v1 Execute call, returning an empty operationID.
func (r *AdaptedV1RestartableBackupItemAction) Execute(item runtime.Unstructured, backup *api.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
updatedItem, additionalItems, err := r.V1Restartable.Execute(item, backup)
return updatedItem, additionalItems, "", err
}
// Progress returns with an error since v1 plugins will never return an operationID, which means that
// any operationID passed in here will be invalid.
func (r *AdaptedV1RestartableBackupItemAction) Progress(operationID string, backup *api.Backup) (velero.OperationProgress, error) {
return velero.OperationProgress{}, biav2.AsyncOperationsNotSupportedError()
}
// Cancel just returns without error since v1 plugins don't implement it.
func (r *AdaptedV1RestartableBackupItemAction) Cancel(operationID string, backup *api.Backup) error {
return nil
}

View File

@ -0,0 +1,164 @@
/*
Copyright 2018 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 v2
import (
"testing"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"github.com/vmware-tanzu/velero/internal/restartabletest"
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/common"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
mocksv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/mocks/backupitemaction/v2"
)
func TestRestartableGetBackupItemAction(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 (returned for {BackupItemActionV2 pod}) is not a BackupItemActionV2!",
},
{
name: "happy path",
plugin: new(mocksv2.BackupItemAction),
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
p := new(restartabletest.MockRestartableProcess)
defer p.AssertExpectations(t)
name := "pod"
key := process.KindAndName{Kind: common.PluginKindBackupItemActionV2, Name: name}
p.On("GetByKindAndName", key).Return(tc.plugin, tc.getError)
r := NewRestartableBackupItemAction(name, p)
a, err := r.getBackupItemAction()
if tc.expectedError != "" {
assert.EqualError(t, err, tc.expectedError)
return
}
require.NoError(t, err)
assert.Equal(t, tc.plugin, a)
})
}
}
func TestRestartableBackupItemActionGetDelegate(t *testing.T) {
p := new(restartabletest.MockRestartableProcess)
defer p.AssertExpectations(t)
// Reset error
p.On("ResetIfNeeded").Return(errors.Errorf("reset error")).Once()
name := "pod"
r := NewRestartableBackupItemAction(name, p)
a, err := r.getDelegate()
assert.Nil(t, a)
assert.EqualError(t, err, "reset error")
// Happy path
p.On("ResetIfNeeded").Return(nil)
expected := new(mocksv2.BackupItemAction)
key := process.KindAndName{Kind: common.PluginKindBackupItemActionV2, Name: name}
p.On("GetByKindAndName", key).Return(expected, nil)
a, err = r.getDelegate()
assert.NoError(t, err)
assert.Equal(t, expected, a)
}
func TestRestartableBackupItemActionDelegatedFunctions(t *testing.T) {
b := new(v1.Backup)
pv := &unstructured.Unstructured{
Object: map[string]interface{}{
"color": "blue",
},
}
oid := "operation1"
pvToReturn := &unstructured.Unstructured{
Object: map[string]interface{}{
"color": "green",
},
}
additionalItems := []velero.ResourceIdentifier{
{
GroupResource: schema.GroupResource{Group: "velero.io", Resource: "backups"},
},
}
restartabletest.RunRestartableDelegateTests(
t,
common.PluginKindBackupItemAction,
func(key process.KindAndName, p process.RestartableProcess) interface{} {
return &RestartableBackupItemAction{
Key: key,
SharedPluginProcess: p,
}
},
func() restartabletest.Mockable {
return new(mocksv2.BackupItemAction)
},
restartabletest.RestartableDelegateTest{
Function: "AppliesTo",
Inputs: []interface{}{},
ExpectedErrorOutputs: []interface{}{velero.ResourceSelector{}, errors.Errorf("reset error")},
ExpectedDelegateOutputs: []interface{}{velero.ResourceSelector{IncludedNamespaces: []string{"a"}}, errors.Errorf("delegate error")},
},
restartabletest.RestartableDelegateTest{
Function: "Execute",
Inputs: []interface{}{pv, b},
ExpectedErrorOutputs: []interface{}{nil, ([]velero.ResourceIdentifier)(nil), "", errors.Errorf("reset error")},
ExpectedDelegateOutputs: []interface{}{pvToReturn, additionalItems, "", errors.Errorf("delegate error")},
},
restartabletest.RestartableDelegateTest{
Function: "Progress",
Inputs: []interface{}{oid, b},
ExpectedErrorOutputs: []interface{}{velero.OperationProgress{}, errors.Errorf("reset error")},
ExpectedDelegateOutputs: []interface{}{velero.OperationProgress{}, errors.Errorf("delegate error")},
},
restartabletest.RestartableDelegateTest{
Function: "Cancel",
Inputs: []interface{}{oid, b},
ExpectedErrorOutputs: []interface{}{errors.Errorf("reset error")},
ExpectedDelegateOutputs: []interface{}{errors.Errorf("delegate error")},
},
)
}

View File

@ -25,12 +25,14 @@ import (
"github.com/sirupsen/logrus"
biav1cli "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/backupitemaction/v1"
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"
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"
vsv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v1"
@ -50,6 +52,12 @@ type Manager interface {
// GetBackupItemAction returns the backup item action plugin for name.
GetBackupItemAction(name string) (biav1.BackupItemAction, error)
// GetBackupItemActionsV2 returns all v2 backup item action plugins (including those adapted from v1).
GetBackupItemActionsV2() ([]biav2.BackupItemAction, error)
// GetBackupItemActionV2 returns the backup item action plugin for name.
GetBackupItemActionV2(name string) (biav2.BackupItemAction, error)
// GetRestoreItemActions returns all restore item action plugins.
GetRestoreItemActions() ([]riav1.RestoreItemAction, error)
@ -218,6 +226,44 @@ func (m *manager) GetBackupItemAction(name string) (biav1.BackupItemAction, erro
return nil, fmt.Errorf("unable to get valid BackupItemAction for %q", name)
}
// GetBackupItemActionsV2 returns all v2 backup item actions as RestartableBackupItemActions.
func (m *manager) GetBackupItemActionsV2() ([]biav2.BackupItemAction, error) {
list := m.registry.List(common.PluginKindBackupItemActionV2)
actions := make([]biav2.BackupItemAction, 0, len(list))
for i := range list {
id := list[i]
r, err := m.GetBackupItemActionV2(id.Name)
if err != nil {
return nil, err
}
actions = append(actions, r)
}
return actions, nil
}
// GetBackupItemActionV2 returns a v2 restartableBackupItemAction for name.
func (m *manager) GetBackupItemActionV2(name string) (biav2.BackupItemAction, error) {
name = sanitizeName(name)
for _, adaptedBackupItemAction := range biav2cli.AdaptedBackupItemActions() {
restartableProcess, err := m.getRestartableProcess(adaptedBackupItemAction.Kind, name)
// Check if plugin was not found
if errors.As(err, &pluginNotFoundErrType) {
continue
}
if err != nil {
return nil, err
}
return adaptedBackupItemAction.GetRestartable(name, restartableProcess), nil
}
return nil, fmt.Errorf("unable to get valid BackupItemActionV2 for %q", name)
}
// GetRestoreItemActions returns all restore item actions as restartableRestoreItemActions.
func (m *manager) GetRestoreItemActions() ([]riav1.RestoreItemAction, error) {
list := m.registry.List(common.PluginKindRestoreItemAction)

View File

@ -28,6 +28,7 @@ import (
"github.com/vmware-tanzu/velero/internal/restartabletest"
biav1cli "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/backupitemaction/v1"
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"
vsv1cli "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/volumesnapshotter/v1"
@ -203,6 +204,23 @@ func TestGetBackupItemAction(t *testing.T) {
)
}
func TestGetBackupItemActionV2(t *testing.T) {
getPluginTest(t,
common.PluginKindBackupItemActionV2,
"velero.io/pod",
func(m Manager, name string) (interface{}, error) {
return m.GetBackupItemActionV2(name)
},
func(name string, sharedPluginProcess process.RestartableProcess) interface{} {
return &biav2cli.RestartableBackupItemAction{
Key: process.KindAndName{Kind: common.PluginKindBackupItemActionV2, Name: name},
SharedPluginProcess: sharedPluginProcess,
}
},
false,
)
}
func TestGetRestoreItemAction(t *testing.T) {
getPluginTest(t,
common.PluginKindRestoreItemAction,
@ -363,6 +381,98 @@ func TestGetBackupItemActions(t *testing.T) {
}
}
func TestGetBackupItemActionsV2(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.PluginKindBackupItemActionV2
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 := &biav2cli.RestartableBackupItemAction{
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)
}
backupItemActions, err := m.GetBackupItemActionsV2()
if tc.newRestartableProcessError != nil {
assert.Nil(t, backupItemActions)
assert.EqualError(t, err, "NewRestartableProcess")
} else {
require.NoError(t, err)
var actual []interface{}
for i := range backupItemActions {
actual = append(actual, backupItemActions[i])
}
assert.Equal(t, expectedActions, actual)
}
})
}
}
func TestGetRestoreItemActions(t *testing.T) {
tests := []struct {
name string

View File

@ -27,6 +27,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/features"
"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"
)
@ -68,13 +69,14 @@ 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.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.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

View File

@ -27,6 +27,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/features"
"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"
"github.com/vmware-tanzu/velero/pkg/test"
)
@ -61,13 +62,14 @@ 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.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.PluginKindDeleteItemAction): framework.NewDeleteItemActionPlugin(common.ClientLogger(logger)),
string(common.PluginKindItemSnapshotter): framework.NewItemSnapshotterPlugin(common.ClientLogger(logger)),
},
Logger: cb.pluginLogger,
Cmd: exec.Command(cb.commandName, cb.commandArgs...),

View File

@ -17,6 +17,7 @@ limitations under the License.
package framework
import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
@ -25,6 +26,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/discovery"
"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"
"github.com/vmware-tanzu/velero/pkg/util/collections"
@ -109,6 +111,17 @@ func NewBackupItemActionResolver(actions []biav1.BackupItemAction) BackupItemAct
}
}
type BackupItemResolvedActionV2 struct {
biav2.BackupItemAction
resolvedAction
}
func NewBackupItemActionResolverV2(actions []biav2.BackupItemAction) BackupItemActionResolverV2 {
return BackupItemActionResolverV2{
actions: actions,
}
}
func NewRestoreItemActionResolver(actions []riav1.RestoreItemAction) RestoreItemActionResolver {
return RestoreItemActionResolver{
actions: actions,
@ -155,6 +168,32 @@ func (recv BackupItemActionResolver) ResolveActions(helper discovery.Helper, log
return resolved, nil
}
type BackupItemActionResolverV2 struct {
actions []biav2.BackupItemAction
}
func (recv BackupItemActionResolverV2) ResolveActions(helper discovery.Helper, log logrus.FieldLogger) ([]BackupItemResolvedActionV2, error) {
var resolved []BackupItemResolvedActionV2
for _, action := range recv.actions {
log.Debugf("resolving BackupItemAction for: %v", action)
resources, namespaces, selector, err := resolveAction(helper, action)
if err != nil {
log.WithError(errors.WithStack(err)).Debugf("resolveAction error, action: %v", action)
return nil, err
}
res := BackupItemResolvedActionV2{
BackupItemAction: action,
resolvedAction: resolvedAction{
ResourceIncludesExcludes: resources,
NamespaceIncludesExcludes: namespaces,
Selector: selector,
},
}
resolved = append(resolved, res)
}
return resolved, nil
}
type RestoreItemResolvedAction struct {
riav1.RestoreItemAction
resolvedAction

View File

@ -0,0 +1,45 @@
/*
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.
*/
package v2
import (
plugin "github.com/hashicorp/go-plugin"
"golang.org/x/net/context"
"google.golang.org/grpc"
"github.com/vmware-tanzu/velero/pkg/plugin/framework/common"
protobiav2 "github.com/vmware-tanzu/velero/pkg/plugin/generated/backupitemaction/v2"
)
// BackupItemActionPlugin is an implementation of go-plugin's Plugin
// interface with support for gRPC for the backup/ItemAction
// interface.
type BackupItemActionPlugin struct {
plugin.NetRPCUnsupportedPlugin
*common.PluginBase
}
// GRPCClient returns a clientDispenser for BackupItemAction gRPC clients.
func (p *BackupItemActionPlugin) GRPCClient(_ context.Context, _ *plugin.GRPCBroker, clientConn *grpc.ClientConn) (interface{}, error) {
return common.NewClientDispenser(p.ClientLogger, clientConn, newBackupItemActionGRPCClient), nil
}
// GRPCServer registers a BackupItemAction gRPC server.
func (p *BackupItemActionPlugin) GRPCServer(_ *plugin.GRPCBroker, server *grpc.Server) error {
protobiav2.RegisterBackupItemActionServer(server, &BackupItemActionGRPCServer{mux: p.ServerMux})
return nil
}

View File

@ -0,0 +1,169 @@
/*
Copyright 2017, 2019 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 v2
import (
"encoding/json"
"github.com/pkg/errors"
"golang.org/x/net/context"
"google.golang.org/grpc"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"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"
protobiav2 "github.com/vmware-tanzu/velero/pkg/plugin/generated/backupitemaction/v2"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
)
// NewBackupItemActionPlugin constructs a BackupItemActionPlugin.
func NewBackupItemActionPlugin(options ...common.PluginOption) *BackupItemActionPlugin {
return &BackupItemActionPlugin{
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 {
*common.ClientBase
grpcClient protobiav2.BackupItemActionClient
}
func newBackupItemActionGRPCClient(base *common.ClientBase, clientConn *grpc.ClientConn) interface{} {
return &BackupItemActionGRPCClient{
ClientBase: base,
grpcClient: protobiav2.NewBackupItemActionClient(clientConn),
}
}
func (c *BackupItemActionGRPCClient) AppliesTo() (velero.ResourceSelector, error) {
req := &protobiav2.BackupItemActionAppliesToRequest{
Plugin: c.Plugin,
}
res, err := c.grpcClient.AppliesTo(context.Background(), req)
if err != nil {
return velero.ResourceSelector{}, common.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 *BackupItemActionGRPCClient) Execute(item runtime.Unstructured, backup *api.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
itemJSON, err := json.Marshal(item.UnstructuredContent())
if err != nil {
return nil, nil, "", errors.WithStack(err)
}
backupJSON, err := json.Marshal(backup)
if err != nil {
return nil, nil, "", errors.WithStack(err)
}
req := &protobiav2.ExecuteRequest{
Plugin: c.Plugin,
Item: itemJSON,
Backup: backupJSON,
}
res, err := c.grpcClient.Execute(context.Background(), req)
if err != nil {
return nil, nil, "", common.FromGRPCError(err)
}
var updatedItem unstructured.Unstructured
if err := json.Unmarshal(res.Item, &updatedItem); err != nil {
return nil, nil, "", errors.WithStack(err)
}
var additionalItems []velero.ResourceIdentifier
for _, itm := range res.AdditionalItems {
newItem := velero.ResourceIdentifier{
GroupResource: schema.GroupResource{
Group: itm.Group,
Resource: itm.Resource,
},
Namespace: itm.Namespace,
Name: itm.Name,
}
additionalItems = append(additionalItems, newItem)
}
return &updatedItem, additionalItems, res.OperationID, nil
}
func (c *BackupItemActionGRPCClient) Progress(operationID string, backup *api.Backup) (velero.OperationProgress, error) {
backupJSON, err := json.Marshal(backup)
if err != nil {
return velero.OperationProgress{}, errors.WithStack(err)
}
req := &protobiav2.BackupItemActionProgressRequest{
Plugin: c.Plugin,
OperationID: operationID,
Backup: backupJSON,
}
res, err := c.grpcClient.Progress(context.Background(), req)
if err != nil {
return velero.OperationProgress{}, common.FromGRPCError(err)
}
return velero.OperationProgress{
Completed: res.Progress.Completed,
Err: res.Progress.Err,
NCompleted: res.Progress.NCompleted,
NTotal: res.Progress.NTotal,
OperationUnits: res.Progress.OperationUnits,
Description: res.Progress.Description,
Started: res.Progress.Started.AsTime(),
Updated: res.Progress.Updated.AsTime(),
}, nil
}
func (c *BackupItemActionGRPCClient) Cancel(operationID string, backup *api.Backup) error {
backupJSON, err := json.Marshal(backup)
if err != nil {
return errors.WithStack(err)
}
req := &protobiav2.BackupItemActionCancelRequest{
Plugin: c.Plugin,
OperationID: operationID,
Backup: backupJSON,
}
_, err = c.grpcClient.Cancel(context.Background(), req)
if err != nil {
return common.FromGRPCError(err)
}
return nil
}

View File

@ -0,0 +1,212 @@
/*
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.
*/
package v2
import (
"encoding/json"
"github.com/pkg/errors"
"golang.org/x/net/context"
"google.golang.org/protobuf/types/known/emptypb"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
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"
protobiav2 "github.com/vmware-tanzu/velero/pkg/plugin/generated/backupitemaction/v2"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
biav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
)
// 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 *common.ServerMux
}
func (s *BackupItemActionGRPCServer) getImpl(name string) (biav2.BackupItemAction, error) {
impl, err := s.mux.GetHandler(name)
if err != nil {
return nil, err
}
itemAction, ok := impl.(biav2.BackupItemAction)
if !ok {
return nil, errors.Errorf("%T is not a backup item action", impl)
}
return itemAction, nil
}
func (s *BackupItemActionGRPCServer) AppliesTo(
ctx context.Context, req *protobiav2.BackupItemActionAppliesToRequest) (
response *protobiav2.BackupItemActionAppliesToResponse, err error) {
defer func() {
if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil {
err = recoveredErr
}
}()
impl, err := s.getImpl(req.Plugin)
if err != nil {
return nil, common.NewGRPCError(err)
}
resourceSelector, err := impl.AppliesTo()
if err != nil {
return nil, common.NewGRPCError(err)
}
return &protobiav2.BackupItemActionAppliesToResponse{
ResourceSelector: &proto.ResourceSelector{
IncludedNamespaces: resourceSelector.IncludedNamespaces,
ExcludedNamespaces: resourceSelector.ExcludedNamespaces,
IncludedResources: resourceSelector.IncludedResources,
ExcludedResources: resourceSelector.ExcludedResources,
Selector: resourceSelector.LabelSelector,
},
}, nil
}
func (s *BackupItemActionGRPCServer) Execute(
ctx context.Context, req *protobiav2.ExecuteRequest) (response *protobiav2.ExecuteResponse, err error) {
defer func() {
if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil {
err = recoveredErr
}
}()
impl, err := s.getImpl(req.Plugin)
if err != nil {
return nil, common.NewGRPCError(err)
}
var item unstructured.Unstructured
var backup api.Backup
if err := json.Unmarshal(req.Item, &item); err != nil {
return nil, common.NewGRPCError(errors.WithStack(err))
}
if err := json.Unmarshal(req.Backup, &backup); err != nil {
return nil, common.NewGRPCError(errors.WithStack(err))
}
updatedItem, additionalItems, operationID, err := impl.Execute(&item, &backup)
if err != nil {
return nil, common.NewGRPCError(err)
}
// If the plugin implementation returned a nil updatedItem (meaning no modifications), reset updatedItem to the
// original item.
var updatedItemJSON []byte
if updatedItem == nil {
updatedItemJSON = req.Item
} else {
updatedItemJSON, err = json.Marshal(updatedItem.UnstructuredContent())
if err != nil {
return nil, common.NewGRPCError(errors.WithStack(err))
}
}
res := &protobiav2.ExecuteResponse{
Item: updatedItemJSON,
OperationID: operationID,
}
for _, item := range additionalItems {
res.AdditionalItems = append(res.AdditionalItems, backupResourceIdentifierToProto(item))
}
return res, nil
}
func (s *BackupItemActionGRPCServer) Progress(
ctx context.Context, req *protobiav2.BackupItemActionProgressRequest) (
response *protobiav2.BackupItemActionProgressResponse, err error) {
defer func() {
if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil {
err = recoveredErr
}
}()
impl, err := s.getImpl(req.Plugin)
if err != nil {
return nil, common.NewGRPCError(err)
}
var backup api.Backup
if err := json.Unmarshal(req.Backup, &backup); err != nil {
return nil, common.NewGRPCError(errors.WithStack(err))
}
progress, err := impl.Progress(req.OperationID, &backup)
if err != nil {
return nil, common.NewGRPCError(err)
}
res := &protobiav2.BackupItemActionProgressResponse{
Progress: &proto.OperationProgress{
Completed: progress.Completed,
Err: progress.Err,
NCompleted: progress.NCompleted,
NTotal: progress.NTotal,
OperationUnits: progress.OperationUnits,
Description: progress.Description,
Started: timestamppb.New(progress.Started),
Updated: timestamppb.New(progress.Updated),
},
}
return res, nil
}
func (s *BackupItemActionGRPCServer) Cancel(
ctx context.Context, req *protobiav2.BackupItemActionCancelRequest) (
response *emptypb.Empty, err error) {
defer func() {
if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil {
err = recoveredErr
}
}()
impl, err := s.getImpl(req.Plugin)
if err != nil {
return nil, common.NewGRPCError(err)
}
var backup api.Backup
if err := json.Unmarshal(req.Backup, &backup); err != nil {
return nil, common.NewGRPCError(errors.WithStack(err))
}
err = impl.Cancel(req.OperationID, &backup)
if err != nil {
return nil, common.NewGRPCError(err)
}
return &emptypb.Empty{}, nil
}
func backupResourceIdentifierToProto(id velero.ResourceIdentifier) *proto.ResourceIdentifier {
return &proto.ResourceIdentifier{
Group: id.Group,
Resource: id.Resource,
Namespace: id.Namespace,
Name: id.Name,
}
}

View File

@ -0,0 +1,202 @@
/*
Copyright 2018 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 v2
import (
"encoding/json"
"testing"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
v1 "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"
protobiav2 "github.com/vmware-tanzu/velero/pkg/plugin/generated/backupitemaction/v2"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
mocks "github.com/vmware-tanzu/velero/pkg/plugin/velero/mocks/backupitemaction/v2"
velerotest "github.com/vmware-tanzu/velero/pkg/test"
)
func TestBackupItemActionGRPCServerExecute(t *testing.T) {
invalidItem := []byte("this is gibberish json")
validItem := []byte(`
{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"namespace": "myns",
"name": "myconfigmap"
},
"data": {
"key": "value"
}
}`)
var validItemObject unstructured.Unstructured
err := json.Unmarshal(validItem, &validItemObject)
require.NoError(t, err)
updatedItem := []byte(`
{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"namespace": "myns",
"name": "myconfigmap"
},
"data": {
"key": "changed!"
}
}`)
var updatedItemObject unstructured.Unstructured
err = json.Unmarshal(updatedItem, &updatedItemObject)
require.NoError(t, err)
invalidBackup := []byte("this is gibberish json")
validBackup := []byte(`
{
"apiVersion": "velero.io/v1",
"kind": "Backup",
"metadata": {
"namespace": "myns",
"name": "mybackup"
},
"spec": {
"includedNamespaces": ["*"],
"includedResources": ["*"],
"ttl": "60m"
}
}`)
var validBackupObject v1.Backup
err = json.Unmarshal(validBackup, &validBackupObject)
require.NoError(t, err)
tests := []struct {
name string
backup []byte
item []byte
implUpdatedItem runtime.Unstructured
implAdditionalItems []velero.ResourceIdentifier
implOperationID string
implError error
expectError bool
skipMock bool
}{
{
name: "error unmarshaling item",
item: invalidItem,
backup: validBackup,
expectError: true,
skipMock: true,
},
{
name: "error unmarshaling backup",
item: validItem,
backup: invalidBackup,
expectError: true,
skipMock: true,
},
{
name: "error running impl",
item: validItem,
backup: validBackup,
implError: errors.New("impl error"),
expectError: true,
},
{
name: "nil updatedItem / no additionalItems",
item: validItem,
backup: validBackup,
},
{
name: "same updatedItem / some additionalItems",
item: validItem,
backup: validBackup,
implUpdatedItem: &validItemObject,
implAdditionalItems: []velero.ResourceIdentifier{
{
GroupResource: schema.GroupResource{Group: "v1", Resource: "pods"},
Namespace: "myns",
Name: "mypod",
},
},
},
{
name: "different updatedItem",
item: validItem,
backup: validBackup,
implUpdatedItem: &updatedItemObject,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
itemAction := &mocks.BackupItemAction{}
defer itemAction.AssertExpectations(t)
if !test.skipMock {
itemAction.On("Execute", &validItemObject, &validBackupObject).Return(test.implUpdatedItem, test.implAdditionalItems, test.implOperationID, test.implError)
}
s := &BackupItemActionGRPCServer{mux: &common.ServerMux{
ServerLog: velerotest.NewLogger(),
Handlers: map[string]interface{}{
"xyz": itemAction,
},
}}
req := &protobiav2.ExecuteRequest{
Plugin: "xyz",
Item: test.item,
Backup: test.backup,
}
resp, err := s.Execute(context.Background(), req)
// Verify error
assert.Equal(t, test.expectError, err != nil)
if err != nil {
return
}
require.NotNil(t, resp)
// Verify updated item
updatedItem := test.implUpdatedItem
if updatedItem == nil {
// If the impl returned nil for its updatedItem, we should expect the plugin to return the original item
updatedItem = &validItemObject
}
var respItem unstructured.Unstructured
err = json.Unmarshal(resp.Item, &respItem)
require.NoError(t, err)
assert.Equal(t, updatedItem, &respItem)
// Verify additional items
var expectedAdditionalItems []*proto.ResourceIdentifier
for _, item := range test.implAdditionalItems {
expectedAdditionalItems = append(expectedAdditionalItems, backupResourceIdentifierToProto(item))
}
assert.Equal(t, expectedAdditionalItems, resp.AdditionalItems)
})
}
}

View File

@ -35,6 +35,9 @@ const (
// PluginKindBackupItemAction represents a backup item action plugin.
PluginKindBackupItemAction PluginKind = "BackupItemAction"
// PluginKindBackupItemActionV2 represents a v2 backup item action plugin.
PluginKindBackupItemActionV2 PluginKind = "BackupItemActionV2"
// PluginKindRestoreItemAction represents a restore item action plugin.
PluginKindRestoreItemAction PluginKind = "RestoreItemAction"
@ -51,7 +54,9 @@ const (
// 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{}
var PluginKindsAdaptableTo = map[PluginKind][]PluginKind{
PluginKindBackupItemAction: {PluginKindBackupItemActionV2},
}
// 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).
@ -60,6 +65,7 @@ func AllPluginKinds() map[string]PluginKind {
allPluginKinds[PluginKindObjectStore.String()] = PluginKindObjectStore
allPluginKinds[PluginKindVolumeSnapshotter.String()] = PluginKindVolumeSnapshotter
allPluginKinds[PluginKindBackupItemAction.String()] = PluginKindBackupItemAction
allPluginKinds[PluginKindBackupItemActionV2.String()] = PluginKindBackupItemActionV2
allPluginKinds[PluginKindRestoreItemAction.String()] = PluginKindRestoreItemAction
allPluginKinds[PluginKindDeleteItemAction.String()] = PluginKindDeleteItemAction
allPluginKinds[PluginKindItemSnapshotter.String()] = PluginKindItemSnapshotter

View File

@ -25,6 +25,7 @@ import (
"github.com/sirupsen/logrus"
"github.com/spf13/pflag"
biav2 "github.com/vmware-tanzu/velero/pkg/plugin/framework/backupitemaction/v2"
"github.com/vmware-tanzu/velero/pkg/plugin/framework/common"
"github.com/vmware-tanzu/velero/pkg/util/logging"
)
@ -46,6 +47,13 @@ type Server interface {
// RegisterBackupItemActions registers multiple backup item actions.
RegisterBackupItemActions(map[string]common.HandlerInitializer) Server
// RegisterBackupItemActionV2 registers a v2 backup item action. Accepted format
// for the plugin name is <DNS subdomain>/<non-empty name>.
RegisterBackupItemActionV2(pluginName string, initializer common.HandlerInitializer) Server
// RegisterBackupItemActionsV2 registers multiple v2 backup item actions.
RegisterBackupItemActionsV2(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 common.HandlerInitializer) Server
@ -85,15 +93,16 @@ type Server interface {
// server implements Server.
type server struct {
log *logrus.Logger
logLevelFlag *logging.LevelFlag
flagSet *pflag.FlagSet
backupItemAction *BackupItemActionPlugin
volumeSnapshotter *VolumeSnapshotterPlugin
objectStore *ObjectStorePlugin
restoreItemAction *RestoreItemActionPlugin
deleteItemAction *DeleteItemActionPlugin
itemSnapshotter *ItemSnapshotterPlugin
log *logrus.Logger
logLevelFlag *logging.LevelFlag
flagSet *pflag.FlagSet
backupItemAction *BackupItemActionPlugin
backupItemActionV2 *biav2.BackupItemActionPlugin
volumeSnapshotter *VolumeSnapshotterPlugin
objectStore *ObjectStorePlugin
restoreItemAction *RestoreItemActionPlugin
deleteItemAction *DeleteItemActionPlugin
itemSnapshotter *ItemSnapshotterPlugin
}
// NewServer returns a new Server
@ -101,14 +110,15 @@ func NewServer() Server {
log := newLogger()
return &server{
log: log,
logLevelFlag: logging.LogLevelFlag(log.Level),
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)),
log: log,
logLevelFlag: logging.LogLevelFlag(log.Level),
backupItemAction: NewBackupItemActionPlugin(common.ServerLogger(log)),
backupItemActionV2: biav2.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)),
}
}
@ -132,6 +142,18 @@ func (s *server) RegisterBackupItemActions(m map[string]common.HandlerInitialize
return s
}
func (s *server) RegisterBackupItemActionV2(name string, initializer common.HandlerInitializer) Server {
s.backupItemActionV2.Register(name, initializer)
return s
}
func (s *server) RegisterBackupItemActionsV2(m map[string]common.HandlerInitializer) Server {
for name := range m {
s.RegisterBackupItemActionV2(name, m[name])
}
return s
}
func (s *server) RegisterVolumeSnapshotter(name string, initializer common.HandlerInitializer) Server {
s.volumeSnapshotter.Register(name, initializer)
return s
@ -216,6 +238,7 @@ func (s *server) Serve() {
var pluginIdentifiers []PluginIdentifier
pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindBackupItemAction, s.backupItemAction)...)
pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindBackupItemActionV2, s.backupItemActionV2)...)
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)...)
@ -227,13 +250,14 @@ func (s *server) Serve() {
plugin.Serve(&plugin.ServeConfig{
HandshakeConfig: Handshake(),
Plugins: map[string]plugin.Plugin{
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,
string(common.PluginKindBackupItemAction): s.backupItemAction,
string(common.PluginKindBackupItemActionV2): s.backupItemActionV2,
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,
})

View File

@ -10,6 +10,7 @@ import (
proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
reflect "reflect"
sync "sync"
)
@ -323,47 +324,171 @@ func (x *ResourceSelector) GetSelector() string {
return ""
}
type OperationProgress struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Completed bool `protobuf:"varint,1,opt,name=completed,proto3" json:"completed,omitempty"`
Err string `protobuf:"bytes,2,opt,name=err,proto3" json:"err,omitempty"`
NCompleted int64 `protobuf:"varint,3,opt,name=nCompleted,proto3" json:"nCompleted,omitempty"`
NTotal int64 `protobuf:"varint,4,opt,name=nTotal,proto3" json:"nTotal,omitempty"`
OperationUnits string `protobuf:"bytes,5,opt,name=operationUnits,proto3" json:"operationUnits,omitempty"`
Description string `protobuf:"bytes,6,opt,name=description,proto3" json:"description,omitempty"`
Started *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=started,proto3" json:"started,omitempty"`
Updated *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=updated,proto3" json:"updated,omitempty"`
}
func (x *OperationProgress) Reset() {
*x = OperationProgress{}
if protoimpl.UnsafeEnabled {
mi := &file_Shared_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *OperationProgress) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*OperationProgress) ProtoMessage() {}
func (x *OperationProgress) ProtoReflect() protoreflect.Message {
mi := &file_Shared_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use OperationProgress.ProtoReflect.Descriptor instead.
func (*OperationProgress) Descriptor() ([]byte, []int) {
return file_Shared_proto_rawDescGZIP(), []int{5}
}
func (x *OperationProgress) GetCompleted() bool {
if x != nil {
return x.Completed
}
return false
}
func (x *OperationProgress) GetErr() string {
if x != nil {
return x.Err
}
return ""
}
func (x *OperationProgress) GetNCompleted() int64 {
if x != nil {
return x.NCompleted
}
return 0
}
func (x *OperationProgress) GetNTotal() int64 {
if x != nil {
return x.NTotal
}
return 0
}
func (x *OperationProgress) GetOperationUnits() string {
if x != nil {
return x.OperationUnits
}
return ""
}
func (x *OperationProgress) GetDescription() string {
if x != nil {
return x.Description
}
return ""
}
func (x *OperationProgress) GetStarted() *timestamppb.Timestamp {
if x != nil {
return x.Started
}
return nil
}
func (x *OperationProgress) GetUpdated() *timestamppb.Timestamp {
if x != nil {
return x.Updated
}
return nil
}
var File_Shared_proto protoreflect.FileDescriptor
var file_Shared_proto_rawDesc = []byte{
0x0a, 0x0c, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09,
0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70,
0x74, 0x79, 0x22, 0x36, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x2d, 0x0a, 0x06, 0x66,
0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x65,
0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x46, 0x72, 0x61,
0x6d, 0x65, 0x52, 0x06, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x50, 0x0a, 0x0a, 0x53, 0x74,
0x61, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04,
0x6c, 0x69, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65,
0x12, 0x1a, 0x0a, 0x08, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01,
0x28, 0x09, 0x52, 0x08, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x78, 0x0a, 0x12,
0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69,
0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xea, 0x01, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x2e, 0x0a, 0x12, 0x69,
0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65,
0x64, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x65,
0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65,
0x64, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x69,
0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64,
0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x65, 0x78, 0x63,
0x6c, 0x75, 0x64, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x04,
0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x52, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63,
0x74, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63,
0x74, 0x6f, 0x72, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x76, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x2d, 0x74, 0x61, 0x6e, 0x7a, 0x75, 0x2f, 0x76,
0x65, 0x6c, 0x65, 0x72, 0x6f, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e,
0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73,
0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d,
0x70, 0x74, 0x79, 0x22, 0x36, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x2d, 0x0a, 0x06,
0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67,
0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x46, 0x72,
0x61, 0x6d, 0x65, 0x52, 0x06, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x50, 0x0a, 0x0a, 0x53,
0x74, 0x61, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a,
0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x6c, 0x69, 0x6e,
0x65, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20,
0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x78, 0x0a,
0x12, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66,
0x69, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70,
0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xea, 0x01, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x2e, 0x0a, 0x12,
0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64,
0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x12,
0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64,
0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x11,
0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65,
0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x65, 0x78,
0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18,
0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x52,
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65,
0x63, 0x74, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x6c, 0x65,
0x63, 0x74, 0x6f, 0x72, 0x22, 0xb1, 0x02, 0x0a, 0x11, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f,
0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63,
0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x65, 0x72, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x6e, 0x43,
0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a,
0x6e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x54,
0x6f, 0x74, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e, 0x54, 0x6f, 0x74,
0x61, 0x6c, 0x12, 0x26, 0x0a, 0x0e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55,
0x6e, 0x69, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6f, 0x70, 0x65, 0x72,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65,
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x07,
0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74,
0x65, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x08, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x2d, 0x74, 0x61,
0x6e, 0x7a, 0x75, 0x2f, 0x76, 0x65, 0x6c, 0x65, 0x72, 0x6f, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70,
0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -378,21 +503,25 @@ func file_Shared_proto_rawDescGZIP() []byte {
return file_Shared_proto_rawDescData
}
var file_Shared_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_Shared_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_Shared_proto_goTypes = []interface{}{
(*Empty)(nil), // 0: generated.Empty
(*Stack)(nil), // 1: generated.Stack
(*StackFrame)(nil), // 2: generated.StackFrame
(*ResourceIdentifier)(nil), // 3: generated.ResourceIdentifier
(*ResourceSelector)(nil), // 4: generated.ResourceSelector
(*Empty)(nil), // 0: generated.Empty
(*Stack)(nil), // 1: generated.Stack
(*StackFrame)(nil), // 2: generated.StackFrame
(*ResourceIdentifier)(nil), // 3: generated.ResourceIdentifier
(*ResourceSelector)(nil), // 4: generated.ResourceSelector
(*OperationProgress)(nil), // 5: generated.OperationProgress
(*timestamppb.Timestamp)(nil), // 6: google.protobuf.Timestamp
}
var file_Shared_proto_depIdxs = []int32{
2, // 0: generated.Stack.frames:type_name -> generated.StackFrame
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
6, // 1: generated.OperationProgress.started:type_name -> google.protobuf.Timestamp
6, // 2: generated.OperationProgress.updated:type_name -> google.protobuf.Timestamp
3, // [3:3] is the sub-list for method output_type
3, // [3:3] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
}
func init() { file_Shared_proto_init() }
@ -461,6 +590,18 @@ func file_Shared_proto_init() {
return nil
}
}
file_Shared_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*OperationProgress); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
@ -468,7 +609,7 @@ func file_Shared_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_Shared_proto_rawDesc,
NumEnums: 0,
NumMessages: 5,
NumMessages: 6,
NumExtensions: 0,
NumServices: 0,
},

View File

@ -0,0 +1,851 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.23.0
// protoc v3.14.0
// source: backupitemaction/v2/BackupItemAction.proto
package v2
import (
context "context"
proto "github.com/golang/protobuf/proto"
generated "github.com/vmware-tanzu/velero/pkg/plugin/generated"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
emptypb "google.golang.org/protobuf/types/known/emptypb"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type ExecuteRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Plugin string `protobuf:"bytes,1,opt,name=plugin,proto3" 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 (x *ExecuteRequest) Reset() {
*x = ExecuteRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_backupitemaction_v2_BackupItemAction_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ExecuteRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ExecuteRequest) ProtoMessage() {}
func (x *ExecuteRequest) ProtoReflect() protoreflect.Message {
mi := &file_backupitemaction_v2_BackupItemAction_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ExecuteRequest.ProtoReflect.Descriptor instead.
func (*ExecuteRequest) Descriptor() ([]byte, []int) {
return file_backupitemaction_v2_BackupItemAction_proto_rawDescGZIP(), []int{0}
}
func (x *ExecuteRequest) GetPlugin() string {
if x != nil {
return x.Plugin
}
return ""
}
func (x *ExecuteRequest) GetItem() []byte {
if x != nil {
return x.Item
}
return nil
}
func (x *ExecuteRequest) GetBackup() []byte {
if x != nil {
return x.Backup
}
return nil
}
type ExecuteResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Item []byte `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
AdditionalItems []*generated.ResourceIdentifier `protobuf:"bytes,2,rep,name=additionalItems,proto3" json:"additionalItems,omitempty"`
OperationID string `protobuf:"bytes,3,opt,name=operationID,proto3" json:"operationID,omitempty"`
}
func (x *ExecuteResponse) Reset() {
*x = ExecuteResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_backupitemaction_v2_BackupItemAction_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ExecuteResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ExecuteResponse) ProtoMessage() {}
func (x *ExecuteResponse) ProtoReflect() protoreflect.Message {
mi := &file_backupitemaction_v2_BackupItemAction_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ExecuteResponse.ProtoReflect.Descriptor instead.
func (*ExecuteResponse) Descriptor() ([]byte, []int) {
return file_backupitemaction_v2_BackupItemAction_proto_rawDescGZIP(), []int{1}
}
func (x *ExecuteResponse) GetItem() []byte {
if x != nil {
return x.Item
}
return nil
}
func (x *ExecuteResponse) GetAdditionalItems() []*generated.ResourceIdentifier {
if x != nil {
return x.AdditionalItems
}
return nil
}
func (x *ExecuteResponse) GetOperationID() string {
if x != nil {
return x.OperationID
}
return ""
}
type BackupItemActionAppliesToRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Plugin string `protobuf:"bytes,1,opt,name=plugin,proto3" json:"plugin,omitempty"`
}
func (x *BackupItemActionAppliesToRequest) Reset() {
*x = BackupItemActionAppliesToRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_backupitemaction_v2_BackupItemAction_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BackupItemActionAppliesToRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BackupItemActionAppliesToRequest) ProtoMessage() {}
func (x *BackupItemActionAppliesToRequest) ProtoReflect() protoreflect.Message {
mi := &file_backupitemaction_v2_BackupItemAction_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BackupItemActionAppliesToRequest.ProtoReflect.Descriptor instead.
func (*BackupItemActionAppliesToRequest) Descriptor() ([]byte, []int) {
return file_backupitemaction_v2_BackupItemAction_proto_rawDescGZIP(), []int{2}
}
func (x *BackupItemActionAppliesToRequest) GetPlugin() string {
if x != nil {
return x.Plugin
}
return ""
}
type BackupItemActionAppliesToResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ResourceSelector *generated.ResourceSelector `protobuf:"bytes,1,opt,name=ResourceSelector,proto3" json:"ResourceSelector,omitempty"`
}
func (x *BackupItemActionAppliesToResponse) Reset() {
*x = BackupItemActionAppliesToResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_backupitemaction_v2_BackupItemAction_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BackupItemActionAppliesToResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BackupItemActionAppliesToResponse) ProtoMessage() {}
func (x *BackupItemActionAppliesToResponse) ProtoReflect() protoreflect.Message {
mi := &file_backupitemaction_v2_BackupItemAction_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BackupItemActionAppliesToResponse.ProtoReflect.Descriptor instead.
func (*BackupItemActionAppliesToResponse) Descriptor() ([]byte, []int) {
return file_backupitemaction_v2_BackupItemAction_proto_rawDescGZIP(), []int{3}
}
func (x *BackupItemActionAppliesToResponse) GetResourceSelector() *generated.ResourceSelector {
if x != nil {
return x.ResourceSelector
}
return nil
}
type BackupItemActionProgressRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Plugin string `protobuf:"bytes,1,opt,name=plugin,proto3" json:"plugin,omitempty"`
OperationID string `protobuf:"bytes,2,opt,name=operationID,proto3" json:"operationID,omitempty"`
Backup []byte `protobuf:"bytes,3,opt,name=backup,proto3" json:"backup,omitempty"`
}
func (x *BackupItemActionProgressRequest) Reset() {
*x = BackupItemActionProgressRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_backupitemaction_v2_BackupItemAction_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BackupItemActionProgressRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BackupItemActionProgressRequest) ProtoMessage() {}
func (x *BackupItemActionProgressRequest) ProtoReflect() protoreflect.Message {
mi := &file_backupitemaction_v2_BackupItemAction_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BackupItemActionProgressRequest.ProtoReflect.Descriptor instead.
func (*BackupItemActionProgressRequest) Descriptor() ([]byte, []int) {
return file_backupitemaction_v2_BackupItemAction_proto_rawDescGZIP(), []int{4}
}
func (x *BackupItemActionProgressRequest) GetPlugin() string {
if x != nil {
return x.Plugin
}
return ""
}
func (x *BackupItemActionProgressRequest) GetOperationID() string {
if x != nil {
return x.OperationID
}
return ""
}
func (x *BackupItemActionProgressRequest) GetBackup() []byte {
if x != nil {
return x.Backup
}
return nil
}
type BackupItemActionProgressResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Progress *generated.OperationProgress `protobuf:"bytes,1,opt,name=progress,proto3" json:"progress,omitempty"`
}
func (x *BackupItemActionProgressResponse) Reset() {
*x = BackupItemActionProgressResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_backupitemaction_v2_BackupItemAction_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BackupItemActionProgressResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BackupItemActionProgressResponse) ProtoMessage() {}
func (x *BackupItemActionProgressResponse) ProtoReflect() protoreflect.Message {
mi := &file_backupitemaction_v2_BackupItemAction_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BackupItemActionProgressResponse.ProtoReflect.Descriptor instead.
func (*BackupItemActionProgressResponse) Descriptor() ([]byte, []int) {
return file_backupitemaction_v2_BackupItemAction_proto_rawDescGZIP(), []int{5}
}
func (x *BackupItemActionProgressResponse) GetProgress() *generated.OperationProgress {
if x != nil {
return x.Progress
}
return nil
}
type BackupItemActionCancelRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Plugin string `protobuf:"bytes,1,opt,name=plugin,proto3" json:"plugin,omitempty"`
OperationID string `protobuf:"bytes,2,opt,name=operationID,proto3" json:"operationID,omitempty"`
Backup []byte `protobuf:"bytes,3,opt,name=backup,proto3" json:"backup,omitempty"`
}
func (x *BackupItemActionCancelRequest) Reset() {
*x = BackupItemActionCancelRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_backupitemaction_v2_BackupItemAction_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BackupItemActionCancelRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BackupItemActionCancelRequest) ProtoMessage() {}
func (x *BackupItemActionCancelRequest) ProtoReflect() protoreflect.Message {
mi := &file_backupitemaction_v2_BackupItemAction_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BackupItemActionCancelRequest.ProtoReflect.Descriptor instead.
func (*BackupItemActionCancelRequest) Descriptor() ([]byte, []int) {
return file_backupitemaction_v2_BackupItemAction_proto_rawDescGZIP(), []int{6}
}
func (x *BackupItemActionCancelRequest) GetPlugin() string {
if x != nil {
return x.Plugin
}
return ""
}
func (x *BackupItemActionCancelRequest) GetOperationID() string {
if x != nil {
return x.OperationID
}
return ""
}
func (x *BackupItemActionCancelRequest) GetBackup() []byte {
if x != nil {
return x.Backup
}
return nil
}
var File_backupitemaction_v2_BackupItemAction_proto protoreflect.FileDescriptor
var file_backupitemaction_v2_BackupItemAction_proto_rawDesc = []byte{
0x0a, 0x2a, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x69, 0x74, 0x65, 0x6d, 0x61, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x2f, 0x76, 0x32, 0x2f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x74, 0x65, 0x6d,
0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x76, 0x32,
0x1a, 0x0c, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f,
0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x54, 0x0a, 0x0e, 0x45,
0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a,
0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70,
0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x61, 0x63,
0x6b, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x62, 0x61, 0x63, 0x6b, 0x75,
0x70, 0x22, 0x90, 0x01, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x47, 0x0a, 0x0f, 0x61, 0x64, 0x64,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x52,
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65,
0x72, 0x52, 0x0f, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x74, 0x65,
0x6d, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49,
0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x49, 0x44, 0x22, 0x3a, 0x0a, 0x20, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x74,
0x65, 0x6d, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x73, 0x54,
0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x6c, 0x75, 0x67,
0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e,
0x22, 0x6c, 0x0a, 0x21, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x41, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x73, 0x54, 0x6f, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x1b, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x52, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x10, 0x52, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x73,
0x0a, 0x1f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x41, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x6f, 0x70, 0x65,
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x62,
0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x62, 0x61, 0x63,
0x6b, 0x75, 0x70, 0x22, 0x5c, 0x0a, 0x20, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x74, 0x65,
0x6d, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72,
0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x65, 0x6e, 0x65,
0x72, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50,
0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73,
0x73, 0x22, 0x71, 0x0a, 0x1d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x41,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x6f, 0x70,
0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0b, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06,
0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x62, 0x61,
0x63, 0x6b, 0x75, 0x70, 0x32, 0xbc, 0x02, 0x0a, 0x10, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49,
0x74, 0x65, 0x6d, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x58, 0x0a, 0x09, 0x41, 0x70, 0x70,
0x6c, 0x69, 0x65, 0x73, 0x54, 0x6f, 0x12, 0x24, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x63, 0x6b,
0x75, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x70, 0x70, 0x6c,
0x69, 0x65, 0x73, 0x54, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x76,
0x32, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x41, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x73, 0x54, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x12, 0x12,
0x2e, 0x76, 0x32, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x13, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x72,
0x65, 0x73, 0x73, 0x12, 0x23, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49,
0x74, 0x65, 0x6d, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61,
0x63, 0x6b, 0x75, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72,
0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43,
0x0a, 0x06, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x12, 0x21, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61,
0x63, 0x6b, 0x75, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61,
0x6e, 0x63, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
0x70, 0x74, 0x79, 0x42, 0x49, 0x5a, 0x47, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x76, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x2d, 0x74, 0x61, 0x6e, 0x7a, 0x75, 0x2f, 0x76,
0x65, 0x6c, 0x65, 0x72, 0x6f, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e,
0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75,
0x70, 0x69, 0x74, 0x65, 0x6d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x32, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_backupitemaction_v2_BackupItemAction_proto_rawDescOnce sync.Once
file_backupitemaction_v2_BackupItemAction_proto_rawDescData = file_backupitemaction_v2_BackupItemAction_proto_rawDesc
)
func file_backupitemaction_v2_BackupItemAction_proto_rawDescGZIP() []byte {
file_backupitemaction_v2_BackupItemAction_proto_rawDescOnce.Do(func() {
file_backupitemaction_v2_BackupItemAction_proto_rawDescData = protoimpl.X.CompressGZIP(file_backupitemaction_v2_BackupItemAction_proto_rawDescData)
})
return file_backupitemaction_v2_BackupItemAction_proto_rawDescData
}
var file_backupitemaction_v2_BackupItemAction_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_backupitemaction_v2_BackupItemAction_proto_goTypes = []interface{}{
(*ExecuteRequest)(nil), // 0: v2.ExecuteRequest
(*ExecuteResponse)(nil), // 1: v2.ExecuteResponse
(*BackupItemActionAppliesToRequest)(nil), // 2: v2.BackupItemActionAppliesToRequest
(*BackupItemActionAppliesToResponse)(nil), // 3: v2.BackupItemActionAppliesToResponse
(*BackupItemActionProgressRequest)(nil), // 4: v2.BackupItemActionProgressRequest
(*BackupItemActionProgressResponse)(nil), // 5: v2.BackupItemActionProgressResponse
(*BackupItemActionCancelRequest)(nil), // 6: v2.BackupItemActionCancelRequest
(*generated.ResourceIdentifier)(nil), // 7: generated.ResourceIdentifier
(*generated.ResourceSelector)(nil), // 8: generated.ResourceSelector
(*generated.OperationProgress)(nil), // 9: generated.OperationProgress
(*emptypb.Empty)(nil), // 10: google.protobuf.Empty
}
var file_backupitemaction_v2_BackupItemAction_proto_depIdxs = []int32{
7, // 0: v2.ExecuteResponse.additionalItems:type_name -> generated.ResourceIdentifier
8, // 1: v2.BackupItemActionAppliesToResponse.ResourceSelector:type_name -> generated.ResourceSelector
9, // 2: v2.BackupItemActionProgressResponse.progress:type_name -> generated.OperationProgress
2, // 3: v2.BackupItemAction.AppliesTo:input_type -> v2.BackupItemActionAppliesToRequest
0, // 4: v2.BackupItemAction.Execute:input_type -> v2.ExecuteRequest
4, // 5: v2.BackupItemAction.Progress:input_type -> v2.BackupItemActionProgressRequest
6, // 6: v2.BackupItemAction.Cancel:input_type -> v2.BackupItemActionCancelRequest
3, // 7: v2.BackupItemAction.AppliesTo:output_type -> v2.BackupItemActionAppliesToResponse
1, // 8: v2.BackupItemAction.Execute:output_type -> v2.ExecuteResponse
5, // 9: v2.BackupItemAction.Progress:output_type -> v2.BackupItemActionProgressResponse
10, // 10: v2.BackupItemAction.Cancel:output_type -> google.protobuf.Empty
7, // [7:11] is the sub-list for method output_type
3, // [3:7] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
}
func init() { file_backupitemaction_v2_BackupItemAction_proto_init() }
func file_backupitemaction_v2_BackupItemAction_proto_init() {
if File_backupitemaction_v2_BackupItemAction_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_backupitemaction_v2_BackupItemAction_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ExecuteRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_backupitemaction_v2_BackupItemAction_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ExecuteResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_backupitemaction_v2_BackupItemAction_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BackupItemActionAppliesToRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_backupitemaction_v2_BackupItemAction_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BackupItemActionAppliesToResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_backupitemaction_v2_BackupItemAction_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BackupItemActionProgressRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_backupitemaction_v2_BackupItemAction_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BackupItemActionProgressResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_backupitemaction_v2_BackupItemAction_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BackupItemActionCancelRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_backupitemaction_v2_BackupItemAction_proto_rawDesc,
NumEnums: 0,
NumMessages: 7,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_backupitemaction_v2_BackupItemAction_proto_goTypes,
DependencyIndexes: file_backupitemaction_v2_BackupItemAction_proto_depIdxs,
MessageInfos: file_backupitemaction_v2_BackupItemAction_proto_msgTypes,
}.Build()
File_backupitemaction_v2_BackupItemAction_proto = out.File
file_backupitemaction_v2_BackupItemAction_proto_rawDesc = nil
file_backupitemaction_v2_BackupItemAction_proto_goTypes = nil
file_backupitemaction_v2_BackupItemAction_proto_depIdxs = nil
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConnInterface
// 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.SupportPackageIsVersion6
// BackupItemActionClient is the client API for BackupItemAction service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type BackupItemActionClient interface {
AppliesTo(ctx context.Context, in *BackupItemActionAppliesToRequest, opts ...grpc.CallOption) (*BackupItemActionAppliesToResponse, error)
Execute(ctx context.Context, in *ExecuteRequest, opts ...grpc.CallOption) (*ExecuteResponse, error)
Progress(ctx context.Context, in *BackupItemActionProgressRequest, opts ...grpc.CallOption) (*BackupItemActionProgressResponse, error)
Cancel(ctx context.Context, in *BackupItemActionCancelRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
}
type backupItemActionClient struct {
cc grpc.ClientConnInterface
}
func NewBackupItemActionClient(cc grpc.ClientConnInterface) BackupItemActionClient {
return &backupItemActionClient{cc}
}
func (c *backupItemActionClient) AppliesTo(ctx context.Context, in *BackupItemActionAppliesToRequest, opts ...grpc.CallOption) (*BackupItemActionAppliesToResponse, error) {
out := new(BackupItemActionAppliesToResponse)
err := c.cc.Invoke(ctx, "/v2.BackupItemAction/AppliesTo", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *backupItemActionClient) Execute(ctx context.Context, in *ExecuteRequest, opts ...grpc.CallOption) (*ExecuteResponse, error) {
out := new(ExecuteResponse)
err := c.cc.Invoke(ctx, "/v2.BackupItemAction/Execute", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *backupItemActionClient) Progress(ctx context.Context, in *BackupItemActionProgressRequest, opts ...grpc.CallOption) (*BackupItemActionProgressResponse, error) {
out := new(BackupItemActionProgressResponse)
err := c.cc.Invoke(ctx, "/v2.BackupItemAction/Progress", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *backupItemActionClient) Cancel(ctx context.Context, in *BackupItemActionCancelRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, "/v2.BackupItemAction/Cancel", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// BackupItemActionServer is the server API for BackupItemAction service.
type BackupItemActionServer interface {
AppliesTo(context.Context, *BackupItemActionAppliesToRequest) (*BackupItemActionAppliesToResponse, error)
Execute(context.Context, *ExecuteRequest) (*ExecuteResponse, error)
Progress(context.Context, *BackupItemActionProgressRequest) (*BackupItemActionProgressResponse, error)
Cancel(context.Context, *BackupItemActionCancelRequest) (*emptypb.Empty, error)
}
// UnimplementedBackupItemActionServer can be embedded to have forward compatible implementations.
type UnimplementedBackupItemActionServer struct {
}
func (*UnimplementedBackupItemActionServer) AppliesTo(context.Context, *BackupItemActionAppliesToRequest) (*BackupItemActionAppliesToResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method AppliesTo not implemented")
}
func (*UnimplementedBackupItemActionServer) Execute(context.Context, *ExecuteRequest) (*ExecuteResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Execute not implemented")
}
func (*UnimplementedBackupItemActionServer) Progress(context.Context, *BackupItemActionProgressRequest) (*BackupItemActionProgressResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Progress not implemented")
}
func (*UnimplementedBackupItemActionServer) Cancel(context.Context, *BackupItemActionCancelRequest) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method Cancel not implemented")
}
func RegisterBackupItemActionServer(s *grpc.Server, srv BackupItemActionServer) {
s.RegisterService(&_BackupItemAction_serviceDesc, srv)
}
func _BackupItemAction_AppliesTo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(BackupItemActionAppliesToRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BackupItemActionServer).AppliesTo(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/v2.BackupItemAction/AppliesTo",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BackupItemActionServer).AppliesTo(ctx, req.(*BackupItemActionAppliesToRequest))
}
return interceptor(ctx, in, info, handler)
}
func _BackupItemAction_Execute_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ExecuteRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BackupItemActionServer).Execute(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/v2.BackupItemAction/Execute",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BackupItemActionServer).Execute(ctx, req.(*ExecuteRequest))
}
return interceptor(ctx, in, info, handler)
}
func _BackupItemAction_Progress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(BackupItemActionProgressRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BackupItemActionServer).Progress(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/v2.BackupItemAction/Progress",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BackupItemActionServer).Progress(ctx, req.(*BackupItemActionProgressRequest))
}
return interceptor(ctx, in, info, handler)
}
func _BackupItemAction_Cancel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(BackupItemActionCancelRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BackupItemActionServer).Cancel(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/v2.BackupItemAction/Cancel",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BackupItemActionServer).Cancel(ctx, req.(*BackupItemActionCancelRequest))
}
return interceptor(ctx, in, info, handler)
}
var _BackupItemAction_serviceDesc = grpc.ServiceDesc{
ServiceName: "v2.BackupItemAction",
HandlerType: (*BackupItemActionServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "AppliesTo",
Handler: _BackupItemAction_AppliesTo_Handler,
},
{
MethodName: "Execute",
Handler: _BackupItemAction_Execute_Handler,
},
{
MethodName: "Progress",
Handler: _BackupItemAction_Progress_Handler,
},
{
MethodName: "Cancel",
Handler: _BackupItemAction_Cancel_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "backupitemaction/v2/BackupItemAction.proto",
}

View File

@ -10,6 +10,8 @@ import (
v1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v1"
v2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
velero "github.com/vmware-tanzu/velero/pkg/plugin/velero"
volumesnapshotterv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v1"
@ -48,6 +50,29 @@ func (_m *Manager) GetBackupItemAction(name string) (v1.BackupItemAction, error)
return r0, r1
}
// GetBackupItemActionV2 provides a mock function with given fields: name
func (_m *Manager) GetBackupItemActionV2(name string) (v2.BackupItemAction, error) {
ret := _m.Called(name)
var r0 v2.BackupItemAction
if rf, ok := ret.Get(0).(func(string) v2.BackupItemAction); ok {
r0 = rf(name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(v2.BackupItemAction)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetBackupItemActions provides a mock function with given fields:
func (_m *Manager) GetBackupItemActions() ([]v1.BackupItemAction, error) {
ret := _m.Called()
@ -71,6 +96,29 @@ func (_m *Manager) GetBackupItemActions() ([]v1.BackupItemAction, error) {
return r0, r1
}
// GetBackupItemActionsV2 provides a mock function with given fields:
func (_m *Manager) GetBackupItemActionsV2() ([]v2.BackupItemAction, error) {
ret := _m.Called()
var r0 []v2.BackupItemAction
if rf, ok := ret.Get(0).(func() []v2.BackupItemAction); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]v2.BackupItemAction)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetDeleteItemAction provides a mock function with given fields: name
func (_m *Manager) GetDeleteItemAction(name string) (velero.DeleteItemAction, error) {
ret := _m.Called(name)

View File

@ -2,6 +2,8 @@ syntax = "proto3";
package generated;
option go_package = "github.com/vmware-tanzu/velero/pkg/plugin/generated";
import "google/protobuf/timestamp.proto";
message Empty {}
message Stack {
@ -27,4 +29,15 @@ message ResourceSelector {
repeated string includedResources = 3;
repeated string excludedResources = 4;
string selector = 5;
}
}
message OperationProgress {
bool completed = 1;
string err = 2;
int64 nCompleted = 3;
int64 nTotal = 4;
string operationUnits = 5;
string description = 6;
google.protobuf.Timestamp started = 7;
google.protobuf.Timestamp updated = 8;
}

View File

@ -0,0 +1,50 @@
syntax = "proto3";
package v2;
option go_package = "github.com/vmware-tanzu/velero/pkg/plugin/generated/backupitemaction/v2";
import "Shared.proto";
import "google/protobuf/empty.proto";
message ExecuteRequest {
string plugin = 1;
bytes item = 2;
bytes backup = 3;
}
message ExecuteResponse {
bytes item = 1;
repeated generated.ResourceIdentifier additionalItems = 2;
string operationID = 3;
}
service BackupItemAction {
rpc AppliesTo(BackupItemActionAppliesToRequest) returns (BackupItemActionAppliesToResponse);
rpc Execute(ExecuteRequest) returns (ExecuteResponse);
rpc Progress(BackupItemActionProgressRequest) returns (BackupItemActionProgressResponse);
rpc Cancel(BackupItemActionCancelRequest) returns (google.protobuf.Empty);
}
message BackupItemActionAppliesToRequest {
string plugin = 1;
}
message BackupItemActionAppliesToResponse {
generated.ResourceSelector ResourceSelector = 1;
}
message BackupItemActionProgressRequest {
string plugin = 1;
string operationID = 2;
bytes backup = 3;
}
message BackupItemActionProgressResponse {
generated.OperationProgress progress = 1;
}
message BackupItemActionCancelRequest {
string plugin = 1;
string operationID = 2;
bytes backup = 3;
}

View File

@ -0,0 +1,63 @@
/*
Copyright 2017 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 v2
import (
"fmt"
"k8s.io/apimachinery/pkg/runtime"
"github.com/pkg/errors"
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
)
// BackupItemAction is an actor that performs an operation on an individual item being backed up.
type BackupItemAction interface {
// AppliesTo returns information about which resources this action should be invoked for.
// A BackupItemAction's Execute function will only be invoked on items that match the returned
// selector. A zero-valued ResourceSelector matches all resources.
AppliesTo() (velero.ResourceSelector, error)
// Execute allows the BackupItemAction to perform arbitrary logic with the item being backed up,
// including mutating the item itself prior to backup. The item (unmodified or modified)
// should be returned, along with an optional slice of ResourceIdentifiers specifying
// additional related items that should be backed up.
Execute(item runtime.Unstructured, backup *api.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error)
// Progress allows the BackupItemAction to report on progress of an asynchronous action.
// For the passed-in operation, the plugin will return an OperationProgress struct, indicating
// whether the operation has completed, whether there were any errors, a plugin-specific
// indication of how much of the operation is done (items completed out of items-to-complete),
// and started/updated timestamps
Progress(operationID string, backup *api.Backup) (velero.OperationProgress, error)
// Cancel allows the BackupItemAction to cancel an asynchronous action (if possible).
// Velero will call this if the wait timeout for asynchronous actions has been reached.
// If operation cancel is not supported, then the plugin just needs to return. No error
// return is expected in this case, since cancellation is optional here.
Cancel(operationID string, backup *api.Backup) error
}
func AsyncOperationsNotSupportedError() error {
return errors.New("Plugin does not support asynchronous operations")
}
func InvalidOperationIDError(operationID string) error {
return errors.New(fmt.Sprintf("Operation ID %v is invalid.", operationID))
}

View File

@ -0,0 +1,127 @@
/*
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 v2
import (
mock "github.com/stretchr/testify/mock"
runtime "k8s.io/apimachinery/pkg/runtime"
v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
velero "github.com/vmware-tanzu/velero/pkg/plugin/velero"
)
// 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
}
// Cancel provides a mock function with given fields: operationID, backup
func (_m *BackupItemAction) Cancel(operationID string, backup *v1.Backup) error {
ret := _m.Called(operationID, backup)
var r0 error
if rf, ok := ret.Get(0).(func(string, *v1.Backup) error); ok {
r0 = rf(operationID, backup)
} else {
r0 = ret.Error(0)
}
return r0
}
// Execute provides a mock function with given fields: item, backup
func (_m *BackupItemAction) Execute(item runtime.Unstructured, backup *v1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
ret := _m.Called(item, backup)
var r0 runtime.Unstructured
if rf, ok := ret.Get(0).(func(runtime.Unstructured, *v1.Backup) runtime.Unstructured); ok {
r0 = rf(item, 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, *v1.Backup) []velero.ResourceIdentifier); ok {
r1 = rf(item, backup)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).([]velero.ResourceIdentifier)
}
}
var r2 string
if rf, ok := ret.Get(2).(func(runtime.Unstructured, *v1.Backup) string); ok {
r2 = rf(item, backup)
} else {
r2 = ret.Get(2).(string)
}
var r3 error
if rf, ok := ret.Get(3).(func(runtime.Unstructured, *v1.Backup) error); ok {
r3 = rf(item, backup)
} else {
r3 = ret.Error(3)
}
return r0, r1, r2, r3
}
// Progress provides a mock function with given fields: operationID, backup
func (_m *BackupItemAction) Progress(operationID string, backup *v1.Backup) (velero.OperationProgress, error) {
ret := _m.Called(operationID, backup)
var r0 velero.OperationProgress
if rf, ok := ret.Get(0).(func(string, *v1.Backup) velero.OperationProgress); ok {
r0 = rf(operationID, backup)
} else {
r0 = ret.Get(0).(velero.OperationProgress)
}
var r1 error
if rf, ok := ret.Get(1).(func(string, *v1.Backup) error); ok {
r1 = rf(operationID, backup)
} else {
r1 = ret.Error(1)
}
return r0, r1
}

View File

@ -20,7 +20,11 @@ limitations under the License.
// plugins of any type can be implemented.
package velero
import "k8s.io/apimachinery/pkg/runtime/schema"
import (
"time"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// ResourceSelector is a collection of included/excluded namespaces,
// included/excluded resources, and a label-selector that can be used
@ -63,3 +67,25 @@ type ResourceIdentifier struct {
Namespace string
Name string
}
// OperationProgress describes progress of an asynchronous plugin operation.
type OperationProgress struct {
// True when the operation has completed, either successfully or with a failure
Completed bool
// Set when the operation has failed
Err string
// Quantity completed so far and the total quantity associated with the operation
// in OperationUnits. For data mover and volume snapshotter use cases, this will
// usually be in bytes. On successful completion, NCompleted and NTotal should be
// the same
NCompleted, NTotal int64
// Units represented by NCompleted and NTotal -- for data mover and item
// snapshotters, this will usually be bytes.
OperationUnits string
// Optional description of operation progress (i.e. "Current phase: Running")
Description string
// When the operation was started and when the last update was seen. Not all
// systems retain when the upload was begun, return Time 0 (time.Unix(0, 0))
// if unknown.
Started, Updated time.Time
}