Skip to content

Commit b61d2ad

Browse files
justinsbcpanato
andcommitted
chore: inline v1beta1 helper utils to enable upgrade
Co-authored-by: Carlos Tadeu Panato Junior <[email protected]>
1 parent 4c6214e commit b61d2ad

File tree

8 files changed

+260
-23
lines changed

8 files changed

+260
-23
lines changed

cloud/scope/machine.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ import (
3737
"sigs.k8s.io/cluster-api-provider-gcp/cloud/providerid"
3838
"sigs.k8s.io/cluster-api-provider-gcp/cloud/services/shared"
3939
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
40-
"sigs.k8s.io/cluster-api/util"
4140
"sigs.k8s.io/cluster-api/util/patch"
4241
"sigs.k8s.io/controller-runtime/pkg/client"
4342
)
@@ -138,18 +137,24 @@ func (m *MachineScope) ControlPlaneGroupName() string {
138137

139138
// IsControlPlane returns true if the machine is a control plane.
140139
func (m *MachineScope) IsControlPlane() bool {
141-
return util.IsControlPlaneMachine(m.Machine)
140+
return IsControlPlaneMachine(m.Machine)
142141
}
143142

144143
// Role returns the machine role from the labels.
145144
func (m *MachineScope) Role() string {
146-
if util.IsControlPlaneMachine(m.Machine) {
145+
if IsControlPlaneMachine(m.Machine) {
147146
return "control-plane"
148147
}
149148

150149
return "node"
151150
}
152151

152+
// IsControlPlaneMachine checks machine is a control plane node.
153+
func IsControlPlaneMachine(machine *clusterv1.Machine) bool {
154+
_, ok := machine.Labels[clusterv1.MachineControlPlaneLabel]
155+
return ok
156+
}
157+
153158
// GetInstanceID returns the GCPMachine instance id by parsing Spec.ProviderID.
154159
func (m *MachineScope) GetInstanceID() *string {
155160
parsed, err := NewProviderID(m.GetProviderID())

controllers/gcpcluster_controller.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"sigs.k8s.io/cluster-api-provider-gcp/cloud/services/compute/loadbalancers"
3232
"sigs.k8s.io/cluster-api-provider-gcp/cloud/services/compute/networks"
3333
"sigs.k8s.io/cluster-api-provider-gcp/cloud/services/compute/subnets"
34+
"sigs.k8s.io/cluster-api-provider-gcp/pkg/capiutils"
3435
"sigs.k8s.io/cluster-api-provider-gcp/util/reconciler"
3536
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
3637
"sigs.k8s.io/cluster-api/util"
@@ -119,7 +120,7 @@ func (r *GCPClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request)
119120
}
120121

121122
// Fetch the Cluster.
122-
cluster, err := util.GetOwnerCluster(ctx, r.Client, gcpCluster.ObjectMeta)
123+
cluster, err := capiutils.GetOwnerCluster(ctx, r.Client, gcpCluster.ObjectMeta)
123124
if err != nil {
124125
log.Error(err, "Failed to get owner cluster")
125126
return ctrl.Result{}, err
@@ -129,7 +130,7 @@ func (r *GCPClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request)
129130
return ctrl.Result{}, nil
130131
}
131132

132-
if annotations.IsPaused(cluster, gcpCluster) {
133+
if capiutils.IsPaused(cluster, gcpCluster) {
133134
log.Info("GCPCluster of linked Cluster is marked as paused. Won't reconcile")
134135
return ctrl.Result{}, nil
135136
}

controllers/gcpmachine_controller.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ import (
2626
infrav1 "sigs.k8s.io/cluster-api-provider-gcp/api/v1beta1"
2727
"sigs.k8s.io/cluster-api-provider-gcp/cloud/scope"
2828
"sigs.k8s.io/cluster-api-provider-gcp/cloud/services/compute/instances"
29+
"sigs.k8s.io/cluster-api-provider-gcp/pkg/capiutils"
2930
"sigs.k8s.io/cluster-api-provider-gcp/util/reconciler"
3031
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
3132
"sigs.k8s.io/cluster-api/util"
32-
"sigs.k8s.io/cluster-api/util/annotations"
3333
"sigs.k8s.io/cluster-api/util/predicates"
3434
"sigs.k8s.io/cluster-api/util/record"
3535
ctrl "sigs.k8s.io/controller-runtime"
@@ -82,7 +82,7 @@ func (r *GCPMachineReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Ma
8282
if err := c.Watch(
8383
source.Kind[client.Object](mgr.GetCache(), &clusterv1.Cluster{},
8484
handler.EnqueueRequestsFromMapFunc(clusterToObjectFunc),
85-
predicates.ClusterPausedTransitionsOrInfrastructureReady(mgr.GetScheme(), log),
85+
capiutils.ClusterPausedTransitionsOrInfrastructureReady(mgr.GetScheme(), log),
8686
)); err != nil {
8787
return errors.Wrap(err, "failed adding a watch for ready clusters")
8888
}
@@ -145,7 +145,7 @@ func (r *GCPMachineReconciler) Reconcile(ctx context.Context, req ctrl.Request)
145145
return ctrl.Result{}, err
146146
}
147147

148-
machine, err := util.GetOwnerMachine(ctx, r.Client, gcpMachine.ObjectMeta)
148+
machine, err := capiutils.GetOwnerMachine(ctx, r.Client, gcpMachine.ObjectMeta)
149149
if err != nil {
150150
return ctrl.Result{}, err
151151
}
@@ -155,14 +155,14 @@ func (r *GCPMachineReconciler) Reconcile(ctx context.Context, req ctrl.Request)
155155
}
156156

157157
log = log.WithValues("machine", machine.Name)
158-
cluster, err := util.GetClusterFromMetadata(ctx, r.Client, machine.ObjectMeta)
158+
cluster, err := capiutils.GetClusterFromMetadata(ctx, r.Client, machine.ObjectMeta)
159159
if err != nil {
160160
log.Info("Machine is missing cluster label or cluster does not exist")
161161

162162
return ctrl.Result{}, nil
163163
}
164164

165-
if annotations.IsPaused(cluster, gcpMachine) {
165+
if capiutils.IsPaused(cluster, gcpMachine) {
166166
log.Info("GCPMachine or linked Cluster is marked as paused. Won't reconcile")
167167
return ctrl.Result{}, nil
168168
}

exp/controllers/gcpmanagedcluster_controller.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ import (
3232
"sigs.k8s.io/cluster-api-provider-gcp/cloud/services/compute/networks"
3333
"sigs.k8s.io/cluster-api-provider-gcp/cloud/services/compute/subnets"
3434
infrav1exp "sigs.k8s.io/cluster-api-provider-gcp/exp/api/v1beta1"
35+
"sigs.k8s.io/cluster-api-provider-gcp/pkg/capiutils"
3536
"sigs.k8s.io/cluster-api-provider-gcp/util/reconciler"
3637
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
3738
"sigs.k8s.io/cluster-api/util"
38-
"sigs.k8s.io/cluster-api/util/annotations"
3939
"sigs.k8s.io/cluster-api/util/predicates"
4040
"sigs.k8s.io/cluster-api/util/record"
4141
ctrl "sigs.k8s.io/controller-runtime"
@@ -81,7 +81,7 @@ func (r *GCPManagedClusterReconciler) Reconcile(ctx context.Context, req ctrl.Re
8181
}
8282

8383
// Fetch the Cluster.
84-
cluster, err := util.GetOwnerCluster(ctx, r.Client, gcpCluster.ObjectMeta)
84+
cluster, err := capiutils.GetOwnerCluster(ctx, r.Client, gcpCluster.ObjectMeta)
8585
if err != nil {
8686
log.Error(err, "Failed to get owner cluster")
8787
return ctrl.Result{}, err
@@ -91,7 +91,7 @@ func (r *GCPManagedClusterReconciler) Reconcile(ctx context.Context, req ctrl.Re
9191
return ctrl.Result{}, nil
9292
}
9393

94-
if annotations.IsPaused(cluster, gcpCluster) {
94+
if capiutils.IsPaused(cluster, gcpCluster) {
9595
log.Info("GCPManagedCluster or linked Cluster is marked as paused. Won't reconcile")
9696
return ctrl.Result{}, nil
9797
}
@@ -280,7 +280,7 @@ func (r *GCPManagedClusterReconciler) managedControlPlaneMapper() handler.MapFun
280280
return nil
281281
}
282282

283-
cluster, err := util.GetOwnerCluster(ctx, r.Client, gcpManagedControlPlane.ObjectMeta)
283+
cluster, err := capiutils.GetOwnerCluster(ctx, r.Client, gcpManagedControlPlane.ObjectMeta)
284284
if err != nil {
285285
log.Error(err, "failed to get owning cluster")
286286
return nil

exp/controllers/gcpmanagedcontrolplane_controller.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,13 @@ import (
2121
"fmt"
2222
"time"
2323

24-
"sigs.k8s.io/cluster-api/util/annotations"
25-
2624
"github.com/pkg/errors"
2725
apierrors "k8s.io/apimachinery/pkg/api/errors"
2826
"sigs.k8s.io/cluster-api-provider-gcp/cloud"
2927
"sigs.k8s.io/cluster-api-provider-gcp/cloud/scope"
3028
"sigs.k8s.io/cluster-api-provider-gcp/cloud/services/container/clusters"
3129
infrav1exp "sigs.k8s.io/cluster-api-provider-gcp/exp/api/v1beta1"
30+
"sigs.k8s.io/cluster-api-provider-gcp/pkg/capiutils"
3231
"sigs.k8s.io/cluster-api-provider-gcp/util/reconciler"
3332
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
3433
"sigs.k8s.io/cluster-api/util"
@@ -76,7 +75,7 @@ func (r *GCPManagedControlPlaneReconciler) SetupWithManager(ctx context.Context,
7675
if err = c.Watch(
7776
source.Kind[client.Object](mgr.GetCache(), &clusterv1.Cluster{},
7877
handler.EnqueueRequestsFromMapFunc(util.ClusterToInfrastructureMapFunc(ctx, gcpManagedControlPlane.GroupVersionKind(), mgr.GetClient(), &infrav1exp.GCPManagedControlPlane{})),
79-
predicates.ClusterPausedTransitionsOrInfrastructureReady(mgr.GetScheme(), log),
78+
capiutils.ClusterPausedTransitionsOrInfrastructureReady(mgr.GetScheme(), log),
8079
)); err != nil {
8180
return fmt.Errorf("failed adding a watch for ready clusters: %w", err)
8281
}
@@ -100,7 +99,7 @@ func (r *GCPManagedControlPlaneReconciler) Reconcile(ctx context.Context, req ct
10099
}
101100

102101
// Get the cluster
103-
cluster, err := util.GetOwnerCluster(ctx, r.Client, gcpManagedControlPlane.ObjectMeta)
102+
cluster, err := capiutils.GetOwnerCluster(ctx, r.Client, gcpManagedControlPlane.ObjectMeta)
104103
if err != nil {
105104
log.Error(err, "Failed to retrieve owner Cluster from the API Server")
106105
return ctrl.Result{}, err
@@ -110,7 +109,7 @@ func (r *GCPManagedControlPlaneReconciler) Reconcile(ctx context.Context, req ct
110109
return ctrl.Result{}, nil
111110
}
112111

113-
if annotations.IsPaused(cluster, gcpManagedControlPlane) {
112+
if capiutils.IsPaused(cluster, gcpManagedControlPlane) {
114113
log.Info("Reconciliation is paused for this object")
115114
return ctrl.Result{}, nil
116115
}

exp/controllers/gcpmanagedmachinepool_controller.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import (
3030
"k8s.io/apimachinery/pkg/runtime/schema"
3131
"sigs.k8s.io/cluster-api-provider-gcp/cloud"
3232
"sigs.k8s.io/cluster-api-provider-gcp/cloud/services/container/nodepools"
33-
"sigs.k8s.io/cluster-api/util/annotations"
33+
"sigs.k8s.io/cluster-api-provider-gcp/pkg/capiutils"
3434
"sigs.k8s.io/cluster-api/util/deprecated/v1beta1/conditions"
3535
"sigs.k8s.io/cluster-api/util/record"
3636
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
@@ -180,7 +180,7 @@ func (r *GCPManagedMachinePoolReconciler) SetupWithManager(ctx context.Context,
180180
if err := c.Watch(
181181
source.Kind[client.Object](mgr.GetCache(), &clusterv1.Cluster{},
182182
handler.EnqueueRequestsFromMapFunc(clusterToObjectFunc),
183-
predicates.ClusterPausedTransitionsOrInfrastructureReady(mgr.GetScheme(), log),
183+
capiutils.ClusterPausedTransitionsOrInfrastructureReady(mgr.GetScheme(), log),
184184
)); err != nil {
185185
return errors.Wrap(err, "failed adding a watch for ready clusters")
186186
}
@@ -251,12 +251,12 @@ func (r *GCPManagedMachinePoolReconciler) Reconcile(ctx context.Context, req ctr
251251
}
252252

253253
// Get the cluster
254-
cluster, err := util.GetClusterFromMetadata(ctx, r.Client, machinePool.ObjectMeta)
254+
cluster, err := capiutils.GetClusterFromMetadata(ctx, r.Client, machinePool.ObjectMeta)
255255
if err != nil {
256256
log.Info("Failed to retrieve Cluster from MachinePool")
257257
return ctrl.Result{}, err
258258
}
259-
if annotations.IsPaused(cluster, gcpManagedMachinePool) {
259+
if capiutils.IsPaused(cluster, gcpManagedMachinePool) {
260260
log.Info("Reconciliation is paused for this object")
261261
return ctrl.Result{}, nil
262262
}

pkg/capiutils/predicates.go

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package capiutils contains utility functions for working with Cluster API resources.
18+
// These have mostly been inlined as part of the CAPI 1.10 -> 1.11 upgrade,
19+
// and should be removed when we switch to reading CAPI v1beta2 objects.
20+
//
21+
// Deprecated: This package is deprecated and is going to be removed when support for v1beta1 will be dropped.
22+
package capiutils
23+
24+
import (
25+
"fmt"
26+
27+
"github.com/go-logr/logr"
28+
"k8s.io/apimachinery/pkg/runtime"
29+
"k8s.io/klog/v2"
30+
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
31+
"sigs.k8s.io/controller-runtime/pkg/event"
32+
"sigs.k8s.io/controller-runtime/pkg/predicate"
33+
34+
"sigs.k8s.io/cluster-api/util/predicates"
35+
36+
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
37+
)
38+
39+
// ClusterUpdateInfraReady returns a predicate that returns true for an update event when a cluster has Status.InfrastructureReady changed from false to true
40+
// it also returns true if the resource provided is not a Cluster to allow for use with controller-runtime NewControllerManagedBy.
41+
func ClusterUpdateInfraReady(scheme *runtime.Scheme, logger logr.Logger) predicate.Funcs {
42+
return predicate.Funcs{
43+
UpdateFunc: func(e event.UpdateEvent) bool {
44+
log := logger.WithValues("predicate", "ClusterUpdateInfraReady", "eventType", "update")
45+
if gvk, err := apiutil.GVKForObject(e.ObjectOld, scheme); err == nil {
46+
log = log.WithValues(gvk.Kind, klog.KObj(e.ObjectOld))
47+
}
48+
49+
oldCluster, ok := e.ObjectOld.(*clusterv1.Cluster)
50+
if !ok {
51+
log.V(4).Info("Expected Cluster", "type", fmt.Sprintf("%T", e.ObjectOld))
52+
return false
53+
}
54+
55+
newCluster := e.ObjectNew.(*clusterv1.Cluster)
56+
57+
if !oldCluster.Status.InfrastructureReady && newCluster.Status.InfrastructureReady {
58+
log.V(6).Info("Cluster infrastructure became ready, allowing further processing")
59+
return true
60+
}
61+
62+
log.V(4).Info("Cluster infrastructure did not become ready, blocking further processing")
63+
return false
64+
},
65+
CreateFunc: func(event.CreateEvent) bool { return false },
66+
DeleteFunc: func(event.DeleteEvent) bool { return false },
67+
GenericFunc: func(event.GenericEvent) bool { return false },
68+
}
69+
}
70+
71+
// ClusterPausedTransitions returns a predicate that returns true for an update event when a cluster has Spec.Paused changed.
72+
func ClusterPausedTransitions(scheme *runtime.Scheme, logger logr.Logger) predicate.Funcs {
73+
return predicate.Funcs{
74+
UpdateFunc: func(e event.UpdateEvent) bool {
75+
log := logger.WithValues("predicate", "ClusterPausedTransitions", "eventType", "update")
76+
if gvk, err := apiutil.GVKForObject(e.ObjectOld, scheme); err == nil {
77+
log = log.WithValues(gvk.Kind, klog.KObj(e.ObjectOld))
78+
}
79+
80+
oldCluster, ok := e.ObjectOld.(*clusterv1.Cluster)
81+
if !ok {
82+
log.V(4).Info("Expected Cluster", "type", fmt.Sprintf("%T", e.ObjectOld))
83+
return false
84+
}
85+
86+
newCluster := e.ObjectNew.(*clusterv1.Cluster)
87+
88+
if oldCluster.Spec.Paused && !newCluster.Spec.Paused {
89+
log.V(6).Info("Cluster unpausing, allowing further processing")
90+
return true
91+
}
92+
93+
if !oldCluster.Spec.Paused && newCluster.Spec.Paused {
94+
log.V(6).Info("Cluster pausing, allowing further processing")
95+
return true
96+
}
97+
98+
// This predicate always work in "or" with Paused predicates
99+
// so the logs are adjusted to not provide false negatives/verbosity at V<=5.
100+
log.V(6).Info("Cluster paused state was not changed, blocking further processing")
101+
return false
102+
},
103+
CreateFunc: func(event.CreateEvent) bool { return false },
104+
DeleteFunc: func(event.DeleteEvent) bool { return false },
105+
GenericFunc: func(event.GenericEvent) bool { return false },
106+
}
107+
}
108+
109+
// ClusterPausedTransitionsOrInfrastructureReady returns a Predicate that returns true on Cluster Update events where
110+
// either Cluster.Spec.Paused transitions or Cluster.Status.InfrastructureReady transitions to true.
111+
// This implements a common requirement for some cluster-api and provider controllers (such as Machine Infrastructure
112+
// controllers) to resume reconciliation when the Cluster gets paused or unpaused and when the infrastructure becomes ready.
113+
// Example use:
114+
//
115+
// err := controller.Watch(
116+
// source.Kind(cache, &clusterv1.Cluster{}),
117+
// handler.EnqueueRequestsFromMapFunc(clusterToMachines)
118+
// predicates.ClusterPausedTransitionsOrInfrastructureReady(mgr.GetScheme(), r.Log),
119+
// )
120+
func ClusterPausedTransitionsOrInfrastructureReady(scheme *runtime.Scheme, logger logr.Logger) predicate.Funcs {
121+
log := logger.WithValues("predicate", "ClusterPausedTransitionsOrInfrastructureReady")
122+
123+
return predicates.Any(scheme, log, ClusterPausedTransitions(scheme, log), ClusterUpdateInfraReady(scheme, log))
124+
}

0 commit comments

Comments
 (0)