1
0
mirror of https://github.com/openshift/installer.git synced 2026-02-05 15:47:14 +01:00

Merge pull request #10238 from tthvo/CORS-4073

CORS-4073: validate instance type support IPv6 in dual-stack
This commit is contained in:
openshift-merge-bot[bot]
2026-01-26 20:06:58 +00:00
committed by GitHub
4 changed files with 101 additions and 18 deletions

View File

@@ -4,36 +4,53 @@ import (
"context"
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/ec2"
)
// Networking describes the network settings for an instance type.
type Networking struct {
// IPv6Supported indicates whether IPv6 is supported.
IPv6Supported bool
}
// InstanceType holds metadata for an instance type.
type InstanceType struct {
DefaultVCpus int64
MemInMiB int64
Arches []string
Networking Networking
}
// instanceTypes retrieves a list of instance types for the given region.
func instanceTypes(ctx context.Context, session *session.Session, region string) (map[string]InstanceType, error) {
func instanceTypes(ctx context.Context, client *ec2.Client) (map[string]InstanceType, error) {
types := map[string]InstanceType{}
client := ec2.New(session, aws.NewConfig().WithRegion(region))
if err := client.DescribeInstanceTypesPagesWithContext(ctx,
&ec2.DescribeInstanceTypesInput{},
func(page *ec2.DescribeInstanceTypesOutput, lastPage bool) bool {
for _, info := range page.InstanceTypes {
types[*info.InstanceType] = InstanceType{
DefaultVCpus: aws.Int64Value(info.VCpuInfo.DefaultVCpus),
MemInMiB: aws.Int64Value(info.MemoryInfo.SizeInMiB),
Arches: aws.StringValueSlice(info.ProcessorInfo.SupportedArchitectures),
paginator := ec2.NewDescribeInstanceTypesPaginator(client, &ec2.DescribeInstanceTypesInput{})
for paginator.HasMorePages() {
page, err := paginator.NextPage(ctx)
if err != nil {
return nil, fmt.Errorf("failed to list instance types: %w", err)
}
for _, sdkTypeInfo := range page.InstanceTypes {
typeInfo := InstanceType{
DefaultVCpus: int64(aws.ToInt32(sdkTypeInfo.VCpuInfo.DefaultVCpus)),
MemInMiB: aws.ToInt64(sdkTypeInfo.MemoryInfo.SizeInMiB),
}
for _, arch := range sdkTypeInfo.ProcessorInfo.SupportedArchitectures {
typeInfo.Arches = append(typeInfo.Arches, string(arch))
}
if netInfo := sdkTypeInfo.NetworkInfo; netInfo != nil {
typeInfo.Networking = Networking{
IPv6Supported: aws.ToBool(netInfo.Ipv6Supported),
}
}
return !lastPage
}); err != nil {
return nil, fmt.Errorf("fetching instance types: %w", err)
types[string(sdkTypeInfo.InstanceType)] = typeInfo
}
}
return types, nil

View File

@@ -377,12 +377,12 @@ func (m *Metadata) InstanceTypes(ctx context.Context) (map[string]InstanceType,
defer m.mutex.Unlock()
if len(m.instanceTypes) == 0 {
session, err := m.unlockedSession(ctx)
client, err := m.EC2Client(ctx)
if err != nil {
return nil, err
}
m.instanceTypes, err = instanceTypes(ctx, session, m.Region)
m.instanceTypes, err = instanceTypes(ctx, client)
if err != nil {
return nil, fmt.Errorf("error listing instance types: %w", err)
}

View File

@@ -447,6 +447,14 @@ func validateMachinePool(ctx context.Context, meta *Metadata, fldPath *field.Pat
errMsg := fmt.Sprintf("instance type supported architectures %s do not match specified architecture %s", sets.List(instanceArches), arch)
allErrs = append(allErrs, field.Invalid(fldPath.Child("type"), pool.InstanceType, errMsg))
}
// dual-stack: the instance type must support IPv6 networking
if platform.IPFamily.DualStackEnabled() {
if !typeMeta.Networking.IPv6Supported {
errMsg := fmt.Sprintf("instance type %s does not support IPv6 networking", pool.InstanceType)
allErrs = append(allErrs, field.Invalid(fldPath.Child("type"), pool.InstanceType, errMsg))
}
}
} else {
errMsg := fmt.Sprintf("instance type %s not found", pool.InstanceType)
allErrs = append(allErrs, field.Invalid(fldPath.Child("type"), pool.InstanceType, errMsg))

View File

@@ -22,6 +22,7 @@ import (
"github.com/openshift/installer/pkg/ipnet"
"github.com/openshift/installer/pkg/types"
"github.com/openshift/installer/pkg/types/aws"
"github.com/openshift/installer/pkg/types/network"
)
var (
@@ -155,6 +156,37 @@ func TestValidate(t *testing.T) {
},
expectErr: `^compute\[1\].architecture: Invalid value: "arm64": all compute machine pools must be of the same architecture$`,
},
{
name: "valid dual-stack with IPv6 supporting instance types",
installConfig: icBuild.build(icBuild.withInstanceType("m5.xlarge", "m5.xlarge", "m5.large"), icBuild.withIPFamily(network.DualStackIPv4Primary)),
availRegions: validAvailRegions(),
availZones: validAvailZones(),
instanceTypes: validInstanceTypes(),
},
{
name: "invalid dual-stack control plane instance type does not support IPv6",
installConfig: icBuild.build(icBuild.withInstanceType("m5.xlarge", "m1.xlarge", "m5.large"), icBuild.withIPFamily(network.DualStackIPv4Primary)),
availRegions: validAvailRegions(),
availZones: validAvailZones(),
instanceTypes: validInstanceTypes(),
expectErr: `controlPlane\.platform\.aws\.type: Invalid value: "m1\.xlarge": instance type m1\.xlarge does not support IPv6 networking`,
},
{
name: "invalid dual-stack compute instance type does not support IPv6",
installConfig: icBuild.build(icBuild.withInstanceType("m5.xlarge", "m5.xlarge", "m1.xlarge"), icBuild.withIPFamily(network.DualStackIPv4Primary)),
availRegions: validAvailRegions(),
availZones: validAvailZones(),
instanceTypes: validInstanceTypes(),
expectErr: `compute\[0\]\.platform\.aws\.type: Invalid value: "m1\.xlarge": instance type m1\.xlarge does not support IPv6 networking`,
},
{
name: "invalid dual-stack default machine platform instance types do not support IPv6",
installConfig: icBuild.build(icBuild.withInstanceType("m1.xlarge", "", ""), icBuild.withIPFamily(network.DualStackIPv6Primary)),
availRegions: validAvailRegions(),
availZones: validAvailZones(),
instanceTypes: validInstanceTypes(),
expectErr: `controlPlane\.platform\.aws\.type: Invalid value: "m1\.xlarge": instance type m1\.xlarge does not support IPv6 networking.*compute\[0\]\.platform\.aws\.type: Invalid value: "m1\.xlarge": instance type m1\.xlarge does not support IPv6 networking`,
},
{
name: "invalid edge pool, missing zones",
installConfig: icBuild.build(
@@ -1761,21 +1793,41 @@ func validInstanceTypes() map[string]InstanceType {
DefaultVCpus: 1,
MemInMiB: 2048,
Arches: []string{ec2.ArchitectureTypeX8664},
Networking: Networking{
IPv6Supported: true,
},
},
"m5.large": {
DefaultVCpus: 2,
MemInMiB: 8192,
Arches: []string{ec2.ArchitectureTypeX8664},
Networking: Networking{
IPv6Supported: true,
},
},
"m5.xlarge": {
DefaultVCpus: 4,
MemInMiB: 16384,
Arches: []string{ec2.ArchitectureTypeX8664},
Networking: Networking{
IPv6Supported: true,
},
},
"m6g.xlarge": {
DefaultVCpus: 4,
MemInMiB: 16384,
Arches: []string{ec2.ArchitectureTypeArm64},
Networking: Networking{
IPv6Supported: true,
},
},
"m1.xlarge": {
DefaultVCpus: 4,
MemInMiB: 15360,
Arches: []string{ec2.ArchitectureTypeX8664},
Networking: Networking{
IPv6Supported: false,
},
},
}
}
@@ -2025,3 +2077,9 @@ func (icBuild icBuildForAWS) withPublicIPv4Pool(publicIPv4Pool string) icOption
ic.Platform.AWS.PublicIpv4Pool = publicIPv4Pool
}
}
func (icBuild icBuildForAWS) withIPFamily(ipFamily network.IPFamily) icOption {
return func(ic *types.InstallConfig) {
ic.Platform.AWS.IPFamily = ipFamily
}
}