mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-03-26 19:45:06 +00:00
Compare commits
7 Commits
release-1.
...
plugin-int
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80828f727e | ||
|
|
de360a4b31 | ||
|
|
3cbd7976bd | ||
|
|
79d1616ecb | ||
|
|
f40f0d4e5b | ||
|
|
5c707d20c1 | ||
|
|
b059030666 |
@@ -29,6 +29,7 @@ import (
|
|||||||
"github.com/vmware-tanzu/velero/pkg/archive"
|
"github.com/vmware-tanzu/velero/pkg/archive"
|
||||||
"github.com/vmware-tanzu/velero/pkg/discovery"
|
"github.com/vmware-tanzu/velero/pkg/discovery"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
deleteactionitemv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/deleteitemaction/v2"
|
||||||
"github.com/vmware-tanzu/velero/pkg/util/collections"
|
"github.com/vmware-tanzu/velero/pkg/util/collections"
|
||||||
"github.com/vmware-tanzu/velero/pkg/util/filesystem"
|
"github.com/vmware-tanzu/velero/pkg/util/filesystem"
|
||||||
)
|
)
|
||||||
@@ -37,7 +38,7 @@ import (
|
|||||||
type Context struct {
|
type Context struct {
|
||||||
Backup *velerov1api.Backup
|
Backup *velerov1api.Backup
|
||||||
BackupReader io.Reader
|
BackupReader io.Reader
|
||||||
Actions []velero.DeleteItemAction
|
Actions []deleteactionitemv2.DeleteItemAction
|
||||||
Filesystem filesystem.Interface
|
Filesystem filesystem.Interface
|
||||||
Log logrus.FieldLogger
|
Log logrus.FieldLogger
|
||||||
DiscoveryHelper discovery.Helper
|
DiscoveryHelper discovery.Helper
|
||||||
@@ -163,7 +164,7 @@ func (ctx *Context) getApplicableActions(groupResource schema.GroupResource, nam
|
|||||||
|
|
||||||
// resolvedActions are DeleteItemActions decorated with resource/namespace include/exclude collections, as well as label selectors for easy comparison.
|
// resolvedActions are DeleteItemActions decorated with resource/namespace include/exclude collections, as well as label selectors for easy comparison.
|
||||||
type resolvedAction struct {
|
type resolvedAction struct {
|
||||||
velero.DeleteItemAction
|
deleteactionitemv2.DeleteItemAction
|
||||||
|
|
||||||
resourceIncludesExcludes *collections.IncludesExcludes
|
resourceIncludesExcludes *collections.IncludesExcludes
|
||||||
namespaceIncludesExcludes *collections.IncludesExcludes
|
namespaceIncludesExcludes *collections.IncludesExcludes
|
||||||
@@ -171,7 +172,7 @@ type resolvedAction struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// resolveActions resolves the AppliesTo ResourceSelectors of DeleteItemActions plugins against the Kubernetes discovery API for fully-qualified names.
|
// resolveActions resolves the AppliesTo ResourceSelectors of DeleteItemActions plugins against the Kubernetes discovery API for fully-qualified names.
|
||||||
func resolveActions(actions []velero.DeleteItemAction, helper discovery.Helper) ([]resolvedAction, error) {
|
func resolveActions(actions []deleteactionitemv2.DeleteItemAction, helper discovery.Helper) ([]resolvedAction, error) {
|
||||||
var resolved []resolvedAction
|
var resolved []resolvedAction
|
||||||
|
|
||||||
for _, action := range actions {
|
for _, action := range actions {
|
||||||
|
|||||||
@@ -44,7 +44,8 @@ import (
|
|||||||
"github.com/vmware-tanzu/velero/pkg/discovery"
|
"github.com/vmware-tanzu/velero/pkg/discovery"
|
||||||
velerov1client "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1"
|
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/kuberesource"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
backupitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
|
||||||
|
volumesnapshotterv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v2"
|
||||||
"github.com/vmware-tanzu/velero/pkg/podexec"
|
"github.com/vmware-tanzu/velero/pkg/podexec"
|
||||||
"github.com/vmware-tanzu/velero/pkg/restic"
|
"github.com/vmware-tanzu/velero/pkg/restic"
|
||||||
"github.com/vmware-tanzu/velero/pkg/util/collections"
|
"github.com/vmware-tanzu/velero/pkg/util/collections"
|
||||||
@@ -61,7 +62,8 @@ const BackupFormatVersion = "1.1.0"
|
|||||||
type Backupper interface {
|
type Backupper interface {
|
||||||
// Backup takes a backup using the specification in the velerov1api.Backup and writes backup and log data
|
// Backup takes a backup using the specification in the velerov1api.Backup and writes backup and log data
|
||||||
// to the given writers.
|
// to the given writers.
|
||||||
Backup(logger logrus.FieldLogger, backup *Request, backupFile io.Writer, actions []velero.BackupItemAction, volumeSnapshotterGetter VolumeSnapshotterGetter) error
|
Backup(logger logrus.FieldLogger, backup *Request, backupFile io.Writer,
|
||||||
|
actions []backupitemactionv2.BackupItemAction, volumeSnapshotterGetter VolumeSnapshotterGetter) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// kubernetesBackupper implements Backupper.
|
// kubernetesBackupper implements Backupper.
|
||||||
@@ -77,7 +79,7 @@ type kubernetesBackupper struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type resolvedAction struct {
|
type resolvedAction struct {
|
||||||
velero.BackupItemAction
|
backupitemactionv2.BackupItemAction
|
||||||
|
|
||||||
resourceIncludesExcludes *collections.IncludesExcludes
|
resourceIncludesExcludes *collections.IncludesExcludes
|
||||||
namespaceIncludesExcludes *collections.IncludesExcludes
|
namespaceIncludesExcludes *collections.IncludesExcludes
|
||||||
@@ -121,7 +123,7 @@ func NewKubernetesBackupper(
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveActions(actions []velero.BackupItemAction, helper discovery.Helper) ([]resolvedAction, error) {
|
func resolveActions(actions []backupitemactionv2.BackupItemAction, helper discovery.Helper) ([]resolvedAction, error) {
|
||||||
var resolved []resolvedAction
|
var resolved []resolvedAction
|
||||||
|
|
||||||
for _, action := range actions {
|
for _, action := range actions {
|
||||||
@@ -197,7 +199,7 @@ func getResourceHook(hookSpec velerov1api.BackupResourceHookSpec, discoveryHelpe
|
|||||||
}
|
}
|
||||||
|
|
||||||
type VolumeSnapshotterGetter interface {
|
type VolumeSnapshotterGetter interface {
|
||||||
GetVolumeSnapshotter(name string) (velero.VolumeSnapshotter, error)
|
GetVolumeSnapshotter(name string) (volumesnapshotterv2.VolumeSnapshotter, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backup backs up the items specified in the Backup, placing them in a gzip-compressed tar file
|
// Backup backs up the items specified in the Backup, placing them in a gzip-compressed tar file
|
||||||
@@ -205,7 +207,8 @@ type VolumeSnapshotterGetter interface {
|
|||||||
// a complete backup failure is returned. Errors that constitute partial failures (i.e. failures to
|
// a complete backup failure is returned. Errors that constitute partial failures (i.e. failures to
|
||||||
// back up individual resources that don't prevent the backup from continuing to be processed) are logged
|
// back up individual resources that don't prevent the backup from continuing to be processed) are logged
|
||||||
// to the backup log.
|
// to the backup log.
|
||||||
func (kb *kubernetesBackupper) Backup(log logrus.FieldLogger, backupRequest *Request, backupFile io.Writer, actions []velero.BackupItemAction, volumeSnapshotterGetter VolumeSnapshotterGetter) error {
|
func (kb *kubernetesBackupper) Backup(log logrus.FieldLogger, backupRequest *Request, backupFile io.Writer,
|
||||||
|
actions []backupitemactionv2.BackupItemAction, volumeSnapshotterGetter VolumeSnapshotterGetter) error {
|
||||||
gzippedData := gzip.NewWriter(backupFile)
|
gzippedData := gzip.NewWriter(backupFile)
|
||||||
defer gzippedData.Close()
|
defer gzippedData.Close()
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import (
|
|||||||
"github.com/vmware-tanzu/velero/pkg/discovery"
|
"github.com/vmware-tanzu/velero/pkg/discovery"
|
||||||
"github.com/vmware-tanzu/velero/pkg/kuberesource"
|
"github.com/vmware-tanzu/velero/pkg/kuberesource"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
backupitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
|
||||||
"github.com/vmware-tanzu/velero/pkg/restic"
|
"github.com/vmware-tanzu/velero/pkg/restic"
|
||||||
"github.com/vmware-tanzu/velero/pkg/test"
|
"github.com/vmware-tanzu/velero/pkg/test"
|
||||||
testutil "github.com/vmware-tanzu/velero/pkg/test"
|
testutil "github.com/vmware-tanzu/velero/pkg/test"
|
||||||
@@ -1331,7 +1332,7 @@ func TestBackupActionsRunForCorrectItems(t *testing.T) {
|
|||||||
h.addItems(t, resource)
|
h.addItems(t, resource)
|
||||||
}
|
}
|
||||||
|
|
||||||
actions := []velero.BackupItemAction{}
|
actions := []backupitemactionv2.BackupItemAction{}
|
||||||
for action := range tc.actions {
|
for action := range tc.actions {
|
||||||
actions = append(actions, action)
|
actions = append(actions, action)
|
||||||
}
|
}
|
||||||
@@ -1357,7 +1358,7 @@ func TestBackupWithInvalidActions(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
backup *velerov1.Backup
|
backup *velerov1.Backup
|
||||||
apiResources []*test.APIResource
|
apiResources []*test.APIResource
|
||||||
actions []velero.BackupItemAction
|
actions []backupitemactionv2.BackupItemAction
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "action with invalid label selector results in an error",
|
name: "action with invalid label selector results in an error",
|
||||||
@@ -1373,7 +1374,7 @@ func TestBackupWithInvalidActions(t *testing.T) {
|
|||||||
builder.ForPersistentVolume("baz").Result(),
|
builder.ForPersistentVolume("baz").Result(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
actions: []velero.BackupItemAction{
|
actions: []backupitemactionv2.BackupItemAction{
|
||||||
new(recordResourcesAction).ForLabelSelector("=invalid-selector"),
|
new(recordResourcesAction).ForLabelSelector("=invalid-selector"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -1391,7 +1392,7 @@ func TestBackupWithInvalidActions(t *testing.T) {
|
|||||||
builder.ForPersistentVolume("baz").Result(),
|
builder.ForPersistentVolume("baz").Result(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
actions: []velero.BackupItemAction{
|
actions: []backupitemactionv2.BackupItemAction{
|
||||||
&appliesToErrorAction{},
|
&appliesToErrorAction{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -1453,7 +1454,7 @@ func TestBackupActionModifications(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
backup *velerov1.Backup
|
backup *velerov1.Backup
|
||||||
apiResources []*test.APIResource
|
apiResources []*test.APIResource
|
||||||
actions []velero.BackupItemAction
|
actions []backupitemactionv2.BackupItemAction
|
||||||
want map[string]unstructuredObject
|
want map[string]unstructuredObject
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@@ -1464,7 +1465,7 @@ func TestBackupActionModifications(t *testing.T) {
|
|||||||
builder.ForPod("ns-1", "pod-1").Result(),
|
builder.ForPod("ns-1", "pod-1").Result(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
actions: []velero.BackupItemAction{
|
actions: []backupitemactionv2.BackupItemAction{
|
||||||
modifyingActionGetter(func(item *unstructured.Unstructured) {
|
modifyingActionGetter(func(item *unstructured.Unstructured) {
|
||||||
item.SetLabels(map[string]string{"updated": "true"})
|
item.SetLabels(map[string]string{"updated": "true"})
|
||||||
}),
|
}),
|
||||||
@@ -1481,7 +1482,7 @@ func TestBackupActionModifications(t *testing.T) {
|
|||||||
builder.ForPod("ns-1", "pod-1").ObjectMeta(builder.WithLabels("should-be-removed", "true")).Result(),
|
builder.ForPod("ns-1", "pod-1").ObjectMeta(builder.WithLabels("should-be-removed", "true")).Result(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
actions: []velero.BackupItemAction{
|
actions: []backupitemactionv2.BackupItemAction{
|
||||||
modifyingActionGetter(func(item *unstructured.Unstructured) {
|
modifyingActionGetter(func(item *unstructured.Unstructured) {
|
||||||
item.SetLabels(nil)
|
item.SetLabels(nil)
|
||||||
}),
|
}),
|
||||||
@@ -1498,7 +1499,7 @@ func TestBackupActionModifications(t *testing.T) {
|
|||||||
builder.ForPod("ns-1", "pod-1").Result(),
|
builder.ForPod("ns-1", "pod-1").Result(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
actions: []velero.BackupItemAction{
|
actions: []backupitemactionv2.BackupItemAction{
|
||||||
modifyingActionGetter(func(item *unstructured.Unstructured) {
|
modifyingActionGetter(func(item *unstructured.Unstructured) {
|
||||||
item.Object["spec"].(map[string]interface{})["nodeName"] = "foo"
|
item.Object["spec"].(map[string]interface{})["nodeName"] = "foo"
|
||||||
}),
|
}),
|
||||||
@@ -1516,7 +1517,7 @@ func TestBackupActionModifications(t *testing.T) {
|
|||||||
builder.ForPod("ns-1", "pod-1").Result(),
|
builder.ForPod("ns-1", "pod-1").Result(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
actions: []velero.BackupItemAction{
|
actions: []backupitemactionv2.BackupItemAction{
|
||||||
modifyingActionGetter(func(item *unstructured.Unstructured) {
|
modifyingActionGetter(func(item *unstructured.Unstructured) {
|
||||||
item.SetName(item.GetName() + "-updated")
|
item.SetName(item.GetName() + "-updated")
|
||||||
item.SetNamespace(item.GetNamespace() + "-updated")
|
item.SetNamespace(item.GetNamespace() + "-updated")
|
||||||
@@ -1557,7 +1558,7 @@ func TestBackupActionAdditionalItems(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
backup *velerov1.Backup
|
backup *velerov1.Backup
|
||||||
apiResources []*test.APIResource
|
apiResources []*test.APIResource
|
||||||
actions []velero.BackupItemAction
|
actions []backupitemactionv2.BackupItemAction
|
||||||
want []string
|
want []string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@@ -1570,7 +1571,7 @@ func TestBackupActionAdditionalItems(t *testing.T) {
|
|||||||
builder.ForPod("ns-3", "pod-3").Result(),
|
builder.ForPod("ns-3", "pod-3").Result(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
actions: []velero.BackupItemAction{
|
actions: []backupitemactionv2.BackupItemAction{
|
||||||
&pluggableAction{
|
&pluggableAction{
|
||||||
selector: velero.ResourceSelector{IncludedNamespaces: []string{"ns-1"}},
|
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, error) {
|
||||||
@@ -1602,7 +1603,7 @@ func TestBackupActionAdditionalItems(t *testing.T) {
|
|||||||
builder.ForPod("ns-3", "pod-3").Result(),
|
builder.ForPod("ns-3", "pod-3").Result(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
actions: []velero.BackupItemAction{
|
actions: []backupitemactionv2.BackupItemAction{
|
||||||
&pluggableAction{
|
&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, error) {
|
||||||
additionalItems := []velero.ResourceIdentifier{
|
additionalItems := []velero.ResourceIdentifier{
|
||||||
@@ -1632,7 +1633,7 @@ func TestBackupActionAdditionalItems(t *testing.T) {
|
|||||||
builder.ForPersistentVolume("pv-2").Result(),
|
builder.ForPersistentVolume("pv-2").Result(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
actions: []velero.BackupItemAction{
|
actions: []backupitemactionv2.BackupItemAction{
|
||||||
&pluggableAction{
|
&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, error) {
|
||||||
additionalItems := []velero.ResourceIdentifier{
|
additionalItems := []velero.ResourceIdentifier{
|
||||||
@@ -1665,7 +1666,7 @@ func TestBackupActionAdditionalItems(t *testing.T) {
|
|||||||
builder.ForPersistentVolume("pv-2").Result(),
|
builder.ForPersistentVolume("pv-2").Result(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
actions: []velero.BackupItemAction{
|
actions: []backupitemactionv2.BackupItemAction{
|
||||||
&pluggableAction{
|
&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, error) {
|
||||||
additionalItems := []velero.ResourceIdentifier{
|
additionalItems := []velero.ResourceIdentifier{
|
||||||
@@ -1695,7 +1696,7 @@ func TestBackupActionAdditionalItems(t *testing.T) {
|
|||||||
builder.ForPersistentVolume("pv-2").Result(),
|
builder.ForPersistentVolume("pv-2").Result(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
actions: []velero.BackupItemAction{
|
actions: []backupitemactionv2.BackupItemAction{
|
||||||
&pluggableAction{
|
&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, error) {
|
||||||
additionalItems := []velero.ResourceIdentifier{
|
additionalItems := []velero.ResourceIdentifier{
|
||||||
@@ -1726,7 +1727,7 @@ func TestBackupActionAdditionalItems(t *testing.T) {
|
|||||||
builder.ForPersistentVolume("pv-2").Result(),
|
builder.ForPersistentVolume("pv-2").Result(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
actions: []velero.BackupItemAction{
|
actions: []backupitemactionv2.BackupItemAction{
|
||||||
&pluggableAction{
|
&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, error) {
|
||||||
additionalItems := []velero.ResourceIdentifier{
|
additionalItems := []velero.ResourceIdentifier{
|
||||||
@@ -1756,7 +1757,7 @@ func TestBackupActionAdditionalItems(t *testing.T) {
|
|||||||
builder.ForPod("ns-3", "pod-3").Result(),
|
builder.ForPod("ns-3", "pod-3").Result(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
actions: []velero.BackupItemAction{
|
actions: []backupitemactionv2.BackupItemAction{
|
||||||
&pluggableAction{
|
&pluggableAction{
|
||||||
selector: velero.ResourceSelector{IncludedNamespaces: []string{"ns-1"}},
|
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, error) {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import (
|
|||||||
"github.com/vmware-tanzu/velero/pkg/client"
|
"github.com/vmware-tanzu/velero/pkg/client"
|
||||||
"github.com/vmware-tanzu/velero/pkg/discovery"
|
"github.com/vmware-tanzu/velero/pkg/discovery"
|
||||||
"github.com/vmware-tanzu/velero/pkg/kuberesource"
|
"github.com/vmware-tanzu/velero/pkg/kuberesource"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
volumesnapshotterv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v2"
|
||||||
"github.com/vmware-tanzu/velero/pkg/restic"
|
"github.com/vmware-tanzu/velero/pkg/restic"
|
||||||
"github.com/vmware-tanzu/velero/pkg/util/boolptr"
|
"github.com/vmware-tanzu/velero/pkg/util/boolptr"
|
||||||
"github.com/vmware-tanzu/velero/pkg/volume"
|
"github.com/vmware-tanzu/velero/pkg/volume"
|
||||||
@@ -56,7 +56,7 @@ type itemBackupper struct {
|
|||||||
volumeSnapshotterGetter VolumeSnapshotterGetter
|
volumeSnapshotterGetter VolumeSnapshotterGetter
|
||||||
|
|
||||||
itemHookHandler hook.ItemHookHandler
|
itemHookHandler hook.ItemHookHandler
|
||||||
snapshotLocationVolumeSnapshotters map[string]velero.VolumeSnapshotter
|
snapshotLocationVolumeSnapshotters map[string]volumesnapshotterv2.VolumeSnapshotter
|
||||||
}
|
}
|
||||||
|
|
||||||
// backupItem backs up an individual item to tarWriter. The item may be excluded based on the
|
// backupItem backs up an individual item to tarWriter. The item may be excluded based on the
|
||||||
@@ -367,7 +367,8 @@ func (ib *itemBackupper) executeActions(
|
|||||||
|
|
||||||
// volumeSnapshotter instantiates and initializes a VolumeSnapshotter given a VolumeSnapshotLocation,
|
// volumeSnapshotter instantiates and initializes a VolumeSnapshotter given a VolumeSnapshotLocation,
|
||||||
// or returns an existing one if one's already been initialized for the location.
|
// or returns an existing one if one's already been initialized for the location.
|
||||||
func (ib *itemBackupper) volumeSnapshotter(snapshotLocation *velerov1api.VolumeSnapshotLocation) (velero.VolumeSnapshotter, error) {
|
func (ib *itemBackupper) volumeSnapshotter(snapshotLocation *velerov1api.VolumeSnapshotLocation) (
|
||||||
|
volumesnapshotterv2.VolumeSnapshotter, error) {
|
||||||
if bs, ok := ib.snapshotLocationVolumeSnapshotters[snapshotLocation.Name]; ok {
|
if bs, ok := ib.snapshotLocationVolumeSnapshotters[snapshotLocation.Name]; ok {
|
||||||
return bs, nil
|
return bs, nil
|
||||||
}
|
}
|
||||||
@@ -382,7 +383,7 @@ func (ib *itemBackupper) volumeSnapshotter(snapshotLocation *velerov1api.VolumeS
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ib.snapshotLocationVolumeSnapshotters == nil {
|
if ib.snapshotLocationVolumeSnapshotters == nil {
|
||||||
ib.snapshotLocationVolumeSnapshotters = make(map[string]velero.VolumeSnapshotter)
|
ib.snapshotLocationVolumeSnapshotters = make(map[string]volumesnapshotterv2.VolumeSnapshotter)
|
||||||
}
|
}
|
||||||
ib.snapshotLocationVolumeSnapshotters[snapshotLocation.Name] = bs
|
ib.snapshotLocationVolumeSnapshotters[snapshotLocation.Name] = bs
|
||||||
|
|
||||||
@@ -438,7 +439,7 @@ func (ib *itemBackupper) takePVSnapshot(obj runtime.Unstructured, log logrus.Fie
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
volumeID, location string
|
volumeID, location string
|
||||||
volumeSnapshotter velero.VolumeSnapshotter
|
volumeSnapshotter volumesnapshotterv2.VolumeSnapshotter
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, snapshotLocation := range ib.backupRequest.SnapshotLocations {
|
for _, snapshotLocation := range ib.backupRequest.SnapshotLocations {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ import (
|
|||||||
persistencemocks "github.com/vmware-tanzu/velero/pkg/persistence/mocks"
|
persistencemocks "github.com/vmware-tanzu/velero/pkg/persistence/mocks"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt"
|
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt"
|
||||||
pluginmocks "github.com/vmware-tanzu/velero/pkg/plugin/mocks"
|
pluginmocks "github.com/vmware-tanzu/velero/pkg/plugin/mocks"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
backupitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
|
||||||
velerotest "github.com/vmware-tanzu/velero/pkg/test"
|
velerotest "github.com/vmware-tanzu/velero/pkg/test"
|
||||||
"github.com/vmware-tanzu/velero/pkg/util/boolptr"
|
"github.com/vmware-tanzu/velero/pkg/util/boolptr"
|
||||||
"github.com/vmware-tanzu/velero/pkg/util/logging"
|
"github.com/vmware-tanzu/velero/pkg/util/logging"
|
||||||
@@ -58,7 +58,7 @@ type fakeBackupper struct {
|
|||||||
mock.Mock
|
mock.Mock
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *fakeBackupper) Backup(logger logrus.FieldLogger, backup *pkgbackup.Request, backupFile io.Writer, actions []velero.BackupItemAction, volumeSnapshotterGetter pkgbackup.VolumeSnapshotterGetter) error {
|
func (b *fakeBackupper) Backup(logger logrus.FieldLogger, backup *pkgbackup.Request, backupFile io.Writer, actions []backupitemactionv2.BackupItemAction, volumeSnapshotterGetter pkgbackup.VolumeSnapshotterGetter) error {
|
||||||
args := b.Called(logger, backup, backupFile, actions, volumeSnapshotterGetter)
|
args := b.Called(logger, backup, backupFile, actions, volumeSnapshotterGetter)
|
||||||
return args.Error(0)
|
return args.Error(0)
|
||||||
}
|
}
|
||||||
@@ -825,7 +825,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
|||||||
|
|
||||||
pluginManager.On("GetBackupItemActions").Return(nil, nil)
|
pluginManager.On("GetBackupItemActions").Return(nil, nil)
|
||||||
pluginManager.On("CleanupClients").Return(nil)
|
pluginManager.On("CleanupClients").Return(nil)
|
||||||
backupper.On("Backup", mock.Anything, mock.Anything, mock.Anything, []velero.BackupItemAction(nil), pluginManager).Return(nil)
|
backupper.On("Backup", mock.Anything, mock.Anything, mock.Anything, []backupitemactionv2.BackupItemAction(nil), pluginManager).Return(nil)
|
||||||
backupStore.On("BackupExists", test.backupLocation.Spec.StorageType.ObjectStorage.Bucket, test.backup.Name).Return(test.backupExists, test.existenceCheckError)
|
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.
|
// Ensure we have a CompletionTimestamp when uploading and that the backup name matches the backup in the object store.
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ import (
|
|||||||
"github.com/vmware-tanzu/velero/pkg/metrics"
|
"github.com/vmware-tanzu/velero/pkg/metrics"
|
||||||
"github.com/vmware-tanzu/velero/pkg/persistence"
|
"github.com/vmware-tanzu/velero/pkg/persistence"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt"
|
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
volumesnapshotter "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v2"
|
||||||
"github.com/vmware-tanzu/velero/pkg/restic"
|
"github.com/vmware-tanzu/velero/pkg/restic"
|
||||||
"github.com/vmware-tanzu/velero/pkg/util/filesystem"
|
"github.com/vmware-tanzu/velero/pkg/util/filesystem"
|
||||||
"github.com/vmware-tanzu/velero/pkg/util/kube"
|
"github.com/vmware-tanzu/velero/pkg/util/kube"
|
||||||
@@ -333,7 +333,7 @@ func (c *backupDeletionController) processRequest(req *velerov1api.DeleteBackupR
|
|||||||
if snapshots, err := backupStore.GetBackupVolumeSnapshots(backup.Name); err != nil {
|
if snapshots, err := backupStore.GetBackupVolumeSnapshots(backup.Name); err != nil {
|
||||||
errs = append(errs, errors.Wrap(err, "error getting backup's volume snapshots").Error())
|
errs = append(errs, errors.Wrap(err, "error getting backup's volume snapshots").Error())
|
||||||
} else {
|
} else {
|
||||||
volumeSnapshotters := make(map[string]velero.VolumeSnapshotter)
|
volumeSnapshotters := make(map[string]volumesnapshotter.VolumeSnapshotter)
|
||||||
|
|
||||||
for _, snapshot := range snapshots {
|
for _, snapshot := range snapshots {
|
||||||
log.WithField("providerSnapshotID", snapshot.Status.ProviderSnapshotID).Info("Removing snapshot associated with backup")
|
log.WithField("providerSnapshotID", snapshot.Status.ProviderSnapshotID).Info("Removing snapshot associated with backup")
|
||||||
@@ -433,7 +433,7 @@ func volumeSnapshotterForSnapshotLocation(
|
|||||||
namespace, snapshotLocationName string,
|
namespace, snapshotLocationName string,
|
||||||
snapshotLocationLister velerov1listers.VolumeSnapshotLocationLister,
|
snapshotLocationLister velerov1listers.VolumeSnapshotLocationLister,
|
||||||
pluginManager clientmgmt.Manager,
|
pluginManager clientmgmt.Manager,
|
||||||
) (velero.VolumeSnapshotter, error) {
|
) (volumesnapshotter.VolumeSnapshotter, error) {
|
||||||
snapshotLocation, err := snapshotLocationLister.VolumeSnapshotLocations(namespace).Get(snapshotLocationName)
|
snapshotLocation, err := snapshotLocationLister.VolumeSnapshotLocations(namespace).Get(snapshotLocationName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "error getting volume snapshot location %s", snapshotLocationName)
|
return nil, errors.Wrapf(err, "error getting volume snapshot location %s", snapshotLocationName)
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ import (
|
|||||||
persistencemocks "github.com/vmware-tanzu/velero/pkg/persistence/mocks"
|
persistencemocks "github.com/vmware-tanzu/velero/pkg/persistence/mocks"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt"
|
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt"
|
||||||
pluginmocks "github.com/vmware-tanzu/velero/pkg/plugin/mocks"
|
pluginmocks "github.com/vmware-tanzu/velero/pkg/plugin/mocks"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
deleteitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/deleteitemaction/v2"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero/mocks"
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero/mocks"
|
||||||
velerotest "github.com/vmware-tanzu/velero/pkg/test"
|
velerotest "github.com/vmware-tanzu/velero/pkg/test"
|
||||||
"github.com/vmware-tanzu/velero/pkg/volume"
|
"github.com/vmware-tanzu/velero/pkg/volume"
|
||||||
@@ -802,7 +802,7 @@ func TestBackupDeletionControllerProcessRequest(t *testing.T) {
|
|||||||
|
|
||||||
pluginManager := &pluginmocks.Manager{}
|
pluginManager := &pluginmocks.Manager{}
|
||||||
pluginManager.On("GetVolumeSnapshotter", "provider-1").Return(td.volumeSnapshotter, nil)
|
pluginManager.On("GetVolumeSnapshotter", "provider-1").Return(td.volumeSnapshotter, nil)
|
||||||
pluginManager.On("GetDeleteItemActions").Return([]velero.DeleteItemAction{}, nil)
|
pluginManager.On("GetDeleteItemActions").Return([]deleteitemactionv2.DeleteItemAction{}, nil)
|
||||||
pluginManager.On("CleanupClients")
|
pluginManager.On("CleanupClients")
|
||||||
td.controller.newPluginManager = func(logrus.FieldLogger) clientmgmt.Manager { return pluginManager }
|
td.controller.newPluginManager = func(logrus.FieldLogger) clientmgmt.Manager { return pluginManager }
|
||||||
|
|
||||||
@@ -932,7 +932,7 @@ func TestBackupDeletionControllerProcessRequest(t *testing.T) {
|
|||||||
|
|
||||||
pluginManager := &pluginmocks.Manager{}
|
pluginManager := &pluginmocks.Manager{}
|
||||||
pluginManager.On("GetVolumeSnapshotter", "provider-1").Return(td.volumeSnapshotter, nil)
|
pluginManager.On("GetVolumeSnapshotter", "provider-1").Return(td.volumeSnapshotter, nil)
|
||||||
pluginManager.On("GetDeleteItemActions").Return([]velero.DeleteItemAction{new(mocks.DeleteItemAction)}, nil)
|
pluginManager.On("GetDeleteItemActions").Return([]deleteitemactionv2.DeleteItemAction{new(mocks.DeleteItemAction)}, nil)
|
||||||
pluginManager.On("CleanupClients")
|
pluginManager.On("CleanupClients")
|
||||||
td.controller.newPluginManager = func(logrus.FieldLogger) clientmgmt.Manager { return pluginManager }
|
td.controller.newPluginManager = func(logrus.FieldLogger) clientmgmt.Manager { return pluginManager }
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import (
|
|||||||
"github.com/vmware-tanzu/velero/internal/credentials"
|
"github.com/vmware-tanzu/velero/internal/credentials"
|
||||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||||
"github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/scheme"
|
"github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/scheme"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
objectstorev2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/objectstore/v2"
|
||||||
"github.com/vmware-tanzu/velero/pkg/volume"
|
"github.com/vmware-tanzu/velero/pkg/volume"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -80,16 +80,16 @@ type BackupStore interface {
|
|||||||
const DownloadURLTTL = 10 * time.Minute
|
const DownloadURLTTL = 10 * time.Minute
|
||||||
|
|
||||||
type objectBackupStore struct {
|
type objectBackupStore struct {
|
||||||
objectStore velero.ObjectStore
|
objectStore objectstorev2.ObjectStore
|
||||||
bucket string
|
bucket string
|
||||||
layout *ObjectStoreLayout
|
layout *ObjectStoreLayout
|
||||||
logger logrus.FieldLogger
|
logger logrus.FieldLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObjectStoreGetter is a type that can get a velero.ObjectStore
|
// ObjectStoreGetter is a type that can get a objectstorev2.ObjectStore
|
||||||
// from a provider name.
|
// from a provider name.
|
||||||
type ObjectStoreGetter interface {
|
type ObjectStoreGetter interface {
|
||||||
GetObjectStore(provider string) (velero.ObjectStore, error)
|
GetObjectStore(provider string) (objectstorev2.ObjectStore, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObjectBackupStoreGetter is a type that can get a velero.BackupStore for a
|
// ObjectBackupStoreGetter is a type that can get a velero.BackupStore for a
|
||||||
@@ -326,7 +326,7 @@ func (s *objectBackupStore) GetBackupVolumeSnapshots(name string) ([]*volume.Sna
|
|||||||
|
|
||||||
// tryGet returns the object with the given key if it exists, nil if it does not exist,
|
// tryGet returns the object with the given key if it exists, nil if it does not exist,
|
||||||
// or an error if it was unable to check existence or get the object.
|
// or an error if it was unable to check existence or get the object.
|
||||||
func tryGet(objectStore velero.ObjectStore, bucket, key string) (io.ReadCloser, error) {
|
func tryGet(objectStore objectstorev2.ObjectStore, bucket, key string) (io.ReadCloser, error) {
|
||||||
exists, err := objectStore.ObjectExists(bucket, key)
|
exists, err := objectStore.ObjectExists(bucket, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.WithStack(err)
|
return nil, errors.WithStack(err)
|
||||||
@@ -494,7 +494,7 @@ func seekToBeginning(r io.Reader) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func seekAndPutObject(objectStore velero.ObjectStore, bucket, key string, file io.Reader) error {
|
func seekAndPutObject(objectStore objectstorev2.ObjectStore, bucket, key string, file io.Reader) error {
|
||||||
if file == nil {
|
if file == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ import (
|
|||||||
"github.com/vmware-tanzu/velero/internal/credentials"
|
"github.com/vmware-tanzu/velero/internal/credentials"
|
||||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||||
"github.com/vmware-tanzu/velero/pkg/builder"
|
"github.com/vmware-tanzu/velero/pkg/builder"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
|
||||||
providermocks "github.com/vmware-tanzu/velero/pkg/plugin/velero/mocks"
|
providermocks "github.com/vmware-tanzu/velero/pkg/plugin/velero/mocks"
|
||||||
|
objectstorev2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/objectstore/v2"
|
||||||
velerotest "github.com/vmware-tanzu/velero/pkg/test"
|
velerotest "github.com/vmware-tanzu/velero/pkg/test"
|
||||||
"github.com/vmware-tanzu/velero/pkg/util/encode"
|
"github.com/vmware-tanzu/velero/pkg/util/encode"
|
||||||
"github.com/vmware-tanzu/velero/pkg/volume"
|
"github.com/vmware-tanzu/velero/pkg/volume"
|
||||||
@@ -595,9 +595,9 @@ func TestGetDownloadURL(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type objectStoreGetter map[string]velero.ObjectStore
|
type objectStoreGetter map[string]objectstorev2.ObjectStore
|
||||||
|
|
||||||
func (osg objectStoreGetter) GetObjectStore(provider string) (velero.ObjectStore, error) {
|
func (osg objectStoreGetter) GetObjectStore(provider string) (objectstorev2.ObjectStore, error) {
|
||||||
res, ok := osg[provider]
|
res, ok := osg[provider]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("object store not found")
|
return nil, errors.New("object store not found")
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2020 the Velero contributors.
|
Copyright 2021 the Velero contributors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -73,6 +73,12 @@ func (b *clientBuilder) clientConfig() *hcplugin.ClientConfig {
|
|||||||
string(framework.PluginKindPluginLister): &framework.PluginListerPlugin{},
|
string(framework.PluginKindPluginLister): &framework.PluginListerPlugin{},
|
||||||
string(framework.PluginKindRestoreItemAction): framework.NewRestoreItemActionPlugin(framework.ClientLogger(b.clientLogger)),
|
string(framework.PluginKindRestoreItemAction): framework.NewRestoreItemActionPlugin(framework.ClientLogger(b.clientLogger)),
|
||||||
string(framework.PluginKindDeleteItemAction): framework.NewDeleteItemActionPlugin(framework.ClientLogger(b.clientLogger)),
|
string(framework.PluginKindDeleteItemAction): framework.NewDeleteItemActionPlugin(framework.ClientLogger(b.clientLogger)),
|
||||||
|
// Version 2
|
||||||
|
string(framework.PluginKindBackupItemActionV2): framework.NewBackupItemActionPlugin(framework.ClientLogger(b.clientLogger)),
|
||||||
|
string(framework.PluginKindVolumeSnapshotterV2): framework.NewVolumeSnapshotterPlugin(framework.ClientLogger(b.clientLogger)),
|
||||||
|
string(framework.PluginKindObjectStoreV2): framework.NewObjectStorePlugin(framework.ClientLogger(b.clientLogger)),
|
||||||
|
string(framework.PluginKindRestoreItemActionV2): framework.NewRestoreItemActionPlugin(framework.ClientLogger(b.clientLogger)),
|
||||||
|
string(framework.PluginKindDeleteItemActionV2): framework.NewDeleteItemActionPlugin(framework.ClientLogger(b.clientLogger)),
|
||||||
},
|
},
|
||||||
Logger: b.pluginLogger,
|
Logger: b.pluginLogger,
|
||||||
Cmd: exec.Command(b.commandName, b.commandArgs...),
|
Cmd: exec.Command(b.commandName, b.commandArgs...),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2020 the Velero contributors.
|
Copyright 2021 the Velero contributors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -17,40 +17,46 @@ limitations under the License.
|
|||||||
package clientmgmt
|
package clientmgmt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
backupitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
|
||||||
|
deleteitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/deleteitemaction/v2"
|
||||||
|
objectstorev2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/objectstore/v2"
|
||||||
|
restoreitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v2"
|
||||||
|
volumesnapshotterv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Manager manages the lifecycles of plugins.
|
// Manager manages the lifecycles of plugins.
|
||||||
type Manager interface {
|
type Manager interface {
|
||||||
// GetObjectStore returns the ObjectStore plugin for name.
|
// GetObjectStore returns the ObjectStore plugin for name.
|
||||||
GetObjectStore(name string) (velero.ObjectStore, error)
|
GetObjectStore(name string) (objectstorev2.ObjectStore, error)
|
||||||
|
|
||||||
// GetVolumeSnapshotter returns the VolumeSnapshotter plugin for name.
|
// GetVolumeSnapshotter returns the VolumeSnapshotter plugin for name.
|
||||||
GetVolumeSnapshotter(name string) (velero.VolumeSnapshotter, error)
|
GetVolumeSnapshotter(name string) (volumesnapshotterv2.VolumeSnapshotter, error)
|
||||||
|
|
||||||
// GetBackupItemActions returns all backup item action plugins.
|
// GetBackupItemActions returns all backup item action plugins.
|
||||||
GetBackupItemActions() ([]velero.BackupItemAction, error)
|
GetBackupItemActions() ([]backupitemactionv2.BackupItemAction, error)
|
||||||
|
|
||||||
// GetBackupItemAction returns the backup item action plugin for name.
|
// GetBackupItemAction returns the backup item action plugin for name.
|
||||||
GetBackupItemAction(name string) (velero.BackupItemAction, error)
|
GetBackupItemAction(name string) (backupitemactionv2.BackupItemAction, error)
|
||||||
|
|
||||||
// GetRestoreItemActions returns all restore item action plugins.
|
// GetRestoreItemActions returns all restore item action plugins.
|
||||||
GetRestoreItemActions() ([]velero.RestoreItemAction, error)
|
GetRestoreItemActions() ([]restoreitemactionv2.RestoreItemAction, error)
|
||||||
|
|
||||||
// GetRestoreItemAction returns the restore item action plugin for name.
|
// GetRestoreItemAction returns the restore item action plugin for name.
|
||||||
GetRestoreItemAction(name string) (velero.RestoreItemAction, error)
|
GetRestoreItemAction(name string) (restoreitemactionv2.RestoreItemAction, error)
|
||||||
|
|
||||||
// GetDeleteItemActions returns all delete item action plugins.
|
// GetDeleteItemActions returns all delete item action plugins.
|
||||||
GetDeleteItemActions() ([]velero.DeleteItemAction, error)
|
GetDeleteItemActions() ([]deleteitemactionv2.DeleteItemAction, error)
|
||||||
|
|
||||||
// GetDeleteItemAction returns the delete item action plugin for name.
|
// GetDeleteItemAction returns the delete item action plugin for name.
|
||||||
GetDeleteItemAction(name string) (velero.DeleteItemAction, error)
|
GetDeleteItemAction(name string) (deleteitemactionv2.DeleteItemAction, error)
|
||||||
|
|
||||||
// CleanupClients terminates all of the Manager's running plugin processes.
|
// CleanupClients terminates all of the Manager's running plugin processes.
|
||||||
CleanupClients()
|
CleanupClients()
|
||||||
@@ -129,39 +135,82 @@ func (m *manager) getRestartableProcess(kind framework.PluginKind, name string)
|
|||||||
return restartableProcess, nil
|
return restartableProcess, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetObjectStore returns a restartableObjectStore for name.
|
type RestartableObjectStore struct {
|
||||||
func (m *manager) GetObjectStore(name string) (velero.ObjectStore, error) {
|
kind framework.PluginKind
|
||||||
name = sanitizeName(name)
|
// Get returns a restartable ObjectStore for the given name and process, wrapping if necessary
|
||||||
|
Get func(name string, restartableProcess RestartableProcess) objectstorev2.ObjectStore
|
||||||
|
}
|
||||||
|
|
||||||
restartableProcess, err := m.getRestartableProcess(framework.PluginKindObjectStore, name)
|
func (m *manager) restartableObjectStores() []RestartableObjectStore {
|
||||||
if err != nil {
|
return []RestartableObjectStore{
|
||||||
return nil, err
|
{
|
||||||
|
kind: framework.PluginKindObjectStoreV2,
|
||||||
|
Get: newRestartableObjectStoreV2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: framework.PluginKindObjectStore,
|
||||||
|
Get: newAdaptedV1ObjectStore, // Adapt v1 plugin to v2
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
r := newRestartableObjectStore(name, restartableProcess)
|
// GetObjectStore returns a restartableObjectStore for name.
|
||||||
|
func (m *manager) GetObjectStore(name string) (objectstorev2.ObjectStore, error) {
|
||||||
|
name = sanitizeName(name)
|
||||||
|
for _, restartableObjStore := range m.restartableObjectStores() {
|
||||||
|
restartableProcess, err := m.getRestartableProcess(restartableObjStore.kind, name)
|
||||||
|
if err != nil {
|
||||||
|
// Check if plugin was not found
|
||||||
|
if errors.Is(err, &pluginNotFoundError{}) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return restartableObjStore.Get(name, restartableProcess), nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unable to get valid ObjectStore for %q", name)
|
||||||
|
}
|
||||||
|
|
||||||
return r, nil
|
type RestartableVolumeSnapshotter struct {
|
||||||
|
kind framework.PluginKind
|
||||||
|
// Get returns a restartable VolumeSnapshotter for the given name and process, wrapping if necessary
|
||||||
|
Get func(name string, restartableProcess RestartableProcess) volumesnapshotterv2.VolumeSnapshotter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *manager) restartableVolumeSnapshotters() []RestartableVolumeSnapshotter {
|
||||||
|
return []RestartableVolumeSnapshotter{
|
||||||
|
{
|
||||||
|
kind: framework.PluginKindVolumeSnapshotterV2,
|
||||||
|
Get: newRestartableVolumeSnapshotterV2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: framework.PluginKindVolumeSnapshotter,
|
||||||
|
Get: newAdaptedV1VolumeSnapshotter, // Adapt v1 plugin to v2
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVolumeSnapshotter returns a restartableVolumeSnapshotter for name.
|
// GetVolumeSnapshotter returns a restartableVolumeSnapshotter for name.
|
||||||
func (m *manager) GetVolumeSnapshotter(name string) (velero.VolumeSnapshotter, error) {
|
func (m *manager) GetVolumeSnapshotter(name string) (volumesnapshotterv2.VolumeSnapshotter, error) {
|
||||||
name = sanitizeName(name)
|
name = sanitizeName(name)
|
||||||
|
for _, restartableVolumeSnapshotter := range m.restartableVolumeSnapshotters() {
|
||||||
restartableProcess, err := m.getRestartableProcess(framework.PluginKindVolumeSnapshotter, name)
|
restartableProcess, err := m.getRestartableProcess(restartableVolumeSnapshotter.kind, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
// Check if plugin was not found
|
||||||
|
if errors.Is(err, &pluginNotFoundError{}) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return restartableVolumeSnapshotter.Get(name, restartableProcess), nil
|
||||||
}
|
}
|
||||||
|
return nil, fmt.Errorf("unable to get valid VolumeSnapshotter for %q", name)
|
||||||
r := newRestartableVolumeSnapshotter(name, restartableProcess)
|
|
||||||
|
|
||||||
return r, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBackupItemActions returns all backup item actions as restartableBackupItemActions.
|
// GetBackupItemActions returns all backup item actions as restartableBackupItemActions.
|
||||||
func (m *manager) GetBackupItemActions() ([]velero.BackupItemAction, error) {
|
func (m *manager) GetBackupItemActions() ([]backupitemactionv2.BackupItemAction, error) {
|
||||||
list := m.registry.List(framework.PluginKindBackupItemAction)
|
list := m.registry.ListForKinds(framework.BackupItemActionKinds())
|
||||||
|
actions := make([]backupitemactionv2.BackupItemAction, 0, len(list))
|
||||||
actions := make([]velero.BackupItemAction, 0, len(list))
|
|
||||||
|
|
||||||
for i := range list {
|
for i := range list {
|
||||||
id := list[i]
|
id := list[i]
|
||||||
@@ -177,24 +226,47 @@ func (m *manager) GetBackupItemActions() ([]velero.BackupItemAction, error) {
|
|||||||
return actions, nil
|
return actions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBackupItemAction returns a restartableBackupItemAction for name.
|
type RestartableBackupItemAction struct {
|
||||||
func (m *manager) GetBackupItemAction(name string) (velero.BackupItemAction, error) {
|
kind framework.PluginKind
|
||||||
name = sanitizeName(name)
|
// Get returns a restartable BackupItemAction for the given name and process, wrapping if necessary
|
||||||
|
Get func(name string, restartableProcess RestartableProcess) backupitemactionv2.BackupItemAction
|
||||||
|
}
|
||||||
|
|
||||||
restartableProcess, err := m.getRestartableProcess(framework.PluginKindBackupItemAction, name)
|
func (m *manager) restartableBackupItemActions() []RestartableBackupItemAction {
|
||||||
if err != nil {
|
return []RestartableBackupItemAction{
|
||||||
return nil, err
|
{
|
||||||
|
kind: framework.PluginKindBackupItemActionV2,
|
||||||
|
Get: newRestartableBackupItemActionV2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: framework.PluginKindBackupItemAction,
|
||||||
|
Get: newAdaptedV1BackupItemAction, // Adapt v1 plugin to v2
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
r := newRestartableBackupItemAction(name, restartableProcess)
|
// GetBackupItemAction returns a restartableBackupItemAction for name.
|
||||||
return r, nil
|
func (m *manager) GetBackupItemAction(name string) (backupitemactionv2.BackupItemAction, error) {
|
||||||
|
name = sanitizeName(name)
|
||||||
|
for _, restartableBackupItemAction := range m.restartableBackupItemActions() {
|
||||||
|
restartableProcess, err := m.getRestartableProcess(restartableBackupItemAction.kind, name)
|
||||||
|
if err != nil {
|
||||||
|
// Check if plugin was not found
|
||||||
|
if errors.Is(err, &pluginNotFoundError{}) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return restartableBackupItemAction.Get(name, restartableProcess), nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unable to get valid BackupItemAction for %q", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRestoreItemActions returns all restore item actions as restartableRestoreItemActions.
|
// GetRestoreItemActions returns all restore item actions as restartableRestoreItemActions.
|
||||||
func (m *manager) GetRestoreItemActions() ([]velero.RestoreItemAction, error) {
|
func (m *manager) GetRestoreItemActions() ([]restoreitemactionv2.RestoreItemAction, error) {
|
||||||
list := m.registry.List(framework.PluginKindRestoreItemAction)
|
list := m.registry.ListForKinds(framework.RestoreItemActionKinds())
|
||||||
|
|
||||||
actions := make([]velero.RestoreItemAction, 0, len(list))
|
actions := make([]restoreitemactionv2.RestoreItemAction, 0, len(list))
|
||||||
|
|
||||||
for i := range list {
|
for i := range list {
|
||||||
id := list[i]
|
id := list[i]
|
||||||
@@ -210,24 +282,47 @@ func (m *manager) GetRestoreItemActions() ([]velero.RestoreItemAction, error) {
|
|||||||
return actions, nil
|
return actions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRestoreItemAction returns a restartableRestoreItemAction for name.
|
type RestartableRestoreItemAction struct {
|
||||||
func (m *manager) GetRestoreItemAction(name string) (velero.RestoreItemAction, error) {
|
kind framework.PluginKind
|
||||||
name = sanitizeName(name)
|
// Get returns a restartable RestoreItemAction for the given name and process, wrapping if necessary
|
||||||
|
Get func(name string, restartableProcess RestartableProcess) restoreitemactionv2.RestoreItemAction
|
||||||
|
}
|
||||||
|
|
||||||
restartableProcess, err := m.getRestartableProcess(framework.PluginKindRestoreItemAction, name)
|
func (m *manager) restartableRestoreItemActions() []RestartableRestoreItemAction {
|
||||||
if err != nil {
|
return []RestartableRestoreItemAction{
|
||||||
return nil, err
|
{
|
||||||
|
kind: framework.PluginKindRestoreItemActionV2,
|
||||||
|
Get: newRestartableRestoreItemActionV2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: framework.PluginKindRestoreItemAction,
|
||||||
|
Get: newAdaptedV1RestoreItemAction, // Adapt v1 plugin to v2
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
r := newRestartableRestoreItemAction(name, restartableProcess)
|
// GetRestoreItemAction returns a restartableRestoreItemAction for name.
|
||||||
return r, nil
|
func (m *manager) GetRestoreItemAction(name string) (restoreitemactionv2.RestoreItemAction, error) {
|
||||||
|
name = sanitizeName(name)
|
||||||
|
for _, restartableRestoreItemAction := range m.restartableRestoreItemActions() {
|
||||||
|
restartableProcess, err := m.getRestartableProcess(restartableRestoreItemAction.kind, name)
|
||||||
|
if err != nil {
|
||||||
|
// Check if plugin was not found
|
||||||
|
if errors.Is(err, &pluginNotFoundError{}) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return restartableRestoreItemAction.Get(name, restartableProcess), nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unable to get valid RestoreItemAction for %q", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDeleteItemActions returns all delete item actions as restartableDeleteItemActions.
|
// GetDeleteItemActions returns all delete item actions as restartableDeleteItemActions.
|
||||||
func (m *manager) GetDeleteItemActions() ([]velero.DeleteItemAction, error) {
|
func (m *manager) GetDeleteItemActions() ([]deleteitemactionv2.DeleteItemAction, error) {
|
||||||
list := m.registry.List(framework.PluginKindDeleteItemAction)
|
list := m.registry.ListForKinds(framework.DeleteItemActionKinds())
|
||||||
|
|
||||||
actions := make([]velero.DeleteItemAction, 0, len(list))
|
actions := make([]deleteitemactionv2.DeleteItemAction, 0, len(list))
|
||||||
|
|
||||||
for i := range list {
|
for i := range list {
|
||||||
id := list[i]
|
id := list[i]
|
||||||
@@ -243,17 +338,40 @@ func (m *manager) GetDeleteItemActions() ([]velero.DeleteItemAction, error) {
|
|||||||
return actions, nil
|
return actions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDeleteItemAction returns a restartableDeleteItemAction for name.
|
type RestartableDeleteItemAction struct {
|
||||||
func (m *manager) GetDeleteItemAction(name string) (velero.DeleteItemAction, error) {
|
kind framework.PluginKind
|
||||||
name = sanitizeName(name)
|
// Get returns a restartable DeleteItemAction for the given name and process, wrapping if necessary
|
||||||
|
Get func(name string, restartableProcess RestartableProcess) deleteitemactionv2.DeleteItemAction
|
||||||
|
}
|
||||||
|
|
||||||
restartableProcess, err := m.getRestartableProcess(framework.PluginKindDeleteItemAction, name)
|
func (m *manager) restartableDeleteItemActions() []RestartableDeleteItemAction {
|
||||||
if err != nil {
|
return []RestartableDeleteItemAction{
|
||||||
return nil, err
|
{
|
||||||
|
kind: framework.PluginKindDeleteItemActionV2,
|
||||||
|
Get: newRestartableDeleteItemActionV2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: framework.PluginKindDeleteItemAction,
|
||||||
|
Get: newAdaptedV1DeleteItemAction, // Adapt v1 plugin to v2
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
r := newRestartableDeleteItemAction(name, restartableProcess)
|
// GetDeleteItemAction returns a restartableDeleteItemAction for name.
|
||||||
return r, nil
|
func (m *manager) GetDeleteItemAction(name string) (deleteitemactionv2.DeleteItemAction, error) {
|
||||||
|
name = sanitizeName(name)
|
||||||
|
for _, restartableDeleteItemAction := range m.restartableDeleteItemActions() {
|
||||||
|
restartableProcess, err := m.getRestartableProcess(restartableDeleteItemAction.kind, name)
|
||||||
|
if err != nil {
|
||||||
|
// Check if plugin was not found
|
||||||
|
if errors.Is(err, &pluginNotFoundError{}) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return restartableDeleteItemAction.Get(name, restartableProcess), nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unable to get valid DeleteItemAction for %q", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sanitizeName adds "velero.io" to legacy plugins that weren't namespaced.
|
// sanitizeName adds "velero.io" to legacy plugins that weren't namespaced.
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ type Registry interface {
|
|||||||
DiscoverPlugins() error
|
DiscoverPlugins() error
|
||||||
// List returns all PluginIdentifiers for kind.
|
// List returns all PluginIdentifiers for kind.
|
||||||
List(kind framework.PluginKind) []framework.PluginIdentifier
|
List(kind framework.PluginKind) []framework.PluginIdentifier
|
||||||
|
// List returns all PluginIdentifiers for a list of kinds.
|
||||||
|
ListForKinds(kinds []framework.PluginKind) (list []framework.PluginIdentifier)
|
||||||
// Get returns the PluginIdentifier for kind and name.
|
// Get returns the PluginIdentifier for kind and name.
|
||||||
Get(kind framework.PluginKind, name string) (framework.PluginIdentifier, error)
|
Get(kind framework.PluginKind, name string) (framework.PluginIdentifier, error)
|
||||||
}
|
}
|
||||||
@@ -108,6 +110,13 @@ func (r *registry) discoverPlugins(commands []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *registry) ListForKinds(kinds []framework.PluginKind) (list []framework.PluginIdentifier) {
|
||||||
|
for _, kind := range kinds {
|
||||||
|
list = append(list, r.pluginsByKind[kind]...)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// List returns info about all plugin binaries that implement the given
|
// List returns info about all plugin binaries that implement the given
|
||||||
// PluginKind.
|
// PluginKind.
|
||||||
func (r *registry) List(kind framework.PluginKind) []framework.PluginIdentifier {
|
func (r *registry) List(kind framework.PluginKind) []framework.PluginIdentifier {
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 the Velero contributors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package clientmgmt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
|
||||||
|
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||||
|
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
||||||
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
backupitemactionv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v1"
|
||||||
|
backupitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type restartableAdaptedV1BackupItemAction struct {
|
||||||
|
key kindAndName
|
||||||
|
sharedPluginProcess RestartableProcess
|
||||||
|
}
|
||||||
|
|
||||||
|
// newAdaptedV1BackupItemAction returns a new restartableAdaptedV1BackupItemAction.
|
||||||
|
func newAdaptedV1BackupItemAction(
|
||||||
|
name string, sharedPluginProcess RestartableProcess) backupitemactionv2.BackupItemAction {
|
||||||
|
r := &restartableAdaptedV1BackupItemAction{
|
||||||
|
key: kindAndName{kind: framework.PluginKindBackupItemAction, name: name},
|
||||||
|
sharedPluginProcess: sharedPluginProcess,
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// getBackupItemAction returns the backup item action for this restartableAdaptedV1BackupItemAction.
|
||||||
|
// It does *not* restart the plugin process.
|
||||||
|
func (r *restartableAdaptedV1BackupItemAction) getBackupItemAction() (backupitemactionv1.BackupItemAction, error) {
|
||||||
|
plugin, err := r.sharedPluginProcess.getByKindAndName(r.key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
backupItemAction, ok := plugin.(backupitemactionv1.BackupItemAction)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.Errorf("%T is not a BackupItemAction!", plugin)
|
||||||
|
}
|
||||||
|
|
||||||
|
return backupItemAction, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getDelegate restarts the plugin process (if needed) and returns the backup item
|
||||||
|
// action for this restartableAdaptedV1BackupItemAction.
|
||||||
|
func (r *restartableAdaptedV1BackupItemAction) getDelegate() (backupitemactionv1.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 *restartableAdaptedV1BackupItemAction) 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 *restartableAdaptedV1BackupItemAction) Execute(
|
||||||
|
item runtime.Unstructured, backup *api.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return delegate.Execute(item, backup)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version 2: simply discard ctx and call version 1 function.
|
||||||
|
// ExecuteV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1BackupItemAction) ExecuteV2(
|
||||||
|
ctx context.Context, item runtime.Unstructured, backup *api.Backup) (
|
||||||
|
runtime.Unstructured, []velero.ResourceIdentifier, error) {
|
||||||
|
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return delegate.Execute(item, backup)
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 the Velero contributors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package clientmgmt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
||||||
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
deleteitemactionv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/deleteitemaction/v1"
|
||||||
|
deleteitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/deleteitemaction/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type restartableAdaptedV1DeleteItemAction struct {
|
||||||
|
key kindAndName
|
||||||
|
sharedPluginProcess RestartableProcess
|
||||||
|
config map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// newAdaptedV1DeleteItemAction returns a new restartableAdaptedV1DeleteItemAction.
|
||||||
|
func newAdaptedV1DeleteItemAction(
|
||||||
|
name string, sharedPluginProcess RestartableProcess) deleteitemactionv2.DeleteItemAction {
|
||||||
|
r := &restartableAdaptedV1DeleteItemAction{
|
||||||
|
key: kindAndName{kind: framework.PluginKindDeleteItemAction, name: name},
|
||||||
|
sharedPluginProcess: sharedPluginProcess,
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// getDeleteItemAction returns the delete item action for this restartableDeleteItemAction.
|
||||||
|
// It does *not* restart the plugin process.
|
||||||
|
func (r *restartableAdaptedV1DeleteItemAction) getDeleteItemAction() (deleteitemactionv1.DeleteItemAction, error) {
|
||||||
|
plugin, err := r.sharedPluginProcess.getByKindAndName(r.key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteItemAction, ok := plugin.(deleteitemactionv1.DeleteItemAction)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.Errorf("%T is not a DeleteItemAction!", plugin)
|
||||||
|
}
|
||||||
|
|
||||||
|
return deleteItemAction, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getDelegate restarts the plugin process (if needed) and returns the delete item action for this restartableDeleteItemAction.
|
||||||
|
func (r *restartableAdaptedV1DeleteItemAction) getDelegate() (deleteitemactionv1.DeleteItemAction, error) {
|
||||||
|
if err := r.sharedPluginProcess.resetIfNeeded(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.getDeleteItemAction()
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppliesTo restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1DeleteItemAction) 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 *restartableAdaptedV1DeleteItemAction) Execute(input *velero.DeleteItemActionExecuteInput) error {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return delegate.Execute(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecuteV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1DeleteItemAction) ExecuteV2(
|
||||||
|
ctx context.Context, input *velero.DeleteItemActionExecuteInput) error {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return delegate.Execute(input)
|
||||||
|
}
|
||||||
246
pkg/plugin/clientmgmt/restartable_adapted_v1_object_store.go
Normal file
246
pkg/plugin/clientmgmt/restartable_adapted_v1_object_store.go
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 the Velero contributors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package clientmgmt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
||||||
|
objectstorev1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/objectstore/v1"
|
||||||
|
objectstorev2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/objectstore/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// restartableAdaptedV1ObjectStore is restartableAdaptedV1ObjectStore version 1 adaptive to version 2 plugin
|
||||||
|
type restartableAdaptedV1ObjectStore struct {
|
||||||
|
restartableObjectStore
|
||||||
|
}
|
||||||
|
|
||||||
|
// newAdaptedV1ObjectStore returns a new restartableAdaptedV1ObjectStore.
|
||||||
|
func newAdaptedV1ObjectStore(name string, sharedPluginProcess RestartableProcess) objectstorev2.ObjectStore {
|
||||||
|
key := kindAndName{kind: framework.PluginKindObjectStore, name: name}
|
||||||
|
r := &restartableAdaptedV1ObjectStore{
|
||||||
|
restartableObjectStore: restartableObjectStore{
|
||||||
|
key: key,
|
||||||
|
sharedPluginProcess: sharedPluginProcess,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register our reinitializer so we can reinitialize after a restart with r.config.
|
||||||
|
sharedPluginProcess.addReinitializer(key, r)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// reinitialize reinitializes a re-dispensed plugin using the initial data passed to Init().
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) reinitialize(dispensed interface{}) error {
|
||||||
|
objectStore, ok := dispensed.(objectstorev1.ObjectStore)
|
||||||
|
if !ok {
|
||||||
|
return errors.Errorf("%T is not a ObjectStore!", dispensed)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.init(objectStore, r.config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getObjectStore returns the object store for this restartableObjectStore.
|
||||||
|
// It does *not* restart the plugin process.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) getObjectStore() (objectstorev1.ObjectStore, error) {
|
||||||
|
plugin, err := r.sharedPluginProcess.getByKindAndName(r.key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
objectStore, ok := plugin.(objectstorev1.ObjectStore)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.Errorf("%T is not a ObjectStore!", plugin)
|
||||||
|
}
|
||||||
|
|
||||||
|
return objectStore, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getDelegate restarts the plugin process (if needed) and returns the object store for this restartableObjectStore.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) getDelegate() (objectstorev1.ObjectStore, error) {
|
||||||
|
if err := r.sharedPluginProcess.resetIfNeeded(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.getObjectStore()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init initializes the object store instance using config. If this is the first invocation, r stores config for future
|
||||||
|
// reinitialization needs. Init does NOT restart the shared plugin process. Init may only be called once.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) Init(config map[string]string) error {
|
||||||
|
if r.config != nil {
|
||||||
|
return errors.Errorf("already initialized")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not using getDelegate() to avoid possible infinite recursion
|
||||||
|
delegate, err := r.getObjectStore()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
r.config = config
|
||||||
|
|
||||||
|
return r.init(delegate, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) InitV2(ctx context.Context, config map[string]string) error {
|
||||||
|
return r.Init(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// init calls Init on objectStore with config. This is split out from Init() so that both Init() and reinitialize() may
|
||||||
|
// call it using a specific ObjectStore.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) init(objectStore objectstorev1.ObjectStore, config map[string]string) error {
|
||||||
|
return objectStore.Init(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PutObject restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) PutObject(bucket string, key string, body io.Reader) error {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return delegate.PutObject(bucket, key, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ObjectExists restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) ObjectExists(bucket, key string) (bool, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return delegate.ObjectExists(bucket, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetObject restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) GetObject(bucket string, key string) (io.ReadCloser, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return delegate.GetObject(bucket, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListCommonPrefixes restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) ListCommonPrefixes(
|
||||||
|
bucket string, prefix string, delimiter string) ([]string, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return delegate.ListCommonPrefixes(bucket, prefix, delimiter)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListObjects restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) ListObjects(bucket string, prefix string) ([]string, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return delegate.ListObjects(bucket, prefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteObject restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) DeleteObject(bucket string, key string) error {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return delegate.DeleteObject(bucket, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSignedURL restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) CreateSignedURL(
|
||||||
|
bucket string, key string, ttl time.Duration) (string, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return delegate.CreateSignedURL(bucket, key, ttl)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version 2. Simply discard ctx.
|
||||||
|
// PutObjectV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) PutObjectV2(
|
||||||
|
ctx context.Context, bucket string, key string, body io.Reader) error {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return delegate.PutObject(bucket, key, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ObjectExistsV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) ObjectExistsV2(ctx context.Context, bucket, key string) (bool, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return delegate.ObjectExists(bucket, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetObjectV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) GetObjectV2(
|
||||||
|
ctx context.Context, bucket string, key string) (io.ReadCloser, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return delegate.GetObject(bucket, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListCommonPrefixesV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) ListCommonPrefixesV2(
|
||||||
|
ctx context.Context, bucket string, prefix string, delimiter string) ([]string, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return delegate.ListCommonPrefixes(bucket, prefix, delimiter)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListObjectsV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) ListObjectsV2(
|
||||||
|
ctx context.Context, bucket string, prefix string) ([]string, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return delegate.ListObjects(bucket, prefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteObjectV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) DeleteObjectV2(ctx context.Context, bucket string, key string) error {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return delegate.DeleteObject(bucket, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSignedURLV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1ObjectStore) CreateSignedURLV2(
|
||||||
|
ctx context.Context, bucket string, key string, ttl time.Duration) (string, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return delegate.CreateSignedURL(bucket, key, ttl)
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 the Velero contributors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package clientmgmt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
||||||
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
restoreitemactionv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1"
|
||||||
|
restoreitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type restartableAdaptedV1RestoreItemAction struct {
|
||||||
|
key kindAndName
|
||||||
|
sharedPluginProcess RestartableProcess
|
||||||
|
config map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// newRestartableRestoreItemAction returns a new restartableRestoreItemAction.
|
||||||
|
func newAdaptedV1RestoreItemAction(
|
||||||
|
name string, sharedPluginProcess RestartableProcess) restoreitemactionv2.RestoreItemAction {
|
||||||
|
r := &restartableAdaptedV1RestoreItemAction{
|
||||||
|
key: kindAndName{kind: framework.PluginKindRestoreItemAction, name: name},
|
||||||
|
sharedPluginProcess: sharedPluginProcess,
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// getRestoreItemAction returns the restore item action for this restartableRestoreItemAction.
|
||||||
|
// It does *not* restart the plugin process.
|
||||||
|
func (r *restartableAdaptedV1RestoreItemAction) getRestoreItemAction() (restoreitemactionv1.RestoreItemAction, error) {
|
||||||
|
plugin, err := r.sharedPluginProcess.getByKindAndName(r.key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
restoreItemAction, ok := plugin.(restoreitemactionv1.RestoreItemAction)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.Errorf("%T is not a RestoreItemAction!", plugin)
|
||||||
|
}
|
||||||
|
|
||||||
|
return restoreItemAction, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getDelegate restarts the plugin process (if needed) and returns the restore item action for this restartableRestoreItemAction.
|
||||||
|
func (r *restartableAdaptedV1RestoreItemAction) getDelegate() (restoreitemactionv1.RestoreItemAction, error) {
|
||||||
|
if err := r.sharedPluginProcess.resetIfNeeded(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.getRestoreItemAction()
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppliesTo restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1RestoreItemAction) 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 *restartableAdaptedV1RestoreItemAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return delegate.Execute(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecuteV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1RestoreItemAction) ExecuteV2(
|
||||||
|
ctx context.Context, input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return delegate.Execute(input)
|
||||||
|
}
|
||||||
@@ -0,0 +1,233 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 the Velero contributors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package clientmgmt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
|
||||||
|
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
||||||
|
volumesnapshotterv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v1"
|
||||||
|
volumesnapshotterv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// restartableAdaptedV1VolumeSnapshotter
|
||||||
|
type restartableAdaptedV1VolumeSnapshotter struct {
|
||||||
|
key kindAndName
|
||||||
|
sharedPluginProcess RestartableProcess
|
||||||
|
config map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// newAdaptedV1VolumeSnapshotter returns a new restartableAdaptedV1VolumeSnapshotter.
|
||||||
|
func newAdaptedV1VolumeSnapshotter(
|
||||||
|
name string, sharedPluginProcess RestartableProcess) volumesnapshotterv2.VolumeSnapshotter {
|
||||||
|
key := kindAndName{kind: framework.PluginKindVolumeSnapshotter, name: name}
|
||||||
|
r := &restartableAdaptedV1VolumeSnapshotter{
|
||||||
|
key: key,
|
||||||
|
sharedPluginProcess: sharedPluginProcess,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register our reinitializer so we can reinitialize after a restart with r.config.
|
||||||
|
sharedPluginProcess.addReinitializer(key, r)
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// reinitialize reinitializes a re-dispensed plugin using the initial data passed to Init().
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) reinitialize(dispensed interface{}) error {
|
||||||
|
volumeSnapshotter, ok := dispensed.(volumesnapshotterv1.VolumeSnapshotter)
|
||||||
|
if !ok {
|
||||||
|
return errors.Errorf("%T is not a VolumeSnapshotter!", dispensed)
|
||||||
|
}
|
||||||
|
return r.init(volumeSnapshotter, r.config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getVolumeSnapshotter returns the volume snapshotter for this restartableVolumeSnapshotter.
|
||||||
|
// It does *not* restart the plugin process.
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) getVolumeSnapshotter() (volumesnapshotterv1.VolumeSnapshotter, error) {
|
||||||
|
plugin, err := r.sharedPluginProcess.getByKindAndName(r.key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
volumeSnapshotter, ok := plugin.(volumesnapshotterv1.VolumeSnapshotter)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.Errorf("%T is not a VolumeSnapshotter!", plugin)
|
||||||
|
}
|
||||||
|
|
||||||
|
return volumeSnapshotter, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getDelegate restarts the plugin process (if needed) and returns the volume snapshotter
|
||||||
|
// for this restartableVolumeSnapshotter.
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) getDelegate() (volumesnapshotterv1.VolumeSnapshotter, error) {
|
||||||
|
if err := r.sharedPluginProcess.resetIfNeeded(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.getVolumeSnapshotter()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init initializes the volume snapshotter instance using config. If this is the first invocation,
|
||||||
|
// r stores config for future reinitialization needs. Init does NOT restart the shared plugin process.
|
||||||
|
// Init may only be called once.
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) Init(config map[string]string) error {
|
||||||
|
if r.config != nil {
|
||||||
|
return errors.Errorf("already initialized")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not using getDelegate() to avoid possible infinite recursion
|
||||||
|
delegate, err := r.getVolumeSnapshotter()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
r.config = config
|
||||||
|
|
||||||
|
return r.init(delegate, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// init calls Init on volumeSnapshotter with config. This is split out from Init() so that both Init()
|
||||||
|
// and reinitialize() may call it using a specific VolumeSnapshotter.
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) init(
|
||||||
|
volumeSnapshotter volumesnapshotterv1.VolumeSnapshotter, config map[string]string) error {
|
||||||
|
return volumeSnapshotter.Init(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateVolumeFromSnapshot restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) CreateVolumeFromSnapshot(
|
||||||
|
snapshotID string, volumeType string, volumeAZ string, iops *int64) (volumeID string, err error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return delegate.CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ, iops)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetVolumeID restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) GetVolumeID(pv runtime.Unstructured) (string, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return delegate.GetVolumeID(pv)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetVolumeID restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) SetVolumeID(
|
||||||
|
pv runtime.Unstructured, volumeID string) (runtime.Unstructured, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return delegate.SetVolumeID(pv, volumeID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetVolumeInfo restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) GetVolumeInfo(
|
||||||
|
volumeID string, volumeAZ string) (string, *int64, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
return delegate.GetVolumeInfo(volumeID, volumeAZ)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSnapshot restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) CreateSnapshot(
|
||||||
|
volumeID string, volumeAZ string, tags map[string]string) (snapshotID string, err error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return delegate.CreateSnapshot(volumeID, volumeAZ, tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteSnapshot restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) DeleteSnapshot(snapshotID string) error {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return delegate.DeleteSnapshot(snapshotID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version 2 simply discard ctx then call Version 1 function
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) InitV2(ctx context.Context, config map[string]string) error {
|
||||||
|
return r.Init(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateVolumeFromSnapshotV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) CreateVolumeFromSnapshotV2(
|
||||||
|
ctx context.Context, snapshotID string, volumeType string, volumeAZ string, iops *int64) (volumeID string, err error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return delegate.CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ, iops)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetVolumeIDV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) GetVolumeIDV2(
|
||||||
|
ctx context.Context, pv runtime.Unstructured) (string, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return delegate.GetVolumeID(pv)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetVolumeIDV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) SetVolumeIDV2(
|
||||||
|
ctx context.Context, pv runtime.Unstructured, volumeID string) (runtime.Unstructured, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return delegate.SetVolumeID(pv, volumeID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetVolumeInfoV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) GetVolumeInfoV2(
|
||||||
|
ctx context.Context, volumeID string, volumeAZ string) (string, *int64, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
return delegate.GetVolumeInfo(volumeID, volumeAZ)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSnapshotV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) CreateSnapshotV2(
|
||||||
|
ctx context.Context, volumeID string, volumeAZ string, tags map[string]string) (snapshotID string, err error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return delegate.CreateSnapshot(volumeID, volumeAZ, tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteSnapshotV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableAdaptedV1VolumeSnapshotter) DeleteSnapshotV2(ctx context.Context, snapshotID string) error {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return delegate.DeleteSnapshot(snapshotID)
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 the Velero contributors.
|
Copyright 2018, 2021 the Velero contributors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -17,12 +17,15 @@ limitations under the License.
|
|||||||
package clientmgmt
|
package clientmgmt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
|
||||||
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
backupitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// restartableBackupItemAction is a backup item action for a given implementation (such as "pod"). It is associated with
|
// restartableBackupItemAction is a backup item action for a given implementation (such as "pod"). It is associated with
|
||||||
@@ -34,10 +37,11 @@ type restartableBackupItemAction struct {
|
|||||||
sharedPluginProcess RestartableProcess
|
sharedPluginProcess RestartableProcess
|
||||||
}
|
}
|
||||||
|
|
||||||
// newRestartableBackupItemAction returns a new restartableBackupItemAction.
|
// newRestartableBackupItemActionV2 returns a new restartableBackupItemAction.
|
||||||
func newRestartableBackupItemAction(name string, sharedPluginProcess RestartableProcess) *restartableBackupItemAction {
|
func newRestartableBackupItemActionV2(
|
||||||
|
name string, sharedPluginProcess RestartableProcess) backupitemactionv2.BackupItemAction {
|
||||||
r := &restartableBackupItemAction{
|
r := &restartableBackupItemAction{
|
||||||
key: kindAndName{kind: framework.PluginKindBackupItemAction, name: name},
|
key: kindAndName{kind: framework.PluginKindBackupItemActionV2, name: name},
|
||||||
sharedPluginProcess: sharedPluginProcess,
|
sharedPluginProcess: sharedPluginProcess,
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
@@ -45,13 +49,13 @@ func newRestartableBackupItemAction(name string, sharedPluginProcess Restartable
|
|||||||
|
|
||||||
// getBackupItemAction returns the backup item action for this restartableBackupItemAction. It does *not* restart the
|
// getBackupItemAction returns the backup item action for this restartableBackupItemAction. It does *not* restart the
|
||||||
// plugin process.
|
// plugin process.
|
||||||
func (r *restartableBackupItemAction) getBackupItemAction() (velero.BackupItemAction, error) {
|
func (r *restartableBackupItemAction) getBackupItemAction() (backupitemactionv2.BackupItemAction, error) {
|
||||||
plugin, err := r.sharedPluginProcess.getByKindAndName(r.key)
|
plugin, err := r.sharedPluginProcess.getByKindAndName(r.key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
backupItemAction, ok := plugin.(velero.BackupItemAction)
|
backupItemAction, ok := plugin.(backupitemactionv2.BackupItemAction)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("%T is not a BackupItemAction!", plugin)
|
return nil, errors.Errorf("%T is not a BackupItemAction!", plugin)
|
||||||
}
|
}
|
||||||
@@ -60,7 +64,7 @@ func (r *restartableBackupItemAction) getBackupItemAction() (velero.BackupItemAc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getDelegate restarts the plugin process (if needed) and returns the backup item action for this restartableBackupItemAction.
|
// getDelegate restarts the plugin process (if needed) and returns the backup item action for this restartableBackupItemAction.
|
||||||
func (r *restartableBackupItemAction) getDelegate() (velero.BackupItemAction, error) {
|
func (r *restartableBackupItemAction) getDelegate() (backupitemactionv2.BackupItemAction, error) {
|
||||||
if err := r.sharedPluginProcess.resetIfNeeded(); err != nil {
|
if err := r.sharedPluginProcess.resetIfNeeded(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -87,3 +91,13 @@ func (r *restartableBackupItemAction) Execute(item runtime.Unstructured, backup
|
|||||||
|
|
||||||
return delegate.Execute(item, backup)
|
return delegate.Execute(item, backup)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecuteV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableBackupItemAction) ExecuteV2(ctx context.Context, item runtime.Unstructured, backup *api.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return delegate.ExecuteV2(ctx, item, backup)
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,10 +17,13 @@ limitations under the License.
|
|||||||
package clientmgmt
|
package clientmgmt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
deleteitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/deleteitemaction/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// restartableDeleteItemAction is a delete item action for a given implementation (such as "pod"). It is associated with
|
// restartableDeleteItemAction is a delete item action for a given implementation (such as "pod"). It is associated with
|
||||||
@@ -34,7 +37,8 @@ type restartableDeleteItemAction struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// newRestartableDeleteItemAction returns a new restartableDeleteItemAction.
|
// newRestartableDeleteItemAction returns a new restartableDeleteItemAction.
|
||||||
func newRestartableDeleteItemAction(name string, sharedPluginProcess RestartableProcess) *restartableDeleteItemAction {
|
func newRestartableDeleteItemActionV2(
|
||||||
|
name string, sharedPluginProcess RestartableProcess) deleteitemactionv2.DeleteItemAction {
|
||||||
r := &restartableDeleteItemAction{
|
r := &restartableDeleteItemAction{
|
||||||
key: kindAndName{kind: framework.PluginKindDeleteItemAction, name: name},
|
key: kindAndName{kind: framework.PluginKindDeleteItemAction, name: name},
|
||||||
sharedPluginProcess: sharedPluginProcess,
|
sharedPluginProcess: sharedPluginProcess,
|
||||||
@@ -44,13 +48,13 @@ func newRestartableDeleteItemAction(name string, sharedPluginProcess Restartable
|
|||||||
|
|
||||||
// getDeleteItemAction returns the delete item action for this restartableDeleteItemAction. It does *not* restart the
|
// getDeleteItemAction returns the delete item action for this restartableDeleteItemAction. It does *not* restart the
|
||||||
// plugin process.
|
// plugin process.
|
||||||
func (r *restartableDeleteItemAction) getDeleteItemAction() (velero.DeleteItemAction, error) {
|
func (r *restartableDeleteItemAction) getDeleteItemAction() (deleteitemactionv2.DeleteItemAction, error) {
|
||||||
plugin, err := r.sharedPluginProcess.getByKindAndName(r.key)
|
plugin, err := r.sharedPluginProcess.getByKindAndName(r.key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteItemAction, ok := plugin.(velero.DeleteItemAction)
|
deleteItemAction, ok := plugin.(deleteitemactionv2.DeleteItemAction)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("%T is not a DeleteItemAction!", plugin)
|
return nil, errors.Errorf("%T is not a DeleteItemAction!", plugin)
|
||||||
}
|
}
|
||||||
@@ -59,7 +63,7 @@ func (r *restartableDeleteItemAction) getDeleteItemAction() (velero.DeleteItemAc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getDelegate restarts the plugin process (if needed) and returns the delete item action for this restartableDeleteItemAction.
|
// getDelegate restarts the plugin process (if needed) and returns the delete item action for this restartableDeleteItemAction.
|
||||||
func (r *restartableDeleteItemAction) getDelegate() (velero.DeleteItemAction, error) {
|
func (r *restartableDeleteItemAction) getDelegate() (deleteitemactionv2.DeleteItemAction, error) {
|
||||||
if err := r.sharedPluginProcess.resetIfNeeded(); err != nil {
|
if err := r.sharedPluginProcess.resetIfNeeded(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -86,3 +90,13 @@ func (r *restartableDeleteItemAction) Execute(input *velero.DeleteItemActionExec
|
|||||||
|
|
||||||
return delegate.Execute(input)
|
return delegate.Execute(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecuteV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableDeleteItemAction) ExecuteV2(ctx context.Context, input *velero.DeleteItemActionExecuteInput) error {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return delegate.ExecuteV2(ctx, input)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 the Velero contributors.
|
Copyright 2021 the Velero contributors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -17,13 +17,14 @@ limitations under the License.
|
|||||||
package clientmgmt
|
package clientmgmt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
objectstorev2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/objectstore/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// restartableObjectStore is an object store for a given implementation (such as "aws"). It is associated with
|
// restartableObjectStore is an object store for a given implementation (such as "aws"). It is associated with
|
||||||
@@ -38,9 +39,9 @@ type restartableObjectStore struct {
|
|||||||
config map[string]string
|
config map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// newRestartableObjectStore returns a new restartableObjectStore.
|
// newRestartableObjectStoreV2 returns a new objectstorev2.ObjectStore for PluginKindObjectStoreV2
|
||||||
func newRestartableObjectStore(name string, sharedPluginProcess RestartableProcess) *restartableObjectStore {
|
func newRestartableObjectStoreV2(name string, sharedPluginProcess RestartableProcess) objectstorev2.ObjectStore {
|
||||||
key := kindAndName{kind: framework.PluginKindObjectStore, name: name}
|
key := kindAndName{kind: framework.PluginKindObjectStoreV2, name: name}
|
||||||
r := &restartableObjectStore{
|
r := &restartableObjectStore{
|
||||||
key: key,
|
key: key,
|
||||||
sharedPluginProcess: sharedPluginProcess,
|
sharedPluginProcess: sharedPluginProcess,
|
||||||
@@ -54,7 +55,7 @@ func newRestartableObjectStore(name string, sharedPluginProcess RestartableProce
|
|||||||
|
|
||||||
// reinitialize reinitializes a re-dispensed plugin using the initial data passed to Init().
|
// reinitialize reinitializes a re-dispensed plugin using the initial data passed to Init().
|
||||||
func (r *restartableObjectStore) reinitialize(dispensed interface{}) error {
|
func (r *restartableObjectStore) reinitialize(dispensed interface{}) error {
|
||||||
objectStore, ok := dispensed.(velero.ObjectStore)
|
objectStore, ok := dispensed.(objectstorev2.ObjectStore)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.Errorf("%T is not a ObjectStore!", dispensed)
|
return errors.Errorf("%T is not a ObjectStore!", dispensed)
|
||||||
}
|
}
|
||||||
@@ -64,13 +65,13 @@ func (r *restartableObjectStore) reinitialize(dispensed interface{}) error {
|
|||||||
|
|
||||||
// getObjectStore returns the object store for this restartableObjectStore. It does *not* restart the
|
// getObjectStore returns the object store for this restartableObjectStore. It does *not* restart the
|
||||||
// plugin process.
|
// plugin process.
|
||||||
func (r *restartableObjectStore) getObjectStore() (velero.ObjectStore, error) {
|
func (r *restartableObjectStore) getObjectStore() (objectstorev2.ObjectStore, error) {
|
||||||
plugin, err := r.sharedPluginProcess.getByKindAndName(r.key)
|
plugin, err := r.sharedPluginProcess.getByKindAndName(r.key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
objectStore, ok := plugin.(velero.ObjectStore)
|
objectStore, ok := plugin.(objectstorev2.ObjectStore)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("%T is not a ObjectStore!", plugin)
|
return nil, errors.Errorf("%T is not a ObjectStore!", plugin)
|
||||||
}
|
}
|
||||||
@@ -79,7 +80,7 @@ func (r *restartableObjectStore) getObjectStore() (velero.ObjectStore, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getDelegate restarts the plugin process (if needed) and returns the object store for this restartableObjectStore.
|
// getDelegate restarts the plugin process (if needed) and returns the object store for this restartableObjectStore.
|
||||||
func (r *restartableObjectStore) getDelegate() (velero.ObjectStore, error) {
|
func (r *restartableObjectStore) getDelegate() (objectstorev2.ObjectStore, error) {
|
||||||
if err := r.sharedPluginProcess.resetIfNeeded(); err != nil {
|
if err := r.sharedPluginProcess.resetIfNeeded(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -105,9 +106,15 @@ func (r *restartableObjectStore) Init(config map[string]string) error {
|
|||||||
return r.init(delegate, config)
|
return r.init(delegate, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InitV2 initializes the object store instance using config. If this is the first invocation, r stores config for future
|
||||||
|
// reinitialization needs. Init does NOT restart the shared plugin process. Init may only be called once.
|
||||||
|
func (r *restartableObjectStore) InitV2(ctx context.Context, config map[string]string) error {
|
||||||
|
return r.Init(config)
|
||||||
|
}
|
||||||
|
|
||||||
// init calls Init on objectStore with config. This is split out from Init() so that both Init() and reinitialize() may
|
// init calls Init on objectStore with config. This is split out from Init() so that both Init() and reinitialize() may
|
||||||
// call it using a specific ObjectStore.
|
// call it using a specific ObjectStore.
|
||||||
func (r *restartableObjectStore) init(objectStore velero.ObjectStore, config map[string]string) error {
|
func (r *restartableObjectStore) init(objectStore objectstorev2.ObjectStore, config map[string]string) error {
|
||||||
return objectStore.Init(config)
|
return objectStore.Init(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,3 +180,68 @@ func (r *restartableObjectStore) CreateSignedURL(bucket string, key string, ttl
|
|||||||
}
|
}
|
||||||
return delegate.CreateSignedURL(bucket, key, ttl)
|
return delegate.CreateSignedURL(bucket, key, ttl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Version 2
|
||||||
|
// PutObjectV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableObjectStore) PutObjectV2(ctx context.Context, bucket string, key string, body io.Reader) error {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return delegate.PutObjectV2(ctx, bucket, key, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ObjectExistsV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableObjectStore) ObjectExistsV2(ctx context.Context, bucket, key string) (bool, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return delegate.ObjectExistsV2(ctx, bucket, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetObjectV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableObjectStore) GetObjectV2(ctx context.Context, bucket string, key string) (io.ReadCloser, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return delegate.GetObjectV2(ctx, bucket, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListCommonPrefixesV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableObjectStore) ListCommonPrefixesV2(
|
||||||
|
ctx context.Context, bucket string, prefix string, delimiter string) ([]string, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return delegate.ListCommonPrefixesV2(ctx, bucket, prefix, delimiter)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListObjectsV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableObjectStore) ListObjectsV2(ctx context.Context, bucket string, prefix string) ([]string, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return delegate.ListObjectsV2(ctx, bucket, prefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteObjectV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableObjectStore) DeleteObjectV2(ctx context.Context, bucket string, key string) error {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return delegate.DeleteObjectV2(ctx, bucket, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSignedURLV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableObjectStore) CreateSignedURLV2(ctx context.Context, bucket string, key string, ttl time.Duration) (string, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return delegate.CreateSignedURLV2(ctx, bucket, key, ttl)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 the Velero contributors.
|
Copyright 2021 the Velero contributors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -17,10 +17,13 @@ limitations under the License.
|
|||||||
package clientmgmt
|
package clientmgmt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
restoreitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// restartableRestoreItemAction is a restore item action for a given implementation (such as "pod"). It is associated with
|
// restartableRestoreItemAction is a restore item action for a given implementation (such as "pod"). It is associated with
|
||||||
@@ -33,10 +36,11 @@ type restartableRestoreItemAction struct {
|
|||||||
config map[string]string
|
config map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// newRestartableRestoreItemAction returns a new restartableRestoreItemAction.
|
// newRestartableRestoreItemActionV2 returns a new restartableRestoreItemAction.
|
||||||
func newRestartableRestoreItemAction(name string, sharedPluginProcess RestartableProcess) *restartableRestoreItemAction {
|
func newRestartableRestoreItemActionV2(
|
||||||
|
name string, sharedPluginProcess RestartableProcess) restoreitemactionv2.RestoreItemAction {
|
||||||
r := &restartableRestoreItemAction{
|
r := &restartableRestoreItemAction{
|
||||||
key: kindAndName{kind: framework.PluginKindRestoreItemAction, name: name},
|
key: kindAndName{kind: framework.PluginKindRestoreItemActionV2, name: name},
|
||||||
sharedPluginProcess: sharedPluginProcess,
|
sharedPluginProcess: sharedPluginProcess,
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
@@ -44,13 +48,13 @@ func newRestartableRestoreItemAction(name string, sharedPluginProcess Restartabl
|
|||||||
|
|
||||||
// getRestoreItemAction returns the restore item action for this restartableRestoreItemAction. It does *not* restart the
|
// getRestoreItemAction returns the restore item action for this restartableRestoreItemAction. It does *not* restart the
|
||||||
// plugin process.
|
// plugin process.
|
||||||
func (r *restartableRestoreItemAction) getRestoreItemAction() (velero.RestoreItemAction, error) {
|
func (r *restartableRestoreItemAction) getRestoreItemAction() (restoreitemactionv2.RestoreItemAction, error) {
|
||||||
plugin, err := r.sharedPluginProcess.getByKindAndName(r.key)
|
plugin, err := r.sharedPluginProcess.getByKindAndName(r.key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
restoreItemAction, ok := plugin.(velero.RestoreItemAction)
|
restoreItemAction, ok := plugin.(restoreitemactionv2.RestoreItemAction)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("%T is not a RestoreItemAction!", plugin)
|
return nil, errors.Errorf("%T is not a RestoreItemAction!", plugin)
|
||||||
}
|
}
|
||||||
@@ -59,7 +63,7 @@ func (r *restartableRestoreItemAction) getRestoreItemAction() (velero.RestoreIte
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getDelegate restarts the plugin process (if needed) and returns the restore item action for this restartableRestoreItemAction.
|
// getDelegate restarts the plugin process (if needed) and returns the restore item action for this restartableRestoreItemAction.
|
||||||
func (r *restartableRestoreItemAction) getDelegate() (velero.RestoreItemAction, error) {
|
func (r *restartableRestoreItemAction) getDelegate() (restoreitemactionv2.RestoreItemAction, error) {
|
||||||
if err := r.sharedPluginProcess.resetIfNeeded(); err != nil {
|
if err := r.sharedPluginProcess.resetIfNeeded(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -86,3 +90,14 @@ func (r *restartableRestoreItemAction) Execute(input *velero.RestoreItemActionEx
|
|||||||
|
|
||||||
return delegate.Execute(input)
|
return delegate.Execute(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecuteV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableRestoreItemAction) ExecuteV2(
|
||||||
|
ctx context.Context, input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return delegate.ExecuteV2(ctx, input)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 the Velero contributors.
|
Copyright 2021 the Velero contributors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -17,11 +17,13 @@ limitations under the License.
|
|||||||
package clientmgmt
|
package clientmgmt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
volumesnapshotterv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// restartableVolumeSnapshotter is a volume snapshotter for a given implementation (such as "aws"). It is associated with
|
// restartableVolumeSnapshotter is a volume snapshotter for a given implementation (such as "aws"). It is associated with
|
||||||
@@ -34,9 +36,10 @@ type restartableVolumeSnapshotter struct {
|
|||||||
config map[string]string
|
config map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// newRestartableVolumeSnapshotter returns a new restartableVolumeSnapshotter.
|
// newRestartableVolumeSnapshotterV2 returns a new restartableVolumeSnapshotter.
|
||||||
func newRestartableVolumeSnapshotter(name string, sharedPluginProcess RestartableProcess) *restartableVolumeSnapshotter {
|
func newRestartableVolumeSnapshotterV2(
|
||||||
key := kindAndName{kind: framework.PluginKindVolumeSnapshotter, name: name}
|
name string, sharedPluginProcess RestartableProcess) volumesnapshotterv2.VolumeSnapshotter {
|
||||||
|
key := kindAndName{kind: framework.PluginKindVolumeSnapshotterV2, name: name}
|
||||||
r := &restartableVolumeSnapshotter{
|
r := &restartableVolumeSnapshotter{
|
||||||
key: key,
|
key: key,
|
||||||
sharedPluginProcess: sharedPluginProcess,
|
sharedPluginProcess: sharedPluginProcess,
|
||||||
@@ -50,7 +53,7 @@ func newRestartableVolumeSnapshotter(name string, sharedPluginProcess Restartabl
|
|||||||
|
|
||||||
// reinitialize reinitializes a re-dispensed plugin using the initial data passed to Init().
|
// reinitialize reinitializes a re-dispensed plugin using the initial data passed to Init().
|
||||||
func (r *restartableVolumeSnapshotter) reinitialize(dispensed interface{}) error {
|
func (r *restartableVolumeSnapshotter) reinitialize(dispensed interface{}) error {
|
||||||
volumeSnapshotter, ok := dispensed.(velero.VolumeSnapshotter)
|
volumeSnapshotter, ok := dispensed.(volumesnapshotterv2.VolumeSnapshotter)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.Errorf("%T is not a VolumeSnapshotter!", dispensed)
|
return errors.Errorf("%T is not a VolumeSnapshotter!", dispensed)
|
||||||
}
|
}
|
||||||
@@ -59,13 +62,13 @@ func (r *restartableVolumeSnapshotter) reinitialize(dispensed interface{}) error
|
|||||||
|
|
||||||
// getVolumeSnapshotter returns the volume snapshotter for this restartableVolumeSnapshotter. It does *not* restart the
|
// getVolumeSnapshotter returns the volume snapshotter for this restartableVolumeSnapshotter. It does *not* restart the
|
||||||
// plugin process.
|
// plugin process.
|
||||||
func (r *restartableVolumeSnapshotter) getVolumeSnapshotter() (velero.VolumeSnapshotter, error) {
|
func (r *restartableVolumeSnapshotter) getVolumeSnapshotter() (volumesnapshotterv2.VolumeSnapshotter, error) {
|
||||||
plugin, err := r.sharedPluginProcess.getByKindAndName(r.key)
|
plugin, err := r.sharedPluginProcess.getByKindAndName(r.key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
volumeSnapshotter, ok := plugin.(velero.VolumeSnapshotter)
|
volumeSnapshotter, ok := plugin.(volumesnapshotterv2.VolumeSnapshotter)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("%T is not a VolumeSnapshotter!", plugin)
|
return nil, errors.Errorf("%T is not a VolumeSnapshotter!", plugin)
|
||||||
}
|
}
|
||||||
@@ -74,7 +77,7 @@ func (r *restartableVolumeSnapshotter) getVolumeSnapshotter() (velero.VolumeSnap
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getDelegate restarts the plugin process (if needed) and returns the volume snapshotter for this restartableVolumeSnapshotter.
|
// getDelegate restarts the plugin process (if needed) and returns the volume snapshotter for this restartableVolumeSnapshotter.
|
||||||
func (r *restartableVolumeSnapshotter) getDelegate() (velero.VolumeSnapshotter, error) {
|
func (r *restartableVolumeSnapshotter) getDelegate() (volumesnapshotterv2.VolumeSnapshotter, error) {
|
||||||
if err := r.sharedPluginProcess.resetIfNeeded(); err != nil {
|
if err := r.sharedPluginProcess.resetIfNeeded(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -102,7 +105,7 @@ func (r *restartableVolumeSnapshotter) Init(config map[string]string) error {
|
|||||||
|
|
||||||
// init calls Init on volumeSnapshotter with config. This is split out from Init() so that both Init() and reinitialize() may
|
// init calls Init on volumeSnapshotter with config. This is split out from Init() so that both Init() and reinitialize() may
|
||||||
// call it using a specific VolumeSnapshotter.
|
// call it using a specific VolumeSnapshotter.
|
||||||
func (r *restartableVolumeSnapshotter) init(volumeSnapshotter velero.VolumeSnapshotter, config map[string]string) error {
|
func (r *restartableVolumeSnapshotter) init(volumeSnapshotter volumesnapshotterv2.VolumeSnapshotter, config map[string]string) error {
|
||||||
return volumeSnapshotter.Init(config)
|
return volumeSnapshotter.Init(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,3 +162,67 @@ func (r *restartableVolumeSnapshotter) DeleteSnapshot(snapshotID string) error {
|
|||||||
}
|
}
|
||||||
return delegate.DeleteSnapshot(snapshotID)
|
return delegate.DeleteSnapshot(snapshotID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Version 2
|
||||||
|
func (r *restartableVolumeSnapshotter) InitV2(ctx context.Context, config map[string]string) error {
|
||||||
|
return r.Init(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateVolumeFromSnapshotV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableVolumeSnapshotter) CreateVolumeFromSnapshotV2(
|
||||||
|
ctx context.Context, snapshotID string, volumeType string, volumeAZ string, iops *int64) (volumeID string, err error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return delegate.CreateVolumeFromSnapshotV2(ctx, snapshotID, volumeType, volumeAZ, iops)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetVolumeIDV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableVolumeSnapshotter) GetVolumeIDV2(
|
||||||
|
ctx context.Context, pv runtime.Unstructured) (string, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return delegate.GetVolumeIDV2(ctx, pv)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetVolumeIDV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableVolumeSnapshotter) SetVolumeIDV2(
|
||||||
|
ctx context.Context, pv runtime.Unstructured, volumeID string) (runtime.Unstructured, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return delegate.SetVolumeIDV2(ctx, pv, volumeID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetVolumeInfoV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableVolumeSnapshotter) GetVolumeInfoV2(
|
||||||
|
ctx context.Context, volumeID string, volumeAZ string) (string, *int64, error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
return delegate.GetVolumeInfoV2(ctx, volumeID, volumeAZ)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSnapshotV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableVolumeSnapshotter) CreateSnapshotV2(
|
||||||
|
ctx context.Context, volumeID string, volumeAZ string, tags map[string]string) (snapshotID string, err error) {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return delegate.CreateSnapshotV2(ctx, volumeID, volumeAZ, tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteSnapshotV2 restarts the plugin's process if needed, then delegates the call.
|
||||||
|
func (r *restartableVolumeSnapshotter) DeleteSnapshotV2(ctx context.Context, snapshotID string) error {
|
||||||
|
delegate, err := r.getDelegate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return delegate.DeleteSnapshotV2(ctx, snapshotID)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2019 the Velero contributors.
|
Copyright 2021 the Velero contributors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -76,6 +76,13 @@ func (c *BackupItemActionGRPCClient) AppliesTo() (velero.ResourceSelector, error
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *BackupItemActionGRPCClient) Execute(item runtime.Unstructured, backup *api.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
|
func (c *BackupItemActionGRPCClient) Execute(item runtime.Unstructured, backup *api.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
|
||||||
|
return c.ExecuteV2(context.Background(), item, backup)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *BackupItemActionGRPCClient) ExecuteV2(
|
||||||
|
ctx context.Context, item runtime.Unstructured, backup *api.Backup) (
|
||||||
|
runtime.Unstructured, []velero.ResourceIdentifier, error) {
|
||||||
|
|
||||||
itemJSON, err := json.Marshal(item.UnstructuredContent())
|
itemJSON, err := json.Marshal(item.UnstructuredContent())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, errors.WithStack(err)
|
return nil, nil, errors.WithStack(err)
|
||||||
@@ -92,7 +99,7 @@ func (c *BackupItemActionGRPCClient) Execute(item runtime.Unstructured, backup *
|
|||||||
Backup: backupJSON,
|
Backup: backupJSON,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := c.grpcClient.Execute(context.Background(), req)
|
res, err := c.grpcClient.Execute(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fromGRPCError(err)
|
return nil, nil, fromGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import (
|
|||||||
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||||
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
backupitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BackupItemActionGRPCServer implements the proto-generated BackupItemAction interface, and accepts
|
// BackupItemActionGRPCServer implements the proto-generated BackupItemAction interface, and accepts
|
||||||
@@ -34,13 +35,13 @@ type BackupItemActionGRPCServer struct {
|
|||||||
mux *serverMux
|
mux *serverMux
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *BackupItemActionGRPCServer) getImpl(name string) (velero.BackupItemAction, error) {
|
func (s *BackupItemActionGRPCServer) getImpl(name string) (backupitemactionv2.BackupItemAction, error) {
|
||||||
impl, err := s.mux.getHandler(name)
|
impl, err := s.mux.getHandler(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
itemAction, ok := impl.(velero.BackupItemAction)
|
itemAction, ok := impl.(backupitemactionv2.BackupItemAction)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("%T is not a backup item action", impl)
|
return nil, errors.Errorf("%T is not a backup item action", impl)
|
||||||
}
|
}
|
||||||
@@ -98,7 +99,7 @@ func (s *BackupItemActionGRPCServer) Execute(ctx context.Context, req *proto.Exe
|
|||||||
return nil, newGRPCError(errors.WithStack(err))
|
return nil, newGRPCError(errors.WithStack(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedItem, additionalItems, err := impl.Execute(&item, &backup)
|
updatedItem, additionalItems, err := impl.ExecuteV2(ctx, &item, &backup)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,10 @@ import (
|
|||||||
|
|
||||||
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
deleteitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/deleteitemaction/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ velero.DeleteItemAction = &DeleteItemActionGRPCClient{}
|
var _ deleteitemactionv2.DeleteItemAction = &DeleteItemActionGRPCClient{}
|
||||||
|
|
||||||
// NewDeleteItemActionPlugin constructs a DeleteItemActionPlugin.
|
// NewDeleteItemActionPlugin constructs a DeleteItemActionPlugin.
|
||||||
func NewDeleteItemActionPlugin(options ...PluginOption) *DeleteItemActionPlugin {
|
func NewDeleteItemActionPlugin(options ...PluginOption) *DeleteItemActionPlugin {
|
||||||
@@ -70,6 +71,10 @@ func (c *DeleteItemActionGRPCClient) AppliesTo() (velero.ResourceSelector, error
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *DeleteItemActionGRPCClient) Execute(input *velero.DeleteItemActionExecuteInput) error {
|
func (c *DeleteItemActionGRPCClient) Execute(input *velero.DeleteItemActionExecuteInput) error {
|
||||||
|
return c.ExecuteV2(context.Background(), input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *DeleteItemActionGRPCClient) ExecuteV2(ctx context.Context, input *velero.DeleteItemActionExecuteInput) error {
|
||||||
itemJSON, err := json.Marshal(input.Item.UnstructuredContent())
|
itemJSON, err := json.Marshal(input.Item.UnstructuredContent())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.WithStack(err)
|
return errors.WithStack(err)
|
||||||
@@ -87,7 +92,7 @@ func (c *DeleteItemActionGRPCClient) Execute(input *velero.DeleteItemActionExecu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// First return item is just an empty struct no matter what.
|
// First return item is just an empty struct no matter what.
|
||||||
if _, err = c.grpcClient.Execute(context.Background(), req); err != nil {
|
if _, err = c.grpcClient.Execute(ctx, req); err != nil {
|
||||||
return fromGRPCError(err)
|
return fromGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import (
|
|||||||
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||||
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
deleteitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/deleteitemaction/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeleteItemActionGRPCServer implements the proto-generated DeleteItemActionServer interface, and accepts
|
// DeleteItemActionGRPCServer implements the proto-generated DeleteItemActionServer interface, and accepts
|
||||||
@@ -34,13 +35,13 @@ type DeleteItemActionGRPCServer struct {
|
|||||||
mux *serverMux
|
mux *serverMux
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DeleteItemActionGRPCServer) getImpl(name string) (velero.DeleteItemAction, error) {
|
func (s *DeleteItemActionGRPCServer) getImpl(name string) (deleteitemactionv2.DeleteItemAction, error) {
|
||||||
impl, err := s.mux.getHandler(name)
|
impl, err := s.mux.getHandler(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
itemAction, ok := impl.(velero.DeleteItemAction)
|
itemAction, ok := impl.(deleteitemactionv2.DeleteItemAction)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("%T is not a delete item action", impl)
|
return nil, errors.Errorf("%T is not a delete item action", impl)
|
||||||
}
|
}
|
||||||
@@ -76,7 +77,8 @@ func (s *DeleteItemActionGRPCServer) AppliesTo(ctx context.Context, req *proto.D
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DeleteItemActionGRPCServer) Execute(ctx context.Context, req *proto.DeleteItemActionExecuteRequest) (_ *proto.Empty, err error) {
|
func (s *DeleteItemActionGRPCServer) Execute(
|
||||||
|
ctx context.Context, req *proto.DeleteItemActionExecuteRequest) (_ *proto.Empty, err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if recoveredErr := handlePanic(recover()); recoveredErr != nil {
|
if recoveredErr := handlePanic(recover()); recoveredErr != nil {
|
||||||
err = recoveredErr
|
err = recoveredErr
|
||||||
@@ -101,7 +103,7 @@ func (s *DeleteItemActionGRPCServer) Execute(ctx context.Context, req *proto.Del
|
|||||||
return nil, newGRPCError(errors.WithStack(err))
|
return nil, newGRPCError(errors.WithStack(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := impl.Execute(&velero.DeleteItemActionExecuteInput{
|
if err := impl.ExecuteV2(ctx, &velero.DeleteItemActionExecuteInput{
|
||||||
Item: &item,
|
Item: &item,
|
||||||
Backup: &backup,
|
Backup: &backup,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
|||||||
@@ -69,7 +69,13 @@ func (c *ObjectStoreGRPCClient) Init(config map[string]string) error {
|
|||||||
// PutObject creates a new object using the data in body within the specified
|
// PutObject creates a new object using the data in body within the specified
|
||||||
// object storage bucket with the given key.
|
// object storage bucket with the given key.
|
||||||
func (c *ObjectStoreGRPCClient) PutObject(bucket, key string, body io.Reader) error {
|
func (c *ObjectStoreGRPCClient) PutObject(bucket, key string, body io.Reader) error {
|
||||||
stream, err := c.grpcClient.PutObject(context.Background())
|
return c.PutObjectV2(context.Background(), bucket, key, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PutObjectV2 creates a new object using the data in body within the specified
|
||||||
|
// object storage bucket with the given key.
|
||||||
|
func (c *ObjectStoreGRPCClient) PutObjectV2(ctx context.Context, bucket, key string, body io.Reader) error {
|
||||||
|
stream, err := c.grpcClient.PutObject(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fromGRPCError(err)
|
return fromGRPCError(err)
|
||||||
}
|
}
|
||||||
@@ -98,13 +104,18 @@ func (c *ObjectStoreGRPCClient) PutObject(bucket, key string, body io.Reader) er
|
|||||||
|
|
||||||
// ObjectExists checks if there is an object with the given key in the object storage bucket.
|
// ObjectExists checks if there is an object with the given key in the object storage bucket.
|
||||||
func (c *ObjectStoreGRPCClient) ObjectExists(bucket, key string) (bool, error) {
|
func (c *ObjectStoreGRPCClient) ObjectExists(bucket, key string) (bool, error) {
|
||||||
|
return c.ObjectExistsV2(context.Background(), bucket, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ObjectExistsV2 checks if there is an object with the given key in the object storage bucket.
|
||||||
|
func (c *ObjectStoreGRPCClient) ObjectExistsV2(ctx context.Context, bucket, key string) (bool, error) {
|
||||||
req := &proto.ObjectExistsRequest{
|
req := &proto.ObjectExistsRequest{
|
||||||
Plugin: c.plugin,
|
Plugin: c.plugin,
|
||||||
Bucket: bucket,
|
Bucket: bucket,
|
||||||
Key: key,
|
Key: key,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := c.grpcClient.ObjectExists(context.Background(), req)
|
res, err := c.grpcClient.ObjectExists(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -115,13 +126,19 @@ func (c *ObjectStoreGRPCClient) ObjectExists(bucket, key string) (bool, error) {
|
|||||||
// GetObject retrieves the object with the given key from the specified
|
// GetObject retrieves the object with the given key from the specified
|
||||||
// bucket in object storage.
|
// bucket in object storage.
|
||||||
func (c *ObjectStoreGRPCClient) GetObject(bucket, key string) (io.ReadCloser, error) {
|
func (c *ObjectStoreGRPCClient) GetObject(bucket, key string) (io.ReadCloser, error) {
|
||||||
|
return c.GetObjectV2(context.Background(), bucket, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetObjectV2 retrieves the object with the given key from the specified
|
||||||
|
// bucket in object storage.
|
||||||
|
func (c *ObjectStoreGRPCClient) GetObjectV2(ctx context.Context, bucket, key string) (io.ReadCloser, error) {
|
||||||
req := &proto.GetObjectRequest{
|
req := &proto.GetObjectRequest{
|
||||||
Plugin: c.plugin,
|
Plugin: c.plugin,
|
||||||
Bucket: bucket,
|
Bucket: bucket,
|
||||||
Key: key,
|
Key: key,
|
||||||
}
|
}
|
||||||
|
|
||||||
stream, err := c.grpcClient.GetObject(context.Background(), req)
|
stream, err := c.grpcClient.GetObject(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fromGRPCError(err)
|
return nil, fromGRPCError(err)
|
||||||
}
|
}
|
||||||
@@ -155,6 +172,14 @@ func (c *ObjectStoreGRPCClient) GetObject(bucket, key string) (io.ReadCloser, er
|
|||||||
// after the provided prefix and before the provided delimiter (this is
|
// after the provided prefix and before the provided delimiter (this is
|
||||||
// often used to simulate a directory hierarchy in object storage).
|
// often used to simulate a directory hierarchy in object storage).
|
||||||
func (c *ObjectStoreGRPCClient) ListCommonPrefixes(bucket, prefix, delimiter string) ([]string, error) {
|
func (c *ObjectStoreGRPCClient) ListCommonPrefixes(bucket, prefix, delimiter string) ([]string, error) {
|
||||||
|
return c.ListCommonPrefixesV2(context.Background(), bucket, prefix, delimiter)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListCommonPrefixesV2 gets a list of all object key prefixes that come
|
||||||
|
// after the provided prefix and before the provided delimiter (this is
|
||||||
|
// often used to simulate a directory hierarchy in object storage).
|
||||||
|
func (c *ObjectStoreGRPCClient) ListCommonPrefixesV2(
|
||||||
|
ctx context.Context, bucket, prefix, delimiter string) ([]string, error) {
|
||||||
req := &proto.ListCommonPrefixesRequest{
|
req := &proto.ListCommonPrefixesRequest{
|
||||||
Plugin: c.plugin,
|
Plugin: c.plugin,
|
||||||
Bucket: bucket,
|
Bucket: bucket,
|
||||||
@@ -162,7 +187,7 @@ func (c *ObjectStoreGRPCClient) ListCommonPrefixes(bucket, prefix, delimiter str
|
|||||||
Delimiter: delimiter,
|
Delimiter: delimiter,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := c.grpcClient.ListCommonPrefixes(context.Background(), req)
|
res, err := c.grpcClient.ListCommonPrefixes(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fromGRPCError(err)
|
return nil, fromGRPCError(err)
|
||||||
}
|
}
|
||||||
@@ -172,13 +197,19 @@ func (c *ObjectStoreGRPCClient) ListCommonPrefixes(bucket, prefix, delimiter str
|
|||||||
|
|
||||||
// ListObjects gets a list of all objects in bucket that have the same prefix.
|
// ListObjects gets a list of all objects in bucket that have the same prefix.
|
||||||
func (c *ObjectStoreGRPCClient) ListObjects(bucket, prefix string) ([]string, error) {
|
func (c *ObjectStoreGRPCClient) ListObjects(bucket, prefix string) ([]string, error) {
|
||||||
|
return c.ListObjectsV2(context.Background(), bucket, prefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListObjectsV2 gets a list of all objects in bucket that have the same prefix.
|
||||||
|
func (c *ObjectStoreGRPCClient) ListObjectsV2(
|
||||||
|
ctx context.Context, bucket, prefix string) ([]string, error) {
|
||||||
req := &proto.ListObjectsRequest{
|
req := &proto.ListObjectsRequest{
|
||||||
Plugin: c.plugin,
|
Plugin: c.plugin,
|
||||||
Bucket: bucket,
|
Bucket: bucket,
|
||||||
Prefix: prefix,
|
Prefix: prefix,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := c.grpcClient.ListObjects(context.Background(), req)
|
res, err := c.grpcClient.ListObjects(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fromGRPCError(err)
|
return nil, fromGRPCError(err)
|
||||||
}
|
}
|
||||||
@@ -189,13 +220,19 @@ func (c *ObjectStoreGRPCClient) ListObjects(bucket, prefix string) ([]string, er
|
|||||||
// DeleteObject removes object with the specified key from the given
|
// DeleteObject removes object with the specified key from the given
|
||||||
// bucket.
|
// bucket.
|
||||||
func (c *ObjectStoreGRPCClient) DeleteObject(bucket, key string) error {
|
func (c *ObjectStoreGRPCClient) DeleteObject(bucket, key string) error {
|
||||||
|
return c.DeleteObjectV2(context.Background(), bucket, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteObjectV2 removes object with the specified key from the given bucket.
|
||||||
|
func (c *ObjectStoreGRPCClient) DeleteObjectV2(
|
||||||
|
ctx context.Context, bucket, key string) error {
|
||||||
req := &proto.DeleteObjectRequest{
|
req := &proto.DeleteObjectRequest{
|
||||||
Plugin: c.plugin,
|
Plugin: c.plugin,
|
||||||
Bucket: bucket,
|
Bucket: bucket,
|
||||||
Key: key,
|
Key: key,
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := c.grpcClient.DeleteObject(context.Background(), req); err != nil {
|
if _, err := c.grpcClient.DeleteObject(ctx, req); err != nil {
|
||||||
return fromGRPCError(err)
|
return fromGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,6 +241,12 @@ func (c *ObjectStoreGRPCClient) DeleteObject(bucket, key string) error {
|
|||||||
|
|
||||||
// CreateSignedURL creates a pre-signed URL for the given bucket and key that expires after ttl.
|
// CreateSignedURL creates a pre-signed URL for the given bucket and key that expires after ttl.
|
||||||
func (c *ObjectStoreGRPCClient) CreateSignedURL(bucket, key string, ttl time.Duration) (string, error) {
|
func (c *ObjectStoreGRPCClient) CreateSignedURL(bucket, key string, ttl time.Duration) (string, error) {
|
||||||
|
return c.CreateSignedURLV2(context.Background(), bucket, key, ttl)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSignedURLV2 creates a pre-signed URL for the given bucket and key that expires after ttl.
|
||||||
|
func (c *ObjectStoreGRPCClient) CreateSignedURLV2(
|
||||||
|
ctx context.Context, bucket, key string, ttl time.Duration) (string, error) {
|
||||||
req := &proto.CreateSignedURLRequest{
|
req := &proto.CreateSignedURLRequest{
|
||||||
Plugin: c.plugin,
|
Plugin: c.plugin,
|
||||||
Bucket: bucket,
|
Bucket: bucket,
|
||||||
@@ -211,7 +254,7 @@ func (c *ObjectStoreGRPCClient) CreateSignedURL(bucket, key string, ttl time.Dur
|
|||||||
Ttl: int64(ttl),
|
Ttl: int64(ttl),
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := c.grpcClient.CreateSignedURL(context.Background(), req)
|
res, err := c.grpcClient.CreateSignedURL(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fromGRPCError(err)
|
return "", fromGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import (
|
|||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
objectstorev2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/objectstore/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ObjectStoreGRPCServer implements the proto-generated ObjectStoreServer interface, and accepts
|
// ObjectStoreGRPCServer implements the proto-generated ObjectStoreServer interface, and accepts
|
||||||
@@ -33,13 +33,13 @@ type ObjectStoreGRPCServer struct {
|
|||||||
mux *serverMux
|
mux *serverMux
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ObjectStoreGRPCServer) getImpl(name string) (velero.ObjectStore, error) {
|
func (s *ObjectStoreGRPCServer) getImpl(name string) (objectstorev2.ObjectStore, error) {
|
||||||
impl, err := s.mux.getHandler(name)
|
impl, err := s.mux.getHandler(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
itemAction, ok := impl.(velero.ObjectStore)
|
itemAction, ok := impl.(objectstorev2.ObjectStore)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("%T is not an object store", impl)
|
return nil, errors.Errorf("%T is not an object store", impl)
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ func (s *ObjectStoreGRPCServer) Init(ctx context.Context, req *proto.ObjectStore
|
|||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := impl.Init(req.Config); err != nil {
|
if err := impl.InitV2(ctx, req.Config); err != nil {
|
||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +141,7 @@ func (s *ObjectStoreGRPCServer) ObjectExists(ctx context.Context, req *proto.Obj
|
|||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
exists, err := impl.ObjectExists(req.Bucket, req.Key)
|
exists, err := impl.ObjectExistsV2(ctx, req.Bucket, req.Key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
@@ -200,7 +200,7 @@ func (s *ObjectStoreGRPCServer) ListCommonPrefixes(ctx context.Context, req *pro
|
|||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
prefixes, err := impl.ListCommonPrefixes(req.Bucket, req.Prefix, req.Delimiter)
|
prefixes, err := impl.ListCommonPrefixesV2(ctx, req.Bucket, req.Prefix, req.Delimiter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
@@ -221,7 +221,7 @@ func (s *ObjectStoreGRPCServer) ListObjects(ctx context.Context, req *proto.List
|
|||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
keys, err := impl.ListObjects(req.Bucket, req.Prefix)
|
keys, err := impl.ListObjectsV2(ctx, req.Bucket, req.Prefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
@@ -243,7 +243,7 @@ func (s *ObjectStoreGRPCServer) DeleteObject(ctx context.Context, req *proto.Del
|
|||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := impl.DeleteObject(req.Bucket, req.Key); err != nil {
|
if err := impl.DeleteObjectV2(ctx, req.Bucket, req.Key); err != nil {
|
||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,7 +263,7 @@ func (s *ObjectStoreGRPCServer) CreateSignedURL(ctx context.Context, req *proto.
|
|||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
url, err := impl.CreateSignedURL(req.Bucket, req.Key, time.Duration(req.Ttl))
|
url, err := impl.CreateSignedURLV2(ctx, req.Bucket, req.Key, time.Duration(req.Ttl))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,58 @@ const (
|
|||||||
PluginKindPluginLister PluginKind = "PluginLister"
|
PluginKindPluginLister PluginKind = "PluginLister"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// PluginKindObjectStoreV2 represents an object store plugin version 2.
|
||||||
|
PluginKindObjectStoreV2 PluginKind = "ObjectStoreV2"
|
||||||
|
|
||||||
|
// PluginKindVolumeSnapshotterV2 represents a volume snapshotter plugin version 2.
|
||||||
|
PluginKindVolumeSnapshotterV2 PluginKind = "VolumeSnapshotterV2"
|
||||||
|
|
||||||
|
// PluginKindBackupItemActionV2 represents a backup item action plugin version 2.
|
||||||
|
PluginKindBackupItemActionV2 PluginKind = "BackupItemActionV2"
|
||||||
|
|
||||||
|
// PluginKindRestoreItemActionV2 represents a restore item action plugin version 2.
|
||||||
|
PluginKindRestoreItemActionV2 PluginKind = "RestoreItemActionV2"
|
||||||
|
|
||||||
|
// PluginKindDeleteItemActionV2 represents a delete item action plugin version 2.
|
||||||
|
PluginKindDeleteItemActionV2 PluginKind = "DeleteItemActionV2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ObjectStoreKinds() []PluginKind {
|
||||||
|
return []PluginKind{
|
||||||
|
PluginKindObjectStoreV2,
|
||||||
|
PluginKindObjectStore,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func VolumeSnapshotterKinds() []PluginKind {
|
||||||
|
return []PluginKind{
|
||||||
|
PluginKindVolumeSnapshotterV2,
|
||||||
|
PluginKindVolumeSnapshotter,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BackupItemActionKinds() []PluginKind {
|
||||||
|
return []PluginKind{
|
||||||
|
PluginKindBackupItemActionV2,
|
||||||
|
PluginKindBackupItemAction,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func RestoreItemActionKinds() []PluginKind {
|
||||||
|
return []PluginKind{
|
||||||
|
PluginKindRestoreItemActionV2,
|
||||||
|
PluginKindRestoreItemAction,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteItemActionKinds() []PluginKind {
|
||||||
|
return []PluginKind{
|
||||||
|
PluginKindDeleteItemActionV2,
|
||||||
|
PluginKindDeleteItemAction,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// AllPluginKinds contains all the valid plugin kinds that Velero supports, excluding PluginLister because that is not a
|
// 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).
|
// kind that a developer would ever need to implement (it's handled by Velero and the Velero plugin library code).
|
||||||
func AllPluginKinds() map[string]PluginKind {
|
func AllPluginKinds() map[string]PluginKind {
|
||||||
@@ -54,5 +106,11 @@ func AllPluginKinds() map[string]PluginKind {
|
|||||||
allPluginKinds[PluginKindBackupItemAction.String()] = PluginKindBackupItemAction
|
allPluginKinds[PluginKindBackupItemAction.String()] = PluginKindBackupItemAction
|
||||||
allPluginKinds[PluginKindRestoreItemAction.String()] = PluginKindRestoreItemAction
|
allPluginKinds[PluginKindRestoreItemAction.String()] = PluginKindRestoreItemAction
|
||||||
allPluginKinds[PluginKindDeleteItemAction.String()] = PluginKindDeleteItemAction
|
allPluginKinds[PluginKindDeleteItemAction.String()] = PluginKindDeleteItemAction
|
||||||
|
// Version 2
|
||||||
|
allPluginKinds[PluginKindObjectStoreV2.String()] = PluginKindObjectStoreV2
|
||||||
|
allPluginKinds[PluginKindVolumeSnapshotterV2.String()] = PluginKindVolumeSnapshotterV2
|
||||||
|
allPluginKinds[PluginKindBackupItemActionV2.String()] = PluginKindBackupItemActionV2
|
||||||
|
allPluginKinds[PluginKindRestoreItemActionV2.String()] = PluginKindRestoreItemActionV2
|
||||||
|
allPluginKinds[PluginKindDeleteItemActionV2.String()] = PluginKindDeleteItemActionV2
|
||||||
return allPluginKinds
|
return allPluginKinds
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,9 +27,10 @@ import (
|
|||||||
|
|
||||||
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
restoreitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ velero.RestoreItemAction = &RestoreItemActionGRPCClient{}
|
var _ restoreitemactionv2.RestoreItemAction = &RestoreItemActionGRPCClient{}
|
||||||
|
|
||||||
// NewRestoreItemActionPlugin constructs a RestoreItemActionPlugin.
|
// NewRestoreItemActionPlugin constructs a RestoreItemActionPlugin.
|
||||||
func NewRestoreItemActionPlugin(options ...PluginOption) *RestoreItemActionPlugin {
|
func NewRestoreItemActionPlugin(options ...PluginOption) *RestoreItemActionPlugin {
|
||||||
@@ -71,7 +72,14 @@ func (c *RestoreItemActionGRPCClient) AppliesTo() (velero.ResourceSelector, erro
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RestoreItemActionGRPCClient) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) {
|
func (c *RestoreItemActionGRPCClient) Execute(
|
||||||
|
input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) {
|
||||||
|
return c.ExecuteV2(context.Background(), input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *RestoreItemActionGRPCClient) ExecuteV2(
|
||||||
|
ctx context.Context, input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) {
|
||||||
|
|
||||||
itemJSON, err := json.Marshal(input.Item.UnstructuredContent())
|
itemJSON, err := json.Marshal(input.Item.UnstructuredContent())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.WithStack(err)
|
return nil, errors.WithStack(err)
|
||||||
@@ -94,7 +102,7 @@ func (c *RestoreItemActionGRPCClient) Execute(input *velero.RestoreItemActionExe
|
|||||||
Restore: restoreJSON,
|
Restore: restoreJSON,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := c.grpcClient.Execute(context.Background(), req)
|
res, err := c.grpcClient.Execute(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fromGRPCError(err)
|
return nil, fromGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import (
|
|||||||
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||||
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
restoreitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RestoreItemActionGRPCServer implements the proto-generated RestoreItemActionServer interface, and accepts
|
// RestoreItemActionGRPCServer implements the proto-generated RestoreItemActionServer interface, and accepts
|
||||||
@@ -34,13 +35,13 @@ type RestoreItemActionGRPCServer struct {
|
|||||||
mux *serverMux
|
mux *serverMux
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *RestoreItemActionGRPCServer) getImpl(name string) (velero.RestoreItemAction, error) {
|
func (s *RestoreItemActionGRPCServer) getImpl(name string) (restoreitemactionv2.RestoreItemAction, error) {
|
||||||
impl, err := s.mux.getHandler(name)
|
impl, err := s.mux.getHandler(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
itemAction, ok := impl.(velero.RestoreItemAction)
|
itemAction, ok := impl.(restoreitemactionv2.RestoreItemAction)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("%T is not a restore item action", impl)
|
return nil, errors.Errorf("%T is not a restore item action", impl)
|
||||||
}
|
}
|
||||||
@@ -76,7 +77,9 @@ func (s *RestoreItemActionGRPCServer) AppliesTo(ctx context.Context, req *proto.
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *RestoreItemActionGRPCServer) Execute(ctx context.Context, req *proto.RestoreItemActionExecuteRequest) (response *proto.RestoreItemActionExecuteResponse, err error) {
|
func (s *RestoreItemActionGRPCServer) Execute(
|
||||||
|
ctx context.Context, req *proto.RestoreItemActionExecuteRequest) (response *proto.RestoreItemActionExecuteResponse, err error) {
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if recoveredErr := handlePanic(recover()); recoveredErr != nil {
|
if recoveredErr := handlePanic(recover()); recoveredErr != nil {
|
||||||
err = recoveredErr
|
err = recoveredErr
|
||||||
@@ -106,11 +109,12 @@ func (s *RestoreItemActionGRPCServer) Execute(ctx context.Context, req *proto.Re
|
|||||||
return nil, newGRPCError(errors.WithStack(err))
|
return nil, newGRPCError(errors.WithStack(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
executeOutput, err := impl.Execute(&velero.RestoreItemActionExecuteInput{
|
executeOutput, err := impl.ExecuteV2(ctx,
|
||||||
Item: &item,
|
&velero.RestoreItemActionExecuteInput{
|
||||||
ItemFromBackup: &itemFromBackup,
|
Item: &item,
|
||||||
Restore: &restoreObj,
|
ItemFromBackup: &itemFromBackup,
|
||||||
})
|
Restore: &restoreObj,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,21 +74,65 @@ type Server interface {
|
|||||||
// RegisterDeleteItemActions registers multiple Delete item actions.
|
// RegisterDeleteItemActions registers multiple Delete item actions.
|
||||||
RegisterDeleteItemActions(map[string]HandlerInitializer) Server
|
RegisterDeleteItemActions(map[string]HandlerInitializer) Server
|
||||||
|
|
||||||
|
// Version 2
|
||||||
|
|
||||||
|
// RegisterVolumeSnapshottersV2 registers multiple volume snapshotters.
|
||||||
|
RegisterVolumeSnapshottersV2(map[string]HandlerInitializer) Server
|
||||||
|
|
||||||
|
// RegisterObjectStoreV2 registers an object store. Accepted format
|
||||||
|
// for the plugin name is <DNS subdomain>/<non-empty name>.
|
||||||
|
RegisterObjectStoreV2(pluginName string, initializer HandlerInitializer) Server
|
||||||
|
|
||||||
|
// RegisterBackupItemActionV2 registers a backup item action. Accepted format
|
||||||
|
// for the plugin name is <DNS subdomain>/<non-empty name>.
|
||||||
|
RegisterBackupItemActionV2(pluginName string, initializer HandlerInitializer) Server
|
||||||
|
|
||||||
|
// RegisterBackupItemActionsV2 registers multiple backup item actions.
|
||||||
|
RegisterBackupItemActionsV2(map[string]HandlerInitializer) Server
|
||||||
|
|
||||||
|
// RegisterVolumeSnapshotterV2 registers a volume snapshotter. Accepted format
|
||||||
|
// for the plugin name is <DNS subdomain>/<non-empty name>.
|
||||||
|
RegisterVolumeSnapshotterV2(pluginName string, initializer HandlerInitializer) Server
|
||||||
|
|
||||||
|
// RegisterObjectStoresV2 registers multiple object stores.
|
||||||
|
RegisterObjectStoresV2(map[string]HandlerInitializer) Server
|
||||||
|
|
||||||
|
// RegisterRestoreItemActionV2 registers a restore item action. Accepted format
|
||||||
|
// for the plugin name is <DNS subdomain>/<non-empty name>.
|
||||||
|
RegisterRestoreItemActionV2(pluginName string, initializer HandlerInitializer) Server
|
||||||
|
|
||||||
|
// RegisterRestoreItemActionsV2 registers multiple restore item actions.
|
||||||
|
RegisterRestoreItemActionsV2(map[string]HandlerInitializer) Server
|
||||||
|
|
||||||
|
// RegisterDeleteItemActionV2 registers a delete item action. Accepted format
|
||||||
|
// for the plugin name is <DNS subdomain>/<non-empty name>.
|
||||||
|
RegisterDeleteItemActionV2(pluginName string, initializer HandlerInitializer) Server
|
||||||
|
|
||||||
|
// RegisterDeleteItemActionsV2 registers multiple Delete item actions.
|
||||||
|
RegisterDeleteItemActionsV2(map[string]HandlerInitializer) Server
|
||||||
|
|
||||||
// Server runs the plugin server.
|
// Server runs the plugin server.
|
||||||
Serve()
|
Serve()
|
||||||
}
|
}
|
||||||
|
|
||||||
// server implements Server.
|
// server implements Server.
|
||||||
type server struct {
|
type server struct {
|
||||||
log *logrus.Logger
|
log *logrus.Logger
|
||||||
logLevelFlag *logging.LevelFlag
|
logLevelFlag *logging.LevelFlag
|
||||||
flagSet *pflag.FlagSet
|
flagSet *pflag.FlagSet
|
||||||
featureSet *veleroflag.StringArray
|
featureSet *veleroflag.StringArray
|
||||||
|
// Version 1
|
||||||
backupItemAction *BackupItemActionPlugin
|
backupItemAction *BackupItemActionPlugin
|
||||||
volumeSnapshotter *VolumeSnapshotterPlugin
|
volumeSnapshotter *VolumeSnapshotterPlugin
|
||||||
objectStore *ObjectStorePlugin
|
objectStore *ObjectStorePlugin
|
||||||
restoreItemAction *RestoreItemActionPlugin
|
restoreItemAction *RestoreItemActionPlugin
|
||||||
deleteItemAction *DeleteItemActionPlugin
|
deleteItemAction *DeleteItemActionPlugin
|
||||||
|
// Version 2
|
||||||
|
backupItemActionV2 *BackupItemActionPlugin
|
||||||
|
volumeSnapshotterV2 *VolumeSnapshotterPlugin
|
||||||
|
objectStoreV2 *ObjectStorePlugin
|
||||||
|
restoreItemActionV2 *RestoreItemActionPlugin
|
||||||
|
deleteItemActionV2 *DeleteItemActionPlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServer returns a new Server
|
// NewServer returns a new Server
|
||||||
@@ -97,14 +141,19 @@ func NewServer() Server {
|
|||||||
features := veleroflag.NewStringArray()
|
features := veleroflag.NewStringArray()
|
||||||
|
|
||||||
return &server{
|
return &server{
|
||||||
log: log,
|
log: log,
|
||||||
logLevelFlag: logging.LogLevelFlag(log.Level),
|
logLevelFlag: logging.LogLevelFlag(log.Level),
|
||||||
featureSet: &features,
|
featureSet: &features,
|
||||||
backupItemAction: NewBackupItemActionPlugin(serverLogger(log)),
|
backupItemAction: NewBackupItemActionPlugin(serverLogger(log)),
|
||||||
volumeSnapshotter: NewVolumeSnapshotterPlugin(serverLogger(log)),
|
volumeSnapshotter: NewVolumeSnapshotterPlugin(serverLogger(log)),
|
||||||
objectStore: NewObjectStorePlugin(serverLogger(log)),
|
objectStore: NewObjectStorePlugin(serverLogger(log)),
|
||||||
restoreItemAction: NewRestoreItemActionPlugin(serverLogger(log)),
|
restoreItemAction: NewRestoreItemActionPlugin(serverLogger(log)),
|
||||||
deleteItemAction: NewDeleteItemActionPlugin(serverLogger(log)),
|
deleteItemAction: NewDeleteItemActionPlugin(serverLogger(log)),
|
||||||
|
backupItemActionV2: NewBackupItemActionPlugin(serverLogger(log)),
|
||||||
|
volumeSnapshotterV2: NewVolumeSnapshotterPlugin(serverLogger(log)),
|
||||||
|
objectStoreV2: NewObjectStorePlugin(serverLogger(log)),
|
||||||
|
restoreItemActionV2: NewRestoreItemActionPlugin(serverLogger(log)),
|
||||||
|
deleteItemActionV2: NewDeleteItemActionPlugin(serverLogger(log)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,6 +226,67 @@ func (s *server) RegisterDeleteItemActions(m map[string]HandlerInitializer) Serv
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Version 2
|
||||||
|
func (s *server) RegisterBackupItemActionV2(name string, initializer HandlerInitializer) Server {
|
||||||
|
s.backupItemActionV2.register(name, initializer)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) RegisterBackupItemActionsV2(m map[string]HandlerInitializer) Server {
|
||||||
|
for name := range m {
|
||||||
|
s.RegisterBackupItemActionV2(name, m[name])
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) RegisterVolumeSnapshotterV2(name string, initializer HandlerInitializer) Server {
|
||||||
|
s.volumeSnapshotterV2.register(name, initializer)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) RegisterVolumeSnapshottersV2(m map[string]HandlerInitializer) Server {
|
||||||
|
for name := range m {
|
||||||
|
s.RegisterVolumeSnapshotterV2(name, m[name])
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) RegisterObjectStoreV2(name string, initializer HandlerInitializer) Server {
|
||||||
|
s.objectStoreV2.register(name, initializer)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) RegisterObjectStoresV2(m map[string]HandlerInitializer) Server {
|
||||||
|
for name := range m {
|
||||||
|
s.RegisterObjectStoreV2(name, m[name])
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) RegisterRestoreItemActionV2(name string, initializer HandlerInitializer) Server {
|
||||||
|
s.restoreItemActionV2.register(name, initializer)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) RegisterRestoreItemActionsV2(m map[string]HandlerInitializer) Server {
|
||||||
|
for name := range m {
|
||||||
|
s.RegisterRestoreItemActionV2(name, m[name])
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) RegisterDeleteItemActionV2(name string, initializer HandlerInitializer) Server {
|
||||||
|
s.deleteItemActionV2.register(name, initializer)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) RegisterDeleteItemActionsV2(m map[string]HandlerInitializer) Server {
|
||||||
|
for name := range m {
|
||||||
|
s.RegisterDeleteItemActionV2(name, m[name])
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
// getNames returns a list of PluginIdentifiers registered with plugin.
|
// getNames returns a list of PluginIdentifiers registered with plugin.
|
||||||
func getNames(command string, kind PluginKind, plugin Interface) []PluginIdentifier {
|
func getNames(command string, kind PluginKind, plugin Interface) []PluginIdentifier {
|
||||||
var pluginIdentifiers []PluginIdentifier
|
var pluginIdentifiers []PluginIdentifier
|
||||||
@@ -206,6 +316,12 @@ func (s *server) Serve() {
|
|||||||
pluginIdentifiers = append(pluginIdentifiers, getNames(command, PluginKindObjectStore, s.objectStore)...)
|
pluginIdentifiers = append(pluginIdentifiers, getNames(command, PluginKindObjectStore, s.objectStore)...)
|
||||||
pluginIdentifiers = append(pluginIdentifiers, getNames(command, PluginKindRestoreItemAction, s.restoreItemAction)...)
|
pluginIdentifiers = append(pluginIdentifiers, getNames(command, PluginKindRestoreItemAction, s.restoreItemAction)...)
|
||||||
pluginIdentifiers = append(pluginIdentifiers, getNames(command, PluginKindDeleteItemAction, s.deleteItemAction)...)
|
pluginIdentifiers = append(pluginIdentifiers, getNames(command, PluginKindDeleteItemAction, s.deleteItemAction)...)
|
||||||
|
// Version 2
|
||||||
|
pluginIdentifiers = append(pluginIdentifiers, getNames(command, PluginKindBackupItemActionV2, s.backupItemActionV2)...)
|
||||||
|
pluginIdentifiers = append(pluginIdentifiers, getNames(command, PluginKindVolumeSnapshotterV2, s.volumeSnapshotterV2)...)
|
||||||
|
pluginIdentifiers = append(pluginIdentifiers, getNames(command, PluginKindObjectStoreV2, s.objectStoreV2)...)
|
||||||
|
pluginIdentifiers = append(pluginIdentifiers, getNames(command, PluginKindRestoreItemActionV2, s.restoreItemActionV2)...)
|
||||||
|
pluginIdentifiers = append(pluginIdentifiers, getNames(command, PluginKindDeleteItemActionV2, s.deleteItemActionV2)...)
|
||||||
|
|
||||||
pluginLister := NewPluginLister(pluginIdentifiers...)
|
pluginLister := NewPluginLister(pluginIdentifiers...)
|
||||||
|
|
||||||
@@ -218,6 +334,12 @@ func (s *server) Serve() {
|
|||||||
string(PluginKindPluginLister): NewPluginListerPlugin(pluginLister),
|
string(PluginKindPluginLister): NewPluginListerPlugin(pluginLister),
|
||||||
string(PluginKindRestoreItemAction): s.restoreItemAction,
|
string(PluginKindRestoreItemAction): s.restoreItemAction,
|
||||||
string(PluginKindDeleteItemAction): s.deleteItemAction,
|
string(PluginKindDeleteItemAction): s.deleteItemAction,
|
||||||
|
// Version 2
|
||||||
|
string(PluginKindBackupItemActionV2): s.backupItemActionV2,
|
||||||
|
string(PluginKindVolumeSnapshotterV2): s.volumeSnapshotterV2,
|
||||||
|
string(PluginKindObjectStoreV2): s.objectStoreV2,
|
||||||
|
string(PluginKindRestoreItemActionV2): s.restoreItemActionV2,
|
||||||
|
string(PluginKindDeleteItemActionV2): s.deleteItemActionV2,
|
||||||
},
|
},
|
||||||
GRPCServer: plugin.DefaultGRPCServer,
|
GRPCServer: plugin.DefaultGRPCServer,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -53,12 +53,19 @@ func newVolumeSnapshotterGRPCClient(base *clientBase, clientConn *grpc.ClientCon
|
|||||||
// configuration key-value pairs. It returns an error if the VolumeSnapshotter
|
// configuration key-value pairs. It returns an error if the VolumeSnapshotter
|
||||||
// cannot be initialized from the provided config.
|
// cannot be initialized from the provided config.
|
||||||
func (c *VolumeSnapshotterGRPCClient) Init(config map[string]string) error {
|
func (c *VolumeSnapshotterGRPCClient) Init(config map[string]string) error {
|
||||||
|
return c.InitV2(context.Background(), config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitV2 prepares the VolumeSnapshotter for usage using the provided map of
|
||||||
|
// configuration key-value pairs. It returns an error if the VolumeSnapshotter
|
||||||
|
// cannot be initialized from the provided config.
|
||||||
|
func (c *VolumeSnapshotterGRPCClient) InitV2(ctx context.Context, config map[string]string) error {
|
||||||
req := &proto.VolumeSnapshotterInitRequest{
|
req := &proto.VolumeSnapshotterInitRequest{
|
||||||
Plugin: c.plugin,
|
Plugin: c.plugin,
|
||||||
Config: config,
|
Config: config,
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := c.grpcClient.Init(context.Background(), req); err != nil {
|
if _, err := c.grpcClient.Init(ctx, req); err != nil {
|
||||||
return fromGRPCError(err)
|
return fromGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +74,14 @@ func (c *VolumeSnapshotterGRPCClient) Init(config map[string]string) error {
|
|||||||
|
|
||||||
// CreateVolumeFromSnapshot creates a new block volume, initialized from the provided snapshot,
|
// CreateVolumeFromSnapshot creates a new block volume, initialized from the provided snapshot,
|
||||||
// and with the specified type and IOPS (if using provisioned IOPS).
|
// and with the specified type and IOPS (if using provisioned IOPS).
|
||||||
func (c *VolumeSnapshotterGRPCClient) CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ string, iops *int64) (string, error) {
|
func (c *VolumeSnapshotterGRPCClient) CreateVolumeFromSnapshot(
|
||||||
|
snapshotID, volumeType, volumeAZ string, iops *int64) (string, error) {
|
||||||
|
return c.CreateVolumeFromSnapshotV2(context.Background(), snapshotID, volumeType, volumeAZ, iops)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *VolumeSnapshotterGRPCClient) CreateVolumeFromSnapshotV2(
|
||||||
|
ctx context.Context, snapshotID, volumeType, volumeAZ string, iops *int64) (string, error) {
|
||||||
|
|
||||||
req := &proto.CreateVolumeRequest{
|
req := &proto.CreateVolumeRequest{
|
||||||
Plugin: c.plugin,
|
Plugin: c.plugin,
|
||||||
SnapshotID: snapshotID,
|
SnapshotID: snapshotID,
|
||||||
@@ -81,7 +95,7 @@ func (c *VolumeSnapshotterGRPCClient) CreateVolumeFromSnapshot(snapshotID, volum
|
|||||||
req.Iops = *iops
|
req.Iops = *iops
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := c.grpcClient.CreateVolumeFromSnapshot(context.Background(), req)
|
res, err := c.grpcClient.CreateVolumeFromSnapshot(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fromGRPCError(err)
|
return "", fromGRPCError(err)
|
||||||
}
|
}
|
||||||
@@ -92,13 +106,19 @@ func (c *VolumeSnapshotterGRPCClient) CreateVolumeFromSnapshot(snapshotID, volum
|
|||||||
// GetVolumeInfo returns the type and IOPS (if using provisioned IOPS) for a specified block
|
// GetVolumeInfo returns the type and IOPS (if using provisioned IOPS) for a specified block
|
||||||
// volume.
|
// volume.
|
||||||
func (c *VolumeSnapshotterGRPCClient) GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, error) {
|
func (c *VolumeSnapshotterGRPCClient) GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, error) {
|
||||||
|
return c.GetVolumeInfoV2(context.Background(), volumeID, volumeAZ)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *VolumeSnapshotterGRPCClient) GetVolumeInfoV2(
|
||||||
|
ctx context.Context, volumeID, volumeAZ string) (string, *int64, error) {
|
||||||
|
|
||||||
req := &proto.GetVolumeInfoRequest{
|
req := &proto.GetVolumeInfoRequest{
|
||||||
Plugin: c.plugin,
|
Plugin: c.plugin,
|
||||||
VolumeID: volumeID,
|
VolumeID: volumeID,
|
||||||
VolumeAZ: volumeAZ,
|
VolumeAZ: volumeAZ,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := c.grpcClient.GetVolumeInfo(context.Background(), req)
|
res, err := c.grpcClient.GetVolumeInfo(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, fromGRPCError(err)
|
return "", nil, fromGRPCError(err)
|
||||||
}
|
}
|
||||||
@@ -114,6 +134,11 @@ func (c *VolumeSnapshotterGRPCClient) GetVolumeInfo(volumeID, volumeAZ string) (
|
|||||||
// CreateSnapshot creates a snapshot of the specified block volume, and applies the provided
|
// CreateSnapshot creates a snapshot of the specified block volume, and applies the provided
|
||||||
// set of tags to the snapshot.
|
// set of tags to the snapshot.
|
||||||
func (c *VolumeSnapshotterGRPCClient) CreateSnapshot(volumeID, volumeAZ string, tags map[string]string) (string, error) {
|
func (c *VolumeSnapshotterGRPCClient) CreateSnapshot(volumeID, volumeAZ string, tags map[string]string) (string, error) {
|
||||||
|
return c.CreateSnapshotV2(context.Background(), volumeID, volumeID, tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *VolumeSnapshotterGRPCClient) CreateSnapshotV2(
|
||||||
|
ctx context.Context, volumeID, volumeAZ string, tags map[string]string) (string, error) {
|
||||||
req := &proto.CreateSnapshotRequest{
|
req := &proto.CreateSnapshotRequest{
|
||||||
Plugin: c.plugin,
|
Plugin: c.plugin,
|
||||||
VolumeID: volumeID,
|
VolumeID: volumeID,
|
||||||
@@ -121,7 +146,7 @@ func (c *VolumeSnapshotterGRPCClient) CreateSnapshot(volumeID, volumeAZ string,
|
|||||||
Tags: tags,
|
Tags: tags,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := c.grpcClient.CreateSnapshot(context.Background(), req)
|
res, err := c.grpcClient.CreateSnapshot(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fromGRPCError(err)
|
return "", fromGRPCError(err)
|
||||||
}
|
}
|
||||||
@@ -131,12 +156,17 @@ func (c *VolumeSnapshotterGRPCClient) CreateSnapshot(volumeID, volumeAZ string,
|
|||||||
|
|
||||||
// DeleteSnapshot deletes the specified volume snapshot.
|
// DeleteSnapshot deletes the specified volume snapshot.
|
||||||
func (c *VolumeSnapshotterGRPCClient) DeleteSnapshot(snapshotID string) error {
|
func (c *VolumeSnapshotterGRPCClient) DeleteSnapshot(snapshotID string) error {
|
||||||
|
return c.DeleteSnapshotV2(context.Background(), snapshotID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *VolumeSnapshotterGRPCClient) DeleteSnapshotV2(
|
||||||
|
ctx context.Context, snapshotID string) error {
|
||||||
req := &proto.DeleteSnapshotRequest{
|
req := &proto.DeleteSnapshotRequest{
|
||||||
Plugin: c.plugin,
|
Plugin: c.plugin,
|
||||||
SnapshotID: snapshotID,
|
SnapshotID: snapshotID,
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := c.grpcClient.DeleteSnapshot(context.Background(), req); err != nil {
|
if _, err := c.grpcClient.DeleteSnapshot(ctx, req); err != nil {
|
||||||
return fromGRPCError(err)
|
return fromGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,6 +174,11 @@ func (c *VolumeSnapshotterGRPCClient) DeleteSnapshot(snapshotID string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *VolumeSnapshotterGRPCClient) GetVolumeID(pv runtime.Unstructured) (string, error) {
|
func (c *VolumeSnapshotterGRPCClient) GetVolumeID(pv runtime.Unstructured) (string, error) {
|
||||||
|
return c.GetVolumeIDV2(context.Background(), pv)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *VolumeSnapshotterGRPCClient) GetVolumeIDV2(
|
||||||
|
ctx context.Context, pv runtime.Unstructured) (string, error) {
|
||||||
encodedPV, err := json.Marshal(pv.UnstructuredContent())
|
encodedPV, err := json.Marshal(pv.UnstructuredContent())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.WithStack(err)
|
return "", errors.WithStack(err)
|
||||||
@@ -154,7 +189,7 @@ func (c *VolumeSnapshotterGRPCClient) GetVolumeID(pv runtime.Unstructured) (stri
|
|||||||
PersistentVolume: encodedPV,
|
PersistentVolume: encodedPV,
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.grpcClient.GetVolumeID(context.Background(), req)
|
resp, err := c.grpcClient.GetVolumeID(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fromGRPCError(err)
|
return "", fromGRPCError(err)
|
||||||
}
|
}
|
||||||
@@ -163,6 +198,11 @@ func (c *VolumeSnapshotterGRPCClient) GetVolumeID(pv runtime.Unstructured) (stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *VolumeSnapshotterGRPCClient) SetVolumeID(pv runtime.Unstructured, volumeID string) (runtime.Unstructured, error) {
|
func (c *VolumeSnapshotterGRPCClient) SetVolumeID(pv runtime.Unstructured, volumeID string) (runtime.Unstructured, error) {
|
||||||
|
return c.SetVolumeIDV2(context.Background(), pv, volumeID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *VolumeSnapshotterGRPCClient) SetVolumeIDV2(
|
||||||
|
ctx context.Context, pv runtime.Unstructured, volumeID string) (runtime.Unstructured, error) {
|
||||||
encodedPV, err := json.Marshal(pv.UnstructuredContent())
|
encodedPV, err := json.Marshal(pv.UnstructuredContent())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.WithStack(err)
|
return nil, errors.WithStack(err)
|
||||||
@@ -174,7 +214,7 @@ func (c *VolumeSnapshotterGRPCClient) SetVolumeID(pv runtime.Unstructured, volum
|
|||||||
VolumeID: volumeID,
|
VolumeID: volumeID,
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.grpcClient.SetVolumeID(context.Background(), req)
|
resp, err := c.grpcClient.SetVolumeID(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fromGRPCError(err)
|
return nil, fromGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
|
||||||
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
volumesnapshotterv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// VolumeSnapshotterGRPCServer implements the proto-generated VolumeSnapshotterServer interface, and accepts
|
// VolumeSnapshotterGRPCServer implements the proto-generated VolumeSnapshotterServer interface, and accepts
|
||||||
@@ -33,13 +33,13 @@ type VolumeSnapshotterGRPCServer struct {
|
|||||||
mux *serverMux
|
mux *serverMux
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *VolumeSnapshotterGRPCServer) getImpl(name string) (velero.VolumeSnapshotter, error) {
|
func (s *VolumeSnapshotterGRPCServer) getImpl(name string) (volumesnapshotterv2.VolumeSnapshotter, error) {
|
||||||
impl, err := s.mux.getHandler(name)
|
impl, err := s.mux.getHandler(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
volumeSnapshotter, ok := impl.(velero.VolumeSnapshotter)
|
volumeSnapshotter, ok := impl.(volumesnapshotterv2.VolumeSnapshotter)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("%T is not a volume snapshotter", impl)
|
return nil, errors.Errorf("%T is not a volume snapshotter", impl)
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ func (s *VolumeSnapshotterGRPCServer) Init(ctx context.Context, req *proto.Volum
|
|||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := impl.Init(req.Config); err != nil {
|
if err := impl.InitV2(ctx, req.Config); err != nil {
|
||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ func (s *VolumeSnapshotterGRPCServer) CreateVolumeFromSnapshot(ctx context.Conte
|
|||||||
iops = &req.Iops
|
iops = &req.Iops
|
||||||
}
|
}
|
||||||
|
|
||||||
volumeID, err := impl.CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ, iops)
|
volumeID, err := impl.CreateVolumeFromSnapshotV2(ctx, snapshotID, volumeType, volumeAZ, iops)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ func (s *VolumeSnapshotterGRPCServer) GetVolumeInfo(ctx context.Context, req *pr
|
|||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
volumeType, iops, err := impl.GetVolumeInfo(req.VolumeID, req.VolumeAZ)
|
volumeType, iops, err := impl.GetVolumeInfoV2(ctx, req.VolumeID, req.VolumeAZ)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ func (s *VolumeSnapshotterGRPCServer) CreateSnapshot(ctx context.Context, req *p
|
|||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshotID, err := impl.CreateSnapshot(req.VolumeID, req.VolumeAZ, req.Tags)
|
snapshotID, err := impl.CreateSnapshotV2(ctx, req.VolumeID, req.VolumeAZ, req.Tags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
@@ -165,7 +165,7 @@ func (s *VolumeSnapshotterGRPCServer) DeleteSnapshot(ctx context.Context, req *p
|
|||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := impl.DeleteSnapshot(req.SnapshotID); err != nil {
|
if err := impl.DeleteSnapshotV2(ctx, req.SnapshotID); err != nil {
|
||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ func (s *VolumeSnapshotterGRPCServer) GetVolumeID(ctx context.Context, req *prot
|
|||||||
return nil, newGRPCError(errors.WithStack(err))
|
return nil, newGRPCError(errors.WithStack(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
volumeID, err := impl.GetVolumeID(&pv)
|
volumeID, err := impl.GetVolumeIDV2(ctx, &pv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
@@ -215,7 +215,7 @@ func (s *VolumeSnapshotterGRPCServer) SetVolumeID(ctx context.Context, req *prot
|
|||||||
return nil, newGRPCError(errors.WithStack(err))
|
return nil, newGRPCError(errors.WithStack(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedPV, err := impl.SetVolumeID(&pv, req.VolumeID)
|
updatedPV, err := impl.SetVolumeIDV2(ctx, &pv, req.VolumeID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newGRPCError(err)
|
return nil, newGRPCError(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,12 @@ package mocks
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
mock "github.com/stretchr/testify/mock"
|
mock "github.com/stretchr/testify/mock"
|
||||||
velero "github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
|
||||||
|
backupitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
|
||||||
|
deleteitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/deleteitemaction/v2"
|
||||||
|
objectstorev2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/objectstore/v2"
|
||||||
|
restoreitemactionv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v2"
|
||||||
|
volumesnapshotterv2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Manager is an autogenerated mock type for the Manager type
|
// Manager is an autogenerated mock type for the Manager type
|
||||||
@@ -18,15 +23,15 @@ func (_m *Manager) CleanupClients() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetBackupItemAction provides a mock function with given fields: name
|
// GetBackupItemAction provides a mock function with given fields: name
|
||||||
func (_m *Manager) GetBackupItemAction(name string) (velero.BackupItemAction, error) {
|
func (_m *Manager) GetBackupItemAction(name string) (backupitemactionv2.BackupItemAction, error) {
|
||||||
ret := _m.Called(name)
|
ret := _m.Called(name)
|
||||||
|
|
||||||
var r0 velero.BackupItemAction
|
var r0 backupitemactionv2.BackupItemAction
|
||||||
if rf, ok := ret.Get(0).(func(string) velero.BackupItemAction); ok {
|
if rf, ok := ret.Get(0).(func(string) backupitemactionv2.BackupItemAction); ok {
|
||||||
r0 = rf(name)
|
r0 = rf(name)
|
||||||
} else {
|
} else {
|
||||||
if ret.Get(0) != nil {
|
if ret.Get(0) != nil {
|
||||||
r0 = ret.Get(0).(velero.BackupItemAction)
|
r0 = ret.Get(0).(backupitemactionv2.BackupItemAction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,15 +46,15 @@ func (_m *Manager) GetBackupItemAction(name string) (velero.BackupItemAction, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetBackupItemActions provides a mock function with given fields:
|
// GetBackupItemActions provides a mock function with given fields:
|
||||||
func (_m *Manager) GetBackupItemActions() ([]velero.BackupItemAction, error) {
|
func (_m *Manager) GetBackupItemActions() ([]backupitemactionv2.BackupItemAction, error) {
|
||||||
ret := _m.Called()
|
ret := _m.Called()
|
||||||
|
|
||||||
var r0 []velero.BackupItemAction
|
var r0 []backupitemactionv2.BackupItemAction
|
||||||
if rf, ok := ret.Get(0).(func() []velero.BackupItemAction); ok {
|
if rf, ok := ret.Get(0).(func() []backupitemactionv2.BackupItemAction); ok {
|
||||||
r0 = rf()
|
r0 = rf()
|
||||||
} else {
|
} else {
|
||||||
if ret.Get(0) != nil {
|
if ret.Get(0) != nil {
|
||||||
r0 = ret.Get(0).([]velero.BackupItemAction)
|
r0 = ret.Get(0).([]backupitemactionv2.BackupItemAction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,15 +69,15 @@ func (_m *Manager) GetBackupItemActions() ([]velero.BackupItemAction, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetDeleteItemAction provides a mock function with given fields: name
|
// GetDeleteItemAction provides a mock function with given fields: name
|
||||||
func (_m *Manager) GetDeleteItemAction(name string) (velero.DeleteItemAction, error) {
|
func (_m *Manager) GetDeleteItemAction(name string) (deleteitemactionv2.DeleteItemAction, error) {
|
||||||
ret := _m.Called(name)
|
ret := _m.Called(name)
|
||||||
|
|
||||||
var r0 velero.DeleteItemAction
|
var r0 deleteitemactionv2.DeleteItemAction
|
||||||
if rf, ok := ret.Get(0).(func(string) velero.DeleteItemAction); ok {
|
if rf, ok := ret.Get(0).(func(string) deleteitemactionv2.DeleteItemAction); ok {
|
||||||
r0 = rf(name)
|
r0 = rf(name)
|
||||||
} else {
|
} else {
|
||||||
if ret.Get(0) != nil {
|
if ret.Get(0) != nil {
|
||||||
r0 = ret.Get(0).(velero.DeleteItemAction)
|
r0 = ret.Get(0).(deleteitemactionv2.DeleteItemAction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,15 +92,15 @@ func (_m *Manager) GetDeleteItemAction(name string) (velero.DeleteItemAction, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetDeleteItemActions provides a mock function with given fields:
|
// GetDeleteItemActions provides a mock function with given fields:
|
||||||
func (_m *Manager) GetDeleteItemActions() ([]velero.DeleteItemAction, error) {
|
func (_m *Manager) GetDeleteItemActions() ([]deleteitemactionv2.DeleteItemAction, error) {
|
||||||
ret := _m.Called()
|
ret := _m.Called()
|
||||||
|
|
||||||
var r0 []velero.DeleteItemAction
|
var r0 []deleteitemactionv2.DeleteItemAction
|
||||||
if rf, ok := ret.Get(0).(func() []velero.DeleteItemAction); ok {
|
if rf, ok := ret.Get(0).(func() []deleteitemactionv2.DeleteItemAction); ok {
|
||||||
r0 = rf()
|
r0 = rf()
|
||||||
} else {
|
} else {
|
||||||
if ret.Get(0) != nil {
|
if ret.Get(0) != nil {
|
||||||
r0 = ret.Get(0).([]velero.DeleteItemAction)
|
r0 = ret.Get(0).([]deleteitemactionv2.DeleteItemAction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,15 +115,15 @@ func (_m *Manager) GetDeleteItemActions() ([]velero.DeleteItemAction, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetObjectStore provides a mock function with given fields: name
|
// GetObjectStore provides a mock function with given fields: name
|
||||||
func (_m *Manager) GetObjectStore(name string) (velero.ObjectStore, error) {
|
func (_m *Manager) GetObjectStore(name string) (objectstorev2.ObjectStore, error) {
|
||||||
ret := _m.Called(name)
|
ret := _m.Called(name)
|
||||||
|
|
||||||
var r0 velero.ObjectStore
|
var r0 objectstorev2.ObjectStore
|
||||||
if rf, ok := ret.Get(0).(func(string) velero.ObjectStore); ok {
|
if rf, ok := ret.Get(0).(func(string) objectstorev2.ObjectStore); ok {
|
||||||
r0 = rf(name)
|
r0 = rf(name)
|
||||||
} else {
|
} else {
|
||||||
if ret.Get(0) != nil {
|
if ret.Get(0) != nil {
|
||||||
r0 = ret.Get(0).(velero.ObjectStore)
|
r0 = ret.Get(0).(objectstorev2.ObjectStore)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,15 +138,15 @@ func (_m *Manager) GetObjectStore(name string) (velero.ObjectStore, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetRestoreItemAction provides a mock function with given fields: name
|
// GetRestoreItemAction provides a mock function with given fields: name
|
||||||
func (_m *Manager) GetRestoreItemAction(name string) (velero.RestoreItemAction, error) {
|
func (_m *Manager) GetRestoreItemAction(name string) (restoreitemactionv2.RestoreItemAction, error) {
|
||||||
ret := _m.Called(name)
|
ret := _m.Called(name)
|
||||||
|
|
||||||
var r0 velero.RestoreItemAction
|
var r0 restoreitemactionv2.RestoreItemAction
|
||||||
if rf, ok := ret.Get(0).(func(string) velero.RestoreItemAction); ok {
|
if rf, ok := ret.Get(0).(func(string) restoreitemactionv2.RestoreItemAction); ok {
|
||||||
r0 = rf(name)
|
r0 = rf(name)
|
||||||
} else {
|
} else {
|
||||||
if ret.Get(0) != nil {
|
if ret.Get(0) != nil {
|
||||||
r0 = ret.Get(0).(velero.RestoreItemAction)
|
r0 = ret.Get(0).(restoreitemactionv2.RestoreItemAction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,15 +161,15 @@ func (_m *Manager) GetRestoreItemAction(name string) (velero.RestoreItemAction,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetRestoreItemActions provides a mock function with given fields:
|
// GetRestoreItemActions provides a mock function with given fields:
|
||||||
func (_m *Manager) GetRestoreItemActions() ([]velero.RestoreItemAction, error) {
|
func (_m *Manager) GetRestoreItemActions() ([]restoreitemactionv2.RestoreItemAction, error) {
|
||||||
ret := _m.Called()
|
ret := _m.Called()
|
||||||
|
|
||||||
var r0 []velero.RestoreItemAction
|
var r0 []restoreitemactionv2.RestoreItemAction
|
||||||
if rf, ok := ret.Get(0).(func() []velero.RestoreItemAction); ok {
|
if rf, ok := ret.Get(0).(func() []restoreitemactionv2.RestoreItemAction); ok {
|
||||||
r0 = rf()
|
r0 = rf()
|
||||||
} else {
|
} else {
|
||||||
if ret.Get(0) != nil {
|
if ret.Get(0) != nil {
|
||||||
r0 = ret.Get(0).([]velero.RestoreItemAction)
|
r0 = ret.Get(0).([]restoreitemactionv2.RestoreItemAction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,15 +184,15 @@ func (_m *Manager) GetRestoreItemActions() ([]velero.RestoreItemAction, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetVolumeSnapshotter provides a mock function with given fields: name
|
// GetVolumeSnapshotter provides a mock function with given fields: name
|
||||||
func (_m *Manager) GetVolumeSnapshotter(name string) (velero.VolumeSnapshotter, error) {
|
func (_m *Manager) GetVolumeSnapshotter(name string) (volumesnapshotterv2.VolumeSnapshotter, error) {
|
||||||
ret := _m.Called(name)
|
ret := _m.Called(name)
|
||||||
|
|
||||||
var r0 velero.VolumeSnapshotter
|
var r0 volumesnapshotterv2.VolumeSnapshotter
|
||||||
if rf, ok := ret.Get(0).(func(string) velero.VolumeSnapshotter); ok {
|
if rf, ok := ret.Get(0).(func(string) volumesnapshotterv2.VolumeSnapshotter); ok {
|
||||||
r0 = rf(name)
|
r0 = rf(name)
|
||||||
} else {
|
} else {
|
||||||
if ret.Get(0) != nil {
|
if ret.Get(0) != nil {
|
||||||
r0 = ret.Get(0).(velero.VolumeSnapshotter)
|
r0 = ret.Get(0).(volumesnapshotterv2.VolumeSnapshotter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2017 the Velero contributors.
|
Copyright 2021 the Velero contributors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -14,13 +14,13 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package velero
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
|
|
||||||
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
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.
|
// BackupItemAction is an actor that performs an operation on an individual item being backed up.
|
||||||
@@ -28,18 +28,12 @@ type BackupItemAction interface {
|
|||||||
// AppliesTo returns information about which resources this action should be invoked for.
|
// 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
|
// A BackupItemAction's Execute function will only be invoked on items that match the returned
|
||||||
// selector. A zero-valued ResourceSelector matches all resources.
|
// selector. A zero-valued ResourceSelector matches all resources.
|
||||||
AppliesTo() (ResourceSelector, error)
|
AppliesTo() (velero.ResourceSelector, error)
|
||||||
|
|
||||||
// Execute allows the ItemAction to perform arbitrary logic with the item being backed up,
|
// Execute allows the ItemAction to perform arbitrary logic with the item being backed up,
|
||||||
// including mutating the item itself prior to backup. The item (unmodified or modified)
|
// including mutating the item itself prior to backup. The item (unmodified or modified)
|
||||||
// should be returned, along with an optional slice of ResourceIdentifiers specifying
|
// should be returned, along with an optional slice of ResourceIdentifiers specifying
|
||||||
// additional related items that should be backed up.
|
// additional related items that should be backed up.
|
||||||
Execute(item runtime.Unstructured, backup *api.Backup) (runtime.Unstructured, []ResourceIdentifier, error)
|
Execute(item runtime.Unstructured, backup *api.Backup) (
|
||||||
}
|
runtime.Unstructured, []velero.ResourceIdentifier, error)
|
||||||
|
|
||||||
// ResourceIdentifier describes a single item by its group, resource, namespace, and name.
|
|
||||||
type ResourceIdentifier struct {
|
|
||||||
schema.GroupResource
|
|
||||||
Namespace string
|
|
||||||
Name string
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 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 (
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
|
||||||
|
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||||
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
v1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v1"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BackupItemAction interface {
|
||||||
|
v1.BackupItemAction
|
||||||
|
|
||||||
|
// ExecuteV2 allows the ItemAction 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.
|
||||||
|
ExecuteV2(ctx context.Context, item runtime.Unstructured,
|
||||||
|
backup *api.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error)
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2020 the Velero contributors.
|
Copyright 2020, 2021 the Velero contributors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -22,20 +22,6 @@ import (
|
|||||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeleteItemAction is an actor that performs an operation on an individual item being restored.
|
|
||||||
type DeleteItemAction interface {
|
|
||||||
// AppliesTo returns information about which resources this action should be invoked for.
|
|
||||||
// A DeleteItemAction's Execute function will only be invoked on items that match the returned
|
|
||||||
// selector. A zero-valued ResourceSelector matches all resources.
|
|
||||||
AppliesTo() (ResourceSelector, error)
|
|
||||||
|
|
||||||
// Execute allows the ItemAction to perform arbitrary logic with the item being deleted.
|
|
||||||
// An error should be returned if there were problems with the deletion process, but the
|
|
||||||
// overall deletion process cannot be stopped.
|
|
||||||
// Returned errors are logged.
|
|
||||||
Execute(input *DeleteItemActionExecuteInput) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteItemActionExecuteInput contains the input parameters for the ItemAction's Execute function.
|
// DeleteItemActionExecuteInput contains the input parameters for the ItemAction's Execute function.
|
||||||
type DeleteItemActionExecuteInput struct {
|
type DeleteItemActionExecuteInput struct {
|
||||||
// Item is the item taken from the pristine backed up version of resource.
|
// Item is the item taken from the pristine backed up version of resource.
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 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 v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeleteItemAction is an actor that performs an operation on an individual item being restored.
|
||||||
|
type DeleteItemAction interface {
|
||||||
|
// AppliesTo returns information about which resources this action should be invoked for.
|
||||||
|
// A DeleteItemAction's Execute function will only be invoked on items that match the returned
|
||||||
|
// selector. A zero-valued ResourceSelector matches all resources.
|
||||||
|
AppliesTo() (velero.ResourceSelector, error)
|
||||||
|
|
||||||
|
// Execute allows the ItemAction to perform arbitrary logic with the item being deleted.
|
||||||
|
// An error should be returned if there were problems with the deletion process, but the
|
||||||
|
// overall deletion process cannot be stopped.
|
||||||
|
// Returned errors are logged.
|
||||||
|
Execute(input *velero.DeleteItemActionExecuteInput) error
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 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/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
v1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/deleteitemaction/v1"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DeleteItemAction interface {
|
||||||
|
v1.DeleteItemAction
|
||||||
|
|
||||||
|
// ExecuteV2 allows the ItemAction to perform arbitrary logic with the item being deleted.
|
||||||
|
// An error should be returned if there were problems with the deletion process, but the
|
||||||
|
// overall deletion process cannot be stopped.
|
||||||
|
// Returned errors are logged.
|
||||||
|
ExecuteV2(ctx context.Context, input *velero.DeleteItemActionExecuteInput) error
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ package mocks
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
mock "github.com/stretchr/testify/mock"
|
mock "github.com/stretchr/testify/mock"
|
||||||
velero "github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeleteItemAction is an autogenerated mock type for the DeleteItemAction type
|
// DeleteItemAction is an autogenerated mock type for the DeleteItemAction type
|
||||||
@@ -46,3 +46,8 @@ func (_m *DeleteItemAction) Execute(input *velero.DeleteItemActionExecuteInput)
|
|||||||
|
|
||||||
return r0
|
return r0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecuteV2 provides a mock function with given fields: ctx, input
|
||||||
|
func (_m *DeleteItemAction) ExecuteV2(ctx context.Context, input *velero.DeleteItemActionExecuteInput) error {
|
||||||
|
return _m.Execute(input)
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package velero
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
68
pkg/plugin/velero/objectstore/v2/object_storev2.go
Normal file
68
pkg/plugin/velero/objectstore/v2/object_storev2.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 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 (
|
||||||
|
v1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/objectstore/v1"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ObjectStore interface {
|
||||||
|
v1.ObjectStore
|
||||||
|
|
||||||
|
// InitV2 prepares the ObjectStore for usage using the provided map of
|
||||||
|
// configuration key-value pairs. It returns an error if the ObjectStore
|
||||||
|
// cannot be initialized from the provided config.
|
||||||
|
InitV2(ctx context.Context, config map[string]string) error
|
||||||
|
|
||||||
|
// PutObjectV2 creates a new object using the data in body within the specified
|
||||||
|
// object storage bucket with the given key.
|
||||||
|
PutObjectV2(ctx context.Context, bucket, key string, body io.Reader) error
|
||||||
|
|
||||||
|
// ObjectExistsV2 checks if there is an object with the given key in the object storage bucket.
|
||||||
|
ObjectExistsV2(ctx context.Context, bucket, key string) (bool, error)
|
||||||
|
|
||||||
|
// GetObjectV2 retrieves the object with the given key from the specified
|
||||||
|
// bucket in object storage.
|
||||||
|
GetObjectV2(ctx context.Context, bucket, key string) (io.ReadCloser, error)
|
||||||
|
|
||||||
|
// ListCommonPrefixesV2 gets a list of all object key prefixes that start with
|
||||||
|
// the specified prefix and stop at the next instance of the provided delimiter.
|
||||||
|
//
|
||||||
|
// For example, if the bucket contains the following keys:
|
||||||
|
// a-prefix/foo-1/bar
|
||||||
|
// a-prefix/foo-1/baz
|
||||||
|
// a-prefix/foo-2/baz
|
||||||
|
// some-other-prefix/foo-3/bar
|
||||||
|
// and the provided prefix arg is "a-prefix/", and the delimiter is "/",
|
||||||
|
// this will return the slice {"a-prefix/foo-1/", "a-prefix/foo-2/"}.
|
||||||
|
ListCommonPrefixesV2(ctx context.Context, bucket, prefix, delimiter string) ([]string, error)
|
||||||
|
|
||||||
|
// ListObjectsV2 gets a list of all keys in the specified bucket
|
||||||
|
// that have the given prefix.
|
||||||
|
ListObjectsV2(ctx context.Context, bucket, prefix string) ([]string, error)
|
||||||
|
|
||||||
|
// DeleteObjectV2 removes the object with the specified key from the given
|
||||||
|
// bucket.
|
||||||
|
DeleteObjectV2(ctx context.Context, bucket, key string) error
|
||||||
|
|
||||||
|
// CreateSignedURLV2 creates a pre-signed URL for the given bucket and key that expires after ttl.
|
||||||
|
CreateSignedURLV2(ctx context.Context, bucket, key string, ttl time.Duration) (string, error)
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2017, 2019 the Velero contributors.
|
Copyright 2017, 2019, 2021 the Velero contributors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -22,22 +22,6 @@ import (
|
|||||||
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RestoreItemAction is an actor that performs an operation on an individual item being restored.
|
|
||||||
type RestoreItemAction interface {
|
|
||||||
// AppliesTo returns information about which resources this action should be invoked for.
|
|
||||||
// A RestoreItemAction's Execute function will only be invoked on items that match the returned
|
|
||||||
// selector. A zero-valued ResourceSelector matches all resources.
|
|
||||||
AppliesTo() (ResourceSelector, error)
|
|
||||||
|
|
||||||
// Execute allows the ItemAction to perform arbitrary logic with the item being restored,
|
|
||||||
// including mutating the item itself prior to restore. The item (unmodified or modified)
|
|
||||||
// should be returned, along with an optional slice of ResourceIdentifiers specifying additional
|
|
||||||
// related items that should be restored, a warning (which will be logged but will not prevent
|
|
||||||
// the item from being restored) or error (which will be logged and will prevent the item
|
|
||||||
// from being restored) if applicable.
|
|
||||||
Execute(input *RestoreItemActionExecuteInput) (*RestoreItemActionExecuteOutput, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RestoreItemActionExecuteInput contains the input parameters for the ItemAction's Execute function.
|
// RestoreItemActionExecuteInput contains the input parameters for the ItemAction's Execute function.
|
||||||
type RestoreItemActionExecuteInput struct {
|
type RestoreItemActionExecuteInput struct {
|
||||||
// Item is the item being restored. It is likely different from the pristine backed up version
|
// Item is the item being restored. It is likely different from the pristine backed up version
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 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 v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RestoreItemAction is an actor that performs an operation on an individual item being restored.
|
||||||
|
type RestoreItemAction interface {
|
||||||
|
// AppliesTo returns information about which resources this action should be invoked for.
|
||||||
|
// A RestoreItemAction'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 ItemAction to perform arbitrary logic with the item being restored,
|
||||||
|
// including mutating the item itself prior to restore. The item (unmodified or modified)
|
||||||
|
// should be returned, along with an optional slice of ResourceIdentifiers specifying additional
|
||||||
|
// related items that should be restored, a warning (which will be logged but will not prevent
|
||||||
|
// the item from being restored) or error (which will be logged and will prevent the item
|
||||||
|
// from being restored) if applicable.
|
||||||
|
Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error)
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 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/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
v1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RestoreItemAction interface {
|
||||||
|
v1.RestoreItemAction
|
||||||
|
|
||||||
|
// ExecuteV2 allows the ItemAction to perform arbitrary logic with the item being restored,
|
||||||
|
// including mutating the item itself prior to restore. The item (unmodified or modified)
|
||||||
|
// should be returned, along with an optional slice of ResourceIdentifiers specifying additional
|
||||||
|
// related items that should be restored, a warning (which will be logged but will not prevent
|
||||||
|
// the item from being restored) or error (which will be logged and will prevent the item
|
||||||
|
// from being restored) if applicable.
|
||||||
|
ExecuteV2(ctx context.Context,
|
||||||
|
input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error)
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2019 the Velero contributors.
|
Copyright 2019, 2021 the Velero contributors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -20,6 +20,10 @@ limitations under the License.
|
|||||||
// plugins of any type can be implemented.
|
// plugins of any type can be implemented.
|
||||||
package velero
|
package velero
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
)
|
||||||
|
|
||||||
// ResourceSelector is a collection of included/excluded namespaces,
|
// ResourceSelector is a collection of included/excluded namespaces,
|
||||||
// included/excluded resources, and a label-selector that can be used
|
// included/excluded resources, and a label-selector that can be used
|
||||||
// to match a set of items from a cluster.
|
// to match a set of items from a cluster.
|
||||||
@@ -48,3 +52,10 @@ type ResourceSelector struct {
|
|||||||
// for details on syntax.
|
// for details on syntax.
|
||||||
LabelSelector string
|
LabelSelector string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResourceIdentifier describes a single item by its group, resource, namespace, and name.
|
||||||
|
type ResourceIdentifier struct {
|
||||||
|
schema.GroupResource
|
||||||
|
Namespace string
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package velero
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 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 (
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
|
||||||
|
v1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v1"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type VolumeSnapshotter interface {
|
||||||
|
v1.VolumeSnapshotter
|
||||||
|
|
||||||
|
// InitV2 prepares the VolumeSnapshotter for usage using the provided map of
|
||||||
|
// configuration key-value pairs. It returns an error if the VolumeSnapshotter
|
||||||
|
// cannot be initialized from the provided config.
|
||||||
|
InitV2(ctx context.Context, config map[string]string) error
|
||||||
|
|
||||||
|
// CreateVolumeFromSnapshotV2 creates a new volume in the specified
|
||||||
|
// availability zone, initialized from the provided snapshot,
|
||||||
|
// and with the specified type and IOPS (if using provisioned IOPS).
|
||||||
|
CreateVolumeFromSnapshotV2(ctx context.Context,
|
||||||
|
snapshotID, volumeType, volumeAZ string, iops *int64) (volumeID string, err error)
|
||||||
|
|
||||||
|
// GetVolumeIDV2 returns the cloud provider specific identifier for the PersistentVolume.
|
||||||
|
GetVolumeIDV2(ctx context.Context, pv runtime.Unstructured) (string, error)
|
||||||
|
|
||||||
|
// SetVolumeIDV2 sets the cloud provider specific identifier for the PersistentVolume.
|
||||||
|
SetVolumeIDV2(ctx context.Context,
|
||||||
|
pv runtime.Unstructured, volumeID string) (runtime.Unstructured, error)
|
||||||
|
|
||||||
|
// GetVolumeInfoV2 returns the type and IOPS (if using provisioned IOPS) for
|
||||||
|
// the specified volume in the given availability zone.
|
||||||
|
GetVolumeInfoV2(ctx context.Context, volumeID, volumeAZ string) (string, *int64, error)
|
||||||
|
|
||||||
|
// CreateSnapshotV2 creates a snapshot of the specified volume, and applies the provided
|
||||||
|
// set of tags to the snapshot.
|
||||||
|
CreateSnapshotV2(ctx context.Context,
|
||||||
|
volumeID, volumeAZ string, tags map[string]string) (snapshotID string, err error)
|
||||||
|
|
||||||
|
// DeleteSnapshotV2 deletes the specified volume snapshot.
|
||||||
|
DeleteSnapshotV2(ctx context.Context, snapshotID string) error
|
||||||
|
}
|
||||||
@@ -57,6 +57,8 @@ import (
|
|||||||
"github.com/vmware-tanzu/velero/pkg/kuberesource"
|
"github.com/vmware-tanzu/velero/pkg/kuberesource"
|
||||||
"github.com/vmware-tanzu/velero/pkg/label"
|
"github.com/vmware-tanzu/velero/pkg/label"
|
||||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||||
|
restoreitemaction "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v2"
|
||||||
|
volumesnapshotter "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v2"
|
||||||
"github.com/vmware-tanzu/velero/pkg/podexec"
|
"github.com/vmware-tanzu/velero/pkg/podexec"
|
||||||
"github.com/vmware-tanzu/velero/pkg/restic"
|
"github.com/vmware-tanzu/velero/pkg/restic"
|
||||||
"github.com/vmware-tanzu/velero/pkg/util/boolptr"
|
"github.com/vmware-tanzu/velero/pkg/util/boolptr"
|
||||||
@@ -75,7 +77,7 @@ const KubeAnnBoundByController = "pv.kubernetes.io/bound-by-controller"
|
|||||||
const KubeAnnDynamicallyProvisioned = "pv.kubernetes.io/provisioned-by"
|
const KubeAnnDynamicallyProvisioned = "pv.kubernetes.io/provisioned-by"
|
||||||
|
|
||||||
type VolumeSnapshotterGetter interface {
|
type VolumeSnapshotterGetter interface {
|
||||||
GetVolumeSnapshotter(name string) (velero.VolumeSnapshotter, error)
|
GetVolumeSnapshotter(name string) (volumesnapshotter.VolumeSnapshotter, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Request struct {
|
type Request struct {
|
||||||
@@ -92,7 +94,7 @@ type Request struct {
|
|||||||
type Restorer interface {
|
type Restorer interface {
|
||||||
// Restore restores the backup data from backupReader, returning warnings and errors.
|
// Restore restores the backup data from backupReader, returning warnings and errors.
|
||||||
Restore(req Request,
|
Restore(req Request,
|
||||||
actions []velero.RestoreItemAction,
|
actions []restoreitemaction.RestoreItemAction,
|
||||||
snapshotLocationLister listers.VolumeSnapshotLocationLister,
|
snapshotLocationLister listers.VolumeSnapshotLocationLister,
|
||||||
volumeSnapshotterGetter VolumeSnapshotterGetter,
|
volumeSnapshotterGetter VolumeSnapshotterGetter,
|
||||||
) (Result, Result)
|
) (Result, Result)
|
||||||
@@ -158,7 +160,7 @@ func NewKubernetesRestorer(
|
|||||||
// respectively, summarizing info about the restore.
|
// respectively, summarizing info about the restore.
|
||||||
func (kr *kubernetesRestorer) Restore(
|
func (kr *kubernetesRestorer) Restore(
|
||||||
req Request,
|
req Request,
|
||||||
actions []velero.RestoreItemAction,
|
actions []restoreitemaction.RestoreItemAction,
|
||||||
snapshotLocationLister listers.VolumeSnapshotLocationLister,
|
snapshotLocationLister listers.VolumeSnapshotLocationLister,
|
||||||
volumeSnapshotterGetter VolumeSnapshotterGetter,
|
volumeSnapshotterGetter VolumeSnapshotterGetter,
|
||||||
) (Result, Result) {
|
) (Result, Result) {
|
||||||
@@ -278,14 +280,14 @@ func (kr *kubernetesRestorer) Restore(
|
|||||||
}
|
}
|
||||||
|
|
||||||
type resolvedAction struct {
|
type resolvedAction struct {
|
||||||
velero.RestoreItemAction
|
restoreitemaction.RestoreItemAction
|
||||||
|
|
||||||
resourceIncludesExcludes *collections.IncludesExcludes
|
resourceIncludesExcludes *collections.IncludesExcludes
|
||||||
namespaceIncludesExcludes *collections.IncludesExcludes
|
namespaceIncludesExcludes *collections.IncludesExcludes
|
||||||
selector labels.Selector
|
selector labels.Selector
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveActions(actions []velero.RestoreItemAction, helper discovery.Helper) ([]resolvedAction, error) {
|
func resolveActions(actions []restoreitemaction.RestoreItemAction, helper discovery.Helper) ([]resolvedAction, error) {
|
||||||
var resolved []resolvedAction
|
var resolved []resolvedAction
|
||||||
|
|
||||||
for _, action := range actions {
|
for _, action := range actions {
|
||||||
|
|||||||
Reference in New Issue
Block a user