@@ -330,14 +330,43 @@ func (ctrl *Controller) handleFeatureErr(err error, key interface{}) {
330330 ctrl .featureQueue .AddAfter (key , 1 * time .Minute )
331331}
332332
333- func (ctrl * Controller ) generateOriginalKubeletConfig (role string , featureGate * configv1.FeatureGate ) (* ign3types.File , error ) {
334- cc , err := ctrl .ccLister .Get (ctrlcommon .ControllerConfigName )
333+ // generateOriginalKubeletConfigWithFeatureGates generates a KubeletConfig and ensure the correct feature gates are set
334+ // based on the given FeatureGate.
335+ func generateOriginalKubeletConfigWithFeatureGates (cc * mcfgv1.ControllerConfig , templatesDir , role string , features * configv1.FeatureGate ) (* kubeletconfigv1beta1.KubeletConfiguration , error ) {
336+ originalKubeletIgn , err := generateOriginalKubeletConfigIgn (cc , templatesDir , role , features )
335337 if err != nil {
336- return nil , fmt .Errorf ("could not get ControllerConfig %v" , err )
338+ return nil , fmt .Errorf ("could not generate the original Kubelet config ignition: %v" , err )
337339 }
340+ if originalKubeletIgn .Contents .Source == nil {
341+ return nil , fmt .Errorf ("the original Kubelet source string is empty: %v" , err )
342+ }
343+ dataURL , err := dataurl .DecodeString (* originalKubeletIgn .Contents .Source )
344+ if err != nil {
345+ return nil , fmt .Errorf ("could not decode the original Kubelet source string: %v" , err )
346+ }
347+ originalKubeConfig , err := decodeKubeletConfig (dataURL .Data )
348+ if err != nil {
349+ return nil , fmt .Errorf ("could not deserialize the Kubelet source: %v" , err )
350+ }
351+
352+ featureGates , err := generateFeatureMap (features , openshiftOnlyFeatureGates ... )
353+ if err != nil {
354+ return nil , fmt .Errorf ("could not generate features map: %v" , err )
355+ }
356+
357+ // Merge in Feature Gates.
358+ // If they are the same, this will be a no-op
359+ if err := mergo .Merge (& originalKubeConfig .FeatureGates , featureGates , mergo .WithOverride ); err != nil {
360+ return nil , fmt .Errorf ("could not merge feature gates: %v" , err )
361+ }
362+
363+ return originalKubeConfig , nil
364+ }
365+
366+ func generateOriginalKubeletConfigIgn (cc * mcfgv1.ControllerConfig , templatesDir , role string , featureGate * configv1.FeatureGate ) (* ign3types.File , error ) {
338367 // Render the default templates
339368 rc := & mtmpl.RenderConfig {ControllerConfigSpec : & cc .Spec , FeatureGate : featureGate }
340- generatedConfigs , err := mtmpl .GenerateMachineConfigsForRole (rc , role , ctrl . templatesDir )
369+ generatedConfigs , err := mtmpl .GenerateMachineConfigsForRole (rc , role , templatesDir )
341370 if err != nil {
342371 return nil , fmt .Errorf ("GenerateMachineConfigsforRole failed with error %s" , err )
343372 }
@@ -478,12 +507,6 @@ func (ctrl *Controller) syncKubeletConfig(key string) error {
478507 err := fmt .Errorf ("could not fetch FeatureGates: %v" , err )
479508 return ctrl .syncStatusOnly (cfg , err )
480509 }
481- featureGates , err := generateFeatureMap (features )
482- if err != nil {
483- err := fmt .Errorf ("could not generate FeatureMap: %v" , err )
484- glog .V (2 ).Infof ("%v" , err )
485- return ctrl .syncStatusOnly (cfg , err )
486- }
487510
488511 for _ , pool := range mcpPools {
489512 if pool .Spec .Configuration .Name == "" {
@@ -512,20 +535,14 @@ func (ctrl *Controller) syncKubeletConfig(key string) error {
512535 userDefinedSystemReserved := make (map [string ]string , 2 )
513536
514537 // Generate the original KubeletConfig
515- originalKubeletIgn , err := ctrl .generateOriginalKubeletConfig (role , features )
516- if err != nil {
517- return ctrl .syncStatusOnly (cfg , err , "could not generate the original Kubelet config: %v" , err )
518- }
519- if originalKubeletIgn .Contents .Source == nil {
520- return ctrl .syncStatusOnly (cfg , err , "the original Kubelet source string is empty: %v" , err )
521- }
522- dataURL , err := dataurl .DecodeString (* originalKubeletIgn .Contents .Source )
538+ cc , err := ctrl .ccLister .Get (ctrlcommon .ControllerConfigName )
523539 if err != nil {
524- return ctrl . syncStatusOnly ( cfg , err , "could not decode the original Kubelet source string: %v" , err )
540+ return fmt . Errorf ( "could not get ControllerConfig %v" , err )
525541 }
526- originalKubeConfig , err := decodeKubeletConfig (dataURL .Data )
542+
543+ originalKubeConfig , err := generateOriginalKubeletConfigWithFeatureGates (cc , ctrl .templatesDir , role , features )
527544 if err != nil {
528- return ctrl .syncStatusOnly (cfg , err , "could not deserialize the Kubelet source : %v" , err )
545+ return ctrl .syncStatusOnly (cfg , err , "could not get original kubelet config : %v" , err )
529546 }
530547
531548 // Get the default API Server Security Profile
@@ -561,29 +578,21 @@ func (ctrl *Controller) syncKubeletConfig(key string) error {
561578 delete (specKubeletConfig .SystemReserved , "cpu" )
562579 }
563580
581+ // FeatureGates must be set from the FeatureGate.
582+ // Remove them here to prevent the specKubeletConfig merge overwriting them.
583+ specKubeletConfig .FeatureGates = nil
584+
564585 // Merge the Old and New
565586 err = mergo .Merge (originalKubeConfig , specKubeletConfig , mergo .WithOverride )
566587 if err != nil {
567588 return ctrl .syncStatusOnly (cfg , err , "could not merge original config and new config: %v" , err )
568589 }
569- // Merge in Feature Gates
570- err = mergo .Merge (& originalKubeConfig .FeatureGates , featureGates , mergo .WithOverride )
571- if err != nil {
572- return ctrl .syncStatusOnly (cfg , err , "could not merge FeatureGates: %v" , err )
573- }
574- // Encode the new config into raw JSON
575- cfgJSON , err := EncodeKubeletConfig (originalKubeConfig , kubeletconfigv1beta1 .SchemeGroupVersion )
576- if err != nil {
577- return ctrl .syncStatusOnly (cfg , err , "could not encode JSON: %v" , err )
578- }
579- kubeletIgnition = createNewKubeletIgnition (cfgJSON )
580- } else {
581- // Encode the new config into raw JSON
582- cfgJSON , err := EncodeKubeletConfig (originalKubeConfig , kubeletconfigv1beta1 .SchemeGroupVersion )
583- if err != nil {
584- return ctrl .syncStatusOnly (cfg , err , "could not encode JSON: %v" , err )
585- }
586- kubeletIgnition = createNewKubeletIgnition (cfgJSON )
590+ }
591+
592+ // Encode the new config into an Ignition File
593+ kubeletIgnition , err = kubeletConfigToIgnFile (originalKubeConfig )
594+ if err != nil {
595+ return ctrl .syncStatusOnly (cfg , err , "could not encode JSON: %v" , err )
587596 }
588597
589598 if isNotFound {
0 commit comments