migrate backup actions to plugins

Signed-off-by: Steve Kriss <steve@heptio.com>
This commit is contained in:
Steve Kriss
2017-11-21 10:03:03 -08:00
parent 2ce15de2f8
commit 0f2d1ab82b
27 changed files with 1817 additions and 678 deletions
+14 -2
View File
@@ -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
+99 -3
View File
@@ -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