Skip to content

Commit 7fd342e

Browse files
committed
Add support for pausing cluster reconcilation
1 parent b4e0e2a commit 7fd342e

File tree

3 files changed

+95
-10
lines changed

3 files changed

+95
-10
lines changed

controllers/ibmpowervscluster_controller.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ import (
3434
ctrl "sigs.k8s.io/controller-runtime"
3535
"sigs.k8s.io/controller-runtime/pkg/client"
3636
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
37+
"sigs.k8s.io/controller-runtime/pkg/handler"
3738
"sigs.k8s.io/controller-runtime/pkg/reconcile"
39+
"sigs.k8s.io/controller-runtime/pkg/source"
3840

3941
capiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
4042
"sigs.k8s.io/cluster-api/util"
@@ -455,8 +457,21 @@ func (c clusterDescendants) filterOwnedDescendants(cluster *infrav1beta2.IBMPowe
455457

456458
// SetupWithManager creates a new IBMPowerVSCluster controller for a manager.
457459
func (r *IBMPowerVSClusterReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager) error {
458-
return ctrl.NewControllerManagedBy(mgr).
460+
controller, err := ctrl.NewControllerManagedBy(mgr).
459461
For(&infrav1beta2.IBMPowerVSCluster{}).
460462
WithEventFilter(predicates.ResourceIsNotExternallyManaged(ctrl.LoggerFrom(ctx))).
461-
Complete(r)
463+
WithEventFilter(predicates.ResourceNotPaused(ctrl.LoggerFrom(ctx))).
464+
Build(r)
465+
if err != nil {
466+
return errors.Wrap(err, "error creating controller")
467+
}
468+
// Add a watch on capiv1beta1.Cluster object for unpause notifications.
469+
if err = controller.Watch(
470+
source.Kind(mgr.GetCache(), &capiv1beta1.Cluster{}),
471+
handler.EnqueueRequestsFromMapFunc(util.ClusterToInfrastructureMapFunc(ctx, infrav1beta2.GroupVersion.WithKind("IBMPowerVSCluster"), mgr.GetClient(), &infrav1beta2.IBMPowerVSCluster{})),
472+
predicates.ClusterUnpaused(ctrl.LoggerFrom(ctx)),
473+
); err != nil {
474+
return errors.Wrap(err, "failed adding a watch for ready clusters")
475+
}
476+
return nil
462477
}

controllers/ibmpowervsmachine_controller.go

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"time"
2323

2424
"github.com/go-logr/logr"
25+
"github.com/pkg/errors"
2526

2627
"github.com/IBM-Cloud/power-go-client/power/models"
2728

@@ -34,11 +35,14 @@ import (
3435
ctrl "sigs.k8s.io/controller-runtime"
3536
"sigs.k8s.io/controller-runtime/pkg/client"
3637
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
38+
"sigs.k8s.io/controller-runtime/pkg/handler"
39+
"sigs.k8s.io/controller-runtime/pkg/source"
3740

3841
capiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
3942
capierrors "sigs.k8s.io/cluster-api/errors"
4043
"sigs.k8s.io/cluster-api/util"
4144
"sigs.k8s.io/cluster-api/util/conditions"
45+
"sigs.k8s.io/cluster-api/util/predicates"
4246

4347
infrav1beta2 "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta2"
4448
"sigs.k8s.io/cluster-api-provider-ibmcloud/cloud/scope"
@@ -157,13 +161,6 @@ func (r *IBMPowerVSMachineReconciler) Reconcile(ctx context.Context, req ctrl.Re
157161
return r.reconcileNormal(machineScope)
158162
}
159163

160-
// SetupWithManager creates a new IBMPowerVSMachine controller for a manager.
161-
func (r *IBMPowerVSMachineReconciler) SetupWithManager(mgr ctrl.Manager) error {
162-
return ctrl.NewControllerManagedBy(mgr).
163-
For(&infrav1beta2.IBMPowerVSMachine{}).
164-
Complete(r)
165-
}
166-
167164
func (r *IBMPowerVSMachineReconciler) reconcileDelete(scope *scope.PowerVSMachineScope) (_ ctrl.Result, reterr error) {
168165
scope.Info("Handling deleted IBMPowerVSMachine")
169166

@@ -299,3 +296,76 @@ func (r *IBMPowerVSMachineReconciler) reconcileNormal(machineScope *scope.PowerV
299296
}
300297
return ctrl.Result{}, nil
301298
}
299+
300+
// IBMPowerVSClusterToIBMPowerVSMachines is a handler.ToRequestsFunc to be used to enqeue requests for reconciliation
301+
// of IBMPowerVSMachines.
302+
func (r *IBMPowerVSMachineReconciler) IBMPowerVSClusterToIBMPowerVSMachines(ctx context.Context) handler.MapFunc {
303+
log := ctrl.LoggerFrom(ctx)
304+
return func(mapCtx context.Context, o client.Object) []ctrl.Request {
305+
result := []ctrl.Request{}
306+
307+
c, ok := o.(*infrav1beta2.IBMPowerVSCluster)
308+
if !ok {
309+
log.Error(errors.Errorf("expected a IBMPowerVSCluster but got a %T", o), "failed to get IBMPowerVSMachines for IBMPowerVSCluster")
310+
return nil
311+
}
312+
313+
cluster, err := util.GetOwnerCluster(mapCtx, r.Client, c.ObjectMeta)
314+
switch {
315+
case apierrors.IsNotFound(err) || cluster == nil:
316+
return result
317+
case err != nil:
318+
log.Error(err, "failed to get owning cluster")
319+
return result
320+
}
321+
322+
labels := map[string]string{capiv1beta1.ClusterNameLabel: cluster.Name}
323+
machineList := &capiv1beta1.MachineList{}
324+
if err := r.List(mapCtx, machineList, client.InNamespace(c.Namespace), client.MatchingLabels(labels)); err != nil {
325+
log.Error(err, "failed to list Machines")
326+
return nil
327+
}
328+
for _, m := range machineList.Items {
329+
if m.Spec.InfrastructureRef.Name == "" {
330+
continue
331+
}
332+
name := client.ObjectKey{Namespace: m.Namespace, Name: m.Spec.InfrastructureRef.Name}
333+
result = append(result, ctrl.Request{NamespacedName: name})
334+
}
335+
336+
return result
337+
}
338+
}
339+
340+
// SetupWithManager creates a new IBMVPCMachine controller for a manager.
341+
func (r *IBMPowerVSMachineReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager) error {
342+
controller, err := ctrl.NewControllerManagedBy(mgr).
343+
For(&infrav1beta2.IBMVPCMachine{}).
344+
WithEventFilter(predicates.ResourceNotPaused(ctrl.LoggerFrom(ctx))).
345+
Watches(
346+
&capiv1beta1.Machine{},
347+
handler.EnqueueRequestsFromMapFunc(util.MachineToInfrastructureMapFunc(infrav1beta2.GroupVersion.WithKind("IBMPowerVSMachine"))),
348+
).
349+
Watches(
350+
&infrav1beta2.IBMPowerVSCluster{},
351+
handler.EnqueueRequestsFromMapFunc(r.IBMPowerVSClusterToIBMPowerVSMachines(ctx)),
352+
).
353+
Build(r)
354+
if err != nil {
355+
return errors.Wrap(err, "error creating controller")
356+
}
357+
358+
clusterToObjectFunc, err := util.ClusterToTypedObjectsMapper(r.Client, &infrav1beta2.IBMPowerVSMachineList{}, mgr.GetScheme())
359+
if err != nil {
360+
return errors.Wrap(err, "failed to create mapper for Cluster to GCPMachines")
361+
}
362+
// Add a watch on capiv1beta1.Cluster object for unpause & ready notifications.
363+
if err := controller.Watch(
364+
source.Kind(mgr.GetCache(), &capiv1beta1.Cluster{}),
365+
handler.EnqueueRequestsFromMapFunc(clusterToObjectFunc),
366+
predicates.ClusterUnpausedAndInfrastructureReady(ctrl.LoggerFrom(ctx)),
367+
); err != nil {
368+
return errors.Wrap(err, "failed adding a watch for ready clusters")
369+
}
370+
return nil
371+
}

main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ func setupReconcilers(ctx context.Context, mgr ctrl.Manager, serviceEndpoint []e
271271
Recorder: mgr.GetEventRecorderFor("ibmpowervsmachine-controller"),
272272
ServiceEndpoint: serviceEndpoint,
273273
Scheme: mgr.GetScheme(),
274-
}).SetupWithManager(mgr); err != nil {
274+
}).SetupWithManager(ctx, mgr); err != nil {
275275
setupLog.Error(err, "unable to create controller", "controller", "IBMPowerVSMachine")
276276
os.Exit(1)
277277
}

0 commit comments

Comments
 (0)