Skip to content
This repository was archived by the owner on Apr 17, 2025. It is now read-only.

Commit bfe42e2

Browse files
authored
Merge pull request #92 from adrianludwin/reorg
Restructure by feature
2 parents e297652 + 779a2d3 commit bfe42e2

38 files changed

+1732
-1505
lines changed

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,9 @@ all: test docker-build
8484
###################### LOCAL ARTIFACTS #########################
8585

8686
# Run tests
87-
test: build
87+
test: build test-only
88+
89+
test-only:
8890
@echo
8991
@echo "If tests fail due to no matches for kind \"CustomResourceDefinition\" in version \"apiextensions.k8s.io/v1\","
9092
@echo "please remove the old kubebuilder and reinstall it - https://book.kubebuilder.io/quick-start.html#installation"

cmd/manager/main.go

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,8 @@ import (
4141
v1a2 "sigs.k8s.io/hierarchical-namespaces/api/v1alpha2"
4242
"sigs.k8s.io/hierarchical-namespaces/internal/config"
4343
"sigs.k8s.io/hierarchical-namespaces/internal/forest"
44-
"sigs.k8s.io/hierarchical-namespaces/internal/mutators"
45-
"sigs.k8s.io/hierarchical-namespaces/internal/reconcilers"
44+
"sigs.k8s.io/hierarchical-namespaces/internal/setup"
4645
"sigs.k8s.io/hierarchical-namespaces/internal/stats"
47-
"sigs.k8s.io/hierarchical-namespaces/internal/validators"
4846
)
4947

