diff --git a/charts/openyurt/templates/yurt-manager.yaml b/charts/openyurt/templates/yurt-manager.yaml index bffaf307f3b..3a9c7da8497 100644 --- a/charts/openyurt/templates/yurt-manager.yaml +++ b/charts/openyurt/templates/yurt-manager.yaml @@ -58,6 +58,9 @@ spec: - --logtostderr=true - --v={{ .Values.yurtManager.log.level }} - --working-namespace={{ include "openyurt.namespace" . }} + {{- if .Values.yurtManager.controllers }} + - --controllers={{ .Values.yurtManager.controllers }} + {{- end }} command: - /usr/local/bin/yurt-manager image: {{ .Values.yurtManager.image.repository }}:{{ .Values.yurtManager.image.tag }} diff --git a/charts/openyurt/values.yaml b/charts/openyurt/values.yaml index 0441601d437..17d123892eb 100644 --- a/charts/openyurt/values.yaml +++ b/charts/openyurt/values.yaml @@ -51,6 +51,8 @@ yurtManager: port: 10270 metrics: port: 10271 + # format should be "foo,-bar,*" + controllers: "" healthProbe: port: 10272 # resources of yurt-manager container diff --git a/cmd/yurt-manager/app/manager.go b/cmd/yurt-manager/app/manager.go index 77bcd8cb335..5c4be910b9e 100644 --- a/cmd/yurt-manager/app/manager.go +++ b/cmd/yurt-manager/app/manager.go @@ -186,7 +186,7 @@ func Run(c *config.CompletedConfig, stopCh <-chan struct{}) error { } setupLog.Info("setup webhook") - if err = webhook.SetupWithManager(mgr); err != nil { + if err = webhook.SetupWithManager(c, mgr); err != nil { setupLog.Error(err, "unable to setup webhook") os.Exit(1) } diff --git a/cmd/yurt-manager/app/options/generic.go b/cmd/yurt-manager/app/options/generic.go index 06dc6707d24..c271b766e4e 100644 --- a/cmd/yurt-manager/app/options/generic.go +++ b/cmd/yurt-manager/app/options/generic.go @@ -23,6 +23,8 @@ import ( "github.com/openyurtio/openyurt/pkg/features" ) +const enableAllController = "*" + type GenericOptions struct { *config.GenericConfiguration } @@ -38,6 +40,7 @@ func NewGenericOptions() *GenericOptions { RestConfigQPS: 30, RestConfigBurst: 50, WorkingNamespace: "kube-system", + Controllers: []string{enableAllController}, }, } } @@ -67,6 +70,7 @@ func (o *GenericOptions) ApplyTo(cfg *config.GenericConfiguration) error { cfg.RestConfigQPS = o.RestConfigQPS cfg.RestConfigBurst = o.RestConfigBurst cfg.WorkingNamespace = o.WorkingNamespace + cfg.Controllers = o.Controllers return nil } @@ -85,6 +89,8 @@ func (o *GenericOptions) AddFlags(fs *pflag.FlagSet) { fs.IntVar(&o.RestConfigQPS, "rest-config-qps", o.RestConfigQPS, "rest-config-qps.") fs.IntVar(&o.RestConfigBurst, "rest-config-burst", o.RestConfigBurst, "rest-config-burst.") fs.StringVar(&o.WorkingNamespace, "working-namespace", o.WorkingNamespace, "The namespace where the yurt-manager is working.") + fs.StringSliceVar(&o.Controllers, "controllers", o.Controllers, "A list of controllers to enable. "+ + "'*' enables all on-by-default controllers, 'foo' enables the controller named 'foo', '-foo' disables the controller named 'foo'.") features.DefaultMutableFeatureGate.AddFlag(fs) } diff --git a/pkg/controller/add_csrapprover.go b/pkg/controller/add_csrapprover.go index 9044684609e..e28a408b476 100644 --- a/pkg/controller/add_csrapprover.go +++ b/pkg/controller/add_csrapprover.go @@ -26,5 +26,5 @@ import ( // Note !!! func init() { - controllerAddFuncs = append(controllerAddFuncs, csrapprover.Add) + addController("csrapprover", csrapprover.Add) } diff --git a/pkg/controller/add_daemonpodupdater.go b/pkg/controller/add_daemonpodupdater.go index a3aed27d6a6..516f2d49264 100644 --- a/pkg/controller/add_daemonpodupdater.go +++ b/pkg/controller/add_daemonpodupdater.go @@ -26,5 +26,5 @@ import ( // Note !!! func init() { - controllerAddFuncs = append(controllerAddFuncs, daemonpodupdater.Add) + addController("daemonpodupdater", daemonpodupdater.Add) } diff --git a/pkg/controller/add_delegatelease.go b/pkg/controller/add_delegatelease.go index a264ce0542a..9f80b588215 100644 --- a/pkg/controller/add_delegatelease.go +++ b/pkg/controller/add_delegatelease.go @@ -21,5 +21,5 @@ import ( ) func init() { - controllerAddFuncs = append(controllerAddFuncs, delegatelease.Add) + addController("delegatelease", delegatelease.Add) } diff --git a/pkg/controller/add_gateway.go b/pkg/controller/add_gateway.go index c9ab9461e49..98cbc5f6576 100644 --- a/pkg/controller/add_gateway.go +++ b/pkg/controller/add_gateway.go @@ -27,5 +27,6 @@ import ( // Note !!! func init() { - controllerAddFuncs = append(controllerAddFuncs, gateway.Add, service.Add) + addController("gateway", gateway.Add) + addController("service", service.Add) } diff --git a/pkg/controller/add_nodepool.go b/pkg/controller/add_nodepool.go index ed9e0fc3594..4b09706621f 100644 --- a/pkg/controller/add_nodepool.go +++ b/pkg/controller/add_nodepool.go @@ -26,5 +26,5 @@ import ( // Note !!! func init() { - controllerAddFuncs = append(controllerAddFuncs, nodepool.Add) + addController("nodepool", nodepool.Add) } diff --git a/pkg/controller/add_podbinding.go b/pkg/controller/add_podbinding.go index 32d7e6d5cc0..8c025ffa6d9 100644 --- a/pkg/controller/add_podbinding.go +++ b/pkg/controller/add_podbinding.go @@ -21,5 +21,5 @@ import ( ) func init() { - controllerAddFuncs = append(controllerAddFuncs, podbinding.Add) + addController("podbinding", podbinding.Add) } diff --git a/pkg/controller/add_poolcoordinatorcert.go b/pkg/controller/add_poolcoordinatorcert.go index 54e3e6b60a1..852e011cc73 100644 --- a/pkg/controller/add_poolcoordinatorcert.go +++ b/pkg/controller/add_poolcoordinatorcert.go @@ -26,5 +26,5 @@ import ( // Note !!! func init() { - controllerAddFuncs = append(controllerAddFuncs, poolcoordinatorcert.Add) + addController("poolcoordinatorcert", poolcoordinatorcert.Add) } diff --git a/pkg/controller/add_servicetopology_endpoints.go b/pkg/controller/add_servicetopology_endpoints.go index 55efeb462bd..722ec545807 100644 --- a/pkg/controller/add_servicetopology_endpoints.go +++ b/pkg/controller/add_servicetopology_endpoints.go @@ -26,5 +26,5 @@ import ( // Note !!! func init() { - controllerAddFuncs = append(controllerAddFuncs, servicetopologyEndpoints.Add) + addController("servicetopologyEndpoints", servicetopologyEndpoints.Add) } diff --git a/pkg/controller/add_servicetopology_endpointslice.go b/pkg/controller/add_servicetopology_endpointslice.go index ce231d9ec16..d53214b8815 100644 --- a/pkg/controller/add_servicetopology_endpointslice.go +++ b/pkg/controller/add_servicetopology_endpointslice.go @@ -26,5 +26,5 @@ import ( // Note !!! func init() { - controllerAddFuncs = append(controllerAddFuncs, servicetopologyEndpointslice.Add) + addController("servicetopologyEndpointslice", servicetopologyEndpointslice.Add) } diff --git a/pkg/controller/add_staticpod.go b/pkg/controller/add_staticpod.go index eae1f74183e..96ee131f00b 100644 --- a/pkg/controller/add_staticpod.go +++ b/pkg/controller/add_staticpod.go @@ -26,5 +26,5 @@ import ( // Note !!! func init() { - controllerAddFuncs = append(controllerAddFuncs, staticpod.Add) + addController("staticpod", staticpod.Add) } diff --git a/pkg/controller/add_yurtappset.go b/pkg/controller/add_yurtappset.go index b990dcc0ddc..590c3ec6572 100644 --- a/pkg/controller/add_yurtappset.go +++ b/pkg/controller/add_yurtappset.go @@ -26,5 +26,5 @@ import ( // Note !!! func init() { - controllerAddFuncs = append(controllerAddFuncs, yurtappset.Add) + addController("yurtappset", yurtappset.Add) } diff --git a/pkg/controller/apis/config/types.go b/pkg/controller/apis/config/types.go index 82491ee259f..7fdabc66850 100644 --- a/pkg/controller/apis/config/types.go +++ b/pkg/controller/apis/config/types.go @@ -65,4 +65,10 @@ type GenericConfiguration struct { RestConfigQPS int RestConfigBurst int WorkingNamespace string + // Controllers is the list of controllers to enable or disable + // '*' means "all enabled by default controllers" + // 'foo' means "enable 'foo'" + // '-foo' means "disable 'foo'" + // first item for a particular name wins + Controllers []string } diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 7d22e5e3be3..924a8b29eaf 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -22,6 +22,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/manager" "github.com/openyurtio/openyurt/cmd/yurt-manager/app/config" + "github.com/openyurtio/openyurt/pkg/controller/util" ) // Note !!! @kadisi @@ -30,9 +31,13 @@ import ( // Don`t Change this Name !!!! @kadisi // TODO support feature gate @kadisi -var controllerAddFuncs []func(*config.CompletedConfig, manager.Manager) error +var controllerAddFuncs map[string]func(*config.CompletedConfig, manager.Manager) error -func init() { +func addController(name string, fn func(*config.CompletedConfig, manager.Manager) error) { + if controllerAddFuncs == nil { + controllerAddFuncs = make(map[string]func(*config.CompletedConfig, manager.Manager) error) + } + controllerAddFuncs[name] = fn } // If you want to add additional RBAC, enter it here !!! @kadisi @@ -42,7 +47,12 @@ func init() { func SetupWithManager(c *config.CompletedConfig, m manager.Manager) error { klog.InfoS("SetupWithManager", "len", len(controllerAddFuncs)) - for _, f := range controllerAddFuncs { + for controllerName, f := range controllerAddFuncs { + if !util.IsControllerEnabled(controllerName, c.ComponentConfig.Generic.Controllers) { + klog.Warningf("Controller %v is disabled", controllerName) + continue + } + if err := f(c, m); err != nil { if kindMatchErr, ok := err.(*meta.NoKindMatchError); ok { klog.Infof("CRD %v is not installed, its controller will perform noops!", kindMatchErr.GroupKind) diff --git a/pkg/controller/util/controller_utils.go b/pkg/controller/util/controller_utils.go new file mode 100644 index 00000000000..09879cbb825 --- /dev/null +++ b/pkg/controller/util/controller_utils.go @@ -0,0 +1,34 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package util + +// IsControllerEnabled check if a specified controller enabled or not. +func IsControllerEnabled(name string, controllers []string) bool { + for _, ctrl := range controllers { + if ctrl == name { + return true + } + if ctrl == "-"+name { + return false + } + if ctrl == "*" { + return true + } + } + + return false +} diff --git a/pkg/webhook/add_v1alpha1_gateway.go b/pkg/webhook/add_v1alpha1_gateway.go index 373640b8af5..c53a51ea3da 100644 --- a/pkg/webhook/add_v1alpha1_gateway.go +++ b/pkg/webhook/add_v1alpha1_gateway.go @@ -21,5 +21,5 @@ import ( ) func init() { - addWebhook(&v1alpha1.GatewayHandler{}) + addWebhook("gateway", &v1alpha1.GatewayHandler{}) } diff --git a/pkg/webhook/add_v1alpha1_nodepool.go b/pkg/webhook/add_v1alpha1_nodepool.go index 0cbcede9237..fdcd8c03a88 100644 --- a/pkg/webhook/add_v1alpha1_nodepool.go +++ b/pkg/webhook/add_v1alpha1_nodepool.go @@ -21,5 +21,5 @@ import ( ) func init() { - addWebhook(&v1alpha1.NodePoolHandler{}) + addWebhook("nodepool", &v1alpha1.NodePoolHandler{}) } diff --git a/pkg/webhook/add_v1alpha1_staticpod.go b/pkg/webhook/add_v1alpha1_staticpod.go index 1b707150a9c..d754b9bf1d1 100644 --- a/pkg/webhook/add_v1alpha1_staticpod.go +++ b/pkg/webhook/add_v1alpha1_staticpod.go @@ -21,5 +21,5 @@ import ( ) func init() { - addWebhook(&v1alpha1.StaticPodHandler{}) + addWebhook("staticpod", &v1alpha1.StaticPodHandler{}) } diff --git a/pkg/webhook/add_v1alpha1_yurtappset.go b/pkg/webhook/add_v1alpha1_yurtappset.go index 3d599284b0b..9ba4ed44a31 100644 --- a/pkg/webhook/add_v1alpha1_yurtappset.go +++ b/pkg/webhook/add_v1alpha1_yurtappset.go @@ -21,5 +21,5 @@ import ( ) func init() { - addWebhook(&v1alpha1.YurtAppSetHandler{}) + addWebhook("yurtappset", &v1alpha1.YurtAppSetHandler{}) } diff --git a/pkg/webhook/add_v1beta1_nodepool.go b/pkg/webhook/add_v1beta1_nodepool.go index 32e8d2653ba..f8d3a65d06f 100644 --- a/pkg/webhook/add_v1beta1_nodepool.go +++ b/pkg/webhook/add_v1beta1_nodepool.go @@ -21,5 +21,5 @@ import ( ) func init() { - addWebhook(&v1beta1.NodePoolHandler{}) + addWebhook("nodepool", &v1beta1.NodePoolHandler{}) } diff --git a/pkg/webhook/server.go b/pkg/webhook/server.go index 3b14f03a70c..c7b28d9521f 100644 --- a/pkg/webhook/server.go +++ b/pkg/webhook/server.go @@ -29,6 +29,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/webhook/admission" "github.com/openyurtio/openyurt/cmd/yurt-manager/app/config" + "github.com/openyurtio/openyurt/pkg/controller/util" webhookcontroller "github.com/openyurtio/openyurt/pkg/webhook/util/controller" "github.com/openyurtio/openyurt/pkg/webhook/util/health" ) @@ -40,33 +41,47 @@ type SetupWebhookWithManager interface { SetupWebhookWithManager(mgr ctrl.Manager) (string, string, error) } -var WebhookLists []SetupWebhookWithManager = make([]SetupWebhookWithManager, 0, 5) +var controllerWebhook map[string][]SetupWebhookWithManager var WebhookHandlerPath = make(map[string]struct{}) +func addWebhook(name string, handler SetupWebhookWithManager) { + if controllerWebhook == nil { + controllerWebhook = make(map[string][]SetupWebhookWithManager) + } + + if controllerWebhook[name] == nil { + controllerWebhook[name] = make([]SetupWebhookWithManager, 0) + } + + controllerWebhook[name] = append(controllerWebhook[name], handler) +} + // Note !!! @kadisi // Do not change the name of the file or the contents of the file !!!!!!!!!! // Note !!! -func addWebhook(w SetupWebhookWithManager) { - WebhookLists = append(WebhookLists, w) -} - -func SetupWithManager(mgr manager.Manager) error { - for _, s := range WebhookLists { - m, v, err := s.SetupWebhookWithManager(mgr) - if err != nil { - return fmt.Errorf("unable to create webhook %v", err) - } - if _, ok := WebhookHandlerPath[m]; ok { - panic(fmt.Errorf("webhook handler path %s duplicated", m)) +func SetupWithManager(c *config.CompletedConfig, mgr manager.Manager) error { + for controllerName, list := range controllerWebhook { + if !util.IsControllerEnabled(controllerName, c.ComponentConfig.Generic.Controllers) { + klog.Warningf("Webhook for %v is disabled", controllerName) + continue } - WebhookHandlerPath[m] = struct{}{} - klog.Infof("Add webhook mutate path %s", m) - if _, ok := WebhookHandlerPath[v]; ok { - panic(fmt.Errorf("webhook handler path %s duplicated", v)) + for _, s := range list { + m, v, err := s.SetupWebhookWithManager(mgr) + if err != nil { + return fmt.Errorf("unable to create webhook %v", err) + } + if _, ok := WebhookHandlerPath[m]; ok { + panic(fmt.Errorf("webhook handler path %s duplicated", m)) + } + WebhookHandlerPath[m] = struct{}{} + klog.Infof("Add webhook mutate path %s", m) + if _, ok := WebhookHandlerPath[v]; ok { + panic(fmt.Errorf("webhook handler path %s duplicated", v)) + } + WebhookHandlerPath[v] = struct{}{} + klog.Infof("Add webhook validate path %s", v) } - WebhookHandlerPath[v] = struct{}{} - klog.Infof("Add webhook validate path %s", v) } return nil }