@@ -26,6 +26,7 @@ import (
26
26
"k8s.io/apimachinery/pkg/types"
27
27
ctrl "sigs.k8s.io/controller-runtime"
28
28
"sigs.k8s.io/controller-runtime/pkg/client"
29
+ "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
29
30
"sigs.k8s.io/controller-runtime/pkg/event"
30
31
"sigs.k8s.io/controller-runtime/pkg/handler"
31
32
"sigs.k8s.io/controller-runtime/pkg/reconcile"
@@ -51,9 +52,6 @@ type Reconciler struct {
51
52
// https://book-v1.book.kubebuilder.io/beyond_basics/controller_watches.html) that is used to
52
53
// enqueue additional objects that need updating.
53
54
affected chan event.GenericEvent
54
-
55
- // ReadOnly disables writebacks
56
- ReadOnly bool
57
55
}
58
56
59
57
// Reconcile sets up some basic variables and then calls the business logic. It currently
@@ -81,9 +79,9 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
81
79
// Anchors in unmanaged namespace should be ignored. Make sure it
82
80
// doesn't have any finalizers, otherwise, leave it alone.
83
81
if why := config .WhyUnmanaged (pnm ); why != "" {
84
- if len (inst . ObjectMeta . Finalizers ) > 0 {
82
+ if controllerutil . ContainsFinalizer (inst , api . MetaGroup ) {
85
83
log .Info ("Removing finalizers from anchor in unmanaged namespace" , "reason" , why )
86
- inst . ObjectMeta . Finalizers = nil
84
+ controllerutil . RemoveFinalizer ( inst , api . MetaGroup )
87
85
return ctrl.Result {}, r .writeInstance (ctx , log , inst )
88
86
}
89
87
return ctrl.Result {}, nil
@@ -94,10 +92,10 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
94
92
// been bypassed and the anchor has been successfully created. Forbidden
95
93
// anchors won't have finalizers.
96
94
if why := config .WhyUnmanaged (nm ); why != "" {
97
- if inst .Status .State != api .Forbidden || len (inst . ObjectMeta . Finalizers ) > 0 {
95
+ if inst .Status .State != api .Forbidden || controllerutil . ContainsFinalizer (inst , api . MetaGroup ) {
98
96
log .Info ("Setting forbidden state on anchor with unmanaged name" , "reason" , why )
99
97
inst .Status .State = api .Forbidden
100
- inst . ObjectMeta . Finalizers = nil
98
+ controllerutil . RemoveFinalizer ( inst , api . MetaGroup )
101
99
return ctrl.Result {}, r .writeInstance (ctx , log , inst )
102
100
}
103
101
return ctrl.Result {}, nil
@@ -113,9 +111,13 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
113
111
r .updateState (log , inst , snsInst )
114
112
115
113
// Handle the case where the anchor is being deleted.
116
- if deleting , err := r .onDeleting (ctx , log , inst , snsInst ); deleting {
117
- return ctrl.Result {}, err
114
+ if ! inst .DeletionTimestamp .IsZero () {
115
+ // Stop reconciliation as anchor is being deleted
116
+ return ctrl.Result {}, r .onDeleting (ctx , log , inst , snsInst )
118
117
}
118
+ // Add finalizers on all non-forbidden anchors to ensure it's not deleted until
119
+ // after the subnamespace is deleted.
120
+ controllerutil .AddFinalizer (inst , api .MetaGroup )
119
121
120
122
// If the subnamespace doesn't exist, create it.
121
123
if inst .Status .State == api .Missing {
@@ -130,9 +132,6 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
130
132
}
131
133
}
132
134
133
- // Add finalizers on all non-forbidden anchors to ensure it's not deleted until
134
- // after the subnamespace is deleted.
135
- inst .ObjectMeta .Finalizers = []string {api .MetaGroup }
136
135
return ctrl.Result {}, r .writeInstance (ctx , log , inst )
137
136
}
138
137
@@ -145,19 +144,14 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
145
144
// There are several conditions where we skip step 1 - for example, if we're uninstalling HNC, or
146
145
// if allowCascadingDeletion is disabled but the subnamespace has descendants (see
147
146
// shouldDeleteSubns for details). In such cases, we move straight to step 2.
148
- func (r * Reconciler ) onDeleting (ctx context.Context , log logr.Logger , inst * api.SubnamespaceAnchor , snsInst * corev1.Namespace ) (bool , error ) {
149
- // Early exit and continue reconciliation if the instance is not being deleted.
150
- if inst .DeletionTimestamp .IsZero () {
151
- return false , nil
152
- }
153
-
147
+ func (r * Reconciler ) onDeleting (ctx context.Context , log logr.Logger , inst * api.SubnamespaceAnchor , snsInst * corev1.Namespace ) error {
154
148
// We handle deletions differently depending on whether _one_ anchor is being deleted (i.e., the
155
149
// user wants to delete the namespace) or whether the Anchor CRD is being deleted, which usually
156
150
// means HNC is being uninstalled and we shouldn't delete _any_ namespaces.
157
151
deletingCRD , err := crd .IsDeletingCRD (ctx , api .Anchors )
158
152
if err != nil {
159
153
log .Error (err , "Couldn't determine if CRD is being deleted" )
160
- return false , err
154
+ return err
161
155
}
162
156
log .V (1 ).Info ("Anchor is being deleted" , "deletingCRD" , deletingCRD )
163
157
@@ -166,21 +160,21 @@ func (r *Reconciler) onDeleting(ctx context.Context, log logr.Logger, inst *api.
166
160
switch {
167
161
case r .shouldDeleteSubns (log , inst , snsInst , deletingCRD ):
168
162
log .Info ("Deleting subnamespace due to anchor being deleted" )
169
- return true , r .deleteNamespace (ctx , log , snsInst )
163
+ return r .deleteNamespace (ctx , log , snsInst )
170
164
case r .shouldFinalizeAnchor (log , inst , snsInst ):
171
165
log .V (1 ).Info ("Unblocking deletion" ) // V(1) since we'll very shortly show an "anchor deleted" message
172
- inst . ObjectMeta . Finalizers = nil
173
- return true , r .writeInstance (ctx , log , inst )
166
+ controllerutil . RemoveFinalizer ( inst , api . MetaGroup )
167
+ return r .writeInstance (ctx , log , inst )
174
168
default :
175
169
// There's nothing to do; we're just waiting for something to happen. Print out a log message
176
170
// indicating what we're waiting for.
177
- if len (inst . ObjectMeta . Finalizers ) > 0 {
171
+ if controllerutil . ContainsFinalizer (inst , api . MetaGroup ) {
178
172
log .Info ("Waiting for subnamespace to be fully purged before letting the anchor be deleted" )
179
173
} else {
180
174
// I doubt we'll ever get here but I suppose it's possible
181
175
log .Info ("Waiting for K8s to delete this anchor (all finalizers are removed)" )
182
176
}
183
- return true , nil
177
+ return nil
184
178
}
185
179
}
186
180
@@ -213,7 +207,7 @@ func (r *Reconciler) shouldDeleteSubns(log logr.Logger, inst *api.SubnamespaceAn
213
207
log .V (1 ).Info ("The subnamespace is already being deleted; no need to delete again" )
214
208
return false
215
209
}
216
- if len (inst . ObjectMeta . Finalizers ) == 0 {
210
+ if ! controllerutil . ContainsFinalizer (inst , api . MetaGroup ) {
217
211
log .V (1 ).Info ("The anchor has already been finalized; do not reconsider deleting the namespace" )
218
212
return false
219
213
}
@@ -257,7 +251,7 @@ func (r *Reconciler) shouldDeleteSubns(log logr.Logger, inst *api.SubnamespaceAn
257
251
// deleted, it's in the process of being deleted, etc).
258
252
func (r * Reconciler ) shouldFinalizeAnchor (log logr.Logger , inst * api.SubnamespaceAnchor , snsInst * corev1.Namespace ) bool {
259
253
// If the anchor is already finalized, there's no need to do it again.
260
- if len (inst . ObjectMeta . Finalizers ) == 0 {
254
+ if ! controllerutil . ContainsFinalizer (inst , api . MetaGroup ) {
261
255
return false
262
256
}
263
257
@@ -348,10 +342,6 @@ func (r *Reconciler) getInstance(ctx context.Context, pnm, nm string) (*api.Subn
348
342
}
349
343
350
344
func (r * Reconciler ) writeInstance (ctx context.Context , log logr.Logger , inst * api.SubnamespaceAnchor ) error {
351
- if r .ReadOnly {
352
- return nil
353
- }
354
-
355
345
if inst .CreationTimestamp .IsZero () {
356
346
if err := r .Create (ctx , inst ); err != nil {
357
347
log .Error (err , "while creating on apiserver" )
@@ -370,10 +360,6 @@ func (r *Reconciler) writeInstance(ctx context.Context, log logr.Logger, inst *a
370
360
// finalizers on the instance before calling this function.
371
361
//lint:ignore U1000 Ignore for now, as it may be used again in the future
372
362
func (r * Reconciler ) deleteInstance (ctx context.Context , inst * api.SubnamespaceAnchor ) error {
373
- if r .ReadOnly {
374
- return nil
375
- }
376
-
377
363
if err := r .Delete (ctx , inst ); err != nil {
378
364
return fmt .Errorf ("while deleting on apiserver: %w" , err )
379
365
}
@@ -396,10 +382,6 @@ func (r *Reconciler) getNamespace(ctx context.Context, nm string) (*corev1.Names
396
382
}
397
383
398
384
func (r * Reconciler ) writeNamespace (ctx context.Context , log logr.Logger , nm , pnm string ) error {
399
- if r .ReadOnly {
400
- return nil
401
- }
402
-
403
385
inst := & corev1.Namespace {}
404
386
inst .ObjectMeta .Name = nm
405
387
metadata .SetAnnotation (inst , api .SubnamespaceOf , pnm )
@@ -417,10 +399,6 @@ func (r *Reconciler) writeNamespace(ctx context.Context, log logr.Logger, nm, pn
417
399
}
418
400
419
401
func (r * Reconciler ) deleteNamespace (ctx context.Context , log logr.Logger , inst * corev1.Namespace ) error {
420
- if r .ReadOnly {
421
- return nil
422
- }
423
-
424
402
if err := r .Delete (ctx , inst ); err != nil {
425
403
log .Error (err , "While deleting subnamespace" )
426
404
return err
0 commit comments