@@ -32,6 +32,7 @@ import (
3232 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
3333 kutil "sigs.k8s.io/cluster-api/util"
3434 conditions "sigs.k8s.io/cluster-api/util/conditions/v1beta2"
35+ "sigs.k8s.io/cluster-api/util/paused"
3536 "sigs.k8s.io/cluster-api/util/predicates"
3637 ctrl "sigs.k8s.io/controller-runtime"
3738 "sigs.k8s.io/controller-runtime/pkg/builder"
@@ -116,14 +117,59 @@ func (r *LinodeClusterReconciler) Reconcile(ctx context.Context, req ctrl.Reques
116117 return r .reconcile (ctx , clusterScope , logger )
117118}
118119
120+ func (r * LinodeClusterReconciler ) reconcilePause (ctx context.Context , clusterScope * scope.ClusterScope , logger logr.Logger ) error {
121+ // First thing to do is handle a paused Cluster. Paused clusters shouldn't be deleted.
122+ isPaused , conditionChanged , err := paused .EnsurePausedCondition (ctx , clusterScope .Client , clusterScope .Cluster , clusterScope .LinodeCluster )
123+ if err == nil && ! isPaused && ! conditionChanged {
124+ return nil
125+ }
126+
127+ if err != nil {
128+ return err
129+ }
130+
131+ if clusterScope .LinodeCluster .Spec .VPCRef == nil {
132+ logger .Info ("Paused reconciliation is skipped due to missing VPC ref" )
133+ return nil
134+ }
135+
136+ linodeVPC := infrav1alpha2.LinodeVPC {
137+ ObjectMeta : metav1.ObjectMeta {
138+ Namespace : clusterScope .LinodeCluster .Spec .VPCRef .Namespace ,
139+ Name : clusterScope .LinodeCluster .Spec .VPCRef .Name ,
140+ },
141+ }
142+
143+ if err := clusterScope .Client .Get (ctx , client .ObjectKeyFromObject (& linodeVPC ), & linodeVPC ); err != nil {
144+ return err
145+ }
146+
147+ annotations := linodeVPC .ObjectMeta .GetAnnotations ()
148+ if annotations == nil {
149+ annotations = map [string ]string {}
150+ }
151+
152+ if isPaused {
153+ logger .Info ("CAPI cluster is paused, pausing VPC" )
154+ // if we're paused, we should slap the pause annotation on our children
155+ // get the vpc & add the annotation
156+ annotations [clusterv1 .PausedAnnotation ] = "true"
157+ } else {
158+ // we are not paused here, but were previously paused (we can get here only if conditionChanged is true.
159+ logger .Info ("CAPI cluster is no longer paused, removing pause annotation from VPC" )
160+ delete (annotations , clusterv1 .PausedAnnotation )
161+ }
162+ linodeVPC .SetAnnotations (annotations )
163+ return clusterScope .PatchHelper .Patch (ctx , & linodeVPC )
164+ }
165+
119166//nolint:cyclop // can't make it simpler with existing API
120167func (r * LinodeClusterReconciler ) reconcile (
121168 ctx context.Context ,
122169 clusterScope * scope.ClusterScope ,
123170 logger logr.Logger ,
124171) (res ctrl.Result , reterr error ) {
125172 res = ctrl.Result {}
126-
127173 clusterScope .LinodeCluster .Status .Ready = false
128174 clusterScope .LinodeCluster .Status .FailureReason = nil
129175 clusterScope .LinodeCluster .Status .FailureMessage = util .Pointer ("" )
@@ -150,6 +196,10 @@ func (r *LinodeClusterReconciler) reconcile(
150196 return res , err
151197 }
152198
199+ if err := r .reconcilePause (ctx , clusterScope , logger ); err != nil {
200+ return res , err
201+ }
202+
153203 // Handle deleted clusters
154204 if ! clusterScope .LinodeCluster .DeletionTimestamp .IsZero () {
155205 if err := r .reconcileDelete (ctx , logger , clusterScope ); err != nil {
0 commit comments