@@ -20,8 +20,10 @@ import (
2020)
2121
2222const (
23+ configDataKey = "cloud.conf"
2324 bootstrapNamespace = "kube-system"
2425 bootstrapPrefix = "bootstrap"
26+ configPrefix = "config"
2527 // bootstrapFileName is built from bootstrapPrefix, resource name and kind
2628 bootstrapFileName = "%s/%s-%s.yaml"
2729)
@@ -32,20 +34,24 @@ type Render struct {
3234 infrastructureFile string
3335 // path to rendered cloud-controller-manager-images ConfigMap manifest for image references to use
3436 imagesFile string
37+ // path to populated cloud-config ConfigMap manifest from cluster-config-operator
38+ // where cloud-config could be extracted for use in CCM static pod
39+ cloudConfigFile string
3540}
3641
3742// New returns controller for render
38- func New (infrastructureFile , imagesFile string ) * Render {
43+ func New (infrastructureFile , imagesFile , cloudConfigFile string ) * Render {
3944 return & Render {
4045 infrastructureFile : infrastructureFile ,
4146 imagesFile : imagesFile ,
47+ cloudConfigFile : cloudConfigFile ,
4248 }
4349}
4450
4551// Run runs boostrap for Machine Config Controller
4652// It writes all the assets to destDir
4753func (r * Render ) Run (destinationDir string ) error {
48- infra , imagesMap , err := r .readAssets ()
54+ infra , imagesMap , cloudConfig , err := r .readAssets ()
4955 if err != nil {
5056 klog .Errorf ("Cannot read assets from provided paths: %v" , err )
5157 return err
@@ -63,36 +69,51 @@ func (r *Render) Run(destinationDir string) error {
6369 klog .Infof ("Collected resource %s %q successfully" , resource .GetObjectKind ().GroupVersionKind (), client .ObjectKeyFromObject (resource ))
6470 }
6571
66- return writeAssets (destinationDir , resources )
72+ if err := writeAssets (destinationDir , resources ); err != nil {
73+ klog .Errorf ("Could not write assets to bootstrap dir: %v" , err )
74+ return err
75+ }
76+
77+ return writeCloudConfig (destinationDir , cloudConfig )
6778}
6879
6980// readAssets collects infrastructure resource and images config map from provided paths
70- func (r * Render ) readAssets () (* configv1.Infrastructure , * corev1.ConfigMap , error ) {
81+ func (r * Render ) readAssets () (* configv1.Infrastructure , * corev1.ConfigMap , string , error ) {
7182 infraData , err := ioutil .ReadFile (r .infrastructureFile )
7283 if err != nil {
7384 klog .Errorf ("Unable to read data from %q: %v" , r .infrastructureFile , err )
74- return nil , nil , err
85+ return nil , nil , "" , err
7586 }
7687
7788 infra := & configv1.Infrastructure {}
7889 if err := yaml .UnmarshalStrict (infraData , infra ); err != nil {
7990 klog .Errorf ("Cannot decode data into configv1.Infrastructure from %q: %v" , r .infrastructureFile , err )
80- return nil , nil , err
91+ return nil , nil , "" , err
8192 }
8293
8394 imagesData , err := ioutil .ReadFile (r .imagesFile )
8495 if err != nil {
8596 klog .Errorf ("Unable to read data from %q: %v" , r .imagesFile , err )
86- return nil , nil , err
97+ return nil , nil , "" , err
8798 }
8899
89100 imagesConfigMap := & corev1.ConfigMap {}
90101 if err := yaml .UnmarshalStrict (imagesData , imagesConfigMap ); err != nil {
91102 klog .Errorf ("Cannot decode data into v1.ConfigMap from %q: %v" , r .imagesFile , err )
92- return nil , nil , err
103+ return nil , nil , "" , err
104+ }
105+
106+ cloudConfig := ""
107+ // if the cloudConfig is set in infra read the cloudConfigFile
108+ if infra .Spec .CloudConfig .Name != "" {
109+ cloudConfig , err = loadBootstrapCloudProviderConfig (infra , r .cloudConfigFile )
110+ if err != nil {
111+ klog .Errorf ("failed to load the cloud provider config: %v" , err )
112+ return nil , nil , "" , err
113+ }
93114 }
94115
95- return infra , imagesConfigMap , nil
116+ return infra , imagesConfigMap , cloudConfig , nil
96117}
97118
98119// writeAssets writes static pods to disk into <destinationDir>/<bootstrapPrefix>/<resourceName>-<resourceKind>.yaml
@@ -118,5 +139,48 @@ func writeAssets(destinationDir string, resources []client.Object) error {
118139 return err
119140 }
120141 }
142+
143+ return nil
144+ }
145+
146+ // writeCloudConfig creates config folder and writes resources such as cloud-config file
147+ // for use in bootstrap
148+ func writeCloudConfig (destinationDir string , cloudConfig string ) error {
149+ // Create config directory in advance to ensure it is present for any provider
150+ configDir := filepath .Join (destinationDir , configPrefix )
151+ if err := os .MkdirAll (configDir , fs .ModePerm ); err != nil {
152+ klog .Errorf ("Unable to create destination dir %q: %v" , configDir , err )
153+ return err
154+ }
155+
156+ if cloudConfig != "" {
157+ cloudConfigFile := filepath .Join (configDir , configDataKey )
158+
159+ klog .Infof ("Writing cloud config on disk in %q" , cloudConfigFile )
160+ err := os .WriteFile (cloudConfigFile , []byte (cloudConfig ), 0666 )
161+ if err != nil {
162+ klog .Errorf ("Failed to write cloud config to disk in %q: %v" , cloudConfigFile , err )
163+ return err
164+ }
165+ }
166+
121167 return nil
122168}
169+
170+ // loadBootstrapCloudProviderConfig reads the cloud provider config from cloudConfigFile based on infra object.
171+ func loadBootstrapCloudProviderConfig (infra * configv1.Infrastructure , cloudConfigFile string ) (string , error ) {
172+ data , err := os .ReadFile (cloudConfigFile )
173+ if err != nil {
174+ return "" , err
175+ }
176+ cloudConfigMap := & corev1.ConfigMap {}
177+ if err := yaml .UnmarshalStrict (data , cloudConfigMap ); err != nil {
178+ return "" , err
179+ }
180+ cloudConf , ok := cloudConfigMap .Data [configDataKey ]
181+ if ! ok {
182+ klog .Infof ("falling back to reading cloud provider config from user specified key %s" , infra .Spec .CloudConfig .Key )
183+ cloudConf = cloudConfigMap .Data [infra .Spec .CloudConfig .Key ]
184+ }
185+ return cloudConf , nil
186+ }
0 commit comments