@@ -126,6 +126,12 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
126126 }
127127 }
128128
129+ account , api , err := InitCloudflareApi (ctx , r .Client , gatewayClass .Name )
130+ if err != nil {
131+ log .Error (err , "Failed to load Cloudflare API" )
132+ return ctrl.Result {}, err
133+ }
134+
129135 // Let's just set the status as Unknown when no status is available
130136 if len (gateway .Status .Conditions ) == 0 {
131137 meta .SetStatusCondition (& gateway .Status .Conditions , metav1.Condition {Type : typeAvailableGateway , Status : metav1 .ConditionUnknown , Reason : "Reconciling" , Message : "Starting reconciliation" })
@@ -162,12 +168,6 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
162168 }
163169 }
164170
165- account , api , err := InitCloudflareApi (ctx , r .Client , gatewayClass .Name )
166- if err != nil {
167- log .Error (err , "Failed to load Cloudflare API" )
168- return ctrl.Result {}, err
169- }
170-
171171 // Check if the Gateway instance is marked to be deleted, which is
172172 // indicated by the deletion timestamp being set.
173173 isGatewayMarkedToBeDeleted := gateway .GetDeletionTimestamp () != nil
@@ -176,7 +176,7 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
176176 log .Info ("Performing Finalizer Operations for Gateway before delete CR" )
177177
178178 // Let's add here a status "Downgrade" to reflect that this resource began its process to be terminated.
179- meta .SetStatusCondition (& gateway .Status .Conditions , metav1.Condition {Type : typeDegradedGateway ,
179+ meta .SetStatusCondition (& gateway .Status .Conditions , metav1.Condition {Type : string ( gatewayv1 . GatewayConditionAccepted ) ,
180180 Status : metav1 .ConditionUnknown , Reason : string (gatewayv1 .GatewayReasonPending ), ObservedGeneration : gateway .Generation ,
181181 Message : fmt .Sprintf ("Performing finalizer operations for the custom resource: %s " , gateway .Name )})
182182
@@ -201,7 +201,7 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
201201 return ctrl.Result {}, err
202202 }
203203
204- meta .SetStatusCondition (& gateway .Status .Conditions , metav1.Condition {Type : typeDegradedGateway ,
204+ meta .SetStatusCondition (& gateway .Status .Conditions , metav1.Condition {Type : string ( gatewayv1 . GatewayConditionAccepted ) ,
205205 Status : metav1 .ConditionTrue , Reason : "Finalizing" , ObservedGeneration : gateway .Generation ,
206206 Message : fmt .Sprintf ("Finalizer operations for custom resource %s name were successfully accomplished" , gateway .Name )})
207207
@@ -439,11 +439,6 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
439439 return ctrl.Result {}, err
440440 }
441441
442- if err := r .Get (ctx , req .NamespacedName , gateway ); err != nil {
443- log .Error (err , "Failed to re-fetch gateway" )
444- return ctrl.Result {}, err
445- }
446-
447442 // The following implementation will update the status
448443 meta .SetStatusCondition (& gateway .Status .Conditions , metav1.Condition {Type : string (gatewayv1 .GatewayConditionProgrammed ),
449444 Status : metav1 .ConditionTrue , Reason : string (gatewayv1 .GatewayReasonProgrammed ), ObservedGeneration : gateway .Generation ,
@@ -479,26 +474,27 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
479474
480475 // Check if the deployment already exists, if not create a new one
481476 found := & appsv1.Deployment {}
482- // Define a new deployment
483- dep , err := r .deploymentForGateway (gateway , token )
484- if err != nil {
485- log .Error (err , "Failed to define new Deployment resource for Gateway" )
477+ err = r .Get (ctx , types.NamespacedName {Name : gateway .Name , Namespace : gateway .Namespace }, found )
478+ // TODO update existing deployment eg image changes
479+ if err != nil && apierrors .IsNotFound (err ) {
480+ // Define a new deployment
481+ dep , err := r .deploymentForGateway (gateway , token )
482+ if err != nil {
483+ log .Error (err , "Failed to define new Deployment resource for Gateway" )
486484
487- // The following implementation will update the status
488- meta .SetStatusCondition (& gateway .Status .Conditions , metav1.Condition {Type : typeAvailableGateway ,
489- Status : metav1 .ConditionFalse , Reason : "Reconciling" , ObservedGeneration : gateway .Generation ,
490- Message : fmt .Sprintf ("Failed to create Deployment for the custom resource (%s): (%s)" , gateway .Name , err )})
485+ // The following implementation will update the status
486+ meta .SetStatusCondition (& gateway .Status .Conditions , metav1.Condition {Type : string (gatewayv1 .GatewayConditionAccepted ),
487+ Status : metav1 .ConditionFalse , Reason : "Reconciling" , ObservedGeneration : gateway .Generation ,
488+ Message : fmt .Sprintf ("Failed to create Deployment for the custom resource (%s): (%s)" , gateway .Name , err )})
489+
490+ if err := r .Status ().Update (ctx , gateway ); err != nil {
491+ log .Error (err , "Failed to update Gateway status" )
492+ return ctrl.Result {}, err
493+ }
491494
492- if err := r .Status ().Update (ctx , gateway ); err != nil {
493- log .Error (err , "Failed to update Gateway status" )
494495 return ctrl.Result {}, err
495496 }
496497
497- return ctrl.Result {}, err
498- }
499- err = r .Get (ctx , types.NamespacedName {Name : gateway .Name , Namespace : gateway .Namespace }, found )
500- if err != nil && apierrors .IsNotFound (err ) {
501-
502498 log .Info ("Creating a new Deployment" ,
503499 "Deployment.Namespace" , dep .Namespace , "Deployment.Name" , dep .Name )
504500 if err = r .Create (ctx , dep ); err != nil {
@@ -513,26 +509,18 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
513509 return ctrl.Result {RequeueAfter : time .Minute }, nil
514510 } else if err != nil {
515511 log .Error (err , "Failed to get Deployment" )
516- // Let's return the error for the reconciliation be re-triggered again
512+ // Let's return the error for the reconciliation be re-trigged again
517513 return ctrl.Result {}, err
518514 } else {
519- if err = r .Update (ctx , dep ); err != nil {
520- log .Error (err , "Failed to update Deployment" ,
521- "Deployment.Namespace" , found .Namespace , "Deployment.Name" , found .Name )
522-
523- // Re-fetch the gateway Custom Resource before updating the status
524- // so that we have the latest state of the resource on the cluster and we will avoid
525- // raising the error "the object has been modified, please apply
526- // your changes to the latest version and try again" which would re-trigger the reconciliation
527- if err := r .Get (ctx , req .NamespacedName , gateway ); err != nil {
528- log .Error (err , "Failed to re-fetch gateway" )
529- return ctrl.Result {}, err
530- }
515+ // Define a new deployment
516+ dep , err := r .deploymentForGateway (gateway , token )
517+ if err != nil {
518+ log .Error (err , "Failed to define new Deployment resource for Gateway" )
531519
532520 // The following implementation will update the status
533- meta .SetStatusCondition (& gateway .Status .Conditions , metav1.Condition {Type : typeAvailableGateway ,
521+ meta .SetStatusCondition (& gateway .Status .Conditions , metav1.Condition {Type : string ( gatewayv1 . GatewayConditionAccepted ) ,
534522 Status : metav1 .ConditionFalse , Reason : "Reconciling" , ObservedGeneration : gateway .Generation ,
535- Message : fmt .Sprintf ("Failed to update the deployment for the custom resource (%s): (%s)" , gateway .Name , err )})
523+ Message : fmt .Sprintf ("Failed to update Deployment for the custom resource (%s): (%s)" , gateway .Name , err )})
536524
537525 if err := r .Status ().Update (ctx , gateway ); err != nil {
538526 log .Error (err , "Failed to update Gateway status" )
@@ -541,6 +529,16 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
541529
542530 return ctrl.Result {}, err
543531 }
532+
533+ if err := r .Update (ctx , dep ); err != nil {
534+ if strings .Contains (err .Error (), "apply your changes to the latest version and try again" ) {
535+ log .Info ("Conflict when updating Deployment, retrying" )
536+ return ctrl.Result {Requeue : true }, nil
537+ } else {
538+ log .Error (err , "Failed to update Deployment" )
539+ return ctrl.Result {}, err
540+ }
541+ }
544542 }
545543
546544 if err := r .Get (ctx , req .NamespacedName , gateway ); err != nil {
@@ -549,7 +547,7 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
549547 }
550548
551549 // The following implementation will update the status
552- meta .SetStatusCondition (& gateway .Status .Conditions , metav1.Condition {Type : typeAvailableGateway ,
550+ meta .SetStatusCondition (& gateway .Status .Conditions , metav1.Condition {Type : string ( gatewayv1 . GatewayConditionProgrammed ) ,
553551 Status : metav1 .ConditionTrue , Reason : string (gatewayv1 .GatewayReasonProgrammed ), ObservedGeneration : gateway .Generation ,
554552 Message : fmt .Sprintf ("Deployment for custom resource (%s) reconciled successfully" , gateway .Name )})
555553
@@ -752,7 +750,7 @@ func imageForGateway() (string, error) {
752750 var imageEnvVar = "GATEWAY_IMAGE"
753751 image , found := os .LookupEnv (imageEnvVar )
754752 if ! found {
755- return "" , fmt .Errorf ("Unable to find %s environment variable with the image" , imageEnvVar )
753+ return "" , fmt .Errorf ("unable to find %s environment variable with the image" , imageEnvVar )
756754 }
757755 return image , nil
758756}
@@ -767,6 +765,7 @@ func imageForGateway() (string, error) {
767765// or deletion of a Custom Resource (CR) of the Gateway kind, as well as any changes
768766// to the Deployment that the controller manages and owns.
769767func (r * GatewayReconciler ) SetupWithManager (mgr ctrl.Manager ) error {
768+ pred := predicate.GenerationChangedPredicate {}
770769 return ctrl .NewControllerManagedBy (mgr ).
771770 // Watch the Gateway CR(s) and trigger reconciliation whenever it
772771 // is created, updated, or deleted
@@ -776,6 +775,6 @@ func (r *GatewayReconciler) SetupWithManager(mgr ctrl.Manager) error {
776775 // owned and managed by this controller, it will trigger reconciliation, ensuring that the cluster
777776 // state aligns with the desired state. See that the ownerRef was set when the Deployment was created.
778777 Owns (& appsv1.Deployment {}).
779- WithEventFilter (predicate. GenerationChangedPredicate {} ).
778+ WithEventFilter (pred ).
780779 Complete (r )
781780}
0 commit comments