From a2bad3fa62d524bd0972662321bab86a24850d95 Mon Sep 17 00:00:00 2001 From: Yiqi Gao Date: Fri, 28 Feb 2020 12:04:36 -0500 Subject: [PATCH] Create a flag to toggle HC and HNS Reconcilers Create a flag to enable/disable the HierarchicalNamespace Reconciler and also toggle the behavior of HierarchyConfig Reconciler accordingly. Changes to the HierarchyConfig Reconciler behaviour is not implemented in this commit. Tested on GKE cluster. The reconcilers were created successfully with/without setting the flag. I saw the test logs with the correct values set in Stackdriver. Part of #467, #457 --- incubator/hnc/cmd/manager/main.go | 4 +- .../hnc/pkg/reconcilers/hierarchy_config.go | 12 +++++ incubator/hnc/pkg/reconcilers/setup.go | 54 ++++++++++++------- incubator/hnc/pkg/reconcilers/suite_test.go | 19 +++++-- 4 files changed, 64 insertions(+), 25 deletions(-) diff --git a/incubator/hnc/cmd/manager/main.go b/incubator/hnc/cmd/manager/main.go index 8c1729447..a2905b697 100644 --- a/incubator/hnc/cmd/manager/main.go +++ b/incubator/hnc/cmd/manager/main.go @@ -63,6 +63,7 @@ func main() { debugLogs bool testLog bool qps int + enableHNSReconciler bool ) flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") flag.BoolVar(&enableLeaderElection, "enable-leader-election", false, @@ -72,6 +73,7 @@ func main() { flag.BoolVar(&testLog, "enable-test-log", false, "Enables test log.") flag.IntVar(&maxReconciles, "max-reconciles", 1, "Number of concurrent reconciles to perform.") flag.IntVar(&qps, "apiserver-qps-throttle", 50, "The maximum QPS to the API server.") + flag.BoolVar(&enableHNSReconciler, "enable-hierarchicalnamespace-reconciler", false, "Enables hierarchicalnamespace reconciler.") flag.Parse() // Enable OpenCensus exporters to export metrics @@ -131,7 +133,7 @@ func main() { // Create all reconciling controllers f := forest.NewForest() setupLog.Info("Creating controllers", "maxReconciles", maxReconciles) - if err := reconcilers.Create(mgr, f, maxReconciles); err != nil { + if err := reconcilers.Create(mgr, f, maxReconciles, enableHNSReconciler); err != nil { setupLog.Error(err, "cannot create controllers") os.Exit(1) } diff --git a/incubator/hnc/pkg/reconcilers/hierarchy_config.go b/incubator/hnc/pkg/reconcilers/hierarchy_config.go index 0a4ce3db3..5dbb3fda4 100644 --- a/incubator/hnc/pkg/reconcilers/hierarchy_config.go +++ b/incubator/hnc/pkg/reconcilers/hierarchy_config.go @@ -63,6 +63,12 @@ type HierarchyConfigReconciler struct { // were part of the same reconciliation attempt, even if multiple are running parallel (or it's // simply hard to tell when one ends and another begins). reconcileID int32 + + // This is a temporary field to toggle different behaviours of this HierarchyConfigurationReconciler + // depending on if the HierarchicalNamespaceReconciler is enabled or not. It will be removed after + // the GitHub issue "Implement self-service namespace" is resolved + // (https://github.com/kubernetes-sigs/multi-tenancy/issues/457) + HNSReconcilerEnabled bool } // +kubebuilder:rbac:groups=hnc.x-k8s.io,resources=hierarchies,verbs=get;list;watch;create;update;patch;delete @@ -83,6 +89,12 @@ func (r *HierarchyConfigReconciler) Reconcile(req ctrl.Request) (ctrl.Result, er rid := (int)(atomic.AddInt32(&r.reconcileID, 1)) log := r.Log.WithValues("ns", ns, "rid", rid) + + // TODO remove this log and use the HNSReconcilerEnabled to toggle the behavour of this + // reconciler accordingly. See issue: https://github.com/kubernetes-sigs/multi-tenancy/issues/467 + // Output a log for testing. + log.Info("HC will be reconciled with", "HNSReconcilerEnabled", r.HNSReconcilerEnabled) + return ctrl.Result{}, r.reconcile(ctx, log, ns) } diff --git a/incubator/hnc/pkg/reconcilers/setup.go b/incubator/hnc/pkg/reconcilers/setup.go index a51c7bf29..ebd07c723 100644 --- a/incubator/hnc/pkg/reconcilers/setup.go +++ b/incubator/hnc/pkg/reconcilers/setup.go @@ -21,18 +21,43 @@ var ex = map[string]bool{ // Create creates all reconcilers. // // This function is called both from main.go as well as from the integ tests. -func Create(mgr ctrl.Manager, f *forest.Forest, maxReconciles int) error { +func Create(mgr ctrl.Manager, f *forest.Forest, maxReconciles int, enableHNSReconciler bool) error { hcChan := make(chan event.GenericEvent) - // Create the HierarchyConfigReconciler. - hr := &HierarchyConfigReconciler{ - Client: mgr.GetClient(), - Log: ctrl.Log.WithName("reconcilers").WithName("Hierarchy"), - Forest: f, - Affected: hcChan, - } - if err := hr.SetupWithManager(mgr, maxReconciles); err != nil { - return fmt.Errorf("cannot create Hierarchy reconciler: %s", err.Error()) + // Create different reconcilers based on if the enableHNSReconciler flag is set or not. + if enableHNSReconciler { + // Create the HierarchyConfigReconciler with HNSReconciler enabled. + hr := &HierarchyConfigReconciler{ + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("reconcilers").WithName("Hierarchy"), + Forest: f, + Affected: hcChan, + HNSReconcilerEnabled: true, + } + if err := hr.SetupWithManager(mgr, maxReconciles); err != nil { + return fmt.Errorf("cannot create Hierarchy reconciler: %s", err.Error()) + } + + // Create HierarchicalNamespaceReconciler. + hnsr := &HierarchicalNamespaceReconciler{ + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("reconcilers").WithName("HierarchicalNamespace"), + } + if err := hnsr.SetupWithManager(mgr); err != nil { + return fmt.Errorf("cannot create HierarchicalNamespace reconciler: %s", err.Error()) + } + } else { + // Create the HierarchyConfigReconciler with HNSReconciler disabled. + hr := &HierarchyConfigReconciler{ + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("reconcilers").WithName("Hierarchy"), + Forest: f, + Affected: hcChan, + HNSReconcilerEnabled: false, + } + if err := hr.SetupWithManager(mgr, maxReconciles); err != nil { + return fmt.Errorf("cannot create Hierarchy reconciler: %s", err.Error()) + } } // Create the ConfigReconciler. @@ -47,14 +72,5 @@ func Create(mgr ctrl.Manager, f *forest.Forest, maxReconciles int) error { return fmt.Errorf("cannot create Config reconciler: %s", err.Error()) } - // Create HierarchicalNamespaceReconciler. - hnsr := &HierarchicalNamespaceReconciler{ - Client: mgr.GetClient(), - Log: ctrl.Log.WithName("reconcilers").WithName("HierarchicalNamespace"), - } - if err := hnsr.SetupWithManager(mgr); err != nil { - return fmt.Errorf("cannot create HierarchicalNamespace reconciler: %s", err.Error()) - } - return nil } diff --git a/incubator/hnc/pkg/reconcilers/suite_test.go b/incubator/hnc/pkg/reconcilers/suite_test.go index 835013f8a..d9dbebf22 100644 --- a/incubator/hnc/pkg/reconcilers/suite_test.go +++ b/incubator/hnc/pkg/reconcilers/suite_test.go @@ -17,6 +17,7 @@ package reconcilers_test import ( "context" + "flag" "path/filepath" "testing" "time" @@ -44,12 +45,20 @@ import ( // http://onsi.github.io/ginkgo/ to learn more about Ginkgo. var ( - cfg *rest.Config - k8sClient client.Client - testEnv *envtest.Environment - k8sManager ctrl.Manager + cfg *rest.Config + k8sClient client.Client + testEnv *envtest.Environment + k8sManager ctrl.Manager + enableHNSReconciler bool ) +func init() { + // This is a temporary flag to enable the hierarchicalnamespace reconciler for testing. + // It will be removed after the GitHub issue "Implement self-service namespace" is resolved + // (https://github.com/kubernetes-sigs/multi-tenancy/issues/457) + flag.BoolVar(&enableHNSReconciler, "enable-hierarchicalnamespace-reconciler", false, "Enables hierarchicalnamespace reconciler.") +} + func TestAPIs(t *testing.T) { RegisterFailHandler(Fail) @@ -86,7 +95,7 @@ var _ = BeforeSuite(func(done Done) { Scheme: scheme.Scheme, }) Expect(err).ToNot(HaveOccurred()) - err = reconcilers.Create(k8sManager, forest.NewForest(), 100) + err = reconcilers.Create(k8sManager, forest.NewForest(), 100, enableHNSReconciler) Expect(err).ToNot(HaveOccurred()) k8sClient = k8sManager.GetClient()