diff --git a/pkg/controller/kubelet-config/kubelet_config_controller.go b/pkg/controller/kubelet-config/kubelet_config_controller.go index b824a8d490..a4d6535acf 100644 --- a/pkg/controller/kubelet-config/kubelet_config_controller.go +++ b/pkg/controller/kubelet-config/kubelet_config_controller.go @@ -138,6 +138,12 @@ func New( fgHandler: fgHandler, } + mcpInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: ctrl.addMachineConfigPool, + UpdateFunc: ctrl.updateMachineConfigPool, + DeleteFunc: ctrl.deleteMachineConfigPool, + }) + mkuInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: ctrl.addKubeletConfig, UpdateFunc: ctrl.updateKubeletConfig, @@ -317,6 +323,66 @@ func (ctrl *Controller) deleteKubeletConfig(obj interface{}) { } } +func (ctrl *Controller) addMachineConfigPool(obj interface{}) { + pool := obj.(*mcfgv1.MachineConfigPool) + klog.V(4).Infof("MachineConfigPool %s added, re-syncing kubelet config controller", pool.Name) + ctrl.requeueKubeletConfigsForPool() +} + +func (ctrl *Controller) updateMachineConfigPool(old, cur interface{}) { + oldPool := old.(*mcfgv1.MachineConfigPool) + curPool := cur.(*mcfgv1.MachineConfigPool) + if !reflect.DeepEqual(oldPool.Labels, curPool.Labels) { + klog.V(4).Infof("MachineConfigPool %s labels changed, re-syncing kubelet config controller", curPool.Name) + ctrl.requeueKubeletConfigsForPool() + } +} + +func (ctrl *Controller) deleteMachineConfigPool(obj interface{}) { + pool, ok := obj.(*mcfgv1.MachineConfigPool) + if !ok { + tombstone, ok := obj.(cache.DeletedFinalStateUnknown) + if !ok { + utilruntime.HandleError(fmt.Errorf("couldn't get object from tombstone %#v", obj)) + return + } + pool, ok = tombstone.Obj.(*mcfgv1.MachineConfigPool) + if !ok { + utilruntime.HandleError(fmt.Errorf("tombstone contained object that is not a MachineConfigPool %#v", obj)) + return + } + } + klog.V(4).Infof("MachineConfigPool %s deleted", pool.Name) +} + +// requeueKubeletConfigsForPool triggers reconciliation of all kubelet-related +// controllers so that generated MachineConfigs are created for any new or +// updated MachineConfigPool. +func (ctrl *Controller) requeueKubeletConfigsForPool() { + kcs, err := ctrl.mckLister.List(labels.Everything()) + if err != nil { + utilruntime.HandleError(fmt.Errorf("could not list KubeletConfigs for MCP re-sync: %w", err)) + } else { + for _, kc := range kcs { + ctrl.enqueueKubeletConfig(kc) + } + } + + features, err := ctrl.featLister.Get(ctrlcommon.ClusterFeatureInstanceName) + if err == nil { + ctrl.enqueueFeature(features) + } else if !macherrors.IsNotFound(err) { + utilruntime.HandleError(fmt.Errorf("could not get FeatureGate for MCP re-sync: %w", err)) + } + + nodeConfig, err := ctrl.nodeConfigLister.Get(ctrlcommon.ClusterNodeInstanceName) + if err == nil { + ctrl.enqueueNodeConfig(nodeConfig) + } else if !macherrors.IsNotFound(err) { + utilruntime.HandleError(fmt.Errorf("could not get NodeConfig for MCP re-sync: %w", err)) + } +} + func (ctrl *Controller) cascadeDelete(cfg *mcfgv1.KubeletConfig) error { if len(cfg.GetFinalizers()) == 0 { return nil