Skip to content

Commit 51d7ea1

Browse files
committed
Add support for pausing cluster reconcilation
1 parent b4e0e2a commit 51d7ea1

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/ibmvpcmachine_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/vpc-go-sdk/vpcv1"
2728

@@ -33,9 +34,12 @@ import (
3334
ctrl "sigs.k8s.io/controller-runtime"
3435
"sigs.k8s.io/controller-runtime/pkg/client"
3536
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
37+
"sigs.k8s.io/controller-runtime/pkg/handler"
38+
"sigs.k8s.io/controller-runtime/pkg/source"
3639

3740
capiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
3841
"sigs.k8s.io/cluster-api/util"
42+
"sigs.k8s.io/cluster-api/util/predicates"
3943

4044
infrav1beta2 "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta2"
4145
"sigs.k8s.io/cluster-api-provider-ibmcloud/cloud/scope"
@@ -132,13 +136,6 @@ func (r *IBMVPCMachineReconciler) Reconcile(ctx context.Context, req ctrl.Reques
132136
return r.reconcileNormal(machineScope)
133137
}
134138

135-
// SetupWithManager creates a new IBMVPCMachine controller for a manager.
136-
func (r *IBMVPCMachineReconciler) SetupWithManager(mgr ctrl.Manager) error {
137-
return ctrl.NewControllerManagedBy(mgr).
138-
For(&infrav1beta2.IBMVPCMachine{}).
139-
Complete(r)
140-
}
141-
142139
func (r *IBMVPCMachineReconciler) reconcileNormal(machineScope *scope.MachineScope) (ctrl.Result, error) {
143140
if controllerutil.AddFinalizer(machineScope.IBMVPCMachine, infrav1beta2.MachineFinalizer) {
144141
return ctrl.Result{}, nil
@@ -221,3 +218,76 @@ func (r *IBMVPCMachineReconciler) reconcileDelete(scope *scope.MachineScope) (_
221218

222219
return ctrl.Result{}, nil
223220
}
221+
222+
// IBMPowerVSClusterToIBMPowerVSMachines is a handler.ToRequestsFunc to be used to enqeue requests for reconciliation
223+
// of IBMPowerVSMachines.
224+
func (r *IBMVPCMachineReconciler) IBMPowerVSClusterToIBMPowerVSMachines(ctx context.Context) handler.MapFunc {
225+
log := ctrl.LoggerFrom(ctx)
226+
return func(mapCtx context.Context, o client.Object) []ctrl.Request {
227+
result := []ctrl.Request{}
228+
229+
c, ok := o.(*infrav1beta2.IBMPowerVSCluster)
230+
if !ok {
231+
log.Error(errors.Errorf("expected a IBMPowerVSCluster but got a %T", o), "failed to get IBMPowerVSMachines for IBMPowerVSCluster")
232+
return nil
233+
}
234+
235+
cluster, err := util.GetOwnerCluster(mapCtx, r.Client, c.ObjectMeta)
236+
switch {
237+
case apierrors.IsNotFound(err) || cluster == nil:
238+
return result
239+
case err != nil:
240+
log.Error(err, "failed to get owning cluster")
241+
return result
242+
}
243+
244+
labels := map[string]string{capiv1beta1.ClusterNameLabel: cluster.Name}
245+
machineList := &capiv1beta1.MachineList{}
246+
if err := r.List(mapCtx, machineList, client.InNamespace(c.Namespace), client.MatchingLabels(labels)); err != nil {
247+
log.Error(err, "failed to list Machines")
248+
return nil
249+
}
250+
for _, m := range machineList.Items {
251+
if m.Spec.InfrastructureRef.Name == "" {
252+
continue
253+
}
254+
name := client.ObjectKey{Namespace: m.Namespace, Name: m.Spec.InfrastructureRef.Name}
255+
result = append(result, ctrl.Request{NamespacedName: name})
256+
}
257+
258+
return result
259+
}
260+
}
261+
262+
// SetupWithManager creates a new IBMVPCMachine controller for a manager.
263+
func (r *IBMVPCMachineReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager) error {
264+
controller, err := ctrl.NewControllerManagedBy(mgr).
265+
For(&infrav1beta2.IBMVPCMachine{}).
266+
WithEventFilter(predicates.ResourceNotPaused(ctrl.LoggerFrom(ctx))).
267+
Watches(
268+
&capiv1beta1.Machine{},
269+
handler.EnqueueRequestsFromMapFunc(util.MachineToInfrastructureMapFunc(infrav1beta2.GroupVersion.WithKind("IBMPowerVSMachine"))),
270+
).
271+
Watches(
272+
&infrav1beta2.IBMPowerVSCluster{},
273+
handler.EnqueueRequestsFromMapFunc(r.IBMPowerVSClusterToIBMPowerVSMachines(ctx)),
274+
).
275+
Build(r)
276+
if err != nil {
277+
return errors.Wrap(err, "error creating controller")
278+
}
279+
280+
clusterToObjectFunc, err := util.ClusterToTypedObjectsMapper(r.Client, &infrav1beta2.IBMPowerVSMachineList{}, mgr.GetScheme())
281+
if err != nil {
282+
return errors.Wrap(err, "failed to create mapper for Cluster to GCPMachines")
283+
}
284+
// Add a watch on capiv1beta1.Cluster object for unpause & ready notifications.
285+
if err := controller.Watch(
286+
source.Kind(mgr.GetCache(), &capiv1beta1.Cluster{}),
287+
handler.EnqueueRequestsFromMapFunc(clusterToObjectFunc),
288+
predicates.ClusterUnpausedAndInfrastructureReady(ctrl.LoggerFrom(ctx)),
289+
); err != nil {
290+
return errors.Wrap(err, "failed adding a watch for ready clusters")
291+
}
292+
return nil
293+
}

main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ func setupReconcilers(ctx context.Context, mgr ctrl.Manager, serviceEndpoint []e
251251
Recorder: mgr.GetEventRecorderFor("ibmvpcmachine-controller"),
252252
ServiceEndpoint: serviceEndpoint,
253253
Scheme: mgr.GetScheme(),
254-
}).SetupWithManager(mgr); err != nil {
254+
}).SetupWithManager(ctx, mgr); err != nil {
255255
setupLog.Error(err, "unable to create controller", "controller", "IBMVPCMachine")
256256
os.Exit(1)
257257
}

0 commit comments

Comments
 (0)