@@ -23,7 +23,6 @@ import (
23
23
"errors"
24
24
"fmt"
25
25
"hash"
26
- "reflect"
27
26
28
27
corev1 "k8s.io/api/core/v1"
29
28
apierrors "k8s.io/apimachinery/pkg/api/errors"
@@ -49,23 +48,27 @@ type GenericProviderReconciler struct {
49
48
Client client.Client
50
49
Config * rest.Config
51
50
WatchConfigSecretChanges bool
51
+ WatchCoreProviderChanges bool
52
+
53
+ DeletePhases []PhaseFn
54
+ ReconcilePhases []PhaseFn
52
55
}
53
56
54
57
const (
55
58
appliedSpecHashAnnotation = "operator.cluster.x-k8s.io/applied-spec-hash"
56
59
)
57
60
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 ) {
59
62
builder := ctrl .NewControllerManagedBy (mgr ).
60
63
For (r .Provider )
61
64
62
65
if r .WatchConfigSecretChanges {
63
66
if err := mgr .GetFieldIndexer ().IndexField (ctx , r .Provider , configSecretNameField , configSecretNameIndexFunc ); err != nil {
64
- return err
67
+ return nil , err
65
68
}
66
69
67
70
if err := mgr .GetFieldIndexer ().IndexField (ctx , r .Provider , configSecretNamespaceField , configSecretNamespaceIndexFunc ); err != nil {
68
- return err
71
+ return nil , err
69
72
}
70
73
71
74
builder .Watches (
@@ -75,15 +78,40 @@ func (r *GenericProviderReconciler) SetupWithManager(ctx context.Context, mgr ct
75
78
}
76
79
77
80
// 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 {
79
82
builder .Watches (
80
83
& operatorv1.CoreProvider {},
81
84
handler .EnqueueRequestsFromMapFunc (newCoreProviderToProviderFuncMapForProviderList (r .Client , r .ProviderList )),
82
85
)
83
86
}
84
87
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 )
87
115
}
88
116
89
117
func (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
128
156
129
157
// Handle deletion reconciliation loop.
130
158
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
132
168
}
133
169
134
170
// 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
142
178
return ctrl.Result {}, nil
143
179
}
144
180
145
- res , err := r .reconcile (ctx , r . Provider , r . ProviderList )
181
+ res , err := r .reconcile (ctx )
146
182
147
183
annotations := r .Provider .GetAnnotations ()
148
184
if annotations == nil {
@@ -164,7 +200,10 @@ func (r *GenericProviderReconciler) Reconcile(ctx context.Context, req reconcile
164
200
165
201
r .Provider .SetAnnotations (annotations )
166
202
167
- return res , ignoreCoreProviderWaitError (err )
203
+ return ctrl.Result {
204
+ Requeue : res .Requeue ,
205
+ RequeueAfter : res .RequeueAfter ,
206
+ }, ignoreCoreProviderWaitError (err )
168
207
}
169
208
170
209
func 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
178
217
return patchHelper .Patch (ctx , provider , options ... )
179
218
}
180
219
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
193
222
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 )
200
225
if err != nil {
201
226
var pe * PhaseError
202
227
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 ()))
204
229
}
205
230
}
206
231
207
232
if ! res .IsZero () || err != nil {
233
+ // Stop the reconciliation if the phase was final
234
+ if res .Completed {
235
+ return & Result {}, nil
236
+ }
237
+
208
238
// the steps are sequential, so we must be complete before progressing.
209
239
return res , err
210
240
}
211
241
}
212
242
213
- return res , nil
243
+ return & res , nil
214
244
}
215
245
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 ) {
217
247
log := ctrl .LoggerFrom (ctx )
218
248
219
249
log .Info ("Deleting provider resources" )
220
250
221
- reconciler := newPhaseReconciler (* r , provider , nil )
222
- phases := []reconcilePhaseFn {
223
- reconciler .delete ,
224
- }
225
-
226
- res := reconcile.Result {}
251
+ var res Result
227
252
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 )
232
255
if err != nil {
233
256
var pe * PhaseError
234
257
if errors .As (err , & pe ) {
@@ -237,14 +260,19 @@ func (r *GenericProviderReconciler) reconcileDelete(ctx context.Context, provide
237
260
}
238
261
239
262
if ! res .IsZero () || err != nil {
263
+ // Stop the reconciliation if the phase was final
264
+ if res .Completed {
265
+ return & Result {}, nil
266
+ }
267
+
240
268
// the steps are sequential, so we must be complete before progressing.
241
269
return res , err
242
270
}
243
271
}
244
272
245
273
controllerutil .RemoveFinalizer (provider , operatorv1 .ProviderFinalizer )
246
274
247
- return res , nil
275
+ return & res , nil
248
276
}
249
277
250
278
func addConfigSecretToHash (ctx context.Context , k8sClient client.Client , hash hash.Hash , provider genericprovider.GenericProvider ) error {
0 commit comments