diff --git a/cmd/kube-controller-manager/app/controllermanager.go b/cmd/kube-controller-manager/app/controllermanager.go index 1d45611b15d..6637e749ee4 100644 --- a/cmd/kube-controller-manager/app/controllermanager.go +++ b/cmd/kube-controller-manager/app/controllermanager.go @@ -73,6 +73,7 @@ import ( "k8s.io/kubernetes/cmd/kube-controller-manager/app/config" "k8s.io/kubernetes/cmd/kube-controller-manager/app/options" + "k8s.io/kubernetes/cmd/kube-controller-manager/names" kubectrlmgrconfig "k8s.io/kubernetes/pkg/controller/apis/config" serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount" "k8s.io/kubernetes/pkg/serviceaccount" @@ -135,7 +136,7 @@ controller, and serviceaccounts controller.`, } cliflag.PrintFlags(cmd.Flags()) - c, err := s.Config(KnownControllers(), ControllersDisabledByDefault.List()) + c, err := s.Config(KnownControllers(), ControllersDisabledByDefault.List(), names.KCMControllerAliases()) if err != nil { return err } @@ -154,7 +155,7 @@ controller, and serviceaccounts controller.`, } fs := cmd.Flags() - namedFlagSets := s.Flags(KnownControllers(), ControllersDisabledByDefault.List()) + namedFlagSets := s.Flags(KnownControllers(), ControllersDisabledByDefault.List(), names.KCMControllerAliases()) verflag.AddFlags(namedFlagSets.FlagSet("global")) globalflag.AddGlobalFlags(namedFlagSets.FlagSet("global"), cmd.Name(), logs.SkipLoggingConfigurationFlags()) registerLegacyGlobalFlags(namedFlagSets) @@ -407,7 +408,7 @@ func KnownControllers() []string { // first to ensure that the SA tokens for future controllers will exist. Think very carefully before adding // to this list. ret.Insert( - saTokenControllerName, + names.ServiceAccountTokenController, ) return ret.List() @@ -415,12 +416,8 @@ func KnownControllers() []string { // ControllersDisabledByDefault is the set of controllers which is disabled by default var ControllersDisabledByDefault = sets.NewString( - "bootstrapsigner", - "tokencleaner", -) - -const ( - saTokenControllerName = "serviceaccount-token" + names.BootstrapSignerController, + names.TokenCleanerController, ) // NewControllerInitializers is a public map of named controller groups (you can start more than one in an init func) @@ -436,55 +433,55 @@ func NewControllerInitializers(loopMode ControllerLoopMode) map[string]InitFunc controllers[name] = fn } - register("endpoint", startEndpointController) - register("endpointslice", startEndpointSliceController) - register("endpointslicemirroring", startEndpointSliceMirroringController) - register("replicationcontroller", startReplicationController) - register("podgc", startPodGCController) - register("resourcequota", startResourceQuotaController) - register("namespace", startNamespaceController) - register("serviceaccount", startServiceAccountController) - register("garbagecollector", startGarbageCollectorController) - register("daemonset", startDaemonSetController) - register("job", startJobController) - register("deployment", startDeploymentController) - register("replicaset", startReplicaSetController) - register("horizontalpodautoscaling", startHPAController) - register("disruption", startDisruptionController) - register("statefulset", startStatefulSetController) - register("cronjob", startCronJobController) - register("csrsigning", startCSRSigningController) - register("csrapproving", startCSRApprovingController) - register("csrcleaner", startCSRCleanerController) - register("ttl", startTTLController) - register("bootstrapsigner", startBootstrapSignerController) - register("tokencleaner", startTokenCleanerController) - register("nodeipam", startNodeIpamController) - register("nodelifecycle", startNodeLifecycleController) + register(names.EndpointsController, startEndpointController) + register(names.EndpointSliceController, startEndpointSliceController) + register(names.EndpointSliceMirroringController, startEndpointSliceMirroringController) + register(names.ReplicationControllerController, startReplicationController) + register(names.PodGarbageCollectorController, startPodGCController) + register(names.ResourceQuotaController, startResourceQuotaController) + register(names.NamespaceController, startNamespaceController) + register(names.ServiceAccountController, startServiceAccountController) + register(names.GarbageCollectorController, startGarbageCollectorController) + register(names.DaemonSetController, startDaemonSetController) + register(names.JobController, startJobController) + register(names.DeploymentController, startDeploymentController) + register(names.ReplicaSetController, startReplicaSetController) + register(names.HorizontalPodAutoscalerController, startHPAController) + register(names.DisruptionController, startDisruptionController) + register(names.StatefulSetController, startStatefulSetController) + register(names.CronJobController, startCronJobController) + register(names.CertificateSigningRequestSigningController, startCSRSigningController) + register(names.CertificateSigningRequestApprovingController, startCSRApprovingController) + register(names.CertificateSigningRequestCleanerController, startCSRCleanerController) + register(names.TTLController, startTTLController) + register(names.BootstrapSignerController, startBootstrapSignerController) + register(names.TokenCleanerController, startTokenCleanerController) + register(names.NodeIpamController, startNodeIpamController) + register(names.NodeLifecycleController, startNodeLifecycleController) if loopMode == IncludeCloudLoops { - register("service", startServiceController) - register("route", startRouteController) - register("cloud-node-lifecycle", startCloudNodeLifecycleController) + register(names.ServiceController, startServiceController) + register(names.RouteController, startRouteController) + register(names.CloudNodeLifecycleController, startCloudNodeLifecycleController) // TODO: volume controller into the IncludeCloudLoops only set. } - register("persistentvolume-binder", startPersistentVolumeBinderController) - register("attachdetach", startAttachDetachController) - register("persistentvolume-expander", startVolumeExpandController) - register("clusterrole-aggregation", startClusterRoleAggregrationController) - register("pvc-protection", startPVCProtectionController) - register("pv-protection", startPVProtectionController) - register("ttl-after-finished", startTTLAfterFinishedController) - register("root-ca-cert-publisher", startRootCACertPublisher) - register("ephemeral-volume", startEphemeralVolumeController) + register(names.PersistentVolumeBinderController, startPersistentVolumeBinderController) + register(names.PersistentVolumeAttachDetachController, startAttachDetachController) + register(names.PersistentVolumeExpanderController, startVolumeExpandController) + register(names.ClusterRoleAggregationController, startClusterRoleAggregrationController) + register(names.PersistentVolumeClaimProtectionController, startPVCProtectionController) + register(names.PersistentVolumeProtectionController, startPVProtectionController) + register(names.TTLAfterFinishedController, startTTLAfterFinishedController) + register(names.RootCACertificatePublisherController, startRootCACertPublisher) + register(names.EphemeralVolumeController, startEphemeralVolumeController) if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.APIServerIdentity) && utilfeature.DefaultFeatureGate.Enabled(genericfeatures.StorageVersionAPI) { - register("storage-version-gc", startStorageVersionGCController) + register(names.StorageVersionGarbageCollectorController, startStorageVersionGCController) } if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.DynamicResourceAllocation) { - register("resource-claim-controller", startResourceClaimController) + register(names.ResourceClaimController, startResourceClaimController) } if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.LegacyServiceAccountTokenCleanUp) { - register("legacy-service-account-token-cleaner", startLegacySATokenCleaner) + register(names.LegacyServiceAccountTokenCleanerController, startLegacySATokenCleaner) } return controllers @@ -655,13 +652,13 @@ type serviceAccountTokenControllerStarter struct { func (c serviceAccountTokenControllerStarter) startServiceAccountTokenController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) { logger := klog.FromContext(ctx) - if !controllerContext.IsControllerEnabled(saTokenControllerName) { - logger.Info("Warning: controller is disabled", "controller", saTokenControllerName) + if !controllerContext.IsControllerEnabled(names.ServiceAccountTokenController) { + logger.Info("Warning: controller is disabled", "controller", names.ServiceAccountTokenController) return nil, false, nil } if len(controllerContext.ComponentConfig.SAController.ServiceAccountKeyFile) == 0 { - logger.Info("Controller is disabled because there is no private key", "controller", saTokenControllerName) + logger.Info("Controller is disabled because there is no private key", "controller", names.ServiceAccountTokenController) return nil, false, nil } privateKey, err := keyutil.PrivateKeyFromFile(controllerContext.ComponentConfig.SAController.ServiceAccountKeyFile) diff --git a/cmd/kube-controller-manager/app/controllermanager_test.go b/cmd/kube-controller-manager/app/controllermanager_test.go new file mode 100644 index 00000000000..3998e0d8a88 --- /dev/null +++ b/cmd/kube-controller-manager/app/controllermanager_test.go @@ -0,0 +1,92 @@ +/* +Copyright 2023 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 app + +import ( + "regexp" + "strings" + "testing" + + "k8s.io/apimachinery/pkg/util/sets" + + "k8s.io/kubernetes/cmd/kube-controller-manager/names" +) + +func TestControllerNamesConsistency(t *testing.T) { + controllerNameRegexp := regexp.MustCompile("^[a-z]([-a-z]*[a-z])?$") + + for _, name := range KnownControllers() { + if !controllerNameRegexp.MatchString(name) { + t.Errorf("name consistency check failed: controller %q must consist of lower case alphabetic characters or '-', and must start and end with an alphabetic character", name) + } + if !strings.HasSuffix(name, "-controller") { + t.Errorf("name consistency check failed: controller %q must have \"-controller\" suffix", name) + } + } +} + +func TestControllerNamesDeclaration(t *testing.T) { + declaredControllers := sets.New( + names.ServiceAccountTokenController, + names.EndpointsController, + names.EndpointSliceController, + names.EndpointSliceMirroringController, + names.ReplicationControllerController, + names.PodGarbageCollectorController, + names.ResourceQuotaController, + names.NamespaceController, + names.ServiceAccountController, + names.GarbageCollectorController, + names.DaemonSetController, + names.JobController, + names.DeploymentController, + names.ReplicaSetController, + names.HorizontalPodAutoscalerController, + names.DisruptionController, + names.StatefulSetController, + names.CronJobController, + names.CertificateSigningRequestSigningController, + names.CertificateSigningRequestApprovingController, + names.CertificateSigningRequestCleanerController, + names.TTLController, + names.BootstrapSignerController, + names.TokenCleanerController, + names.NodeIpamController, + names.NodeLifecycleController, + names.ServiceController, + names.RouteController, + names.CloudNodeLifecycleController, + names.PersistentVolumeBinderController, + names.PersistentVolumeAttachDetachController, + names.PersistentVolumeExpanderController, + names.ClusterRoleAggregationController, + names.PersistentVolumeClaimProtectionController, + names.PersistentVolumeProtectionController, + names.TTLAfterFinishedController, + names.RootCACertificatePublisherController, + names.EphemeralVolumeController, + names.StorageVersionGarbageCollectorController, + names.ResourceClaimController, + names.LegacyServiceAccountTokenCleanerController, + ) + + for _, name := range KnownControllers() { + if !declaredControllers.Has(name) { + t.Errorf("name declaration check failed: controller name %q should be declared in \"controller_names.go\" and added to this test", name) + } + } +} diff --git a/cmd/kube-controller-manager/app/options/options.go b/cmd/kube-controller-manager/app/options/options.go index 1b92c0a5ff4..f57202b81c0 100644 --- a/cmd/kube-controller-manager/app/options/options.go +++ b/cmd/kube-controller-manager/app/options/options.go @@ -224,9 +224,9 @@ func NewDefaultComponentConfig() (kubectrlmgrconfig.KubeControllerManagerConfigu } // Flags returns flags for a specific KubeController by section name -func (s *KubeControllerManagerOptions) Flags(allControllers []string, disabledByDefaultControllers []string) cliflag.NamedFlagSets { +func (s *KubeControllerManagerOptions) Flags(allControllers []string, disabledByDefaultControllers []string, controllerAliases map[string]string) cliflag.NamedFlagSets { fss := cliflag.NamedFlagSets{} - s.Generic.AddFlags(&fss, allControllers, disabledByDefaultControllers) + s.Generic.AddFlags(&fss, allControllers, disabledByDefaultControllers, controllerAliases) s.KubeCloudShared.AddFlags(fss.FlagSet("generic")) s.ServiceController.AddFlags(fss.FlagSet("service controller")) @@ -271,8 +271,8 @@ func (s *KubeControllerManagerOptions) Flags(allControllers []string, disabledBy } // ApplyTo fills up controller manager config with options. -func (s *KubeControllerManagerOptions) ApplyTo(c *kubecontrollerconfig.Config) error { - if err := s.Generic.ApplyTo(&c.ComponentConfig.Generic); err != nil { +func (s *KubeControllerManagerOptions) ApplyTo(c *kubecontrollerconfig.Config, allControllers []string, disabledByDefaultControllers []string, controllerAliases map[string]string) error { + if err := s.Generic.ApplyTo(&c.ComponentConfig.Generic, allControllers, disabledByDefaultControllers, controllerAliases); err != nil { return err } if err := s.KubeCloudShared.ApplyTo(&c.ComponentConfig.KubeCloudShared); err != nil { @@ -371,10 +371,10 @@ func (s *KubeControllerManagerOptions) ApplyTo(c *kubecontrollerconfig.Config) e } // Validate is used to validate the options and config before launching the controller manager -func (s *KubeControllerManagerOptions) Validate(allControllers []string, disabledByDefaultControllers []string) error { +func (s *KubeControllerManagerOptions) Validate(allControllers []string, disabledByDefaultControllers []string, controllerAliases map[string]string) error { var errs []error - errs = append(errs, s.Generic.Validate(allControllers, disabledByDefaultControllers)...) + errs = append(errs, s.Generic.Validate(allControllers, disabledByDefaultControllers, controllerAliases)...) errs = append(errs, s.KubeCloudShared.Validate()...) errs = append(errs, s.AttachDetachController.Validate()...) errs = append(errs, s.CSRSigningController.Validate()...) @@ -413,8 +413,8 @@ func (s *KubeControllerManagerOptions) Validate(allControllers []string, disable } // Config return a controller manager config objective -func (s KubeControllerManagerOptions) Config(allControllers []string, disabledByDefaultControllers []string) (*kubecontrollerconfig.Config, error) { - if err := s.Validate(allControllers, disabledByDefaultControllers); err != nil { +func (s KubeControllerManagerOptions) Config(allControllers []string, disabledByDefaultControllers []string, controllerAliases map[string]string) (*kubecontrollerconfig.Config, error) { + if err := s.Validate(allControllers, disabledByDefaultControllers, controllerAliases); err != nil { return nil, err } @@ -446,7 +446,7 @@ func (s KubeControllerManagerOptions) Config(allControllers []string, disabledBy EventBroadcaster: eventBroadcaster, EventRecorder: eventRecorder, } - if err := s.ApplyTo(c); err != nil { + if err := s.ApplyTo(c, allControllers, disabledByDefaultControllers, controllerAliases); err != nil { return nil, err } s.Metrics.Apply() diff --git a/cmd/kube-controller-manager/app/options/options_test.go b/cmd/kube-controller-manager/app/options/options_test.go index 9940b9fe532..335e97b600c 100644 --- a/cmd/kube-controller-manager/app/options/options_test.go +++ b/cmd/kube-controller-manager/app/options/options_test.go @@ -166,7 +166,7 @@ var args = []string{ func TestAddFlags(t *testing.T) { fs := pflag.NewFlagSet("addflagstest", pflag.ContinueOnError) s, _ := NewKubeControllerManagerOptions() - for _, f := range s.Flags([]string{""}, []string{""}).FlagSets { + for _, f := range s.Flags([]string{""}, []string{""}, nil).FlagSets { fs.AddFlagSet(f) } @@ -457,7 +457,7 @@ func TestApplyTo(t *testing.T) { fs := pflag.NewFlagSet("addflagstest", pflag.ContinueOnError) s, _ := NewKubeControllerManagerOptions() // flag set to parse the args that are required to start the kube controller manager - for _, f := range s.Flags([]string{""}, []string{""}).FlagSets { + for _, f := range s.Flags([]string{""}, []string{""}, nil).FlagSets { fs.AddFlagSet(f) } @@ -648,7 +648,7 @@ func TestApplyTo(t *testing.T) { sort.Sort(sortedGCIgnoredResources(expected.ComponentConfig.GarbageCollectorController.GCIgnoredResources)) c := &kubecontrollerconfig.Config{} - s.ApplyTo(c) + s.ApplyTo(c, []string{""}, []string{""}, nil) if !reflect.DeepEqual(expected.ComponentConfig, c.ComponentConfig) { t.Errorf("Got different configuration than expected.\nDifference detected on:\n%s", cmp.Diff(expected.ComponentConfig, c.ComponentConfig)) @@ -1270,11 +1270,55 @@ func TestValidateControllerManagerOptions(t *testing.T) { opts.EndpointSliceController.MaxEndpointsPerSlice = 1001 // max endpoints per slice should be a positive integer <= 1000 - if err := opts.Validate([]string{"*"}, []string{""}); err == nil { + if err := opts.Validate([]string{"*"}, []string{""}, nil); err == nil { t.Error("expected error, no error found") } } +func TestControllerManagerAliases(t *testing.T) { + opts, err := NewKubeControllerManagerOptions() + if err != nil { + t.Errorf("expected no error, error found %+v", err) + } + opts.Generic.Controllers = []string{"deployment", "-job", "-cronjob-controller", "podgc", "token-cleaner-controller"} + expectedControllers := []string{"deployment-controller", "-job-controller", "-cronjob-controller", "pod-garbage-collector-controller", "token-cleaner-controller"} + + allControllers := []string{ + "bootstrap-signer-controller", + "job-controller", + "deployment-controller", + "cronjob-controller", + "namespace-controller", + "pod-garbage-collector-controller", + "token-cleaner-controller", + } + disabledByDefaultControllers := []string{ + "bootstrap-signer-controller", + "token-cleaner-controller", + } + controllerAliases := map[string]string{ + "bootstrapsigner": "bootstrap-signer-controller", + "job": "job-controller", + "deployment": "deployment-controller", + "cronjob": "cronjob-controller", + "namespace": "namespace-controller", + "podgc": "pod-garbage-collector-controller", + "tokencleaner": "token-cleaner-controller", + } + + if err := opts.Validate(allControllers, disabledByDefaultControllers, controllerAliases); err != nil { + t.Errorf("expected no error, error found %v", err) + } + + cfg := &kubecontrollerconfig.Config{} + if err := opts.ApplyTo(cfg, allControllers, disabledByDefaultControllers, controllerAliases); err != nil { + t.Errorf("expected no error, error found %v", err) + } + if !reflect.DeepEqual(cfg.ComponentConfig.Generic.Controllers, expectedControllers) { + t.Errorf("controller aliases not resolved correctly, expected %+v, got %+v", expectedControllers, cfg.ComponentConfig.Generic.Controllers) + } +} + type sortedGCIgnoredResources []garbagecollectorconfig.GroupResource func (r sortedGCIgnoredResources) Len() int { diff --git a/cmd/kube-controller-manager/app/testing/testserver.go b/cmd/kube-controller-manager/app/testing/testserver.go index 69a631920a5..0af0f2c0709 100644 --- a/cmd/kube-controller-manager/app/testing/testserver.go +++ b/cmd/kube-controller-manager/app/testing/testserver.go @@ -28,11 +28,12 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" restclient "k8s.io/client-go/rest" + "k8s.io/klog/v2" + "k8s.io/kubernetes/cmd/kube-controller-manager/app" kubecontrollerconfig "k8s.io/kubernetes/cmd/kube-controller-manager/app/config" "k8s.io/kubernetes/cmd/kube-controller-manager/app/options" - - "k8s.io/klog/v2" + "k8s.io/kubernetes/cmd/kube-controller-manager/names" ) // TearDownFunc is to be called to tear down a test server. @@ -89,8 +90,8 @@ func StartTestServer(ctx context.Context, customFlags []string) (result TestServ if err != nil { return TestServer{}, err } - all, disabled := app.KnownControllers(), app.ControllersDisabledByDefault.List() - namedFlagSets := s.Flags(all, disabled) + all, disabled, aliases := app.KnownControllers(), app.ControllersDisabledByDefault.List(), names.KCMControllerAliases() + namedFlagSets := s.Flags(all, disabled, aliases) for _, f := range namedFlagSets.FlagSets { fs.AddFlagSet(f) } @@ -106,7 +107,7 @@ func StartTestServer(ctx context.Context, customFlags []string) (result TestServ logger.Info("kube-controller-manager will listen securely", "port", s.SecureServing.BindPort) } - config, err := s.Config(all, disabled) + config, err := s.Config(all, disabled, aliases) if err != nil { return result, fmt.Errorf("failed to create config from options: %v", err) } diff --git a/cmd/kube-controller-manager/names/controller_names.go b/cmd/kube-controller-manager/names/controller_names.go new file mode 100644 index 00000000000..1042569588e --- /dev/null +++ b/cmd/kube-controller-manager/names/controller_names.go @@ -0,0 +1,141 @@ +/* +Copyright 2023 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 names + +// Canonical controller names +// +// NAMING CONVENTIONS +// 1. naming should be consistent across the controllers +// 2. use of shortcuts should be avoided, unless they are well-known non-Kubernetes shortcuts +// 3. Kubernetes' resources should be written together without a hyphen ("-") +// +// CHANGE POLICY +// The controller names should be treated as IDs. +// They can only be changed if absolutely necessary. For example if an inappropriate name was chosen in the past, or if the scope of the controller changes. +// When a name is changed, the old name should be aliased in KCMControllerAliases, while preserving all old aliases. +// This is done to achieve backwards compatibility +// +// USE CASES +// The following places should use the controller name constants, when: +// 1. registering a controller in app.NewControllerInitializers or app.KnownControllers: +// 1.1. disabling a controller by default in app.ControllersDisabledByDefault +// 1.2. checking if IsControllerEnabled +// 1.3. defining an alias in KCMControllerAliases (for backwards compatibility only) +// 2. used anywhere inside the controller itself: +// 2.1. [TODO] logger component should be configured with the controller name by calling LoggerWithName +// 2.2. [TODO] logging should use a canonical controller name when referencing a controller (Eg. Starting X, Shutting down X) +// 2.3. [TODO] emitted events should have an EventSource.Component set to the controller name (usually when initializing an EventRecorder) +// 2.4. [TODO] registering ControllerManagerMetrics with ControllerStarted and ControllerStopped +// 2.5. [TODO] calling WaitForNamedCacheSync +// 3. defining controller options for "--help" command or generated documentation +// 3.1. controller name should be used to create a pflag.FlagSet when registering controller options (the name is rendered in a controller flag group header) +// 3.2. when defined flag's help mentions a controller name +// 4. defining a new service account for a new controller (old controllers may have inconsistent service accounts to stay backwards compatible) +const ( + ServiceAccountTokenController = "serviceaccount-token-controller" + EndpointsController = "endpoints-controller" + EndpointSliceController = "endpointslice-controller" + EndpointSliceMirroringController = "endpointslice-mirroring-controller" + ReplicationControllerController = "replicationcontroller-controller" + PodGarbageCollectorController = "pod-garbage-collector-controller" + ResourceQuotaController = "resourcequota-controller" + NamespaceController = "namespace-controller" + ServiceAccountController = "serviceaccount-controller" + GarbageCollectorController = "garbage-collector-controller" + DaemonSetController = "daemonset-controller" + JobController = "job-controller" + DeploymentController = "deployment-controller" + ReplicaSetController = "replicaset-controller" + HorizontalPodAutoscalerController = "horizontal-pod-autoscaler-controller" + DisruptionController = "disruption-controller" + StatefulSetController = "statefulset-controller" + CronJobController = "cronjob-controller" + CertificateSigningRequestSigningController = "certificatesigningrequest-signing-controller" + CertificateSigningRequestApprovingController = "certificatesigningrequest-approving-controller" + CertificateSigningRequestCleanerController = "certificatesigningrequest-cleaner-controller" + TTLController = "ttl-controller" + BootstrapSignerController = "bootstrap-signer-controller" + TokenCleanerController = "token-cleaner-controller" + NodeIpamController = "node-ipam-controller" + NodeLifecycleController = "node-lifecycle-controller" + ServiceController = "service-controller" + RouteController = "route-controller" + CloudNodeLifecycleController = "cloud-node-lifecycle-controller" + PersistentVolumeBinderController = "persistentvolume-binder-controller" + PersistentVolumeAttachDetachController = "persistentvolume-attach-detach-controller" + PersistentVolumeExpanderController = "persistentvolume-expander-controller" + ClusterRoleAggregationController = "clusterrole-aggregation-controller" + PersistentVolumeClaimProtectionController = "persistentvolumeclaim-protection-controller" + PersistentVolumeProtectionController = "persistentvolume-protection-controller" + TTLAfterFinishedController = "ttl-after-finished-controller" + RootCACertificatePublisherController = "root-ca-certificate-publisher-controller" + EphemeralVolumeController = "ephemeral-volume-controller" + StorageVersionGarbageCollectorController = "storageversion-garbage-collector-controller" + ResourceClaimController = "resourceclaim-controller" + LegacyServiceAccountTokenCleanerController = "legacy-serviceaccount-token-cleaner-controller" +) + +// KCMControllerAliases returns a mapping of aliases to canonical controller names +// +// These aliases ensure backwards compatibility and should never be removed! +// Only addition of new aliases is allowed, and only when a canonical name is changed (please see CHANGE POLICY of controller names) +func KCMControllerAliases() map[string]string { + // return a new reference to achieve immutability of the mapping + return map[string]string{ + "serviceaccount-token": ServiceAccountTokenController, + "endpoint": EndpointsController, + "endpointslice": EndpointSliceController, + "endpointslicemirroring": EndpointSliceMirroringController, + "replicationcontroller": ReplicationControllerController, + "podgc": PodGarbageCollectorController, + "resourcequota": ResourceQuotaController, + "namespace": NamespaceController, + "serviceaccount": ServiceAccountController, + "garbagecollector": GarbageCollectorController, + "daemonset": DaemonSetController, + "job": JobController, + "deployment": DeploymentController, + "replicaset": ReplicaSetController, + "horizontalpodautoscaling": HorizontalPodAutoscalerController, + "disruption": DisruptionController, + "statefulset": StatefulSetController, + "cronjob": CronJobController, + "csrsigning": CertificateSigningRequestSigningController, + "csrapproving": CertificateSigningRequestApprovingController, + "csrcleaner": CertificateSigningRequestCleanerController, + "ttl": TTLController, + "bootstrapsigner": BootstrapSignerController, + "tokencleaner": TokenCleanerController, + "nodeipam": NodeIpamController, + "nodelifecycle": NodeLifecycleController, + "service": ServiceController, + "route": RouteController, + "cloud-node-lifecycle": CloudNodeLifecycleController, + "persistentvolume-binder": PersistentVolumeBinderController, + "attachdetach": PersistentVolumeAttachDetachController, + "persistentvolume-expander": PersistentVolumeExpanderController, + "clusterrole-aggregation": ClusterRoleAggregationController, + "pvc-protection": PersistentVolumeClaimProtectionController, + "pv-protection": PersistentVolumeProtectionController, + "ttl-after-finished": TTLAfterFinishedController, + "root-ca-cert-publisher": RootCACertificatePublisherController, + "ephemeral-volume": EphemeralVolumeController, + "storage-version-gc": StorageVersionGarbageCollectorController, + "resource-claim-controller": ResourceClaimController, + "legacy-service-account-token-cleaner": LegacyServiceAccountTokenCleanerController, + } +}