@@ -330,14 +330,43 @@ func (ctrl *Controller) handleFeatureErr(err error, key interface{}) {
330
330
ctrl .featureQueue .AddAfter (key , 1 * time .Minute )
331
331
}
332
332
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 )
335
337
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 )
337
339
}
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 ) {
338
367
// Render the default templates
339
368
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 )
341
370
if err != nil {
342
371
return nil , fmt .Errorf ("GenerateMachineConfigsforRole failed with error %s" , err )
343
372
}
@@ -478,12 +507,6 @@ func (ctrl *Controller) syncKubeletConfig(key string) error {
478
507
err := fmt .Errorf ("could not fetch FeatureGates: %v" , err )
479
508
return ctrl .syncStatusOnly (cfg , err )
480
509
}
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
- }
487
510
488
511
for _ , pool := range mcpPools {
489
512
if pool .Spec .Configuration .Name == "" {
@@ -512,20 +535,14 @@ func (ctrl *Controller) syncKubeletConfig(key string) error {
512
535
userDefinedSystemReserved := make (map [string ]string , 2 )
513
536
514
537
// 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 )
523
539
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 )
525
541
}
526
- originalKubeConfig , err := decodeKubeletConfig (dataURL .Data )
542
+
543
+ originalKubeConfig , err := generateOriginalKubeletConfigWithFeatureGates (cc , ctrl .templatesDir , role , features )
527
544
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 )
529
546
}
530
547
531
548
// Get the default API Server Security Profile
@@ -561,29 +578,21 @@ func (ctrl *Controller) syncKubeletConfig(key string) error {
561
578
delete (specKubeletConfig .SystemReserved , "cpu" )
562
579
}
563
580
581
+ // FeatureGates must be set from the FeatureGate.
582
+ // Remove them here to prevent the specKubeletConfig merge overwriting them.
583
+ specKubeletConfig .FeatureGates = nil
584
+
564
585
// Merge the Old and New
565
586
err = mergo .Merge (originalKubeConfig , specKubeletConfig , mergo .WithOverride )
566
587
if err != nil {
567
588
return ctrl .syncStatusOnly (cfg , err , "could not merge original config and new config: %v" , err )
568
589
}
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 )
587
596
}
588
597
589
598
if isNotFound {
0 commit comments