diff --git a/cmd/kube-controller-manager/app/controllermanager.go b/cmd/kube-controller-manager/app/controllermanager.go index 2938d1d759f..fb6546e58d0 100644 --- a/cmd/kube-controller-manager/app/controllermanager.go +++ b/cmd/kube-controller-manager/app/controllermanager.go @@ -422,49 +422,58 @@ const ( // paired to their InitFunc. This allows for structured downstream composition and subdivision. func NewControllerInitializers(loopMode ControllerLoopMode) map[string]InitFunc { controllers := map[string]InitFunc{} - controllers["endpoint"] = startEndpointController - controllers["endpointslice"] = startEndpointSliceController - controllers["endpointslicemirroring"] = startEndpointSliceMirroringController - controllers["replicationcontroller"] = startReplicationController - controllers["podgc"] = startPodGCController - controllers["resourcequota"] = startResourceQuotaController - controllers["namespace"] = startNamespaceController - controllers["serviceaccount"] = startServiceAccountController - controllers["garbagecollector"] = startGarbageCollectorController - controllers["daemonset"] = startDaemonSetController - controllers["job"] = startJobController - controllers["deployment"] = startDeploymentController - controllers["replicaset"] = startReplicaSetController - controllers["horizontalpodautoscaling"] = startHPAController - controllers["disruption"] = startDisruptionController - controllers["statefulset"] = startStatefulSetController - controllers["cronjob"] = startCronJobController - controllers["csrsigning"] = startCSRSigningController - controllers["csrapproving"] = startCSRApprovingController - controllers["csrcleaner"] = startCSRCleanerController - controllers["ttl"] = startTTLController - controllers["bootstrapsigner"] = startBootstrapSignerController - controllers["tokencleaner"] = startTokenCleanerController - controllers["nodeipam"] = startNodeIpamController - controllers["nodelifecycle"] = startNodeLifecycleController + + // All of the controllers must have unique names, or else we will explode. + register := func(name string, fn InitFunc) { + if _, found := controllers[name]; found { + panic(fmt.Sprintf("controller name %q was registered twice", name)) + } + 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) if loopMode == IncludeCloudLoops { - controllers["service"] = startServiceController - controllers["route"] = startRouteController - controllers["cloud-node-lifecycle"] = startCloudNodeLifecycleController + register("service", startServiceController) + register("route", startRouteController) + register("cloud-node-lifecycle", startCloudNodeLifecycleController) // TODO: volume controller into the IncludeCloudLoops only set. } - controllers["persistentvolume-binder"] = startPersistentVolumeBinderController - controllers["attachdetach"] = startAttachDetachController - controllers["persistentvolume-expander"] = startVolumeExpandController - controllers["clusterrole-aggregation"] = startClusterRoleAggregrationController - controllers["pvc-protection"] = startPVCProtectionController - controllers["pv-protection"] = startPVProtectionController - controllers["ttl-after-finished"] = startTTLAfterFinishedController - controllers["root-ca-cert-publisher"] = startRootCACertPublisher - controllers["ephemeral-volume"] = startEphemeralVolumeController + 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) if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.APIServerIdentity) && utilfeature.DefaultFeatureGate.Enabled(genericfeatures.StorageVersionAPI) { - controllers["storage-version-gc"] = startStorageVersionGCController + register("storage-version-gc", startStorageVersionGCController) } return controllers