mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-08-15 19:56:06 +00:00
Merge branch 'main' into issue-fix-5043
This commit is contained in:
@@ -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/**':
|
||||
|
||||
@@ -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'
|
||||
@@ -0,0 +1 @@
|
||||
BackupItemAction v2 API implementation
|
||||
@@ -0,0 +1,4 @@
|
||||
new backup and restore phases to support async plugin operations:
|
||||
- WaitingForPluginOperations
|
||||
- WaitingForPluginOperationsPartiallyFailed
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Fix error with Restic backup empty volumes
|
||||
@@ -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
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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=
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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!"
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")},
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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...),
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"`
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user