5048
var (
@@ -183,7 +181,7 @@ func main() {
183181

184182
// Make sure certs are generated and valid if webhooks are enabled and internal certs are used.
185183
setupLog.Info("Starting certificate generation")
186-
certsCreated, err := validators.CreateCertsIfNeeded(mgr, novalidation, internalCert, restartOnSecretRefresh)
184+
certsCreated, err := setup.CreateCertsIfNeeded(mgr, novalidation, internalCert, restartOnSecretRefresh)
187185
if err != nil {
188186
setupLog.Error(err, "unable to set up cert rotation")
189187
os.Exit(1)
@@ -212,19 +210,15 @@ func startControllers(mgr ctrl.Manager, certsCreated chan struct{}) {
212210
// other components.
213211
f := forest.NewForest()
214212

215-
// Create all validating admission controllers.
213+
// Create all validating and mutating admission controllers.
216214
if !novalidation {
217215
setupLog.Info("Registering validating webhook (won't work when running locally; use --novalidation)")
218-
validators.Create(mgr, f)
216+
setup.CreateWebhooks(mgr, f)
219217
}
220218

221-
// Create mutating admission controllers.
222-
setupLog.Info("Registering mutating webhook")
223-
mutators.Create(mgr)
224-
225219
// Create all reconciling controllers
226220
setupLog.Info("Creating controllers", "maxReconciles", maxReconciles)
227-
if err := reconcilers.Create(mgr, f, maxReconciles, false); err != nil {
221+
if err := setup.CreateReconcilers(mgr, f, maxReconciles, false); err != nil {
228222
setupLog.Error(err, "cannot create controllers")
229223
os.Exit(1)
230224
}

config/webhook/manifests.yaml

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -80,60 +80,60 @@ webhooks:
8080
service:
8181
name: webhook-service
8282
namespace: system
83-
path: /validate-hnc-x-k8s-io-v1alpha2-hncconfigurations
83+
path: /validate-objects
8484
failurePolicy: Fail
85-
name: hncconfigurations.hnc.x-k8s.io
85+
name: objects.hnc.x-k8s.io
8686
rules:
8787
- apiGroups:
88-
- hnc.x-k8s.io
88+
- '*'
8989
apiVersions:
90-
- v1alpha2
90+
- '*'
9191
operations:
9292
- CREATE
9393
- UPDATE
9494
- DELETE
9595
resources:
96-
- hncconfigurations
96+
- '*'
9797
sideEffects: None
9898
- admissionReviewVersions:
9999
- v1
100100
clientConfig:
101101
service:
102102
name: webhook-service
103103
namespace: system
104-
path: /validate-v1-namespace
104+
path: /validate-hnc-x-k8s-io-v1alpha2-hncconfigurations
105105
failurePolicy: Fail
106-
name: namespaces.hnc.x-k8s.io
106+
name: hncconfigurations.hnc.x-k8s.io
107107
rules:
108108
- apiGroups:
109-
- ""
109+
- hnc.x-k8s.io
110110
apiVersions:
111-
- v1
111+
- v1alpha2
112112
operations:
113-
- DELETE
114113
- CREATE
115114
- UPDATE
115+
- DELETE
116116
resources:
117-
- namespaces
117+
- hncconfigurations
118118
sideEffects: None
119119
- admissionReviewVersions:
120120
- v1
121121
clientConfig:
122122
service:
123123
name: webhook-service
124124
namespace: system
125-
path: /validate-objects
125+
path: /validate-v1-namespace
126126
failurePolicy: Fail
127-
name: objects.hnc.x-k8s.io
127+
name: namespaces.hnc.x-k8s.io
128128
rules:
129129
- apiGroups:
130-
- '*'
130+
- ""
131131
apiVersions:
132-
- '*'
132+
- v1
133133
operations:
134+
- DELETE
134135
- CREATE
135136
- UPDATE
136-
- DELETE
137137
resources:
138-
- '*'
138+
- namespaces
139139
sideEffects: None

internal/reconcilers/anchor.go renamed to internal/anchor/reconciler.go

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
1313
limitations under the License.
1414
*/
1515

16-
package reconcilers
16+
package anchor
1717

1818
import (
1919
"context"
@@ -33,17 +33,19 @@ import (
3333

3434
api "sigs.k8s.io/hierarchical-namespaces/api/v1alpha2"
3535
"sigs.k8s.io/hierarchical-namespaces/internal/config"
36+
"sigs.k8s.io/hierarchical-namespaces/internal/crd"
3637
"sigs.k8s.io/hierarchical-namespaces/internal/forest"
38+
"sigs.k8s.io/hierarchical-namespaces/internal/logutils"
3739
"sigs.k8s.io/hierarchical-namespaces/internal/metadata"
3840
)
3941

40-
// AnchorReconciler reconciles SubnamespaceAnchor CRs to make sure all the subnamespaces are
42+
// Reconciler reconciles SubnamespaceAnchor CRs to make sure all the subnamespaces are
4143
// properly maintained.
42-
type AnchorReconciler struct {
44+
type Reconciler struct {
4345
client.Client
4446
Log logr.Logger
4547

46-
forest *forest.Forest
48+
Forest *forest.Forest
4749

4850
// Affected is a channel of event.GenericEvent (see "Watching Channels" in
4951
// https://book-v1.book.kubebuilder.io/beyond_basics/controller_watches.html) that is used to
@@ -53,8 +55,8 @@ type AnchorReconciler struct {
5355

5456
// Reconcile sets up some basic variables and then calls the business logic. It currently
5557
// only handles the creation of the namespaces but no deletion or state reporting yet.
56-
func (r *AnchorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
57-
log := loggerWithRID(r.Log).WithValues("trigger", req.NamespacedName)
58+
func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
59+
log := logutils.WithRID(r.Log).WithValues("trigger", req.NamespacedName)
5860
log.V(1).Info("Reconciling anchor")
5961

6062
// Get names of the hierarchical namespace and the current namespace.
@@ -134,7 +136,7 @@ func (r *AnchorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
134136
// There are several conditions where we skip step 1 - for example, if we're uninstalling HNC, or
135137
// if allowCascadingDeletion is disabled but the subnamespace has descendants (see
136138
// shouldDeleteSubns for details). In such cases, we move straight to step 2.
137-
func (r *AnchorReconciler) onDeleting(ctx context.Context, log logr.Logger, inst *api.SubnamespaceAnchor, snsInst *corev1.Namespace) (bool, error) {
139+
func (r *Reconciler) onDeleting(ctx context.Context, log logr.Logger, inst *api.SubnamespaceAnchor, snsInst *corev1.Namespace) (bool, error) {
138140
// Early exit and continue reconciliation if the instance is not being deleted.
139141
if inst.DeletionTimestamp.IsZero() {
140142
return false, nil
@@ -143,7 +145,7 @@ func (r *AnchorReconciler) onDeleting(ctx context.Context, log logr.Logger, inst
143145
// We handle deletions differently depending on whether _one_ anchor is being deleted (i.e., the
144146
// user wants to delete the namespace) or whether the Anchor CRD is being deleted, which usually
145147
// means HNC is being uninstalled and we shouldn't delete _any_ namespaces.
146-
deletingCRD, err := isDeletingCRD(ctx, api.Anchors)
148+
deletingCRD, err := crd.IsDeletingCRD(ctx, api.Anchors)
147149
if err != nil {
148150
log.Error(err, "Couldn't determine if CRD is being deleted")
149151
return false, err
@@ -180,9 +182,9 @@ func (r *AnchorReconciler) onDeleting(ctx context.Context, log logr.Logger, inst
180182
//
181183
// This is the only part of the deletion process that needs to access the forest, in order to check
182184
// the recursive AllowCascadingDeletion setting.
183-
func (r *AnchorReconciler) shouldDeleteSubns(log logr.Logger, inst *api.SubnamespaceAnchor, nsInst *corev1.Namespace, deletingCRD bool) bool {
184-
r.forest.Lock()
185-
defer r.forest.Unlock()
185+
func (r *Reconciler) shouldDeleteSubns(log logr.Logger, inst *api.SubnamespaceAnchor, nsInst *corev1.Namespace, deletingCRD bool) bool {
186+
r.Forest.Lock()
187+
defer r.Forest.Unlock()
186188

187189
// If the CRD is being deleted, we want to leave the subnamespace alone.
188190
if deletingCRD {
@@ -211,7 +213,7 @@ func (r *AnchorReconciler) shouldDeleteSubns(log logr.Logger, inst *api.Subnames
211213
// if ACD=true on one of their ancestors; the webhooks *should* ensure that this is always true
212214
// before we get here, but if something slips by, we'll just leave the old subnamespace alone
213215
// with a missing-anchor condition.
214-
cns := r.forest.Get(inst.Name)
216+
cns := r.Forest.Get(inst.Name)
215217
if cns.ChildNames() != nil && !cns.AllowsCascadingDeletion() {
216218
log.Info("This subnamespace has descendants and allowCascadingDeletion is disabled; will not delete")
217219
return false
@@ -244,7 +246,7 @@ func (r *AnchorReconciler) shouldDeleteSubns(log logr.Logger, inst *api.Subnames
244246
// shouldFinalizeAnchor determines whether the anchor is safe to delete. It should only be called once
245247
// we know that we don't need to delete the subnamespace itself (e.g. it's already gone, it can't be
246248
// deleted, it's in the process of being deleted, etc).
247-
func (r *AnchorReconciler) shouldFinalizeAnchor(log logr.Logger, inst *api.SubnamespaceAnchor, snsInst *corev1.Namespace) bool {
249+
func (r *Reconciler) shouldFinalizeAnchor(log logr.Logger, inst *api.SubnamespaceAnchor, snsInst *corev1.Namespace) bool {
248250
// If the anchor is already finalized, there's no need to do it again.
249251
if len(inst.ObjectMeta.Finalizers) == 0 {
250252
return false
@@ -289,7 +291,7 @@ func (r *AnchorReconciler) shouldFinalizeAnchor(log logr.Logger, inst *api.Subna
289291
}
290292
}
291293

292-
func (r *AnchorReconciler) updateState(log logr.Logger, inst *api.SubnamespaceAnchor, snsInst *corev1.Namespace) {
294+
func (r *Reconciler) updateState(log logr.Logger, inst *api.SubnamespaceAnchor, snsInst *corev1.Namespace) {
293295
pnm := inst.Namespace
294296
sOf := snsInst.Annotations[api.SubnamespaceOf]
295297
switch {
@@ -308,9 +310,9 @@ func (r *AnchorReconciler) updateState(log logr.Logger, inst *api.SubnamespaceAn
308310
}
309311
}
310312

311-
// It enqueues a subnamespace anchor for later reconciliation. This occurs in a goroutine
313+
// Enqueue enqueues a subnamespace anchor for later reconciliation. This occurs in a goroutine
312314
// so the caller doesn't block; since the reconciler is never garbage-collected, this is safe.
313-
func (r *AnchorReconciler) enqueue(log logr.Logger, nm, pnm, reason string) {
315+
func (r *Reconciler) Enqueue(log logr.Logger, nm, pnm, reason string) {
314316
go func() {
315317
// The watch handler doesn't care about anything except the metadata.
316318
inst := &api.SubnamespaceAnchor{}
@@ -321,7 +323,7 @@ func (r *AnchorReconciler) enqueue(log logr.Logger, nm, pnm, reason string) {
321323
}()
322324
}
323325

324-
func (r *AnchorReconciler) getInstance(ctx context.Context, pnm, nm string) (*api.SubnamespaceAnchor, error) {
326+
func (r *Reconciler) getInstance(ctx context.Context, pnm, nm string) (*api.SubnamespaceAnchor, error) {
325327
nsn := types.NamespacedName{Namespace: pnm, Name: nm}
326328
inst := &api.SubnamespaceAnchor{}
327329
if err := r.Get(ctx, nsn, inst); err != nil {
@@ -330,7 +332,7 @@ func (r *AnchorReconciler) getInstance(ctx context.Context, pnm, nm string) (*ap
330332
return inst, nil
331333
}
332334

333-
func (r *AnchorReconciler) writeInstance(ctx context.Context, log logr.Logger, inst *api.SubnamespaceAnchor) error {
335+
func (r *Reconciler) writeInstance(ctx context.Context, log logr.Logger, inst *api.SubnamespaceAnchor) error {
334336
if inst.CreationTimestamp.IsZero() {
335337
if err := r.Create(ctx, inst); err != nil {
336338
log.Error(err, "while creating on apiserver")
@@ -347,7 +349,7 @@ func (r *AnchorReconciler) writeInstance(ctx context.Context, log logr.Logger, i
347349

348350
// deleteInstance deletes the anchor instance. Note: Make sure there's no
349351
// finalizers on the instance before calling this function.
350-
func (r *AnchorReconciler) deleteInstance(ctx context.Context, log logr.Logger, inst *api.SubnamespaceAnchor) error {
352+
func (r *Reconciler) deleteInstance(ctx context.Context, log logr.Logger, inst *api.SubnamespaceAnchor) error {
351353
if err := r.Delete(ctx, inst); err != nil {
352354
return fmt.Errorf("while deleting on apiserver: %w", err)
353355
}
@@ -357,7 +359,7 @@ func (r *AnchorReconciler) deleteInstance(ctx context.Context, log logr.Logger,
357359
// getNamespace returns the namespace if it exists, or returns an invalid, blank, unnamed one if it
358360
// doesn't. This allows it to be trivially identified as a namespace that doesn't exist, and also
359361
// allows us to easily modify it if we want to create it.
360-
func (r *AnchorReconciler) getNamespace(ctx context.Context, nm string) (*corev1.Namespace, error) {
362+
func (r *Reconciler) getNamespace(ctx context.Context, nm string) (*corev1.Namespace, error) {
361363
ns := &corev1.Namespace{}
362364
nnm := types.NamespacedName{Name: nm}
363365
if err := r.Get(ctx, nnm, ns); err != nil {
@@ -369,7 +371,7 @@ func (r *AnchorReconciler) getNamespace(ctx context.Context, nm string) (*corev1
369371
return ns, nil
370372
}
371373

372-
func (r *AnchorReconciler) writeNamespace(ctx context.Context, log logr.Logger, nm, pnm string) error {
374+
func (r *Reconciler) writeNamespace(ctx context.Context, log logr.Logger, nm, pnm string) error {
373375
inst := &corev1.Namespace{}
374376
inst.ObjectMeta.Name = nm
375377
metadata.SetAnnotation(inst, api.SubnamespaceOf, pnm)
@@ -386,15 +388,15 @@ func (r *AnchorReconciler) writeNamespace(ctx context.Context, log logr.Logger,
386388
return nil
387389
}
388390

389-
func (r *AnchorReconciler) deleteNamespace(ctx context.Context, log logr.Logger, inst *corev1.Namespace) error {
391+
func (r *Reconciler) deleteNamespace(ctx context.Context, log logr.Logger, inst *corev1.Namespace) error {
390392
if err := r.Delete(ctx, inst); err != nil {
391393
log.Error(err, "While deleting subnamespace")
392394
return err
393395
}
394396
return nil
395397
}
396398

397-
func (r *AnchorReconciler) SetupWithManager(mgr ctrl.Manager) error {
399+
func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error {
398400
// Maps an subnamespace to its anchor in the parent namespace.
399401
nsMapFn := func(obj client.Object) []reconcile.Request {
400402
if obj.GetAnnotations()[api.SubnamespaceOf] == "" {

0 commit comments

Comments
 (0)