Refactor code to make it easier to add future version.

This commit is contained in:
Hoang, Phuong
2021-07-22 12:09:23 -07:00
committed by Bridget McErlean
parent b059030666
commit 5c707d20c1
11 changed files with 160 additions and 106 deletions

View File

@@ -18,6 +18,7 @@ package clientmgmt
import (
"errors"
"fmt"
"strings"
"sync"
@@ -96,7 +97,23 @@ func (m *manager) CleanupClients() {
m.lock.Unlock()
}
// getRestartableProcessV2 returns a restartableProcess for a plugin identified by kind and name, creating a
func (m *manager) getRestartableProcessOfKinds(
kinds []framework.PluginKind, name string) (RestartableProcess, framework.PluginKind, error) {
var err error
var process RestartableProcess
var kind framework.PluginKind
for _, kind = range kinds {
process, err = m.getRestartableProcess(kind, name)
if err == nil {
return process, kind, nil
} else if !errors.Is(err, &pluginNotFoundError{}) {
return nil, kind, err
}
}
return nil, kind, err
}
// getRestartableProcess returns a restartableProcess for a plugin identified by kind and name, creating a
// restartableProcess if it is the first time it has been requested.
func (m *manager) getRestartableProcess(kind framework.PluginKind, name string) (RestartableProcess, error) {
m.lock.Lock()
@@ -133,61 +150,57 @@ func (m *manager) getRestartableProcess(kind framework.PluginKind, name string)
return restartableProcess, nil
}
type NewObjectStoreFunction func(string, RestartableProcess) objectstorev2.ObjectStore
var ObjectStoreFunctions = map[framework.PluginKind]NewObjectStoreFunction{
framework.PluginKindObjectStoreV2: newRestartableObjectStoreV2,
framework.PluginKindObjectStore: newAdaptedV1ObjectStore,
}
// GetObjectStore returns a restartableObjectStore for name.
func (m *manager) GetObjectStore(name string) (objectstorev2.ObjectStore, error) {
name = sanitizeName(name)
restartableProcess, err := m.getRestartableProcess(framework.PluginKindObjectStoreV2, name)
restartableProcess, kind, err := m.getRestartableProcessOfKinds(framework.ObjectStoreKinds(), name)
if err != nil {
// Check if plugin was not found
if errors.Is(err, &pluginNotFoundError{}) {
// Try again but with previous version
restartableProcess, err := m.getRestartableProcess(framework.PluginKindObjectStore, name)
if err != nil {
// No v1 version found, return
return nil, err
}
// Adapt v1 plugin to v2
return newAdaptedV1ObjectStore(name, restartableProcess), nil
} else {
return nil, err
}
return nil, err
}
return newRestartableObjectStoreV2(name, restartableProcess), nil
f, ok := ObjectStoreFunctions[kind]
if !ok || f == nil {
err = fmt.Errorf("Unable to create ObjectStore for kind '%s'.", kind)
return nil, err
}
return f(name, restartableProcess), nil
}
type NewVolumeSnapshotterFunction func(string, RestartableProcess) volumesnapshotterv2.VolumeSnapshotter
var VolumeSnapshotterFunctions = map[framework.PluginKind]NewVolumeSnapshotterFunction{
framework.PluginKindVolumeSnapshotterV2: newRestartableVolumeSnapshotterV2,
framework.PluginKindVolumeSnapshotter: newAdaptedV1VolumeSnapshotter,
}
// GetVolumeSnapshotter returns a restartableVolumeSnapshotter for name.
func (m *manager) GetVolumeSnapshotter(name string) (volumesnapshotterv2.VolumeSnapshotter, error) {
name = sanitizeName(name)
restartableProcess, err := m.getRestartableProcess(framework.PluginKindVolumeSnapshotterV2, name)
restartableProcess, kind, err := m.getRestartableProcessOfKinds(framework.VolumeSnapshotterKinds(), name)
if err != nil {
// Check if plugin was not found
if errors.Is(err, &pluginNotFoundError{}) {
// Try again but with previous version
restartableProcess, err := m.getRestartableProcess(framework.PluginKindVolumeSnapshotter, name)
if err != nil {
// No v1 version found, return
return nil, err
}
// Adapt v1 plugin to v2
return newAdaptedV1VolumeSnapshotter(name, restartableProcess), nil
} else {
return nil, err
}
return nil, err
}
r := newRestartableVolumeSnapshotterV2(name, restartableProcess)
return r, nil
f, ok := VolumeSnapshotterFunctions[kind]
if !ok || f == nil {
err = fmt.Errorf("Unable to create VolumeSnapshotter for kind '%s'.", kind)
return nil, err
}
return f(name, restartableProcess), nil
}
// GetBackupItemActions returns all backup item actions as restartableBackupItemActions.
func (m *manager) GetBackupItemActions() ([]backupitemactionv2.BackupItemAction, error) {
listv1 := m.registry.List(framework.PluginKindBackupItemAction)
listv2 := m.registry.List(framework.PluginKindBackupItemActionV2)
list := append(listv1, listv2...)
list := m.registry.ListForKinds(framework.BackupItemActionKinds())
actions := make([]backupitemactionv2.BackupItemAction, 0, len(list))
for i := range list {
@@ -204,36 +217,33 @@ func (m *manager) GetBackupItemActions() ([]backupitemactionv2.BackupItemAction,
return actions, nil
}
type NewBackupItemActionFunction func(string, RestartableProcess) backupitemactionv2.BackupItemAction
var BackupItemActionFunctions = map[framework.PluginKind]NewBackupItemActionFunction {
framework.PluginKindBackupItemActionV2: newRestartableBackupItemActionV2,
framework.PluginKindBackupItemAction: newAdaptedV1BackupItemAction,
}
// GetBackupItemAction returns a restartableBackupItemAction for name.
func (m *manager) GetBackupItemAction(name string) (backupitemactionv2.BackupItemAction, error) {
name = sanitizeName(name)
restartableProcess, err := m.getRestartableProcess(framework.PluginKindBackupItemActionV2, name)
restartableProcess, kind, err := m.getRestartableProcessOfKinds(framework.BackupItemActionKinds(), name)
if err != nil {
// Check if plugin was not found
if errors.Is(err, &pluginNotFoundError{}) {
// Try again but with previous version
restartableProcess, err := m.getRestartableProcess(framework.PluginKindBackupItemAction, name)
if err != nil {
// No v1 version found, return
return nil, err
}
// Adapt v1 plugin to v2
return newAdaptedV1BackupItemAction(name, restartableProcess), nil
} else {
return nil, err
}
return nil, err
}
r := newRestartableBackupItemActionV2(name, restartableProcess)
return r, nil
f, ok := BackupItemActionFunctions[kind]
if !ok || f == nil {
err = fmt.Errorf("Unable to create BackupItemAction for kind '%s'.", kind)
return nil, err
}
return f(name, restartableProcess), nil
}
// GetRestoreItemActions returns all restore item actions as restartableRestoreItemActions.
func (m *manager) GetRestoreItemActions() ([]restoreitemactionv2.RestoreItemAction, error) {
listv1 := m.registry.List(framework.PluginKindRestoreItemAction)
listv2 := m.registry.List(framework.PluginKindRestoreItemActionV2)
list := append(listv1, listv2...)
list := m.registry.ListForKinds(framework.RestoreItemActionKinds())
actions := make([]restoreitemactionv2.RestoreItemAction, 0, len(list))
@@ -251,36 +261,33 @@ func (m *manager) GetRestoreItemActions() ([]restoreitemactionv2.RestoreItemActi
return actions, nil
}
type NewRestoreItemActionFunction func(string, RestartableProcess) restoreitemactionv2.RestoreItemAction
var RestoreItemActionFunctions = map[framework.PluginKind]NewRestoreItemActionFunction {
framework.PluginKindRestoreItemActionV2: newRestartableRestoreItemActionV2,
framework.PluginKindRestoreItemAction: newAdaptedV1RestoreItemAction,
}
// GetRestoreItemAction returns a restartableRestoreItemAction for name.
func (m *manager) GetRestoreItemAction(name string) (restoreitemactionv2.RestoreItemAction, error) {
name = sanitizeName(name)
restartableProcess, err := m.getRestartableProcess(framework.PluginKindRestoreItemActionV2, name)
restartableProcess, kind, err := m.getRestartableProcessOfKinds(framework.RestoreItemActionKinds(), name)
if err != nil {
// Check if plugin was not found
if errors.Is(err, &pluginNotFoundError{}) {
// Try again but with previous version
restartableProcess, err := m.getRestartableProcess(framework.PluginKindRestoreItemAction, name)
if err != nil {
// No v1 version found, return
return nil, err
}
// Adapt v1 plugin to v2
return newAdaptedV1RestoreItemAction(name, restartableProcess), nil
} else {
return nil, err
}
return nil, err
}
r := newRestartableRestoreItemActionV2(name, restartableProcess)
return r, nil
f, ok := RestoreItemActionFunctions[kind]
if !ok || f == nil {
err = fmt.Errorf("Unable to create RestoreItemAction for kind '%s'.", kind)
return nil, err
}
return f(name, restartableProcess), nil
}
// GetDeleteItemActions returns all delete item actions as restartableDeleteItemActions.
func (m *manager) GetDeleteItemActions() ([]deleteitemactionv2.DeleteItemAction, error) {
listv1 := m.registry.List(framework.PluginKindDeleteItemAction)
listv2 := m.registry.List(framework.PluginKindDeleteItemActionV2)
list := append(listv1, listv2...)
list := m.registry.ListForKinds(framework.DeleteItemActionKinds())
actions := make([]deleteitemactionv2.DeleteItemAction, 0, len(list))
@@ -298,29 +305,27 @@ func (m *manager) GetDeleteItemActions() ([]deleteitemactionv2.DeleteItemAction,
return actions, nil
}
type NewDeleteItemActionFunction func(string, RestartableProcess) deleteitemactionv2.DeleteItemAction
var DeleteItemActionFunctions = map[framework.PluginKind]NewDeleteItemActionFunction {
framework.PluginKindDeleteItemActionV2: newRestartableDeleteItemActionV2,
framework.PluginKindDeleteItemAction: newAdaptedV1DeleteItemAction,
}
// GetDeleteItemAction returns a restartableDeleteItemAction for name.
func (m *manager) GetDeleteItemAction(name string) (deleteitemactionv2.DeleteItemAction, error) {
name = sanitizeName(name)
restartableProcess, err := m.getRestartableProcess(framework.PluginKindDeleteItemActionV2, name)
restartableProcess, kind, err := m.getRestartableProcessOfKinds(framework.DeleteItemActionKinds(), name)
if err != nil {
// Check if plugin was not found
if errors.Is(err, &pluginNotFoundError{}) {
// Try again but with previous version
restartableProcess, err := m.getRestartableProcess(framework.PluginKindDeleteItemAction, name)
if err != nil {
// No v1 version found, return
return nil, err
}
// Adapt v1 plugin to v2
return newAdaptedV1DeleteItemAction(name, restartableProcess), nil
} else {
return nil, err
}
return nil, err
}
r := newRestartableDeleteItemActionV2(name, restartableProcess)
return r, nil
f, ok := DeleteItemActionFunctions[kind]
if !ok || f == nil {
err = fmt.Errorf("Unable to create DeleteItemAction for kind '%s'.", kind)
return nil, err
}
return f(name, restartableProcess), nil
}
// sanitizeName adds "velero.io" to legacy plugins that weren't namespaced.

View File

@@ -34,6 +34,8 @@ type Registry interface {
DiscoverPlugins() error
// List returns all PluginIdentifiers for kind.
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(kind framework.PluginKind, name string) (framework.PluginIdentifier, error)
}
@@ -108,6 +110,13 @@ func (r *registry) discoverPlugins(commands []string) error {
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
// PluginKind.
func (r *registry) List(kind framework.PluginKind) []framework.PluginIdentifier {

View File

@@ -20,11 +20,12 @@ 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"
"k8s.io/apimachinery/pkg/runtime"
)
type restartableAdaptedV1BackupItemAction struct {
@@ -33,7 +34,8 @@ type restartableAdaptedV1BackupItemAction struct {
}
// newAdaptedV1BackupItemAction returns a new restartableAdaptedV1BackupItemAction.
func newAdaptedV1BackupItemAction(name string, sharedPluginProcess RestartableProcess) *restartableAdaptedV1BackupItemAction {
func newAdaptedV1BackupItemAction(
name string, sharedPluginProcess RestartableProcess) backupitemactionv2.BackupItemAction {
r := &restartableAdaptedV1BackupItemAction{
key: kindAndName{kind: framework.PluginKindBackupItemAction, name: name},
sharedPluginProcess: sharedPluginProcess,

View File

@@ -18,12 +18,13 @@ package clientmgmt
import (
"context"
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
"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
@@ -32,7 +33,7 @@ type restartableAdaptedV1ObjectStore struct {
}
// newAdaptedV1ObjectStore returns a new restartableAdaptedV1ObjectStore.
func newAdaptedV1ObjectStore(name string, sharedPluginProcess RestartableProcess) *restartableAdaptedV1ObjectStore {
func newAdaptedV1ObjectStore(name string, sharedPluginProcess RestartableProcess) objectstorev2.ObjectStore {
key := kindAndName{kind: framework.PluginKindObjectStore, name: name}
r := &restartableAdaptedV1ObjectStore{
restartableObjectStore: restartableObjectStore{

View File

@@ -23,6 +23,7 @@ import (
"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 {
@@ -32,7 +33,8 @@ type restartableAdaptedV1RestoreItemAction struct {
}
// newRestartableRestoreItemAction returns a new restartableRestoreItemAction.
func newAdaptedV1RestoreItemAction(name string, sharedPluginProcess RestartableProcess) *restartableAdaptedV1RestoreItemAction {
func newAdaptedV1RestoreItemAction(
name string, sharedPluginProcess RestartableProcess) restoreitemactionv2.RestoreItemAction {
r := &restartableAdaptedV1RestoreItemAction{
key: kindAndName{kind: framework.PluginKindRestoreItemAction, name: name},
sharedPluginProcess: sharedPluginProcess,

View File

@@ -38,7 +38,8 @@ type restartableBackupItemAction struct {
}
// newRestartableBackupItemActionV2 returns a new restartableBackupItemAction.
func newRestartableBackupItemActionV2(name string, sharedPluginProcess RestartableProcess) *restartableBackupItemAction {
func newRestartableBackupItemActionV2(
name string, sharedPluginProcess RestartableProcess) backupitemactionv2.BackupItemAction {
r := &restartableBackupItemAction{
key: kindAndName{kind: framework.PluginKindBackupItemActionV2, name: name},
sharedPluginProcess: sharedPluginProcess,

View File

@@ -38,7 +38,8 @@ type restartableDeleteItemAction struct {
}
// newRestartableDeleteItemAction returns a new restartableDeleteItemAction.
func newRestartableDeleteItemActionV2(name string, sharedPluginProcess RestartableProcess) *restartableDeleteItemAction {
func newRestartableDeleteItemActionV2(
name string, sharedPluginProcess RestartableProcess) deleteitemactionv2.DeleteItemAction {
r := &restartableDeleteItemAction{
key: kindAndName{kind: framework.PluginKindDeleteItemAction, name: name},
sharedPluginProcess: sharedPluginProcess,

View File

@@ -39,8 +39,8 @@ type restartableObjectStore struct {
config map[string]string
}
// newRestartableObjectStoreV2 returns a new restartableObjectStore for version 2.
func newRestartableObjectStoreV2(name string, sharedPluginProcess RestartableProcess) *restartableObjectStore {
// newRestartableObjectStoreV2 returns a new objectstorev2.ObjectStore for PluginKindObjectStoreV2
func newRestartableObjectStoreV2(name string, sharedPluginProcess RestartableProcess) objectstorev2.ObjectStore {
key := kindAndName{kind: framework.PluginKindObjectStoreV2, name: name}
r := &restartableObjectStore{
key: key,

View File

@@ -36,7 +36,8 @@ type restartableRestoreItemAction struct {
}
// newRestartableRestoreItemActionV2 returns a new restartableRestoreItemAction.
func newRestartableRestoreItemActionV2(name string, sharedPluginProcess RestartableProcess) *restartableRestoreItemAction {
func newRestartableRestoreItemActionV2(
name string, sharedPluginProcess RestartableProcess) restoreitemactionv2.RestoreItemAction {
r := &restartableRestoreItemAction{
key: kindAndName{kind: framework.PluginKindRestoreItemActionV2, name: name},
sharedPluginProcess: sharedPluginProcess,

View File

@@ -37,7 +37,8 @@ type restartableVolumeSnapshotter struct {
}
// newRestartableVolumeSnapshotterV2 returns a new restartableVolumeSnapshotter.
func newRestartableVolumeSnapshotterV2(name string, sharedPluginProcess RestartableProcess) *restartableVolumeSnapshotter {
func newRestartableVolumeSnapshotterV2(
name string, sharedPluginProcess RestartableProcess) volumesnapshotterv2.VolumeSnapshotter {
key := kindAndName{kind: framework.PluginKindVolumeSnapshotterV2, name: name}
r := &restartableVolumeSnapshotter{
key: key,

View File

@@ -60,12 +60,43 @@ const (
// PluginKindDeleteItemActionV2 represents a delete item action plugin version 2.
PluginKindDeleteItemActionV2 PluginKind = "DeleteItemActionV2"
// TODO: we may not need this
// PluginKindPluginListerV2 represents a plugin lister plugin version 2.
PluginKindPluginListerV2 PluginKind = "PluginListerV2"
)
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
// 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 {