Migrate backup sync controller from code-generator to kubebuilder (#5218)

* Migrate backup sync controller from code-generator to kubebuilder

1. use kubebuilder's reconcile logic to replace controller's old logic.
2. use ginkgo and gomega to replace testing.
3. modify BSL reconciler registration method.

Signed-off-by: Xun Jiang <blackpiglet@gmail.com>

* Add Option for PeriodicalEnqueueSource.

Signed-off-by: Xun Jiang <blackpiglet@gmail.com>

Signed-off-by: Xun Jiang <blackpiglet@gmail.com>
Co-authored-by: Xun Jiang <blackpiglet@gmail.com>
This commit is contained in:
Xun Jiang/Bruce Jiang
2022-08-30 16:55:39 +08:00
committed by GitHub
parent 8bc464aaa6
commit 6fea973c57
12 changed files with 1036 additions and 996 deletions

View File

@@ -44,35 +44,55 @@ const (
)
// BackupStorageLocationReconciler reconciles a BackupStorageLocation object
type BackupStorageLocationReconciler struct {
Ctx context.Context
Client client.Client
Scheme *runtime.Scheme
DefaultBackupLocationInfo storage.DefaultBackupLocationInfo
type backupStorageLocationReconciler struct {
ctx context.Context
client client.Client
scheme *runtime.Scheme
defaultBackupLocationInfo storage.DefaultBackupLocationInfo
// use variables to refer to these functions so they can be
// replaced with fakes for testing.
NewPluginManager func(logrus.FieldLogger) clientmgmt.Manager
BackupStoreGetter persistence.ObjectBackupStoreGetter
newPluginManager func(logrus.FieldLogger) clientmgmt.Manager
backupStoreGetter persistence.ObjectBackupStoreGetter
Log logrus.FieldLogger
log logrus.FieldLogger
}
// NewBackupStorageLocationReconciler initialize and return a backupStorageLocationReconciler struct
func NewBackupStorageLocationReconciler(
ctx context.Context,
client client.Client,
scheme *runtime.Scheme,
defaultBackupLocationInfo storage.DefaultBackupLocationInfo,
newPluginManager func(logrus.FieldLogger) clientmgmt.Manager,
backupStoreGetter persistence.ObjectBackupStoreGetter,
log logrus.FieldLogger) *backupStorageLocationReconciler {
return &backupStorageLocationReconciler{
ctx: ctx,
client: client,
scheme: scheme,
defaultBackupLocationInfo: defaultBackupLocationInfo,
newPluginManager: newPluginManager,
backupStoreGetter: backupStoreGetter,
log: log,
}
}
// +kubebuilder:rbac:groups=velero.io,resources=backupstoragelocations,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=velero.io,resources=backupstoragelocations/status,verbs=get;update;patch
func (r *BackupStorageLocationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
func (r *backupStorageLocationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
var unavailableErrors []string
var location velerov1api.BackupStorageLocation
log := r.Log.WithField("controller", BackupStorageLocation).WithField(BackupStorageLocation, req.NamespacedName.String())
log := r.log.WithField("controller", BackupStorageLocation).WithField(BackupStorageLocation, req.NamespacedName.String())
log.Debug("Validating availability of BackupStorageLocation")
locationList, err := storage.ListBackupStorageLocations(r.Ctx, r.Client, req.Namespace)
locationList, err := storage.ListBackupStorageLocations(r.ctx, r.client, req.Namespace)
if err != nil {
log.WithError(err).Error("No BackupStorageLocations found, at least one is required")
return ctrl.Result{}, nil
}
pluginManager := r.NewPluginManager(log)
pluginManager := r.newPluginManager(log)
defer pluginManager.CleanupClients()
var defaultFound bool
@@ -93,7 +113,7 @@ func (r *BackupStorageLocationReconciler) Reconcile(ctx context.Context, req ctr
isDefault := location.Spec.Default
// TODO(2.0) remove this check since the server default will be deprecated
if !defaultFound && location.Name == r.DefaultBackupLocationInfo.StorageLocation {
if !defaultFound && location.Name == r.defaultBackupLocationInfo.StorageLocation {
// For backward-compatible, to configure the backup storage location as the default if
// none of the BSLs be marked as the default and the BSL name matches against the
// "velero server --default-backup-storage-location".
@@ -117,12 +137,12 @@ func (r *BackupStorageLocationReconciler) Reconcile(ctx context.Context, req ctr
location.Status.Phase = velerov1api.BackupStorageLocationPhaseAvailable
location.Status.Message = ""
}
if err := r.Client.Patch(r.Ctx, &location, client.MergeFrom(original)); err != nil {
if err := r.client.Patch(r.ctx, &location, client.MergeFrom(original)); err != nil {
log.WithError(err).Error("Error updating BackupStorageLocation phase")
}
}()
backupStore, err := r.BackupStoreGetter.Get(&location, pluginManager, log)
backupStore, err := r.backupStoreGetter.Get(&location, pluginManager, log)
if err != nil {
log.WithError(err).Error("Error getting a backup store")
return
@@ -144,11 +164,11 @@ func (r *BackupStorageLocationReconciler) Reconcile(ctx context.Context, req ctr
return ctrl.Result{}, nil
}
func (r *BackupStorageLocationReconciler) logReconciledPhase(defaultFound bool, locationList velerov1api.BackupStorageLocationList, errs []string) {
func (r *backupStorageLocationReconciler) logReconciledPhase(defaultFound bool, locationList velerov1api.BackupStorageLocationList, errs []string) {
var availableBSLs []*velerov1api.BackupStorageLocation
var unAvailableBSLs []*velerov1api.BackupStorageLocation
var unknownBSLs []*velerov1api.BackupStorageLocation
log := r.Log.WithField("controller", BackupStorageLocation)
log := r.log.WithField("controller", BackupStorageLocation)
for i, location := range locationList.Items {
phase := location.Status.Phase
@@ -181,16 +201,19 @@ func (r *BackupStorageLocationReconciler) logReconciledPhase(defaultFound bool,
}
}
func (r *BackupStorageLocationReconciler) SetupWithManager(mgr ctrl.Manager) error {
func (r *backupStorageLocationReconciler) SetupWithManager(mgr ctrl.Manager) error {
g := kube.NewPeriodicalEnqueueSource(
r.Log,
r.log,
mgr.GetClient(),
&velerov1api.BackupStorageLocationList{},
bslValidationEnqueuePeriod,
// Add filter function to enqueue BSL per ValidationFrequency setting.
func(object client.Object) bool {
location := object.(*velerov1api.BackupStorageLocation)
return storage.IsReadyToValidate(location.Spec.ValidationFrequency, location.Status.LastValidationTime, r.DefaultBackupLocationInfo.ServerValidationFrequency, r.Log.WithField("controller", BackupStorageLocation))
kube.PeriodicalEnqueueSourceOption{
FilterFuncs: []func(object client.Object) bool{
func(object client.Object) bool {
location := object.(*velerov1api.BackupStorageLocation)
return storage.IsReadyToValidate(location.Spec.ValidationFrequency, location.Status.LastValidationTime, r.defaultBackupLocationInfo.ServerValidationFrequency, r.log.WithField("controller", BackupStorageLocation))
},
},
},
)
return ctrl.NewControllerManagedBy(mgr).