Merge branch 'main' into issue-fix-5043

This commit is contained in:
Lyndon-Li
2023-01-12 16:54:50 +08:00
55 changed files with 2878 additions and 203 deletions
+4 -2
View File
@@ -9,7 +9,6 @@ reviewers:
groups:
maintainers:
- dsu-igeek
- sseago
- reasonerjt
- ywk253100
@@ -19,7 +18,10 @@ reviewers:
- Lyndon-Li
tech-writer:
- a-mccarthy
- sseago
- reasonerjt
- ywk253100
- Lyndon-Li
files:
'site/**':
+36
View File
@@ -0,0 +1,36 @@
name: Trivy Nightly Scan
on:
schedule:
- cron: '0 2 * * *' # run at 2 AM UTC
jobs:
nightly-scan:
name: Trivy nightly scan
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# maintain the versions of Velero those need security scan
versions: [main]
# list of images that need scan
images: [velero, velero-restore-helper]
permissions:
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'docker.io/velero/${{ matrix.images }}:${{ matrix.versions }}'
severity: 'CRITICAL,HIGH,MEDIUM'
format: 'template'
template: '@/contrib/sarif.tpl'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
+1
View File
@@ -0,0 +1 @@
BackupItemAction v2 API implementation
+4
View File
@@ -0,0 +1,4 @@
new backup and restore phases to support async plugin operations:
- WaitingForPluginOperations
- WaitingForPluginOperationsPartiallyFailed
+1
View File
@@ -0,0 +1 @@
Fix error with Restic backup empty volumes
+1
View File
@@ -0,0 +1 @@
Fix issue 5696, check if the repo is still openable before running the prune and forget operation, if not, try to reconnect the repo
+1
View File
@@ -0,0 +1 @@
Add Trivy nightly scan.
@@ -455,6 +455,8 @@ spec:
- New
- FailedValidation
- InProgress
- WaitingForPluginOperations
- WaitingForPluginOperationsPartiallyFailed
- Completed
- PartiallyFailed
- Failed
@@ -412,6 +412,8 @@ spec:
- New
- FailedValidation
- InProgress
- WaitingForPluginOperations
- WaitingForPluginOperationsPartiallyFailed
- Completed
- PartiallyFailed
- Failed
File diff suppressed because one or more lines are too long
+2 -2
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;
+39 -28
View File
@@ -145,7 +145,7 @@ allow for data movement to be handled in the "WaitingForPluginOperations" phase,
The next phase is either "Completed", "WaitingForPluginOperations", "Failed" or "PartiallyFailed".
Backups/restores which would have a final phase of "Completed" or "PartiallyFailed" may move to the
"WaitingForPluginOperations" or "WaitingForPluginOperationsPartialFailure" state. A backup/restore
"WaitingForPluginOperations" or "WaitingForPluginOperationsPartiallyFailed" state. A backup/restore
which will be marked "Failed" will go directly to the "Failed" phase. Uploads may continue in the
background for snapshots that were taken by a "Failed" backup/restore, but no progress will not be
monitored or updated. If there are any operations in progress when a backup is moved to the "Failed"
@@ -157,14 +157,14 @@ any uploads still in progress should be aborted.
The "WaitingForPluginOperations" phase signifies that the main part of the backup/restore, including
snapshotting has completed successfully and uploading and any other asynchronous BIA/RIA plugin
operations are continuing. In the event of an error during this phase, the phase will change to
WaitingForPluginOperationsPartialFailure. On success, the phase changes to Completed. Backups
WaitingForPluginOperationsPartiallyFailed. On success, the phase changes to Completed. Backups
cannot be restored from when they are in the WaitingForPluginOperations state.
### WaitingForPluginOperationsPartialFailure (new)
The "WaitingForPluginOperationsPartialFailure" phase signifies that the main part of the
### WaitingForPluginOperationsPartiallyFailed (new)
The "WaitingForPluginOperationsPartiallyFailed" phase signifies that the main part of the
backup/restore, including snapshotting has completed, but there were partial failures either during
the main part or during any async operations, including snapshot uploads. Backups cannot be
restored from when they are in the WaitingForPluginOperationsPartialFailure state.
restored from when they are in the WaitingForPluginOperationsPartiallyFailed state.
### Failed
When a backup/restore has had fatal errors it is marked as "Failed" Backups in this state cannot be
@@ -203,20 +203,20 @@ Velero will poll the plugins for status on the operations when the backup/restor
"InProgress" phase and has no fatal errors.
If any operations are not complete, the backup/restore will move to either WaitingForPluginOperations
or WaitingForPluginOperationsPartialFailure or Failed.
or WaitingForPluginOperationsPartiallyFailed or Failed.
Post-snapshot and other operations may take a long time and Velero and its plugins may be restarted
during this time. Once a backup/restore has moved into the WaitingForPluginOperations or
WaitingForPluginOperationsPartialFailure phase, another backup/restore may be started.
WaitingForPluginOperationsPartiallyFailed phase, another backup/restore may be started.
While in the WaitingForPluginOperations or WaitingForPluginOperationsPartialFailure phase, the
While in the WaitingForPluginOperations or WaitingForPluginOperationsPartiallyFailed phase, the
snapshots and item actions will be periodically polled. When all of the snapshots and item actions
have reported success, the backup/restore will move to the Completed or PartiallyFailed phase,
depending on whether the backup/restore was in the WaitingForPluginOperations or
WaitingForPluginOperationsPartialFailure phase.
WaitingForPluginOperationsPartiallyFailed phase.
The Backup resources will not be written to object storage until the backup has entered a final phase:
Completed, Failed or PartialFailure
Completed, Failed or PartiallyFailed
## Reconciliation of InProgress backups
@@ -231,7 +231,7 @@ ignored.
type OperationProgress struct {
Completed bool // True when the operation has completed, either successfully or with a failure
Err string // Set when the operation has failed
Completed, Total int64 // Quantity completed so far and the total quanity associated with the operaation in operationUnits
NCompleted, NTotal int64 // Quantity completed so far and the total quanity associated with the operaation in operationUnits
// For data mover and volume snapshotter use cases, this would be in bytes
// On successful completion, completed and total should be the same.
OperationUnits string // Units represented by completed and total -- for data mover and item
@@ -267,14 +267,17 @@ process/controller so we will modify BackupItemAction and RestoreItemAction to o
operationID in addition to the modified item.
Velero can attempt to cancel an operation by calling the Cancel API call on the BIA/RIA. The plugin
can then take any appropriate action as needed. Cancel will be called on backup deletion, and
possibly upon reaching timeouts, if timeout support is included in this feature. Cancel is not
intended to be used to delete/remove the results of completed actions.
can then take any appropriate action as needed. Cancel will be called for unfinished operations on
backup deletion, and possibly reaching timeout. Cancel is not intended to be used to delete/remove
the results of completed actions and will have no effect on a completed action. Cancel has no return
value apart from the standard Error return, but this should only be used for unexpected
failures. Under normal operations, Cancel will simply return a nil error (and nothing else), whether
or not the plugin is able to cancel the operation.
_AsyncOperationsNotSupportedError_ should only be returned (by either Cancel or by Progress) if the
_AsyncOperationsNotSupportedError_ should only be returned (by Progress) if the
Backup/RestoreItemAction plugin should not be handling the item. If the Backup/RestoreItemAction
plugin should handle the item but, for example, the item/snapshot ID cannot be found to report
progress, Progress or Cancel will return an InvalidOperationIDError error rather than a populated
progress, Progress will return an InvalidOperationIDError error rather than a populated
OperationProgress struct. If the item action does not start an asynchronous operation, then
operationID will be empty.
@@ -368,9 +371,17 @@ of what a record for a datamover plugin might look like:
```
{
"itemOperation": {
"plugin": "velero.io/datamover-backup",
"itemID": "<VolumeSnapshotContent objectReference>",
"operationID": "<DataMoverBackup objectReference>"
"plugin": "velero.io/datamover-backup",
"itemID": "<VolumeSnapshotContent objectReference>",
"operationID": "<DataMoverBackup objectReference>",
"completed": true,
"err": "",
"NCompleted": 12345,
"NTotal": 12345,
"OperationUnits": "byte",
"Description": "",
"Started": "2022-12-14T12:01:00Z",
"Updated": "2022-12-14T12:11:02Z"
}
}
```
@@ -424,8 +435,8 @@ will be completed and the backup will move to the appropriate terminal phase and
If any of the snapshots or backup items are still being processed, the phase of the backup will be
set to the appropriate phase (_WaitingForPluginOperations_ or
_WaitingForPluginOperationsPartialFailure_). In the event of any of the progress checks return an
error, the phase will move to _WaitingForPluginOperationsPartialFailure_. The backup will then be
_WaitingForPluginOperationsPartiallyFailed_). In the event of any of the progress checks return an
error, the phase will move to _WaitingForPluginOperationsPartiallyFailed_. The backup will then be
requeued and will be rechecked again after some time has passed.
## Restore workflow changes
@@ -440,16 +451,16 @@ completed and the restore will move to the appropriate terminal phase and the re
complete.
If any of the restore items are still being processed, the phase of the restore will be set to the
appropriate phase (_WaitingForPluginOperations_ or _WaitingForPluginOperationsPartialFailure_). In
appropriate phase (_WaitingForPluginOperations_ or _WaitingForPluginOperationsPartiallyFailed_). In
the event of any of the progress checks return an error, the phase will move to
_WaitingForPluginOperationsPartialFailure_. The restore will then be requeued and will be rechecked
_WaitingForPluginOperationsPartiallyFailed_. The restore will then be requeued and will be rechecked
again after some time has passed.
## Restart workflow
On restart, the Velero server will scan all Backup/Restore resources. Any Backup/Restore resources
which are in the _InProgress_ phase will be moved to the _Failed_ phase. Any Backup/Restore
resources in the _WaitingForPluginOperations_ or _WaitingForPluginOperationsPartialFailure_ phase
resources in the _WaitingForPluginOperations_ or _WaitingForPluginOperationsPartiallyFailed_ phase
will be treated as if they have been requeued and progress checked and the backup/restore will be
requeued or moved to a terminal phase as appropriate.
@@ -459,9 +470,9 @@ Since this design is modifying a previously-approved design, there is some prepa
the earlier upload progress monitoring design that may need modification as a result of these
updates. Here is a list of some of these items:
1. Consts for the "Uploading" and "UploadingPartialFailure" phases have already been defined. These
1. Consts for the "Uploading" and "UploadingPartiallyFailed" phases have already been defined. These
will need to be removed when the "WaitingForPluginOperations" and
"WaitingForPluginOperationsPartialFailure" phases are defined.
"WaitingForPluginOperationsPartiallyFailed" phases are defined.
- https://github.com/vmware-tanzu/velero/pull/3805
1. Remove the ItemSnapshotter plugin APIs (and related code) since the revised design will reuse
VolumeSnapshotter and BackupItemAction plugins.
@@ -507,9 +518,9 @@ vSphere plug-in BackupItemAction Progress implementation (vSphere plug-in team)
required custom cancellation actions, now would be a good time to perform them. For snapshot
uploads that are already in proress, there's not really anything else to cancel.
2. Should we actually write the backup *before* moving to the WaitingForPluginOperations or
WaitingForPluginOperationsPartialFailure phase rather than waiting until all operations
WaitingForPluginOperationsPartiallyFailed phase rather than waiting until all operations
have completed? The operations in question won't affect what gets written to object storage
for the backup, and since we've already written the list of operations we're waiting for to
object storage, writing the backup now would make the process resilient to Velero restart if
it happens during WaitingForPluginOperations or WaitingForPluginOperationsPartialFailure
it happens during WaitingForPluginOperations or WaitingForPluginOperationsPartiallyFailed
+1 -1
View File
@@ -5,7 +5,7 @@ go 1.18
require (
cloud.google.com/go/storage v1.21.0
github.com/Azure/azure-pipeline-go v0.2.3
github.com/Azure/azure-sdk-for-go v61.4.0+incompatible
github.com/Azure/azure-sdk-for-go v67.2.0+incompatible
github.com/Azure/azure-storage-blob-go v0.14.0
github.com/Azure/go-autorest/autorest v0.11.21
github.com/Azure/go-autorest/autorest/azure/auth v0.5.8
+2 -2
View File
@@ -60,8 +60,8 @@ cloud.google.com/go/storage v1.21.0/go.mod h1:XmRlxkgPjlBONznT2dDUU/5XlpU2OjMnKu
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/Azure/azure-pipeline-go v0.2.3 h1:7U9HBg1JFK3jHl5qmo4CTZKFTVgMwdFHMVtCdfBE21U=
github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k=
github.com/Azure/azure-sdk-for-go v61.4.0+incompatible h1:BF2Pm3aQWIa6q9KmxyF1JYKYXtVw67vtvu2Wd54NGuY=
github.com/Azure/azure-sdk-for-go v61.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go v67.2.0+incompatible h1:Uu/Ww6ernvPTrpq31kITVTIm/I5jlJ1wjtEH/bmSB2k=
github.com/Azure/azure-sdk-for-go v67.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1 h1:qoVeMsc9/fh/yhxVaA0obYjVH/oI/ihrOoMwsLS9KSA=
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM=
github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3 h1:E+m3SkZCN0Bf5q7YdTs5lSm2CYY3CK4spn5OmUIiQtk=
+4
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
+1 -1
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!"
+14 -10
View File
@@ -221,7 +221,7 @@ const (
// BackupPhase is a string representation of the lifecycle phase
// of a Velero backup.
// +kubebuilder:validation:Enum=New;FailedValidation;InProgress;Completed;PartiallyFailed;Failed;Deleting
// +kubebuilder:validation:Enum=New;FailedValidation;InProgress;WaitingForPluginOperations;WaitingForPluginOperationsPartiallyFailed;Completed;PartiallyFailed;Failed;Deleting
type BackupPhase string
const (
@@ -236,16 +236,20 @@ const (
// BackupPhaseInProgress means the backup is currently executing.
BackupPhaseInProgress BackupPhase = "InProgress"
// BackupPhaseUploading means the backups of Kubernetes resources
// and creation of snapshots was successful and snapshot data
// is currently uploading. The backup is not usable yet.
BackupPhaseUploading BackupPhase = "Uploading"
// BackupPhaseWaitingForPluginOperations means the backup of
// Kubernetes resources, creation of snapshots, and other
// async plugin operations was successful and snapshot data is
// currently uploading or other plugin operations are still
// ongoing. The backup is not usable yet.
BackupPhaseWaitingForPluginOperations BackupPhase = "WaitingForPluginOperations"
// BackupPhaseUploadingPartialFailure means the backup of Kubernetes
// resources and creation of snapshots partially failed (final phase
// will be PartiallyFailed) and snapshot data is currently uploading.
// The backup is not usable yet.
BackupPhaseUploadingPartialFailure BackupPhase = "UploadingPartialFailure"
// BackupPhaseWaitingForPluginOperationsPartiallyFailed means
// the backup of Kubernetes resources, creation of snapshots,
// and other async plugin operations partially failed (final
// phase will be PartiallyFailed) and snapshot data is
// currently uploading or other plugin operations are still
// ongoing. The backup is not usable yet.
BackupPhaseWaitingForPluginOperationsPartiallyFailed BackupPhase = "WaitingForPluginOperationsPartiallyFailed"
// BackupPhaseCompleted means the backup has run successfully without
// errors.
+14 -1
View File
@@ -220,7 +220,7 @@ type InitRestoreHook struct {
// RestorePhase is a string representation of the lifecycle phase
// of a Velero restore
// +kubebuilder:validation:Enum=New;FailedValidation;InProgress;Completed;PartiallyFailed;Failed
// +kubebuilder:validation:Enum=New;FailedValidation;InProgress;WaitingForPluginOperations;WaitingForPluginOperationsPartiallyFailed;Completed;PartiallyFailed;Failed
type RestorePhase string
const (
@@ -235,6 +235,19 @@ const (
// RestorePhaseInProgress means the restore is currently executing.
RestorePhaseInProgress RestorePhase = "InProgress"
// RestorePhaseWaitingForPluginOperations means the restore of
// Kubernetes resources and other async plugin operations was
// successful and plugin operations are still ongoing. The
// restore is not complete yet.
RestorePhaseWaitingForPluginOperations RestorePhase = "WaitingForPluginOperations"
// RestorePhaseWaitingForPluginOperationsPartiallyFailed means
// the restore of Kubernetes resources and other async plugin
// operations partially failed (final phase will be
// PartiallyFailed) and other plugin operations are still
// ongoing. The restore is not complete yet.
RestorePhaseWaitingForPluginOperationsPartiallyFailed RestorePhase = "WaitingForPluginOperationsPartiallyFailed"
// RestorePhaseCompleted means the restore has run successfully
// without errors.
RestorePhaseCompleted RestorePhase = "Completed"
+6 -6
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)
+67 -42
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
+3 -1
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)
}
+1 -1
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
+2 -2
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
+6 -6
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.
@@ -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
}
@@ -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")},
},
)
}
+46
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)
+110
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
@@ -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
@@ -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...),
+39
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
@@ -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
}
@@ -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
}
@@ -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,
}
}
@@ -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)
})
}
}
+7 -1
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
+48 -24
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,
})
+190 -49
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,
},
@@ -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",
}
+48
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)
+14 -1
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;
}
@@ -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;
}
@@ -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))
}
@@ -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
}
+27 -1
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
}
+10
View File
@@ -172,6 +172,11 @@ func (m *manager) PruneRepo(repo *velerov1api.BackupRepository) error {
if err != nil {
return errors.WithStack(err)
}
if err := prd.BoostRepoConnect(context.Background(), param); err != nil {
return errors.WithStack(err)
}
return prd.PruneRepo(context.Background(), param)
}
@@ -207,6 +212,11 @@ func (m *manager) Forget(ctx context.Context, snapshot SnapshotIdentifier) error
if err != nil {
return errors.WithStack(err)
}
if err := prd.BoostRepoConnect(context.Background(), param); err != nil {
return errors.WithStack(err)
}
return prd.Forget(context.Background(), snapshot.SnapshotID, param)
}
+5
View File
@@ -43,6 +43,11 @@ type Provider interface {
// is already initialized, or do nothing if the repository is already connected
PrepareRepo(ctx context.Context, param RepoParam) error
// BoostRepoConnect is used to re-ensure the local connection to the repo,
// so that the followed operations could succeed in some environment reset
// scenarios, for example, pod restart
BoostRepoConnect(ctx context.Context, param RepoParam) error
// PruneRepo does a full prune/maintenance of the repository
PruneRepo(ctx context.Context, param RepoParam) error
+4
View File
@@ -62,6 +62,10 @@ func (r *resticRepositoryProvider) PrepareRepo(ctx context.Context, param RepoPa
return nil
}
func (r *resticRepositoryProvider) BoostRepoConnect(ctx context.Context, param RepoParam) error {
return nil
}
func (r *resticRepositoryProvider) PruneRepo(ctx context.Context, param RepoParam) error {
return r.svc.PruneRepo(param.BackupLocation, param.BackupRepo)
}
+31
View File
@@ -200,6 +200,37 @@ func (urp *unifiedRepoProvider) PrepareRepo(ctx context.Context, param RepoParam
return nil
}
func (urp *unifiedRepoProvider) BoostRepoConnect(ctx context.Context, param RepoParam) error {
log := urp.log.WithFields(logrus.Fields{
"BSL name": param.BackupLocation.Name,
"repo name": param.BackupRepo.Name,
"repo UID": param.BackupRepo.UID,
})
log.Debug("Start to boost repo connect")
repoOption, err := udmrepo.NewRepoOptions(
udmrepo.WithPassword(urp, param),
udmrepo.WithConfigFile(urp.workPath, string(param.BackupRepo.UID)),
udmrepo.WithDescription(repoConnectDesc),
)
if err != nil {
return errors.Wrap(err, "error to get repo options")
}
bkRepo, err := urp.repoService.Open(ctx, *repoOption)
if err == nil {
if c := bkRepo.Close(ctx); c != nil {
log.WithError(c).Error("Failed to close repo")
}
return nil
}
return urp.ConnectToRepo(ctx, param)
}
func (urp *unifiedRepoProvider) PruneRepo(ctx context.Context, param RepoParam) error {
log := urp.log.WithFields(logrus.Fields{
"BSL name": param.BackupLocation.Name,
+1 -1
View File
@@ -137,7 +137,7 @@ func (rp *resticProvider) RunBackup(
summary, stderrBuf, err := restic.RunBackup(backupCmd, log, updater)
if err != nil {
if strings.Contains(err.Error(), "snapshot is empty") {
if strings.Contains(stderrBuf, "snapshot is empty") {
log.Debugf("Restic backup got empty dir with %s path", path)
return "", true, nil
}
+1 -1
View File
@@ -187,7 +187,7 @@ func isProvisionedByCSI(log logrus.FieldLogger, pv *corev1api.PersistentVolume,
}
for _, driver := range list.Items {
if driverName == driver.Name || migratedDriver == driver.Name {
log.Debugf("the annotation %s or %s equals to %s indicates the volume is provisioned by a CSI driver", KubeAnnDynamicallyProvisioned, KubeAnnMigratedTo, driverName)
log.Debugf("the annotation %s or %s equals to %s indicates the volume is provisioned by a CSI driver", KubeAnnDynamicallyProvisioned, KubeAnnMigratedTo, driver.Name)
return true, nil
}
}
+1 -1
View File
@@ -37,7 +37,7 @@ type SnapshotSpec struct {
Location string `json:"location"`
// PersistentVolumeName is the Kubernetes name for the volume.
PersistentVolumeName string `json:persistentVolumeName`
PersistentVolumeName string `json:"persistentVolumeName"`
// ProviderVolumeID is the provider's ID for the volume.
ProviderVolumeID string `json:"providerVolumeID"`
+3 -1
View File
@@ -145,7 +145,9 @@ status:
version: 1
# The date and time when the Backup is eligible for garbage collection.
expiration: null
# The current phase. Valid values are New, FailedValidation, InProgress, Completed, PartiallyFailed, Failed.
# The current phase.
# Valid values are New, FailedValidation, InProgress, WaitingForPluginOperations,
# WaitingForPluginOperationsPartiallyFailed, Completed, PartiallyFailed, Failed.
phase: ""
# An array of any validation errors encountered.
validationErrors: null
+3 -1
View File
@@ -179,7 +179,9 @@ spec:
onError: Continue
# RestoreStatus captures the current status of a Velero restore. Users should not set any data here.
status:
# The current phase. Valid values are New, FailedValidation, InProgress, Completed, PartiallyFailed, Failed.
# The current phase.
# Valid values are New, FailedValidation, InProgress, WaitingForPluginOperations,
# WaitingForPluginOperationsPartiallyFailed, Completed, PartiallyFailed, Failed.
phase: ""
# An array of any validation errors encountered.
validationErrors: null
+2 -1
View File
@@ -143,7 +143,8 @@ spec:
post:
# Same content as pre above.
status:
# The current phase of the latest scheduled backup. Valid values are New, FailedValidation, InProgress, Completed, PartiallyFailed, Failed.
# The current phase.
# Valid values are New, Enabled, FailedValidation.
phase: ""
# Date/time of the last backup for a given schedule
lastBackup: