diff --git a/pkg/asset/manifests/cloudproviderconfig.go b/pkg/asset/manifests/cloudproviderconfig.go index 0c4d027200..53e9d08ae3 100644 --- a/pkg/asset/manifests/cloudproviderconfig.go +++ b/pkg/asset/manifests/cloudproviderconfig.go @@ -33,6 +33,7 @@ import ( externaltypes "github.com/openshift/installer/pkg/types/external" gcptypes "github.com/openshift/installer/pkg/types/gcp" ibmcloudtypes "github.com/openshift/installer/pkg/types/ibmcloud" + networktypes "github.com/openshift/installer/pkg/types/network" nonetypes "github.com/openshift/installer/pkg/types/none" nutanixtypes "github.com/openshift/installer/pkg/types/nutanix" openstacktypes "github.com/openshift/installer/pkg/types/openstack" @@ -113,12 +114,27 @@ func (cpc *CloudProviderConfig) Generate(ctx context.Context, dependencies asset cm.Data[cloudProviderConfigCABundleDataKey] = trustBundle } - // Include a non-empty kube config to appease components--such as the kube-apiserver--that - // expect there to be a kube config if the cloud-provider-config ConfigMap exists. See - // https://bugzilla.redhat.com/show_bug.cgi?id=1926975. - // Note that the newline is required in order to be valid yaml. - cm.Data[cloudProviderConfigDataKey] = `[Global] + var cloudCfg string + switch installConfig.Config.AWS.IPFamily { + case networktypes.DualStackIPv4Primary: + cloudCfg = `[Global] +NodeIPFamilies=ipv4 +NodeIPFamilies=ipv6 ` + case networktypes.DualStackIPv6Primary: + cloudCfg = `[Global] +NodeIPFamilies=ipv6 +NodeIPFamilies=ipv4 +` + default: + // Include a non-empty kube config to appease components--such as the kube-apiserver--that + // expect there to be a kube config if the cloud-provider-config ConfigMap exists. See + // https://bugzilla.redhat.com/show_bug.cgi?id=1926975. + // Note that the newline is required in order to be valid yaml. + cloudCfg = `[Global] +` + } + cm.Data[cloudProviderConfigDataKey] = cloudCfg case openstacktypes.Name, powervctypes.Name: cloudProviderConfigData, cloudProviderConfigCABundleData, err := openstackmanifests.GenerateCloudProviderConfig(ctx, *installConfig.Config) if err != nil { diff --git a/pkg/asset/manifests/cloudproviderconfig_test.go b/pkg/asset/manifests/cloudproviderconfig_test.go new file mode 100644 index 0000000000..64fa36bf3b --- /dev/null +++ b/pkg/asset/manifests/cloudproviderconfig_test.go @@ -0,0 +1,122 @@ +package manifests + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/yaml" + + "github.com/openshift/installer/pkg/asset" + "github.com/openshift/installer/pkg/asset/installconfig" + "github.com/openshift/installer/pkg/types" + "github.com/openshift/installer/pkg/types/network" +) + +func TestGenerateCloudProviderConfig(t *testing.T) { + cases := []struct { + name string + installConfig *types.InstallConfig + expectedCloudCfg map[string]string + }{ + { + name: "aws: empty ipFamily - default IPv4", + installConfig: icBuild.build( + icBuild.forAWS(), + icBuild.withAWSRegion("us-east-1"), + ), + expectedCloudCfg: map[string]string{ + cloudProviderConfigDataKey: `[Global] +`, + }, + }, + { + name: "aws: ipFamily IPv4", + installConfig: icBuild.build( + icBuild.forAWS(), + icBuild.withAWSRegion("us-east-1"), + icBuild.withAWSIPFamily(network.IPv4), + ), + expectedCloudCfg: map[string]string{ + cloudProviderConfigDataKey: `[Global] +`, + }, + }, + { + name: "aws: ipFamily DualStackIPv4Primary", + installConfig: icBuild.build( + icBuild.forAWS(), + icBuild.withAWSRegion("us-east-1"), + icBuild.withAWSIPFamily(network.DualStackIPv4Primary), + ), + expectedCloudCfg: map[string]string{ + cloudProviderConfigDataKey: `[Global] +NodeIPFamilies=ipv4 +NodeIPFamilies=ipv6 +`, + }, + }, + { + name: "aws: ipFamily DualStackIPv6Primary", + installConfig: icBuild.build( + icBuild.forAWS(), + icBuild.withAWSRegion("us-east-1"), + icBuild.withAWSIPFamily(network.DualStackIPv6Primary), + ), + expectedCloudCfg: map[string]string{ + cloudProviderConfigDataKey: `[Global] +NodeIPFamilies=ipv6 +NodeIPFamilies=ipv4 +`, + }, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + parents := asset.Parents{} + parents.Add( + installconfig.MakeAsset(tc.installConfig), + &installconfig.ClusterID{ + InfraID: "test-infra-id", + }, + ) + + cloudConfig := &CloudProviderConfig{} + + err := cloudConfig.Generate(context.Background(), parents) + if !assert.NoError(t, err, "failed to generate asset") { + return + } + + if tc.expectedCloudCfg == nil { + assert.Nil(t, cloudConfig.ConfigMap) + assert.Len(t, cloudConfig.Files(), 0) + return + } + + if !assert.NotNil(t, cloudConfig.ConfigMap) { + return + } + + assert.Equal(t, "openshift-config", cloudConfig.ConfigMap.Namespace) + assert.Equal(t, "cloud-provider-config", cloudConfig.ConfigMap.Name) + assert.Equal(t, tc.expectedCloudCfg, cloudConfig.ConfigMap.Data) + + if !assert.Len(t, cloudConfig.Files(), 1, "expected 1 file to be generated") { + return + } + + assert.Equal(t, cloudConfig.Files()[0].Filename, cloudProviderConfigFileName) + + var actualCloudConfig corev1.ConfigMap + err = yaml.Unmarshal(cloudConfig.Files()[0].Data, &actualCloudConfig) + if !assert.NoError(t, err, "failed to unmarshal cloud-provider-config manifest") { + return + } + + assert.Equal(t, tc.expectedCloudCfg, actualCloudConfig.Data) + }) + } +} diff --git a/pkg/asset/manifests/infrastructure_test.go b/pkg/asset/manifests/infrastructure_test.go index 3eee311a5f..f3fcbd6969 100644 --- a/pkg/asset/manifests/infrastructure_test.go +++ b/pkg/asset/manifests/infrastructure_test.go @@ -450,6 +450,13 @@ func (b icBuildNamespace) withAWSIPFamily(ipFamily network.IPFamily) icOption { } } +func (b icBuildNamespace) withAWSRegion(region string) icOption { + return func(ic *types.InstallConfig) { + b.forAWS()(ic) + ic.Platform.AWS.Region = region + } +} + func (b icBuildNamespace) withVSphereAPIVIP(vip string) icOption { return func(ic *types.InstallConfig) { b.forVSphere()(ic)