From b4097f91bc3fb52eaf4333edf06658932cb73ec0 Mon Sep 17 00:00:00 2001 From: yue9944882 <291271447@qq.com> Date: Wed, 24 Feb 2021 14:38:51 +0800 Subject: [PATCH] introducing ClusterClaim feature gate to opt-out from list-watching cluster-claims Signed-off-by: yue9944882 <291271447@qq.com> --- pkg/features/feature.go | 44 +++++++++++++++++++++++++++++++++++++++++ pkg/spoke/spokeagent.go | 29 ++++++++++++++++----------- 2 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 pkg/features/feature.go diff --git a/pkg/features/feature.go b/pkg/features/feature.go new file mode 100644 index 000000000..16ba90220 --- /dev/null +++ b/pkg/features/feature.go @@ -0,0 +1,44 @@ +package features + +import ( + "k8s.io/component-base/featuregate" + "k8s.io/klog/v2" +) + +const ( + // Every feature gate should add method here following this template: + // + // // owner: @username + // // alpha: v1.X + // MyFeature featuregate.Feature = "MyFeature" + + // ClusterClaim will start a new controller in the spoke-agent to manage the cluster-claim + // resources in the managed cluster. + // + // The cluster-claim controller is majorly for collecting claims and updating claims field + // in managedcluster status. When it exceeds the limit specified by "--max-custom-cluster-claims", + // the extra claims will be truncated. + // + // If it is disabled, the user will see empty claims field in managedcluster status. The + // deployer who disable the feature may need to update claim field in managed cluster status + // itself to avoid impact to users. + ClusterClaim featuregate.Feature = "ClusterClaim" +) + +var ( + // DefaultMutableFeatureGate is made up of multiple mutable feature-gates. + DefaultMutableFeatureGate featuregate.MutableFeatureGate = featuregate.NewFeatureGate() +) + +func init() { + if err := DefaultMutableFeatureGate.Add(defaultRegistrationFeatureGates); err != nil { + klog.Fatalf("Unexpected error: %v", err) + } +} + +// defaultRegistrationFeatureGates consists of all known ocm-registration +// feature keys. To add a new feature, define a key for it above and +// add it here. +var defaultRegistrationFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ + ClusterClaim: {Default: true, PreRelease: featuregate.Beta}, +} diff --git a/pkg/spoke/spokeagent.go b/pkg/spoke/spokeagent.go index 12fde3177..7215d2751 100644 --- a/pkg/spoke/spokeagent.go +++ b/pkg/spoke/spokeagent.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "github.com/openshift/library-go/pkg/controller/factory" "io/ioutil" "os" "path" @@ -11,6 +12,7 @@ import ( clusterv1client "github.com/open-cluster-management/api/client/cluster/clientset/versioned" clusterv1informers "github.com/open-cluster-management/api/client/cluster/informers/externalversions" + "github.com/open-cluster-management/registration/pkg/features" "github.com/open-cluster-management/registration/pkg/helpers" "github.com/open-cluster-management/registration/pkg/spoke/hubclientcert" "github.com/open-cluster-management/registration/pkg/spoke/managedcluster" @@ -255,22 +257,24 @@ func (o *SpokeAgentOptions) RunSpokeAgent(ctx context.Context, controllerContext o.ClusterHealthCheckPeriod, controllerContext.EventRecorder, ) - spokeClusterClient, err := clusterv1client.NewForConfig(controllerContext.KubeConfig) if err != nil { return err } spokeClusterInformers := clusterv1informers.NewSharedInformerFactory(spokeClusterClient, 10*time.Minute) - // create managedClusterClaimController to sync cluster claims - managedClusterClaimController := managedcluster.NewManagedClusterClaimController( - o.ClusterName, - o.MaxCustomClusterClaims, - hubClusterClient, - hubClusterInformerFactory.Cluster().V1().ManagedClusters(), - spokeClusterInformers.Cluster().V1alpha1().ClusterClaims(), - controllerContext.EventRecorder, - ) + var managedClusterClaimController factory.Controller + if features.DefaultMutableFeatureGate.Enabled(features.ClusterClaim) { + // create managedClusterClaimController to sync cluster claims + managedClusterClaimController = managedcluster.NewManagedClusterClaimController( + o.ClusterName, + o.MaxCustomClusterClaims, + hubClusterClient, + hubClusterInformerFactory.Cluster().V1().ManagedClusters(), + spokeClusterInformers.Cluster().V1alpha1().ClusterClaims(), + controllerContext.EventRecorder, + ) + } go hubKubeInformerFactory.Start(ctx.Done()) go hubClusterInformerFactory.Start(ctx.Done()) @@ -282,7 +286,9 @@ func (o *SpokeAgentOptions) RunSpokeAgent(ctx context.Context, controllerContext go managedClusterJoiningController.Run(ctx, 1) go managedClusterLeaseController.Run(ctx, 1) go managedClusterHealthCheckController.Run(ctx, 1) - go managedClusterClaimController.Run(ctx, 1) + if features.DefaultMutableFeatureGate.Enabled(features.ClusterClaim) { + go managedClusterClaimController.Run(ctx, 1) + } <-ctx.Done() return nil @@ -290,6 +296,7 @@ func (o *SpokeAgentOptions) RunSpokeAgent(ctx context.Context, controllerContext // AddFlags registers flags for Agent func (o *SpokeAgentOptions) AddFlags(fs *pflag.FlagSet) { + features.DefaultMutableFeatureGate.AddFlag(fs) fs.StringVar(&o.ClusterName, "cluster-name", o.ClusterName, "If non-empty, will use as cluster name instead of generated random name.") fs.StringVar(&o.BootstrapKubeconfig, "bootstrap-kubeconfig", o.BootstrapKubeconfig,