@@ -20,6 +20,7 @@ import (
20
20
"context"
21
21
"encoding/base64"
22
22
"fmt"
23
+ "reflect"
23
24
"time"
24
25
25
26
"github.com/go-logr/logr"
@@ -28,6 +29,7 @@ import (
28
29
"github.com/pkg/errors"
29
30
corev1 "k8s.io/api/core/v1"
30
31
apierrors "k8s.io/apimachinery/pkg/api/errors"
32
+ "k8s.io/apimachinery/pkg/runtime"
31
33
"k8s.io/apimachinery/pkg/types"
32
34
"k8s.io/client-go/tools/record"
33
35
"k8s.io/utils/pointer"
@@ -51,6 +53,8 @@ import (
51
53
)
52
54
53
55
const (
56
+ InstanceIDIndex = ".spec.instanceID"
57
+
54
58
waitForClusterInfrastructureReadyDuration = 15 * time .Second
55
59
)
56
60
@@ -121,7 +125,7 @@ func (r *OpenStackMachineReconciler) Reconcile(req ctrl.Request) (_ ctrl.Result,
121
125
return ctrl.Result {}, err
122
126
}
123
127
124
- // Always patch the openStackMachine when exiting this function so we can persist any AWSMachine changes.
128
+ // Always patch the openStackMachine when exiting this function so we can persist any OpenStackMachine changes.
125
129
defer func () {
126
130
if err := patchHelper .Patch (ctx , openStackMachine ); err != nil {
127
131
if reterr == nil {
@@ -154,12 +158,41 @@ func (r *OpenStackMachineReconciler) SetupWithManager(mgr ctrl.Manager, options
154
158
& handler.EnqueueRequestsFromMapFunc {ToRequests : handler .ToRequestsFunc (r .OpenStackClusterToOpenStackMachines )},
155
159
).
156
160
WithEventFilter (pausedPredicates (r .Log )).
161
+ WithEventFilter (
162
+ predicate.Funcs {
163
+ // Avoid reconciling if the event triggering the reconciliation is related to incremental status updates
164
+ // for OpenStackMachine resources only
165
+ UpdateFunc : func (e event.UpdateEvent ) bool {
166
+ if e .ObjectOld .GetObjectKind ().GroupVersionKind ().Kind != "OpenStackMachine" {
167
+ return true
168
+ }
169
+
170
+ oldMachine := e .ObjectOld .(* infrav1.OpenStackMachine ).DeepCopy ()
171
+ newMachine := e .ObjectNew .(* infrav1.OpenStackMachine ).DeepCopy ()
172
+
173
+ oldMachine .Status = infrav1.OpenStackMachineStatus {}
174
+ newMachine .Status = infrav1.OpenStackMachineStatus {}
175
+
176
+ oldMachine .ObjectMeta .ResourceVersion = ""
177
+ newMachine .ObjectMeta .ResourceVersion = ""
178
+
179
+ return ! reflect .DeepEqual (oldMachine , newMachine )
180
+ },
181
+ },
182
+ ).
157
183
Build (r )
158
-
159
184
if err != nil {
160
185
return err
161
186
}
162
187
188
+ // Add index to OpenStackMachine to find by providerID
189
+ if err := mgr .GetFieldIndexer ().IndexField (& infrav1.OpenStackMachine {},
190
+ InstanceIDIndex ,
191
+ r .indexOpenStackMachineByInstanceID ,
192
+ ); err != nil {
193
+ return errors .Wrap (err , "error setting index fields" )
194
+ }
195
+
163
196
return controller .Watch (
164
197
& source.Kind {Type : & clusterv1.Cluster {}},
165
198
& handler.EnqueueRequestsFromMapFunc {
@@ -169,13 +202,48 @@ func (r *OpenStackMachineReconciler) SetupWithManager(mgr ctrl.Manager, options
169
202
UpdateFunc : func (e event.UpdateEvent ) bool {
170
203
oldCluster := e .ObjectOld .(* clusterv1.Cluster )
171
204
newCluster := e .ObjectNew .(* clusterv1.Cluster )
172
- return oldCluster .Spec .Paused && ! newCluster .Spec .Paused
205
+ log := r .Log .WithValues ("predicate" , "updateEvent" , "namespace" , newCluster .Namespace , "cluster" , newCluster .Name )
206
+
207
+ switch {
208
+ // never return true for a paused Cluster
209
+ case newCluster .Spec .Paused :
210
+ log .V (4 ).Info ("Cluster is paused, will not attempt to map associated OpenStackMachine." )
211
+ return false
212
+ // return true if Cluster.Status.InfrastructureReady has changed from false to true
213
+ case ! oldCluster .Status .InfrastructureReady && newCluster .Status .InfrastructureReady :
214
+ log .V (4 ).Info ("Cluster InfrastructureReady became ready, will attempt to map associated OpenStackMachine." )
215
+ return true
216
+ // return true if Cluster.Spec.Paused has changed from true to false
217
+ case oldCluster .Spec .Paused && ! newCluster .Spec .Paused :
218
+ log .V (4 ).Info ("Cluster was unpaused, will attempt to map associated OpenStackMachine." )
219
+ return true
220
+ // otherwise, return false
221
+ default :
222
+ log .V (4 ).Info ("Cluster did not match expected conditions, will not attempt to map associated OpenStackMachine." )
223
+ return false
224
+ }
173
225
},
174
226
CreateFunc : func (e event.CreateEvent ) bool {
175
227
cluster := e .Object .(* clusterv1.Cluster )
176
- return ! cluster .Spec .Paused
228
+ log := r .Log .WithValues ("predicateEvent" , "create" , "namespace" , cluster .Namespace , "cluster" , cluster .Name )
229
+
230
+ // Only need to trigger a reconcile if the Cluster.Spec.Paused is false and
231
+ // Cluster.Status.InfrastructureReady is true
232
+ if ! cluster .Spec .Paused && cluster .Status .InfrastructureReady {
233
+ log .V (4 ).Info ("Cluster is not paused and has infrastructure ready, will attempt to map associated OpenStackMachine." )
234
+ return true
235
+ }
236
+ log .V (4 ).Info ("Cluster did not match expected conditions, will not attempt to map associated OpenStackMachine." )
237
+ return false
177
238
},
178
239
DeleteFunc : func (e event.DeleteEvent ) bool {
240
+ log := r .Log .WithValues ("predicateEvent" , "delete" , "namespace" , e .Meta .GetNamespace (), "cluster" , e .Meta .GetName ())
241
+ log .V (4 ).Info ("Cluster did not match expected conditions, will not attempt to map associated OpenStackMachine." )
242
+ return false
243
+ },
244
+ GenericFunc : func (e event.GenericEvent ) bool {
245
+ log := r .Log .WithValues ("predicateEvent" , "generic" , "namespace" , e .Meta .GetNamespace (), "cluster" , e .Meta .GetName ())
246
+ log .V (4 ).Info ("Cluster did not match expected conditions, will not attempt to map associated OpenStackMachine." )
179
247
return false
180
248
},
181
249
},
@@ -316,6 +384,7 @@ func (r *OpenStackMachineReconciler) reconcileNormal(ctx context.Context, logger
316
384
// TODO(sbueringer) From CAPA: TODO(ncdc): move this validation logic into a validating webhook (for us: create validation logic in webhook)
317
385
318
386
openStackMachine .Spec .ProviderID = pointer .StringPtr (fmt .Sprintf ("openstack:///%s" , instance .ID ))
387
+ openStackMachine .Spec .InstanceID = pointer .StringPtr (instance .ID )
319
388
320
389
openStackMachine .Status .InstanceState = & instance .State
321
390
@@ -493,3 +562,17 @@ func (r *OpenStackMachineReconciler) requestsForCluster(namespace, name string)
493
562
}
494
563
return result
495
564
}
565
+
566
+ func (r * OpenStackMachineReconciler ) indexOpenStackMachineByInstanceID (o runtime.Object ) []string {
567
+ openstackMachine , ok := o .(* infrav1.OpenStackMachine )
568
+ if ! ok {
569
+ r .Log .Error (errors .New ("incorrect type" ), "expected an OpenStackMachine" , "type" , fmt .Sprintf ("%T" , o ))
570
+ return nil
571
+ }
572
+
573
+ if openstackMachine .Spec .InstanceID != nil {
574
+ return []string {* openstackMachine .Spec .InstanceID }
575
+ }
576
+
577
+ return nil
578
+ }
0 commit comments