@@ -17,6 +17,7 @@ import (
17
17
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
18
18
"k8s.io/apimachinery/pkg/runtime"
19
19
"k8s.io/apimachinery/pkg/types"
20
+ "k8s.io/apimachinery/pkg/util/wait"
20
21
"k8s.io/client-go/tools/record"
21
22
ctrl "sigs.k8s.io/controller-runtime"
22
23
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -30,6 +31,7 @@ import (
30
31
"github.com/nais/unleasherator/pkg/federation"
31
32
"github.com/nais/unleasherator/pkg/resources"
32
33
"github.com/nais/unleasherator/pkg/unleashclient"
34
+ "github.com/nais/unleasherator/pkg/utils"
33
35
)
34
36
35
37
const (
@@ -40,6 +42,9 @@ const (
40
42
)
41
43
42
44
var (
45
+ deploymentTimeout = 5 * time .Minute
46
+ requeueAfter = 1 * time .Hour
47
+
43
48
// unleashStatus is a Prometheus metric which will be used to expose the status of the Unleash instances
44
49
unleashStatus = prometheus .NewGaugeVec (
45
50
prometheus.GaugeOpts {
@@ -205,38 +210,38 @@ func (r *UnleashReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
205
210
206
211
res , err = r .reconcileSecrets (ctx , unleash )
207
212
if err != nil {
208
- if err := r .updateStatusReconcileFailed (ctx , unleash , err , "Failed to reconcile Secrets" ); err != nil {
209
- return ctrl.Result {}, err
213
+ if statsusErr := r .updateStatusReconcileFailed (ctx , unleash , err , "Failed to reconcile Secrets" ); statsusErr != nil {
214
+ return ctrl.Result {}, statsusErr
210
215
}
211
216
return ctrl.Result {}, err
212
217
} else if res .Requeue {
213
218
return res , nil
214
219
}
215
220
216
- res , err = r .reconcileDeployment (ctx , unleash )
221
+ res , err = r .reconcileNetworkPolicy (ctx , unleash )
217
222
if err != nil {
218
- if err := r .updateStatusReconcileFailed (ctx , unleash , err , "Failed to reconcile Deployment " ); err != nil {
219
- return ctrl.Result {}, err
223
+ if statsusErr := r .updateStatusReconcileFailed (ctx , unleash , err , "Failed to reconcile NetworkPolicy " ); statsusErr != nil {
224
+ return ctrl.Result {}, statsusErr
220
225
}
221
226
return ctrl.Result {}, err
222
227
} else if res .Requeue {
223
228
return res , nil
224
229
}
225
230
226
- res , err = r .reconcileService (ctx , unleash )
231
+ res , err = r .reconcileDeployment (ctx , unleash )
227
232
if err != nil {
228
- if err := r .updateStatusReconcileFailed (ctx , unleash , err , "Failed to reconcile Service " ); err != nil {
229
- return ctrl.Result {}, err
233
+ if statsusErr := r .updateStatusReconcileFailed (ctx , unleash , err , "Failed to reconcile Deployment " ); statsusErr != nil {
234
+ return ctrl.Result {}, statsusErr
230
235
}
231
236
return ctrl.Result {}, err
232
237
} else if res .Requeue {
233
238
return res , nil
234
239
}
235
240
236
- res , err = r .reconcileNetworkPolicy (ctx , unleash )
241
+ res , err = r .reconcileService (ctx , unleash )
237
242
if err != nil {
238
- if err := r .updateStatusReconcileFailed (ctx , unleash , err , "Failed to reconcile NetworkPolicy " ); err != nil {
239
- return ctrl.Result {}, err
243
+ if statsusErr := r .updateStatusReconcileFailed (ctx , unleash , err , "Failed to reconcile Service " ); statsusErr != nil {
244
+ return ctrl.Result {}, statsusErr
240
245
}
241
246
return ctrl.Result {}, err
242
247
} else if res .Requeue {
@@ -245,8 +250,8 @@ func (r *UnleashReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
245
250
246
251
res , err = r .reconcileIngresses (ctx , unleash )
247
252
if err != nil {
248
- if err := r .updateStatusReconcileFailed (ctx , unleash , err , "Failed to reconcile Ingresses" ); err != nil {
249
- return ctrl.Result {}, err
253
+ if statsusErr := r .updateStatusReconcileFailed (ctx , unleash , err , "Failed to reconcile Ingresses" ); statsusErr != nil {
254
+ return ctrl.Result {}, statsusErr
250
255
}
251
256
return ctrl.Result {}, err
252
257
} else if res .Requeue {
@@ -255,8 +260,8 @@ func (r *UnleashReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
255
260
256
261
res , err = r .reconcileServiceMonitor (ctx , unleash )
257
262
if err != nil {
258
- if err := r .updateStatusReconcileFailed (ctx , unleash , err , "Failed to reconcile ServiceMonitor" ); err != nil {
259
- return ctrl.Result {}, err
263
+ if statsusErr := r .updateStatusReconcileFailed (ctx , unleash , err , "Failed to reconcile ServiceMonitor" ); statsusErr != nil {
264
+ return ctrl.Result {}, statsusErr
260
265
}
261
266
return ctrl.Result {}, err
262
267
} else if res .Requeue {
@@ -270,6 +275,19 @@ func (r *UnleashReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
270
275
return ctrl.Result {}, err
271
276
}
272
277
278
+ // Wait for Deployment rollout to finish before testing connection This is to
279
+ // avoid testing connection to the previous instance if the Deployment is not
280
+ // ready yet. Delay requeue to avoid tying up the reconciler since waiting is
281
+ // done in the same reconcile loop.
282
+ log .Info ("Waiting for Deployment rollout to finish" )
283
+ err = r .waitForDeployment (ctx , deploymentTimeout , req .NamespacedName )
284
+ if err != nil {
285
+ if statusErr := r .updateStatusReconcileFailed (ctx , unleash , err , "Deployment rollout timed out" ); statusErr != nil {
286
+ return ctrl.Result {RequeueAfter : deploymentTimeout }, statusErr
287
+ }
288
+ return ctrl.Result {RequeueAfter : deploymentTimeout }, err
289
+ }
290
+
273
291
// Set the reconcile status of the Unleash instance to available
274
292
log .Info ("Successfully reconciled Unleash resources" )
275
293
if err = r .updateStatusReconcileSuccess (ctx , unleash ); err != nil {
@@ -279,28 +297,27 @@ func (r *UnleashReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
279
297
// Test connection to Unleash instance
280
298
stats , err := r .testConnection (unleash , ctx , log )
281
299
if err != nil {
282
- if err := r .updateStatusConnectionFailed (ctx , unleash , err , "Failed to connect to Unleash instance" ); err != nil {
283
- return ctrl.Result {}, err
300
+ if statusErr := r .updateStatusConnectionFailed (ctx , unleash , err , "Failed to connect to Unleash instance" ); statusErr != nil {
301
+ return ctrl.Result {}, statusErr
284
302
}
285
303
286
304
return ctrl.Result {}, err
287
305
}
288
306
289
307
// Set the connection status of the Unleash instance to available
290
308
log .Info ("Successfully connected to Unleash instance" , "version" , stats .VersionOSS )
291
- err = r .updateStatusConnectionSuccess (ctx , unleash , stats )
292
- if err != nil {
293
- return ctrl.Result {}, err
309
+ statusErr : = r .updateStatusConnectionSuccess (ctx , unleash , stats )
310
+ if statusErr != nil {
311
+ return ctrl.Result {}, statusErr
294
312
}
295
313
296
314
// Publish the Unleash instance to federation if enabled
297
- err = r .publish (ctx , unleash )
298
- if err != nil {
315
+ if err = r .publish (ctx , unleash ); err != nil {
299
316
return ctrl.Result {}, err
300
317
}
301
318
302
319
log .Info ("Reconciliation of Unleash finished" )
303
- return ctrl.Result {RequeueAfter : 1 * time . Hour }, nil
320
+ return ctrl.Result {RequeueAfter : requeueAfter }, nil
304
321
}
305
322
306
323
// publish the Unleash instance to pubsub if federation is enabled.
@@ -530,8 +547,6 @@ func (r *UnleashReconciler) reconcileIngress(ctx context.Context, unleash *unlea
530
547
return ctrl.Result {}, nil
531
548
}
532
549
533
- // update prometheus metrics
534
-
535
550
return ctrl.Result {}, nil
536
551
}
537
552
@@ -677,6 +692,23 @@ func (r *UnleashReconciler) reconcileService(ctx context.Context, unleash *unlea
677
692
return ctrl.Result {}, nil
678
693
}
679
694
695
+ // waitForDeployment will wait for the deployment to be available
696
+ func (r * UnleashReconciler ) waitForDeployment (ctx context.Context , timeout time.Duration , key types.NamespacedName ) error {
697
+ ctx , cancel := context .WithTimeout (ctx , timeout )
698
+ defer cancel ()
699
+
700
+ err := wait .PollUntilContextCancel (ctx , time .Second , true , func (ctx context.Context ) (bool , error ) {
701
+ deployment := & appsv1.Deployment {}
702
+ if err := r .Client .Get (ctx , key , deployment ); err != nil {
703
+ return false , err
704
+ }
705
+
706
+ return utils .DeploymentIsReady (deployment ), nil
707
+ })
708
+
709
+ return err
710
+ }
711
+
680
712
// testConnection will test the connection to the Unleash instance
681
713
func (r * UnleashReconciler ) testConnection (unleash resources.UnleashInstance , ctx context.Context , log logr.Logger ) (* unleashclient.InstanceAdminStatsResult , error ) {
682
714
client , err := unleash .ApiClient (ctx , r .Client , r .OperatorNamespace )
0 commit comments