@@ -660,8 +660,110 @@ var Addons = map[string]*Addon{
660
660
}),
661
661
}
662
662
663
+ // parseMapString creates a map based on `str` which is encoded as <key1>=<value1>,<key2>=<value2>,...
664
+ func parseMapString (str string ) map [string ]string {
665
+ mapResult := make (map [string ]string )
666
+ if str == "" {
667
+ return mapResult
668
+ }
669
+ for _ , pairText := range strings .Split (str , "," ) {
670
+ vals := strings .Split (pairText , "=" )
671
+ if len (vals ) != 2 {
672
+ out .WarningT ("Ignoring invalid pair entry {{.pair}}" , out.V {"pair" : pairText })
673
+ continue
674
+ }
675
+ mapResult [vals [0 ]] = vals [1 ]
676
+ }
677
+ return mapResult
678
+ }
679
+
680
+ // mergeMaps creates a map with the union of `sourceMap` and `overrideMap` where collisions take the value of `overrideMap`.
681
+ func mergeMaps (sourceMap , overrideMap map [string ]string ) map [string ]string {
682
+ result := make (map [string ]string )
683
+ for name , value := range sourceMap {
684
+ result [name ] = value
685
+ }
686
+ for name , value := range overrideMap {
687
+ result [name ] = value
688
+ }
689
+ return result
690
+ }
691
+
692
+ // filterKeySpace creates a map of the values in `targetMap` where the keys are also in `keySpace`.
693
+ func filterKeySpace (keySpace map [string ]string , targetMap map [string ]string ) map [string ]string {
694
+ result := make (map [string ]string )
695
+ for name := range keySpace {
696
+ if value , ok := targetMap [name ]; ok {
697
+ result [name ] = value
698
+ }
699
+ }
700
+ return result
701
+ }
702
+
703
+ // overrideDefaults creates a copy of `defaultMap` where `overrideMap` replaces any of its values that `overrideMap` contains.
704
+ func overrideDefaults (defaultMap , overrideMap map [string ]string ) map [string ]string {
705
+ return mergeMaps (defaultMap , filterKeySpace (defaultMap , overrideMap ))
706
+ }
707
+
708
+ // SelectAndPersistImages selects which images to use based on addon default images, previously persisted images, and newly requested images - which are then persisted for future enables.
709
+ func SelectAndPersistImages (addon * Addon , cc * config.ClusterConfig ) (images , customRegistries map [string ]string , err error ) {
710
+ addonDefaultImages := addon .Images
711
+ if addonDefaultImages == nil {
712
+ addonDefaultImages = make (map [string ]string )
713
+ }
714
+
715
+ // Use previously configured custom images.
716
+ images = overrideDefaults (addonDefaultImages , cc .CustomAddonImages )
717
+ if viper .IsSet (config .AddonImages ) {
718
+ // Parse the AddonImages flag if present.
719
+ newImages := parseMapString (viper .GetString (config .AddonImages ))
720
+ for name , image := range newImages {
721
+ if image == "" {
722
+ out .WarningT ("Ignoring empty custom image {{.name}}" , out.V {"name" : name })
723
+ delete (newImages , name )
724
+ continue
725
+ }
726
+ if _ , ok := addonDefaultImages [name ]; ! ok {
727
+ out .WarningT ("Ignoring unknown custom image {{.name}}" , out.V {"name" : name })
728
+ }
729
+ }
730
+ // Use newly configured custom images.
731
+ images = overrideDefaults (addonDefaultImages , newImages )
732
+ // Store custom addon images to be written.
733
+ cc .CustomAddonImages = mergeMaps (cc .CustomAddonImages , images )
734
+ }
735
+
736
+ // Use previously configured custom registries.
737
+ customRegistries = filterKeySpace (addonDefaultImages , cc .CustomAddonRegistries ) // filter by images map because registry map may omit default registry.
738
+ if viper .IsSet (config .AddonRegistries ) {
739
+ // Parse the AddonRegistries flag if present.
740
+ customRegistries = parseMapString (viper .GetString (config .AddonRegistries ))
741
+ for name := range customRegistries {
742
+ if _ , ok := addonDefaultImages [name ]; ! ok { // check images map because registry map may omitted default registry
743
+ out .WarningT ("Ignoring unknown custom registry {{.name}}" , out.V {"name" : name })
744
+ delete (customRegistries , name )
745
+ }
746
+ }
747
+ // Since registry map may omit default registry, any previously set custom registries for these images must be cleared.
748
+ for name := range addonDefaultImages {
749
+ delete (cc .CustomAddonRegistries , name )
750
+ }
751
+ // Merge newly set registries into custom addon registries to be written.
752
+ cc .CustomAddonRegistries = mergeMaps (cc .CustomAddonRegistries , customRegistries )
753
+ }
754
+
755
+ err = nil
756
+ // If images or registries were specified, save the config afterward.
757
+ if viper .IsSet (config .AddonImages ) || viper .IsSet (config .AddonRegistries ) {
758
+ // Since these values are only set when a user enables an addon, it is safe to refer to the profile name.
759
+ err = config .Write (viper .GetString (config .ProfileName ), cc )
760
+ // Whether err is nil or not we still return here.
761
+ }
762
+ return images , customRegistries , err
763
+ }
764
+
663
765
// GenerateTemplateData generates template data for template assets
664
- func GenerateTemplateData (addon * Addon , cfg config.KubernetesConfig , netInfo NetworkInfo ) interface {} {
766
+ func GenerateTemplateData (addon * Addon , cfg config.KubernetesConfig , netInfo NetworkInfo , images , customRegistries map [ string ] string ) interface {} {
665
767
666
768
a := runtime .GOARCH
667
769
// Some legacy docker images still need the -arch suffix
@@ -670,6 +772,7 @@ func GenerateTemplateData(addon *Addon, cfg config.KubernetesConfig, netInfo Net
670
772
if runtime .GOARCH != "amd64" {
671
773
ea = "-" + runtime .GOARCH
672
774
}
775
+
673
776
opts := struct {
674
777
Arch string
675
778
ExoticArch string
@@ -688,58 +791,21 @@ func GenerateTemplateData(addon *Addon, cfg config.KubernetesConfig, netInfo Net
688
791
LoadBalancerStartIP : cfg .LoadBalancerStartIP ,
689
792
LoadBalancerEndIP : cfg .LoadBalancerEndIP ,
690
793
CustomIngressCert : cfg .CustomIngressCert ,
691
- Images : addon . Images ,
794
+ Images : images ,
692
795
Registries : addon .Registries ,
693
- CustomRegistries : make ( map [ string ] string ) ,
796
+ CustomRegistries : customRegistries ,
694
797
NetworkInfo : make (map [string ]string ),
695
798
}
696
799
if opts .ImageRepository != "" && ! strings .HasSuffix (opts .ImageRepository , "/" ) {
697
800
opts .ImageRepository += "/"
698
801
}
699
-
700
- // Network info for generating template
701
- opts .NetworkInfo ["ControlPlaneNodeIP" ] = netInfo .ControlPlaneNodeIP
702
- opts .NetworkInfo ["ControlPlaneNodePort" ] = fmt .Sprint (netInfo .ControlPlaneNodePort )
703
-
704
- if opts .Images == nil {
705
- opts .Images = make (map [string ]string ) // Avoid nil access when rendering
706
- }
707
-
708
- images := viper .GetString (config .AddonImages )
709
- if images != "" {
710
- for _ , image := range strings .Split (images , "," ) {
711
- vals := strings .Split (image , "=" )
712
- if len (vals ) != 2 || vals [1 ] == "" {
713
- out .WarningT ("Ignoring invalid custom image {{.conf}}" , out.V {"conf" : image })
714
- continue
715
- }
716
- if _ , ok := opts .Images [vals [0 ]]; ok {
717
- opts .Images [vals [0 ]] = vals [1 ]
718
- } else {
719
- out .WarningT ("Ignoring unknown custom image {{.name}}" , out.V {"name" : vals [0 ]})
720
- }
721
- }
722
- }
723
-
724
802
if opts .Registries == nil {
725
803
opts .Registries = make (map [string ]string )
726
804
}
727
805
728
- registries := viper .GetString (config .AddonRegistries )
729
- if registries != "" {
730
- for _ , registry := range strings .Split (registries , "," ) {
731
- vals := strings .Split (registry , "=" )
732
- if len (vals ) != 2 {
733
- out .WarningT ("Ignoring invalid custom registry {{.conf}}" , out.V {"conf" : registry })
734
- continue
735
- }
736
- if _ , ok := opts .Images [vals [0 ]]; ok { // check images map because registry map may omitted default registry
737
- opts .CustomRegistries [vals [0 ]] = vals [1 ]
738
- } else {
739
- out .WarningT ("Ignoring unknown custom registry {{.name}}" , out.V {"name" : vals [0 ]})
740
- }
741
- }
742
- }
806
+ // Network info for generating template
807
+ opts .NetworkInfo ["ControlPlaneNodeIP" ] = netInfo .ControlPlaneNodeIP
808
+ opts .NetworkInfo ["ControlPlaneNodePort" ] = fmt .Sprint (netInfo .ControlPlaneNodePort )
743
809
744
810
// Append postfix "/" to registries
745
811
for k , v := range opts .Registries {
0 commit comments