@@ -20,6 +20,7 @@ import (
2020 "github.com/openshift/installer/pkg/asset/lbconfig"
2121 "github.com/openshift/installer/pkg/asset/machines"
2222 "github.com/openshift/installer/pkg/asset/tls"
23+ "github.com/openshift/installer/pkg/types"
2324 awstypes "github.com/openshift/installer/pkg/types/aws"
2425 gcptypes "github.com/openshift/installer/pkg/types/gcp"
2526)
@@ -31,20 +32,24 @@ const (
3132 mcsCertFile = "/opt/openshift/tls/machine-config-server.crt"
3233 masterUserDataFile = "/opt/openshift/openshift/99_openshift-cluster-api_master-user-data-secret.yaml"
3334 workerUserDataFile = "/opt/openshift/openshift/99_openshift-cluster-api_worker-user-data-secret.yaml"
35+ clusterConfigDataFile = "/opt/openshift/manifests/cluster-config.yaml"
3436
3537 // header is the string that precedes the encoded data in the ignition data.
3638 // The data must be replaced before decoding the string, and the string must be
3739 // prepended to the encoded data.
3840 header = "data:text/plain;charset=utf-8;base64,"
3941
42+ // The key in the cluster-config-v1 ConfigMap to extract the install-config.
43+ clusterConfigCMKey = "install-config"
44+
4045 masterRole = "master"
4146 workerRole = "worker"
4247)
4348
44- // EditIgnition attempts to edit the contents of the bootstrap ignition when the user has selected
49+ // EditIgnitionForCustomDNS attempts to edit the contents of the bootstrap ignition when the user has selected
4550// a custom DNS configuration. Find the public and private load balancer addresses and fill in the
4651// infrastructure file within the ignition struct.
47- func EditIgnition (in IgnitionInput , platform string , publicIPAddresses , privateIPAddresses []string ) (* IgnitionOutput , error ) {
52+ func EditIgnitionForCustomDNS (in IgnitionInput , platform string , publicIPAddresses , privateIPAddresses []string ) (* IgnitionOutput , error ) {
4853 ignData := & igntypes.Config {}
4954 err := json .Unmarshal (in .BootstrapIgnData , ignData )
5055 if err != nil {
@@ -287,3 +292,76 @@ func updateUserDataSecret(in IgnitionInput, role string, config *igntypes.Config
287292 }
288293 return nil
289294}
295+
296+ // EditIgnitionForDualStack attempts to edit the contents of the bootstrap ignition when the cluster is in dualstack.
297+ // This addes the missing IPv6 manchine network for platform where IPv6 CIDRs are not known at install time, for example, AWS.
298+ func EditIgnitionForDualStack (in IgnitionInput , platform string , machineNetworks []types.MachineNetworkEntry ) (* IgnitionOutput , error ) {
299+ ignData := & igntypes.Config {}
300+ err := json .Unmarshal (in .BootstrapIgnData , ignData )
301+ if err != nil {
302+ return nil , fmt .Errorf ("failed to unmarshal bootstrap ignition: %w" , err )
303+ }
304+
305+ err = updateMachineNetworks (in , ignData , machineNetworks )
306+ if err != nil {
307+ return nil , fmt .Errorf ("failed to add VPC IPv6 CIDR to ignition config: %w" , err )
308+ }
309+ logrus .Debugf ("Successfully added VPC IPv6 CIDR to the install-config machine networks" )
310+
311+ editedIgnBytes , err := json .Marshal (ignData )
312+ if err != nil {
313+ return nil , fmt .Errorf ("failed to convert ignition data to json: %w" , err )
314+ }
315+ logrus .Debugf ("Successfully updated bootstrap ignition with updated manifests" )
316+
317+ return & IgnitionOutput {
318+ UpdatedBootstrapIgn : editedIgnBytes ,
319+ UpdatedMasterIgn : in .MasterIgnData ,
320+ UpdatedWorkerIgn : in .WorkerIgnData ,
321+ }, nil
322+ }
323+
324+ func updateMachineNetworks (in IgnitionInput , config * igntypes.Config , machineNetworks []types.MachineNetworkEntry ) error {
325+ for i , fileData := range config .Storage .Files {
326+ if fileData .Path == clusterConfigDataFile {
327+ contents := strings .Split (* config .Storage .Files [i ].Contents .Source , "," )
328+ rawDecodedText , err := base64 .StdEncoding .DecodeString (contents [1 ])
329+ if err != nil {
330+ return fmt .Errorf ("failed to decode contents of ignition file: %w" , err )
331+ }
332+
333+ configCM := & corev1.ConfigMap {}
334+ if err := yaml .Unmarshal (rawDecodedText , configCM ); err != nil {
335+ return fmt .Errorf ("failed to unmarshal cluster-config ConfigMap: %w" , err )
336+ }
337+
338+ installConfig := & types.InstallConfig {}
339+ if err := yaml .Unmarshal ([]byte (configCM .Data [clusterConfigCMKey ]), installConfig ); err != nil {
340+ return fmt .Errorf ("failed to unmarshal install-config content: %w" , err )
341+ }
342+
343+ // Update the machine network field
344+ installConfig .MachineNetwork = machineNetworks
345+
346+ // Convert the installconfig back to string and save it to the configmap
347+ icContents , err := yaml .Marshal (installConfig )
348+ if err != nil {
349+ return fmt .Errorf ("failed to marshal install-config: %w" , err )
350+ }
351+ configCM .Data [clusterConfigCMKey ] = string (icContents )
352+
353+ // convert the infrastructure back to an encoded string
354+ configCMContents , err := yaml .Marshal (configCM )
355+ if err != nil {
356+ return fmt .Errorf ("failed to marshal cluster-config ConfigMap: %w" , err )
357+ }
358+
359+ encoded := fmt .Sprintf ("%s%s" , header , base64 .StdEncoding .EncodeToString (configCMContents ))
360+ // replace the contents with the edited information
361+ config .Storage .Files [i ].Contents .Source = & encoded
362+
363+ break
364+ }
365+ }
366+ return nil
367+ }
0 commit comments