mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-01-05 21:14:56 +00:00
Controller refactor code modifications.
1. Add some refactored controllers initiation code into enabledRuntimeControllers. 2. Add reconciler struct initiation function for DownloadRequest and ServerStatusRequest controllers. Signed-off-by: Xun Jiang <blackpiglet@gmail.com>
This commit is contained in:
1
changelogs/unreleased/5241-jxun
Normal file
1
changelogs/unreleased/5241-jxun
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Controller refactor code modifications.
|
||||||
@@ -737,9 +737,13 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
|
|||||||
controller.Restore: restoreControllerRunInfo,
|
controller.Restore: restoreControllerRunInfo,
|
||||||
}
|
}
|
||||||
// Note: all runtime type controllers that can be disabled are grouped separately, below:
|
// Note: all runtime type controllers that can be disabled are grouped separately, below:
|
||||||
enabledRuntimeControllers := make(map[string]struct{})
|
enabledRuntimeControllers := map[string]struct{}{
|
||||||
enabledRuntimeControllers[controller.ServerStatusRequest] = struct{}{}
|
controller.ServerStatusRequest: {},
|
||||||
enabledRuntimeControllers[controller.DownloadRequest] = struct{}{}
|
controller.DownloadRequest: {},
|
||||||
|
controller.Schedule: {},
|
||||||
|
controller.ResticRepo: {},
|
||||||
|
controller.BackupDeletion: {},
|
||||||
|
}
|
||||||
|
|
||||||
if s.config.restoreOnly {
|
if s.config.restoreOnly {
|
||||||
s.logger.Info("Restore only mode - not starting the backup, schedule, delete-backup, or GC controllers")
|
s.logger.Info("Restore only mode - not starting the backup, schedule, delete-backup, or GC controllers")
|
||||||
@@ -802,50 +806,53 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
|
|||||||
s.logger.Fatal(err, "unable to create controller", "controller", controller.BackupStorageLocation)
|
s.logger.Fatal(err, "unable to create controller", "controller", controller.BackupStorageLocation)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := controller.NewScheduleReconciler(s.namespace, s.logger, s.mgr.GetClient(), s.metrics).SetupWithManager(s.mgr); err != nil {
|
if _, ok := enabledRuntimeControllers[controller.Schedule]; ok {
|
||||||
s.logger.Fatal(err, "unable to create controller", "controller", controller.Schedule)
|
if err := controller.NewScheduleReconciler(s.namespace, s.logger, s.mgr.GetClient(), s.metrics).SetupWithManager(s.mgr); err != nil {
|
||||||
|
s.logger.Fatal(err, "unable to create controller", "controller", controller.Schedule)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := controller.NewResticRepoReconciler(s.namespace, s.logger, s.mgr.GetClient(), s.config.defaultResticMaintenanceFrequency, s.repoManager).SetupWithManager(s.mgr); err != nil {
|
if _, ok := enabledRuntimeControllers[controller.ResticRepo]; ok {
|
||||||
s.logger.Fatal(err, "unable to create controller", "controller", controller.ResticRepo)
|
if err := controller.NewResticRepoReconciler(s.namespace, s.logger, s.mgr.GetClient(), s.config.defaultResticMaintenanceFrequency, s.repoManager).SetupWithManager(s.mgr); err != nil {
|
||||||
|
s.logger.Fatal(err, "unable to create controller", "controller", controller.ResticRepo)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := controller.NewBackupDeletionReconciler(
|
if _, ok := enabledRuntimeControllers[controller.BackupDeletion]; ok {
|
||||||
s.logger,
|
if err := controller.NewBackupDeletionReconciler(
|
||||||
s.mgr.GetClient(),
|
s.logger,
|
||||||
backupTracker,
|
s.mgr.GetClient(),
|
||||||
s.repoManager,
|
backupTracker,
|
||||||
s.metrics,
|
s.repoManager,
|
||||||
s.discoveryHelper,
|
s.metrics,
|
||||||
newPluginManager,
|
s.discoveryHelper,
|
||||||
backupStoreGetter,
|
newPluginManager,
|
||||||
).SetupWithManager(s.mgr); err != nil {
|
backupStoreGetter,
|
||||||
s.logger.Fatal(err, "unable to create controller", "controller", controller.BackupDeletion)
|
).SetupWithManager(s.mgr); err != nil {
|
||||||
|
s.logger.Fatal(err, "unable to create controller", "controller", controller.BackupDeletion)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := enabledRuntimeControllers[controller.ServerStatusRequest]; ok {
|
if _, ok := enabledRuntimeControllers[controller.ServerStatusRequest]; ok {
|
||||||
r := controller.ServerStatusRequestReconciler{
|
if err := controller.NewServerStatusRequestReconciler(
|
||||||
Scheme: s.mgr.GetScheme(),
|
s.mgr.GetClient(),
|
||||||
Client: s.mgr.GetClient(),
|
s.ctx,
|
||||||
Ctx: s.ctx,
|
s.pluginRegistry,
|
||||||
PluginRegistry: s.pluginRegistry,
|
clock.RealClock{},
|
||||||
Clock: clock.RealClock{},
|
s.logger,
|
||||||
Log: s.logger,
|
).SetupWithManager(s.mgr); err != nil {
|
||||||
}
|
|
||||||
if err := r.SetupWithManager(s.mgr); err != nil {
|
|
||||||
s.logger.Fatal(err, "unable to create controller", "controller", controller.ServerStatusRequest)
|
s.logger.Fatal(err, "unable to create controller", "controller", controller.ServerStatusRequest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := enabledRuntimeControllers[controller.DownloadRequest]; ok {
|
if _, ok := enabledRuntimeControllers[controller.DownloadRequest]; ok {
|
||||||
r := controller.DownloadRequestReconciler{
|
r := controller.NewDownloadRequestReconciler(
|
||||||
Scheme: s.mgr.GetScheme(),
|
s.mgr.GetClient(),
|
||||||
Client: s.mgr.GetClient(),
|
clock.RealClock{},
|
||||||
Clock: clock.RealClock{},
|
newPluginManager,
|
||||||
NewPluginManager: newPluginManager,
|
backupStoreGetter,
|
||||||
BackupStoreGetter: backupStoreGetter,
|
s.logger,
|
||||||
Log: s.logger,
|
)
|
||||||
}
|
|
||||||
if err := r.SetupWithManager(s.mgr); err != nil {
|
if err := r.SetupWithManager(s.mgr); err != nil {
|
||||||
s.logger.Fatal(err, "unable to create controller", "controller", controller.DownloadRequest)
|
s.logger.Fatal(err, "unable to create controller", "controller", controller.DownloadRequest)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,14 +80,14 @@ func TestRemoveControllers(t *testing.T) {
|
|||||||
errorExpected bool
|
errorExpected bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Remove one disabable controller",
|
name: "Remove one disable controller",
|
||||||
disabledControllers: []string{
|
disabledControllers: []string{
|
||||||
controller.Backup,
|
controller.Backup,
|
||||||
},
|
},
|
||||||
errorExpected: false,
|
errorExpected: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Remove all disabable controllers",
|
name: "Remove all disable controllers",
|
||||||
disabledControllers: []string{
|
disabledControllers: []string{
|
||||||
controller.Backup,
|
controller.Backup,
|
||||||
controller.BackupDeletion,
|
controller.BackupDeletion,
|
||||||
@@ -102,7 +102,7 @@ func TestRemoveControllers(t *testing.T) {
|
|||||||
errorExpected: false,
|
errorExpected: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Remove with a non-disabable controller included",
|
name: "Remove with a non-disable controller included",
|
||||||
disabledControllers: []string{
|
disabledControllers: []string{
|
||||||
controller.Backup,
|
controller.Backup,
|
||||||
controller.BackupStorageLocation,
|
controller.BackupStorageLocation,
|
||||||
@@ -110,7 +110,7 @@ func TestRemoveControllers(t *testing.T) {
|
|||||||
errorExpected: true,
|
errorExpected: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Remove with a misspelled/inexisting controller name",
|
name: "Remove with a misspelled/non-existing controller name",
|
||||||
disabledControllers: []string{
|
disabledControllers: []string{
|
||||||
"go",
|
"go",
|
||||||
},
|
},
|
||||||
@@ -122,16 +122,16 @@ func TestRemoveControllers(t *testing.T) {
|
|||||||
enabledControllers := map[string]func() controllerRunInfo{
|
enabledControllers := map[string]func() controllerRunInfo{
|
||||||
controller.BackupSync: func() controllerRunInfo { return controllerRunInfo{} },
|
controller.BackupSync: func() controllerRunInfo { return controllerRunInfo{} },
|
||||||
controller.Backup: func() controllerRunInfo { return controllerRunInfo{} },
|
controller.Backup: func() controllerRunInfo { return controllerRunInfo{} },
|
||||||
controller.Schedule: func() controllerRunInfo { return controllerRunInfo{} },
|
|
||||||
controller.GarbageCollection: func() controllerRunInfo { return controllerRunInfo{} },
|
controller.GarbageCollection: func() controllerRunInfo { return controllerRunInfo{} },
|
||||||
controller.BackupDeletion: func() controllerRunInfo { return controllerRunInfo{} },
|
|
||||||
controller.Restore: func() controllerRunInfo { return controllerRunInfo{} },
|
controller.Restore: func() controllerRunInfo { return controllerRunInfo{} },
|
||||||
controller.ResticRepo: func() controllerRunInfo { return controllerRunInfo{} },
|
|
||||||
controller.DownloadRequest: func() controllerRunInfo { return controllerRunInfo{} },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enabledRuntimeControllers := map[string]struct{}{
|
enabledRuntimeControllers := map[string]struct{}{
|
||||||
controller.ServerStatusRequest: {},
|
controller.ServerStatusRequest: {},
|
||||||
|
controller.Schedule: {},
|
||||||
|
controller.BackupDeletion: {},
|
||||||
|
controller.ResticRepo: {},
|
||||||
|
controller.DownloadRequest: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
totalNumOriginalControllers := len(enabledControllers) + len(enabledRuntimeControllers)
|
totalNumOriginalControllers := len(enabledControllers) + len(enabledRuntimeControllers)
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import (
|
|||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
|
||||||
"k8s.io/apimachinery/pkg/util/clock"
|
"k8s.io/apimachinery/pkg/util/clock"
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
|
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
@@ -33,23 +32,39 @@ import (
|
|||||||
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt"
|
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DownloadRequestReconciler reconciles a DownloadRequest object
|
// downloadRequestReconciler reconciles a DownloadRequest object
|
||||||
type DownloadRequestReconciler struct {
|
type downloadRequestReconciler struct {
|
||||||
Scheme *runtime.Scheme
|
client kbclient.Client
|
||||||
Client kbclient.Client
|
clock clock.Clock
|
||||||
Clock clock.Clock
|
|
||||||
// use variables to refer to these functions so they can be
|
// use variables to refer to these functions so they can be
|
||||||
// replaced with fakes for testing.
|
// replaced with fakes for testing.
|
||||||
NewPluginManager func(logrus.FieldLogger) clientmgmt.Manager
|
newPluginManager func(logrus.FieldLogger) clientmgmt.Manager
|
||||||
BackupStoreGetter persistence.ObjectBackupStoreGetter
|
backupStoreGetter persistence.ObjectBackupStoreGetter
|
||||||
|
|
||||||
Log logrus.FieldLogger
|
log logrus.FieldLogger
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDownloadRequestReconciler initializes and returns downloadRequestReconciler struct.
|
||||||
|
func NewDownloadRequestReconciler(
|
||||||
|
client kbclient.Client,
|
||||||
|
clock clock.Clock,
|
||||||
|
newPluginManager func(logrus.FieldLogger) clientmgmt.Manager,
|
||||||
|
backupStoreGetter persistence.ObjectBackupStoreGetter,
|
||||||
|
log logrus.FieldLogger,
|
||||||
|
) *downloadRequestReconciler {
|
||||||
|
return &downloadRequestReconciler{
|
||||||
|
client: client,
|
||||||
|
clock: clock,
|
||||||
|
newPluginManager: newPluginManager,
|
||||||
|
backupStoreGetter: backupStoreGetter,
|
||||||
|
log: log,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// +kubebuilder:rbac:groups=velero.io,resources=downloadrequests,verbs=get;list;watch;create;update;patch;delete
|
// +kubebuilder:rbac:groups=velero.io,resources=downloadrequests,verbs=get;list;watch;create;update;patch;delete
|
||||||
// +kubebuilder:rbac:groups=velero.io,resources=downloadrequests/status,verbs=get;update;patch
|
// +kubebuilder:rbac:groups=velero.io,resources=downloadrequests/status,verbs=get;update;patch
|
||||||
func (r *DownloadRequestReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
func (r *downloadRequestReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||||
log := r.Log.WithFields(logrus.Fields{
|
log := r.log.WithFields(logrus.Fields{
|
||||||
"controller": "download-request",
|
"controller": "download-request",
|
||||||
"downloadRequest": req.NamespacedName,
|
"downloadRequest": req.NamespacedName,
|
||||||
})
|
})
|
||||||
@@ -57,7 +72,7 @@ func (r *DownloadRequestReconciler) Reconcile(ctx context.Context, req ctrl.Requ
|
|||||||
// Fetch the DownloadRequest instance.
|
// Fetch the DownloadRequest instance.
|
||||||
log.Debug("Getting DownloadRequest")
|
log.Debug("Getting DownloadRequest")
|
||||||
downloadRequest := &velerov1api.DownloadRequest{}
|
downloadRequest := &velerov1api.DownloadRequest{}
|
||||||
if err := r.Client.Get(ctx, req.NamespacedName, downloadRequest); err != nil {
|
if err := r.client.Get(ctx, req.NamespacedName, downloadRequest); err != nil {
|
||||||
if apierrors.IsNotFound(err) {
|
if apierrors.IsNotFound(err) {
|
||||||
log.Debug("Unable to find DownloadRequest")
|
log.Debug("Unable to find DownloadRequest")
|
||||||
return ctrl.Result{}, nil
|
return ctrl.Result{}, nil
|
||||||
@@ -70,19 +85,19 @@ func (r *DownloadRequestReconciler) Reconcile(ctx context.Context, req ctrl.Requ
|
|||||||
original := downloadRequest.DeepCopy()
|
original := downloadRequest.DeepCopy()
|
||||||
defer func() {
|
defer func() {
|
||||||
// Always attempt to Patch the downloadRequest object and status after each reconciliation.
|
// Always attempt to Patch the downloadRequest object and status after each reconciliation.
|
||||||
if err := r.Client.Patch(ctx, downloadRequest, kbclient.MergeFrom(original)); err != nil {
|
if err := r.client.Patch(ctx, downloadRequest, kbclient.MergeFrom(original)); err != nil {
|
||||||
log.WithError(err).Error("Error updating download request")
|
log.WithError(err).Error("Error updating download request")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if downloadRequest.Status != (velerov1api.DownloadRequestStatus{}) && downloadRequest.Status.Expiration != nil {
|
if downloadRequest.Status != (velerov1api.DownloadRequestStatus{}) && downloadRequest.Status.Expiration != nil {
|
||||||
if downloadRequest.Status.Expiration.Time.Before(r.Clock.Now()) {
|
if downloadRequest.Status.Expiration.Time.Before(r.clock.Now()) {
|
||||||
|
|
||||||
// Delete any request that is expired, regardless of the phase: it is not
|
// Delete any request that is expired, regardless of the phase: it is not
|
||||||
// worth proceeding and trying/retrying to find it.
|
// worth proceeding and trying/retrying to find it.
|
||||||
log.Debug("DownloadRequest has expired - deleting")
|
log.Debug("DownloadRequest has expired - deleting")
|
||||||
if err := r.Client.Delete(ctx, downloadRequest); err != nil {
|
if err := r.client.Delete(ctx, downloadRequest); err != nil {
|
||||||
log.WithError(err).Error("Error deleting an expired download request")
|
log.WithError(err).Error("Error deleting an expired download request")
|
||||||
return ctrl.Result{}, errors.WithStack(err)
|
return ctrl.Result{}, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
@@ -103,12 +118,12 @@ func (r *DownloadRequestReconciler) Reconcile(ctx context.Context, req ctrl.Requ
|
|||||||
if downloadRequest.Status.Phase == "" || downloadRequest.Status.Phase == velerov1api.DownloadRequestPhaseNew {
|
if downloadRequest.Status.Phase == "" || downloadRequest.Status.Phase == velerov1api.DownloadRequestPhaseNew {
|
||||||
|
|
||||||
// Update the expiration.
|
// Update the expiration.
|
||||||
downloadRequest.Status.Expiration = &metav1.Time{Time: r.Clock.Now().Add(persistence.DownloadURLTTL)}
|
downloadRequest.Status.Expiration = &metav1.Time{Time: r.clock.Now().Add(persistence.DownloadURLTTL)}
|
||||||
|
|
||||||
if downloadRequest.Spec.Target.Kind == velerov1api.DownloadTargetKindRestoreLog ||
|
if downloadRequest.Spec.Target.Kind == velerov1api.DownloadTargetKindRestoreLog ||
|
||||||
downloadRequest.Spec.Target.Kind == velerov1api.DownloadTargetKindRestoreResults {
|
downloadRequest.Spec.Target.Kind == velerov1api.DownloadTargetKindRestoreResults {
|
||||||
restore := &velerov1api.Restore{}
|
restore := &velerov1api.Restore{}
|
||||||
if err := r.Client.Get(ctx, kbclient.ObjectKey{
|
if err := r.client.Get(ctx, kbclient.ObjectKey{
|
||||||
Namespace: downloadRequest.Namespace,
|
Namespace: downloadRequest.Namespace,
|
||||||
Name: downloadRequest.Spec.Target.Name,
|
Name: downloadRequest.Spec.Target.Name,
|
||||||
}, restore); err != nil {
|
}, restore); err != nil {
|
||||||
@@ -118,7 +133,7 @@ func (r *DownloadRequestReconciler) Reconcile(ctx context.Context, req ctrl.Requ
|
|||||||
}
|
}
|
||||||
|
|
||||||
backup := &velerov1api.Backup{}
|
backup := &velerov1api.Backup{}
|
||||||
if err := r.Client.Get(ctx, kbclient.ObjectKey{
|
if err := r.client.Get(ctx, kbclient.ObjectKey{
|
||||||
Namespace: downloadRequest.Namespace,
|
Namespace: downloadRequest.Namespace,
|
||||||
Name: backupName,
|
Name: backupName,
|
||||||
}, backup); err != nil {
|
}, backup); err != nil {
|
||||||
@@ -126,17 +141,17 @@ func (r *DownloadRequestReconciler) Reconcile(ctx context.Context, req ctrl.Requ
|
|||||||
}
|
}
|
||||||
|
|
||||||
location := &velerov1api.BackupStorageLocation{}
|
location := &velerov1api.BackupStorageLocation{}
|
||||||
if err := r.Client.Get(ctx, kbclient.ObjectKey{
|
if err := r.client.Get(ctx, kbclient.ObjectKey{
|
||||||
Namespace: backup.Namespace,
|
Namespace: backup.Namespace,
|
||||||
Name: backup.Spec.StorageLocation,
|
Name: backup.Spec.StorageLocation,
|
||||||
}, location); err != nil {
|
}, location); err != nil {
|
||||||
return ctrl.Result{}, errors.WithStack(err)
|
return ctrl.Result{}, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pluginManager := r.NewPluginManager(log)
|
pluginManager := r.newPluginManager(log)
|
||||||
defer pluginManager.CleanupClients()
|
defer pluginManager.CleanupClients()
|
||||||
|
|
||||||
backupStore, err := r.BackupStoreGetter.Get(location, pluginManager, log)
|
backupStore, err := r.backupStoreGetter.Get(location, pluginManager, log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Error("Error getting a backup store")
|
log.WithError(err).Error("Error getting a backup store")
|
||||||
return ctrl.Result{}, errors.WithStack(err)
|
return ctrl.Result{}, errors.WithStack(err)
|
||||||
@@ -149,7 +164,7 @@ func (r *DownloadRequestReconciler) Reconcile(ctx context.Context, req ctrl.Requ
|
|||||||
downloadRequest.Status.Phase = velerov1api.DownloadRequestPhaseProcessed
|
downloadRequest.Status.Phase = velerov1api.DownloadRequestPhaseProcessed
|
||||||
|
|
||||||
// Update the expiration again to extend the time we wait (the TTL) to start after successfully processing the URL.
|
// Update the expiration again to extend the time we wait (the TTL) to start after successfully processing the URL.
|
||||||
downloadRequest.Status.Expiration = &metav1.Time{Time: r.Clock.Now().Add(persistence.DownloadURLTTL)}
|
downloadRequest.Status.Expiration = &metav1.Time{Time: r.clock.Now().Add(persistence.DownloadURLTTL)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Requeue is mostly to handle deleting any expired requests that were not
|
// Requeue is mostly to handle deleting any expired requests that were not
|
||||||
@@ -157,7 +172,7 @@ func (r *DownloadRequestReconciler) Reconcile(ctx context.Context, req ctrl.Requ
|
|||||||
return ctrl.Result{Requeue: true}, nil
|
return ctrl.Result{Requeue: true}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *DownloadRequestReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
func (r *downloadRequestReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||||
return ctrl.NewControllerManagedBy(mgr).
|
return ctrl.NewControllerManagedBy(mgr).
|
||||||
For(&velerov1api.DownloadRequest{}).
|
For(&velerov1api.DownloadRequest{}).
|
||||||
Complete(r)
|
Complete(r)
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ var _ = Describe("Download Request Reconciler", func() {
|
|||||||
test.downloadRequest.Status.Expiration = &metav1.Time{Time: rClock.Now().Add(-1 * time.Minute)}
|
test.downloadRequest.Status.Expiration = &metav1.Time{Time: rClock.Now().Add(-1 * time.Minute)}
|
||||||
}
|
}
|
||||||
|
|
||||||
fakeClient := fake.NewFakeClientWithScheme(scheme.Scheme)
|
fakeClient := fake.NewClientBuilder().WithScheme(scheme.Scheme).Build()
|
||||||
err = fakeClient.Create(context.TODO(), test.downloadRequest)
|
err = fakeClient.Create(context.TODO(), test.downloadRequest)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
@@ -109,13 +109,13 @@ var _ = Describe("Download Request Reconciler", func() {
|
|||||||
|
|
||||||
// Setup reconciler
|
// Setup reconciler
|
||||||
Expect(velerov1api.AddToScheme(scheme.Scheme)).To(Succeed())
|
Expect(velerov1api.AddToScheme(scheme.Scheme)).To(Succeed())
|
||||||
r := DownloadRequestReconciler{
|
r := NewDownloadRequestReconciler(
|
||||||
Client: fakeClient,
|
fakeClient,
|
||||||
Clock: rClock,
|
rClock,
|
||||||
NewPluginManager: func(logrus.FieldLogger) clientmgmt.Manager { return pluginManager },
|
func(logrus.FieldLogger) clientmgmt.Manager { return pluginManager },
|
||||||
BackupStoreGetter: NewFakeObjectBackupStoreGetter(backupStores),
|
NewFakeObjectBackupStoreGetter(backupStores),
|
||||||
Log: velerotest.NewLogger(),
|
velerotest.NewLogger(),
|
||||||
}
|
)
|
||||||
|
|
||||||
if test.backupLocation != nil && test.expectGetsURL {
|
if test.backupLocation != nil && test.expectGetsURL {
|
||||||
backupStores[test.backupLocation.Name].On("GetDownloadURL", test.downloadRequest.Spec.Target).Return("a-url", nil)
|
backupStores[test.backupLocation.Name].On("GetDownloadURL", test.downloadRequest.Spec.Target).Return("a-url", nil)
|
||||||
@@ -136,7 +136,7 @@ var _ = Describe("Download Request Reconciler", func() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
instance := &velerov1api.DownloadRequest{}
|
instance := &velerov1api.DownloadRequest{}
|
||||||
err = r.Client.Get(ctx, kbclient.ObjectKey{Name: test.downloadRequest.Name, Namespace: test.downloadRequest.Namespace}, instance)
|
err = r.client.Get(ctx, kbclient.ObjectKey{Name: test.downloadRequest.Name, Namespace: test.downloadRequest.Namespace}, instance)
|
||||||
|
|
||||||
if test.expired {
|
if test.expired {
|
||||||
Expect(instance).ToNot(Equal(test.downloadRequest))
|
Expect(instance).ToNot(Equal(test.downloadRequest))
|
||||||
@@ -153,7 +153,7 @@ var _ = Describe("Download Request Reconciler", func() {
|
|||||||
if test.expectGetsURL {
|
if test.expectGetsURL {
|
||||||
Expect(string(instance.Status.Phase)).To(Equal(string(velerov1api.DownloadRequestPhaseProcessed)))
|
Expect(string(instance.Status.Phase)).To(Equal(string(velerov1api.DownloadRequestPhaseProcessed)))
|
||||||
Expect(instance.Status.DownloadURL).To(Equal("a-url"))
|
Expect(instance.Status.DownloadURL).To(Equal("a-url"))
|
||||||
Expect(velerotest.TimesAreEqual(instance.Status.Expiration.Time, r.Clock.Now().Add(signedURLTTL))).To(BeTrue())
|
Expect(velerotest.TimesAreEqual(instance.Status.Expiration.Time, r.clock.Now().Add(signedURLTTL))).To(BeTrue())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import (
|
|||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
|
||||||
"k8s.io/apimachinery/pkg/util/clock"
|
"k8s.io/apimachinery/pkg/util/clock"
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
@@ -46,21 +45,36 @@ type PluginLister interface {
|
|||||||
List(kind framework.PluginKind) []framework.PluginIdentifier
|
List(kind framework.PluginKind) []framework.PluginIdentifier
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerStatusRequestReconciler reconciles a ServerStatusRequest object
|
// serverStatusRequestReconciler reconciles a ServerStatusRequest object
|
||||||
type ServerStatusRequestReconciler struct {
|
type serverStatusRequestReconciler struct {
|
||||||
Scheme *runtime.Scheme
|
client client.Client
|
||||||
Client client.Client
|
ctx context.Context
|
||||||
Ctx context.Context
|
pluginRegistry PluginLister
|
||||||
PluginRegistry PluginLister
|
clock clock.Clock
|
||||||
Clock clock.Clock
|
|
||||||
|
|
||||||
Log logrus.FieldLogger
|
log logrus.FieldLogger
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewServerStatusRequestReconciler initializes and returns serverStatusRequestReconciler struct.
|
||||||
|
func NewServerStatusRequestReconciler(
|
||||||
|
client client.Client,
|
||||||
|
ctx context.Context,
|
||||||
|
pluginRegistry PluginLister,
|
||||||
|
clock clock.Clock,
|
||||||
|
log logrus.FieldLogger) *serverStatusRequestReconciler {
|
||||||
|
return &serverStatusRequestReconciler{
|
||||||
|
client: client,
|
||||||
|
ctx: ctx,
|
||||||
|
pluginRegistry: pluginRegistry,
|
||||||
|
clock: clock,
|
||||||
|
log: log,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// +kubebuilder:rbac:groups=velero.io,resources=serverstatusrequests,verbs=get;list;watch;create;update;patch;delete
|
// +kubebuilder:rbac:groups=velero.io,resources=serverstatusrequests,verbs=get;list;watch;create;update;patch;delete
|
||||||
// +kubebuilder:rbac:groups=velero.io,resources=serverstatusrequests/status,verbs=get;update;patch
|
// +kubebuilder:rbac:groups=velero.io,resources=serverstatusrequests/status,verbs=get;update;patch
|
||||||
func (r *ServerStatusRequestReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
func (r *serverStatusRequestReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||||
log := r.Log.WithFields(logrus.Fields{
|
log := r.log.WithFields(logrus.Fields{
|
||||||
"controller": ServerStatusRequest,
|
"controller": ServerStatusRequest,
|
||||||
"serverStatusRequest": req.NamespacedName,
|
"serverStatusRequest": req.NamespacedName,
|
||||||
})
|
})
|
||||||
@@ -68,7 +82,7 @@ func (r *ServerStatusRequestReconciler) Reconcile(ctx context.Context, req ctrl.
|
|||||||
// Fetch the ServerStatusRequest instance.
|
// Fetch the ServerStatusRequest instance.
|
||||||
log.Debug("Getting ServerStatusRequest")
|
log.Debug("Getting ServerStatusRequest")
|
||||||
statusRequest := &velerov1api.ServerStatusRequest{}
|
statusRequest := &velerov1api.ServerStatusRequest{}
|
||||||
if err := r.Client.Get(r.Ctx, req.NamespacedName, statusRequest); err != nil {
|
if err := r.client.Get(r.ctx, req.NamespacedName, statusRequest); err != nil {
|
||||||
if apierrors.IsNotFound(err) {
|
if apierrors.IsNotFound(err) {
|
||||||
log.Debug("Unable to find ServerStatusRequest")
|
log.Debug("Unable to find ServerStatusRequest")
|
||||||
return ctrl.Result{}, nil
|
return ctrl.Result{}, nil
|
||||||
@@ -78,7 +92,7 @@ func (r *ServerStatusRequestReconciler) Reconcile(ctx context.Context, req ctrl.
|
|||||||
return ctrl.Result{}, err
|
return ctrl.Result{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log = r.Log.WithFields(logrus.Fields{
|
log = r.log.WithFields(logrus.Fields{
|
||||||
"controller": ServerStatusRequest,
|
"controller": ServerStatusRequest,
|
||||||
"serverStatusRequest": req.NamespacedName,
|
"serverStatusRequest": req.NamespacedName,
|
||||||
"phase": statusRequest.Status.Phase,
|
"phase": statusRequest.Status.Phase,
|
||||||
@@ -90,23 +104,23 @@ func (r *ServerStatusRequestReconciler) Reconcile(ctx context.Context, req ctrl.
|
|||||||
original := statusRequest.DeepCopy()
|
original := statusRequest.DeepCopy()
|
||||||
statusRequest.Status.ServerVersion = buildinfo.Version
|
statusRequest.Status.ServerVersion = buildinfo.Version
|
||||||
statusRequest.Status.Phase = velerov1api.ServerStatusRequestPhaseProcessed
|
statusRequest.Status.Phase = velerov1api.ServerStatusRequestPhaseProcessed
|
||||||
statusRequest.Status.ProcessedTimestamp = &metav1.Time{Time: r.Clock.Now()}
|
statusRequest.Status.ProcessedTimestamp = &metav1.Time{Time: r.clock.Now()}
|
||||||
statusRequest.Status.Plugins = velero.GetInstalledPluginInfo(r.PluginRegistry)
|
statusRequest.Status.Plugins = velero.GetInstalledPluginInfo(r.pluginRegistry)
|
||||||
|
|
||||||
if err := r.Client.Patch(r.Ctx, statusRequest, client.MergeFrom(original)); err != nil {
|
if err := r.client.Patch(r.ctx, statusRequest, client.MergeFrom(original)); err != nil {
|
||||||
log.WithError(err).Error("Error updating ServerStatusRequest status")
|
log.WithError(err).Error("Error updating ServerStatusRequest status")
|
||||||
return ctrl.Result{RequeueAfter: statusRequestResyncPeriod}, err
|
return ctrl.Result{RequeueAfter: statusRequestResyncPeriod}, err
|
||||||
}
|
}
|
||||||
case velerov1api.ServerStatusRequestPhaseProcessed:
|
case velerov1api.ServerStatusRequestPhaseProcessed:
|
||||||
log.Debug("Checking whether ServerStatusRequest has expired")
|
log.Debug("Checking whether ServerStatusRequest has expired")
|
||||||
expiration := statusRequest.Status.ProcessedTimestamp.Add(ttl)
|
expiration := statusRequest.Status.ProcessedTimestamp.Add(ttl)
|
||||||
if expiration.After(r.Clock.Now()) {
|
if expiration.After(r.clock.Now()) {
|
||||||
log.Debug("ServerStatusRequest has not expired")
|
log.Debug("ServerStatusRequest has not expired")
|
||||||
return ctrl.Result{RequeueAfter: statusRequestResyncPeriod}, nil
|
return ctrl.Result{RequeueAfter: statusRequestResyncPeriod}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug("ServerStatusRequest has expired, deleting it")
|
log.Debug("ServerStatusRequest has expired, deleting it")
|
||||||
if err := r.Client.Delete(r.Ctx, statusRequest); err != nil {
|
if err := r.client.Delete(r.ctx, statusRequest); err != nil {
|
||||||
log.WithError(err).Error("Unable to delete the request")
|
log.WithError(err).Error("Unable to delete the request")
|
||||||
return ctrl.Result{}, nil
|
return ctrl.Result{}, nil
|
||||||
}
|
}
|
||||||
@@ -119,7 +133,7 @@ func (r *ServerStatusRequestReconciler) Reconcile(ctx context.Context, req ctrl.
|
|||||||
return ctrl.Result{RequeueAfter: statusRequestResyncPeriod}, nil
|
return ctrl.Result{RequeueAfter: statusRequestResyncPeriod}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ServerStatusRequestReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
func (r *serverStatusRequestReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||||
return ctrl.NewControllerManagedBy(mgr).
|
return ctrl.NewControllerManagedBy(mgr).
|
||||||
For(&velerov1api.ServerStatusRequest{}).
|
For(&velerov1api.ServerStatusRequest{}).
|
||||||
WithOptions(controller.Options{
|
WithOptions(controller.Options{
|
||||||
|
|||||||
@@ -62,15 +62,15 @@ var _ = Describe("Server Status Request Reconciler", func() {
|
|||||||
func(test request) {
|
func(test request) {
|
||||||
// Setup reconciler
|
// Setup reconciler
|
||||||
Expect(velerov1api.AddToScheme(scheme.Scheme)).To(Succeed())
|
Expect(velerov1api.AddToScheme(scheme.Scheme)).To(Succeed())
|
||||||
r := ServerStatusRequestReconciler{
|
r := NewServerStatusRequestReconciler(
|
||||||
Client: fake.NewFakeClientWithScheme(scheme.Scheme, test.req),
|
fake.NewClientBuilder().WithScheme(scheme.Scheme).WithObjects(test.req).Build(),
|
||||||
Ctx: context.Background(),
|
context.Background(),
|
||||||
PluginRegistry: test.reqPluginLister,
|
test.reqPluginLister,
|
||||||
Clock: clock.NewFakeClock(now),
|
clock.NewFakeClock(now),
|
||||||
Log: velerotest.NewLogger(),
|
velerotest.NewLogger(),
|
||||||
}
|
)
|
||||||
|
|
||||||
actualResult, err := r.Reconcile(r.Ctx, ctrl.Request{
|
actualResult, err := r.Reconcile(r.ctx, ctrl.Request{
|
||||||
NamespacedName: types.NamespacedName{
|
NamespacedName: types.NamespacedName{
|
||||||
Namespace: velerov1api.DefaultNamespace,
|
Namespace: velerov1api.DefaultNamespace,
|
||||||
Name: test.req.Name,
|
Name: test.req.Name,
|
||||||
@@ -86,7 +86,7 @@ var _ = Describe("Server Status Request Reconciler", func() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
instance := &velerov1api.ServerStatusRequest{}
|
instance := &velerov1api.ServerStatusRequest{}
|
||||||
err = r.Client.Get(ctx, kbclient.ObjectKey{Name: test.req.Name, Namespace: test.req.Namespace}, instance)
|
err = r.client.Get(ctx, kbclient.ObjectKey{Name: test.req.Name, Namespace: test.req.Namespace}, instance)
|
||||||
|
|
||||||
// Assertions
|
// Assertions
|
||||||
if test.expected == nil {
|
if test.expected == nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user