@@ -23,7 +23,6 @@ import (
2323 "errors"
2424 "fmt"
2525 "hash"
26- "reflect"
2726
2827 corev1 "k8s.io/api/core/v1"
2928 apierrors "k8s.io/apimachinery/pkg/api/errors"
@@ -49,23 +48,27 @@ type GenericProviderReconciler struct {
4948 Client client.Client
5049 Config * rest.Config
5150 WatchConfigSecretChanges bool
51+ WatchCoreProviderChanges bool
52+
53+ DeletePhases []PhaseFn
54+ ReconcilePhases []PhaseFn
5255}
5356
5457const (
5558 appliedSpecHashAnnotation = "operator.cluster.x-k8s.io/applied-spec-hash"
5659)
5760
58- func (r * GenericProviderReconciler ) SetupWithManager (ctx context.Context , mgr ctrl.Manager , options controller. Options ) error {
61+ func (r * GenericProviderReconciler ) BuildWithManager (ctx context.Context , mgr ctrl.Manager ) ( * ctrl. Builder , error ) {
5962 builder := ctrl .NewControllerManagedBy (mgr ).
6063 For (r .Provider )
6164
6265 if r .WatchConfigSecretChanges {
6366 if err := mgr .GetFieldIndexer ().IndexField (ctx , r .Provider , configSecretNameField , configSecretNameIndexFunc ); err != nil {
64- return err
67+ return nil , err
6568 }
6669
6770 if err := mgr .GetFieldIndexer ().IndexField (ctx , r .Provider , configSecretNamespaceField , configSecretNamespaceIndexFunc ); err != nil {
68- return err
71+ return nil , err
6972 }
7073
7174 builder .Watches (
@@ -75,15 +78,40 @@ func (r *GenericProviderReconciler) SetupWithManager(ctx context.Context, mgr ct
7578 }
7679
7780 // We don't want to receive secondary events from the CoreProvider for itself.
78- if reflect . TypeOf ( r . Provider ) != reflect . TypeOf ( genericprovider . GenericProvider ( & operatorv1. CoreProvider {})) {
81+ if r . WatchCoreProviderChanges {
7982 builder .Watches (
8083 & operatorv1.CoreProvider {},
8184 handler .EnqueueRequestsFromMapFunc (newCoreProviderToProviderFuncMapForProviderList (r .Client , r .ProviderList )),
8285 )
8386 }
8487
85- return builder .WithOptions (options ).
86- Complete (r )
88+ reconciler := NewPhaseReconciler (* r , r .Provider , r .ProviderList )
89+
90+ r .ReconcilePhases = []PhaseFn {
91+ reconciler .PreflightChecks ,
92+ reconciler .InitializePhaseReconciler ,
93+ reconciler .DownloadManifests ,
94+ reconciler .Load ,
95+ reconciler .Fetch ,
96+ reconciler .Upgrade ,
97+ reconciler .Install ,
98+ reconciler .ReportStatus ,
99+ }
100+
101+ r .DeletePhases = []PhaseFn {
102+ reconciler .Delete ,
103+ }
104+
105+ return builder , nil
106+ }
107+
108+ func (r * GenericProviderReconciler ) SetupWithManager (ctx context.Context , mgr ctrl.Manager , options controller.Options ) error {
109+ builder , err := r .BuildWithManager (ctx , mgr )
110+ if err != nil {
111+ return err
112+ }
113+
114+ return builder .WithOptions (options ).Complete (r )
87115}
88116
89117func (r * GenericProviderReconciler ) Reconcile (ctx context.Context , req reconcile.Request ) (_ reconcile.Result , reterr error ) {
@@ -128,7 +156,15 @@ func (r *GenericProviderReconciler) Reconcile(ctx context.Context, req reconcile
128156
129157 // Handle deletion reconciliation loop.
130158 if ! r .Provider .GetDeletionTimestamp ().IsZero () {
131- return r .reconcileDelete (ctx , r .Provider )
159+ res , err := r .reconcileDelete (ctx , r .Provider )
160+ if err != nil {
161+ return reconcile.Result {}, err
162+ }
163+
164+ return ctrl.Result {
165+ Requeue : res .Requeue ,
166+ RequeueAfter : res .RequeueAfter ,
167+ }, nil
132168 }
133169
134170 // Check if spec hash stays the same and don't go further in this case.
@@ -142,7 +178,7 @@ func (r *GenericProviderReconciler) Reconcile(ctx context.Context, req reconcile
142178 return ctrl.Result {}, nil
143179 }
144180
145- res , err := r .reconcile (ctx , r . Provider , r . ProviderList )
181+ res , err := r .reconcile (ctx )
146182
147183 annotations := r .Provider .GetAnnotations ()
148184 if annotations == nil {
@@ -164,7 +200,10 @@ func (r *GenericProviderReconciler) Reconcile(ctx context.Context, req reconcile
164200
165201 r .Provider .SetAnnotations (annotations )
166202
167- return res , ignoreCoreProviderWaitError (err )
203+ return ctrl.Result {
204+ Requeue : res .Requeue ,
205+ RequeueAfter : res .RequeueAfter ,
206+ }, ignoreCoreProviderWaitError (err )
168207}
169208
170209func patchProvider (ctx context.Context , provider operatorv1.GenericProvider , patchHelper * patch.Helper , options ... patch.Option ) error {
@@ -178,57 +217,41 @@ func patchProvider(ctx context.Context, provider operatorv1.GenericProvider, pat
178217 return patchHelper .Patch (ctx , provider , options ... )
179218}
180219
181- func (r * GenericProviderReconciler ) reconcile (ctx context.Context , provider genericprovider.GenericProvider , genericProviderList genericprovider.GenericProviderList ) (ctrl.Result , error ) {
182- reconciler := newPhaseReconciler (* r , provider , genericProviderList )
183- phases := []reconcilePhaseFn {
184- reconciler .preflightChecks ,
185- reconciler .initializePhaseReconciler ,
186- reconciler .downloadManifests ,
187- reconciler .load ,
188- reconciler .fetch ,
189- reconciler .upgrade ,
190- reconciler .install ,
191- reconciler .reportStatus ,
192- }
220+ func (r * GenericProviderReconciler ) reconcile (ctx context.Context ) (* Result , error ) {
221+ var res Result
193222
194- res := reconcile.Result {}
195-
196- var err error
197-
198- for _ , phase := range phases {
199- res , err = phase (ctx )
223+ for _ , phase := range r .ReconcilePhases {
224+ res , err := phase (ctx )
200225 if err != nil {
201226 var pe * PhaseError
202227 if errors .As (err , & pe ) {
203- conditions .Set (provider , conditions .FalseCondition (pe .Type , pe .Reason , pe .Severity , "%s" , err .Error ()))
228+ conditions .Set (r . Provider , conditions .FalseCondition (pe .Type , pe .Reason , pe .Severity , "%s" , err .Error ()))
204229 }
205230 }
206231
207232 if ! res .IsZero () || err != nil {
233+ // Stop the reconciliation if the phase was final
234+ if res .Completed {
235+ return & Result {}, nil
236+ }
237+
208238 // the steps are sequential, so we must be complete before progressing.
209239 return res , err
210240 }
211241 }
212242
213- return res , nil
243+ return & res , nil
214244}
215245
216- func (r * GenericProviderReconciler ) reconcileDelete (ctx context.Context , provider operatorv1.GenericProvider ) (ctrl. Result , error ) {
246+ func (r * GenericProviderReconciler ) reconcileDelete (ctx context.Context , provider operatorv1.GenericProvider ) (* Result , error ) {
217247 log := ctrl .LoggerFrom (ctx )
218248
219249 log .Info ("Deleting provider resources" )
220250
221- reconciler := newPhaseReconciler (* r , provider , nil )
222- phases := []reconcilePhaseFn {
223- reconciler .delete ,
224- }
225-
226- res := reconcile.Result {}
251+ var res Result
227252
228- var err error
229-
230- for _ , phase := range phases {
231- res , err = phase (ctx )
253+ for _ , phase := range r .DeletePhases {
254+ res , err := phase (ctx )
232255 if err != nil {
233256 var pe * PhaseError
234257 if errors .As (err , & pe ) {
@@ -237,14 +260,19 @@ func (r *GenericProviderReconciler) reconcileDelete(ctx context.Context, provide
237260 }
238261
239262 if ! res .IsZero () || err != nil {
263+ // Stop the reconciliation if the phase was final
264+ if res .Completed {
265+ return & Result {}, nil
266+ }
267+
240268 // the steps are sequential, so we must be complete before progressing.
241269 return res , err
242270 }
243271 }
244272
245273 controllerutil .RemoveFinalizer (provider , operatorv1 .ProviderFinalizer )
246274
247- return res , nil
275+ return & res , nil
248276}
249277
250278func addConfigSecretToHash (ctx context.Context , k8sClient client.Client , hash hash.Hash , provider genericprovider.GenericProvider ) error {
0 commit comments