mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-07-29 03:22:43 +00:00
migrate backup actions to plugins
Signed-off-by: Steve Kriss <steve@heptio.com>
This commit is contained in:
@@ -41,6 +41,7 @@ import (
|
||||
arkv1client "github.com/heptio/ark/pkg/generated/clientset/versioned/typed/ark/v1"
|
||||
informers "github.com/heptio/ark/pkg/generated/informers/externalversions/ark/v1"
|
||||
listers "github.com/heptio/ark/pkg/generated/listers/ark/v1"
|
||||
"github.com/heptio/ark/pkg/plugin"
|
||||
"github.com/heptio/ark/pkg/util/collections"
|
||||
"github.com/heptio/ark/pkg/util/encode"
|
||||
kubeutil "github.com/heptio/ark/pkg/util/kube"
|
||||
@@ -60,6 +61,7 @@ type backupController struct {
|
||||
queue workqueue.RateLimitingInterface
|
||||
clock clock.Clock
|
||||
logger *logrus.Logger
|
||||
pluginManager plugin.Manager
|
||||
}
|
||||
|
||||
func NewBackupController(
|
||||
@@ -70,6 +72,7 @@ func NewBackupController(
|
||||
bucket string,
|
||||
pvProviderExists bool,
|
||||
logger *logrus.Logger,
|
||||
pluginManager plugin.Manager,
|
||||
) Interface {
|
||||
c := &backupController{
|
||||
backupper: backupper,
|
||||
@@ -82,6 +85,7 @@ func NewBackupController(
|
||||
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "backup"),
|
||||
clock: &clock.RealClock{},
|
||||
logger: logger,
|
||||
pluginManager: pluginManager,
|
||||
}
|
||||
|
||||
c.syncHandler = c.processBackup
|
||||
@@ -316,10 +320,18 @@ func (controller *backupController) runBackup(backup *api.Backup, bucket string)
|
||||
err = kuberrs.NewAggregate(errs)
|
||||
}()
|
||||
|
||||
controller.logger.WithField("backup", kubeutil.NamespaceAndName(backup)).Info("starting backup")
|
||||
if err := controller.backupper.Backup(backup, backupFile, logFile); err != nil {
|
||||
actions, err := controller.pluginManager.GetBackupItemActions(backup.Name, controller.logger, controller.logger.Level)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer controller.pluginManager.CloseBackupItemActions(backup.Name)
|
||||
|
||||
controller.logger.WithField("backup", kubeutil.NamespaceAndName(backup)).Info("starting backup")
|
||||
|
||||
if err := controller.backupper.Backup(backup, backupFile, logFile, actions); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
controller.logger.WithField("backup", kubeutil.NamespaceAndName(backup)).Info("backup completed")
|
||||
|
||||
// note: updating this here so the uploaded JSON shows "completed". If
|
||||
|
||||
@@ -25,12 +25,15 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/clock"
|
||||
core "k8s.io/client-go/testing"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
testlogger "github.com/sirupsen/logrus/hooks/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/heptio/ark/pkg/apis/ark/v1"
|
||||
"github.com/heptio/ark/pkg/backup"
|
||||
"github.com/heptio/ark/pkg/cloudprovider"
|
||||
"github.com/heptio/ark/pkg/generated/clientset/versioned/fake"
|
||||
"github.com/heptio/ark/pkg/generated/clientset/versioned/scheme"
|
||||
informers "github.com/heptio/ark/pkg/generated/informers/externalversions"
|
||||
@@ -41,11 +44,99 @@ type fakeBackupper struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (b *fakeBackupper) Backup(backup *v1.Backup, data, log io.Writer) error {
|
||||
args := b.Called(backup, data, log)
|
||||
func (b *fakeBackupper) Backup(backup *v1.Backup, data, log io.Writer, actions []backup.ItemAction) error {
|
||||
args := b.Called(backup, data, log, actions)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
// Manager is an autogenerated mock type for the Manager type
|
||||
type Manager struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// CloseBackupItemActions provides a mock function with given fields: backupName
|
||||
func (_m *Manager) CloseBackupItemActions(backupName string) error {
|
||||
ret := _m.Called(backupName)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||
r0 = rf(backupName)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetBackupItemActions provides a mock function with given fields: backupName, logger, level
|
||||
func (_m *Manager) GetBackupItemActions(backupName string, logger logrus.FieldLogger, level logrus.Level) ([]backup.ItemAction, error) {
|
||||
ret := _m.Called(backupName, logger, level)
|
||||
|
||||
var r0 []backup.ItemAction
|
||||
if rf, ok := ret.Get(0).(func(string, logrus.FieldLogger, logrus.Level) []backup.ItemAction); ok {
|
||||
r0 = rf(backupName, logger, level)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]backup.ItemAction)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, logrus.FieldLogger, logrus.Level) error); ok {
|
||||
r1 = rf(backupName, logger, level)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetBlockStore provides a mock function with given fields: name
|
||||
func (_m *Manager) GetBlockStore(name string) (cloudprovider.BlockStore, error) {
|
||||
ret := _m.Called(name)
|
||||
|
||||
var r0 cloudprovider.BlockStore
|
||||
if rf, ok := ret.Get(0).(func(string) cloudprovider.BlockStore); ok {
|
||||
r0 = rf(name)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(cloudprovider.BlockStore)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||
r1 = rf(name)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetObjectStore provides a mock function with given fields: name
|
||||
func (_m *Manager) GetObjectStore(name string) (cloudprovider.ObjectStore, error) {
|
||||
ret := _m.Called(name)
|
||||
|
||||
var r0 cloudprovider.ObjectStore
|
||||
if rf, ok := ret.Get(0).(func(string) cloudprovider.ObjectStore); ok {
|
||||
r0 = rf(name)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(cloudprovider.ObjectStore)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||
r1 = rf(name)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func TestProcessBackup(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -152,6 +243,7 @@ func TestProcessBackup(t *testing.T) {
|
||||
cloudBackups = &BackupService{}
|
||||
sharedInformers = informers.NewSharedInformerFactory(client, 0)
|
||||
logger, _ = testlogger.NewNullLogger()
|
||||
pluginManager = &Manager{}
|
||||
)
|
||||
|
||||
c := NewBackupController(
|
||||
@@ -162,6 +254,7 @@ func TestProcessBackup(t *testing.T) {
|
||||
"bucket",
|
||||
test.allowSnapshots,
|
||||
logger,
|
||||
pluginManager,
|
||||
).(*backupController)
|
||||
c.clock = clock.NewFakeClock(time.Now())
|
||||
|
||||
@@ -187,9 +280,12 @@ func TestProcessBackup(t *testing.T) {
|
||||
backup.Status.Phase = v1.BackupPhaseInProgress
|
||||
backup.Status.Expiration.Time = expiration
|
||||
backup.Status.Version = 1
|
||||
backupper.On("Backup", backup, mock.Anything, mock.Anything).Return(nil)
|
||||
backupper.On("Backup", backup, mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
|
||||
cloudBackups.On("UploadBackup", "bucket", backup.Name, mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
|
||||
pluginManager.On("GetBackupItemActions", backup.Name, logger, logger.Level).Return(nil, nil)
|
||||
pluginManager.On("CloseBackupItemActions", backup.Name).Return(nil)
|
||||
}
|
||||
|
||||
// this is necessary so the Update() call returns the appropriate object
|
||||
|
||||
Reference in New Issue
Block a user