Skip to content

Commit adbdc5d

Browse files
committed
test integration eni-subnet-discovery: extend tests for IPv6 mode
1 parent c40cba5 commit adbdc5d

3 files changed

Lines changed: 109 additions & 18 deletions

File tree

test/integration/eni-subnet-discovery/eni_subnet_discovery_enhanced_test.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ package eni_subnet_discovery
1515

1616
import (
1717
"context"
18+
"fmt"
19+
"net"
1820
"os"
1921
"time"
2022

@@ -320,8 +322,21 @@ var _ = Describe("ENI Subnet Discovery Enhanced Tests", func() {
320322

321323
// Create another subnet that has a different cluster tag
322324
By("Creating a subnet for a different cluster")
323-
subnetCidr, err := cidr.Subnet(cidrRange, 2, 1) // Use a different subnet
324-
Expect(err).ToNot(HaveOccurred())
325+
var subnetCidr *net.IPNet
326+
if useIPv6 {
327+
// For IPv6, calculate the appropriate number of bits to get a /64 subnet
328+
prefixLen, _ := cidrRange.Mask.Size()
329+
if prefixLen > 64 {
330+
Fail(fmt.Sprintf("IPv6 parent CIDR prefix length must be <= 64, got /%d", prefixLen))
331+
}
332+
// Calculate how many bits we need to extend to reach /64
333+
bitsToExtend := 64 - prefixLen
334+
subnetCidr, err = cidr.Subnet(cidrRange, bitsToExtend, 1) // Use index 1 for different subnet
335+
Expect(err).ToNot(HaveOccurred())
336+
} else {
337+
subnetCidr, err = cidr.Subnet(cidrRange, 2, 1) // Use a different subnet
338+
Expect(err).ToNot(HaveOccurred())
339+
}
325340

326341
otherSubnetOutput, err := f.CloudServices.EC2().
327342
CreateSubnet(context.TODO(), subnetCidr.String(), f.Options.AWSVPCID, *primaryInstance.Placement.AvailabilityZone)

test/integration/eni-subnet-discovery/eni_subnet_discovery_suite_test.go

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,13 @@ var (
4747
cidrBlockAssociationID string
4848
createdSubnet string
4949
primaryInstance ec2types.Instance
50+
useIPv6 bool
5051
)
5152

5253
// Parse test specific variable from flag
5354
func init() {
5455
flag.StringVar(&cidrRangeString, "secondary-cidr-range", "100.64.0.0/16", "second cidr range to be associated with the VPC")
56+
flag.BoolVar(&useIPv6, "use-ipv6", false, "Use IPv6 for subnet discovery tests")
5557
}
5658

5759
var _ = BeforeSuite(func() {
@@ -79,9 +81,21 @@ var _ = BeforeSuite(func() {
7981
primaryInstance, err = f.CloudServices.EC2().DescribeInstance(context.TODO(), instanceID)
8082
Expect(err).ToNot(HaveOccurred())
8183

84+
// Adjust default CIDR if IPv6 is enabled and no custom CIDR provided
85+
if useIPv6 && cidrRangeString == "100.64.0.0/16" {
86+
cidrRangeString = "2600:1f13:000::/56" // AWS IPv6 example range
87+
}
88+
8289
_, cidrRange, err = net.ParseCIDR(cidrRangeString)
8390
Expect(err).ToNot(HaveOccurred())
8491

92+
// Validate CIDR matches IP version
93+
if useIPv6 {
94+
Expect(cidrRange.IP.To4()).To(BeNil(), "IPv6 mode requires IPv6 CIDR")
95+
} else {
96+
Expect(cidrRange.IP.To4()).ToNot(BeNil(), "IPv4 mode requires IPv4 CIDR")
97+
}
98+
8599
By("creating test namespace")
86100
_ = f.K8sResourceManagers.NamespaceManager().CreateNamespace(utils.DefaultTestNamespace)
87101

@@ -90,15 +104,54 @@ var _ = BeforeSuite(func() {
90104
Expect(err).ToNot(HaveOccurred())
91105

92106
By("associating cidr range to the VPC")
93-
association, err := f.CloudServices.EC2().AssociateVPCCIDRBlock(context.TODO(), f.Options.AWSVPCID, cidrRange.String())
94-
Expect(err).ToNot(HaveOccurred())
95-
cidrBlockAssociationID = *association.CidrBlockAssociation.AssociationId
107+
if useIPv6 {
108+
// The current framework only supports IPv4 CIDR association
109+
// For IPv6, we assume the VPC already has IPv6 enabled
110+
// In a production environment, you would extend the framework to support IPv6 association
111+
By("IPv6 mode: assuming VPC already has IPv6 enabled")
112+
113+
// Verify VPC has IPv6 and get an existing association ID for cleanup
114+
vpcInfo, err := f.CloudServices.EC2().DescribeVPC(context.TODO(), f.Options.AWSVPCID)
115+
Expect(err).ToNot(HaveOccurred())
116+
117+
hasIPv6 := false
118+
for _, assoc := range vpcInfo.Vpcs[0].Ipv6CidrBlockAssociationSet {
119+
if assoc.Ipv6CidrBlockState != nil && assoc.Ipv6CidrBlockState.State == "associated" {
120+
hasIPv6 = true
121+
// We won't disassociate existing IPv6, so set empty ID
122+
cidrBlockAssociationID = ""
123+
break
124+
}
125+
}
126+
127+
if !hasIPv6 {
128+
Skip("IPv6 tests require a VPC with IPv6 already enabled")
129+
}
130+
} else {
131+
// IPv4 association works with current framework
132+
association, err := f.CloudServices.EC2().AssociateVPCCIDRBlock(context.TODO(), f.Options.AWSVPCID, cidrRange.String())
133+
Expect(err).ToNot(HaveOccurred())
134+
cidrBlockAssociationID = *association.CidrBlockAssociation.AssociationId
135+
}
96136

97137
By(fmt.Sprintf("creating the subnet in %s", *primaryInstance.Placement.AvailabilityZone))
98138

99-
// Subnet must be greater than /19
100-
subnetCidr, err := cidr.Subnet(cidrRange, 2, 0)
101-
Expect(err).ToNot(HaveOccurred())
139+
var subnetCidr *net.IPNet
140+
if useIPv6 {
141+
// For IPv6, calculate the appropriate number of bits to get a /64 subnet
142+
prefixLen, _ := cidrRange.Mask.Size()
143+
if prefixLen > 64 {
144+
Fail(fmt.Sprintf("IPv6 parent CIDR prefix length must be <= 64, got /%d", prefixLen))
145+
}
146+
// Calculate how many bits we need to extend to reach /64
147+
bitsToExtend := 64 - prefixLen
148+
subnetCidr, err = cidr.Subnet(cidrRange, bitsToExtend, 0)
149+
Expect(err).ToNot(HaveOccurred())
150+
} else {
151+
// IPv4: Subnet must be greater than /19
152+
subnetCidr, err = cidr.Subnet(cidrRange, 2, 0)
153+
Expect(err).ToNot(HaveOccurred())
154+
}
102155

103156
createSubnetOutput, err := f.CloudServices.EC2().
104157
CreateSubnet(context.TODO(), subnetCidr.String(), f.Options.AWSVPCID, *primaryInstance.Placement.AvailabilityZone)
@@ -134,7 +187,9 @@ var _ = AfterSuite(func() {
134187
errs.Append(f.CloudServices.EC2().DeleteSubnet(context.TODO(), createdSubnet))
135188

136189
By("disassociating the CIDR range to the VPC")
137-
errs.Append(f.CloudServices.EC2().DisAssociateVPCCIDRBlock(context.TODO(), cidrBlockAssociationID))
190+
if cidrBlockAssociationID != "" {
191+
errs.Append(f.CloudServices.EC2().DisAssociateVPCCIDRBlock(context.TODO(), cidrBlockAssociationID))
192+
}
138193

139194
Expect(errs.MaybeUnwrap()).ToNot(HaveOccurred())
140195

test/integration/eni-subnet-discovery/eni_subnet_discovery_test.go

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -305,16 +305,37 @@ func checkSecondaryENISubnets(expectNewCidr bool) {
305305
vpcOutput, err := f.CloudServices.EC2().DescribeVPC(context.TODO(), *primaryInstance.VpcId)
306306
Expect(err).ToNot(HaveOccurred())
307307

308-
expectedCidrRangeString := *vpcOutput.Vpcs[0].CidrBlock
309-
expectedCidrSplit := strings.Split(*vpcOutput.Vpcs[0].CidrBlock, "/")
310-
expectedSuffix, _ := strconv.Atoi(expectedCidrSplit[1])
311-
_, expectedCIDR, _ := net.ParseCIDR(*vpcOutput.Vpcs[0].CidrBlock)
312-
313-
if expectNewCidr {
314-
expectedCidrRangeString = cidrRangeString
315-
expectedCidrSplit = strings.Split(cidrRangeString, "/")
308+
var expectedCidrRangeString string
309+
var expectedCIDR *net.IPNet
310+
var expectedSuffix int
311+
312+
if useIPv6 {
313+
// For IPv6, look for associated IPv6 CIDR blocks
314+
if len(vpcOutput.Vpcs[0].Ipv6CidrBlockAssociationSet) > 0 {
315+
for _, assoc := range vpcOutput.Vpcs[0].Ipv6CidrBlockAssociationSet {
316+
if assoc.Ipv6CidrBlockState != nil && assoc.Ipv6CidrBlockState.State == "associated" {
317+
expectedCidrRangeString = *assoc.Ipv6CidrBlock
318+
break
319+
}
320+
}
321+
}
322+
Expect(expectedCidrRangeString).ToNot(BeEmpty(), "No associated IPv6 CIDR found in VPC")
323+
_, expectedCIDR, _ = net.ParseCIDR(expectedCidrRangeString)
324+
expectedCidrSplit := strings.Split(expectedCidrRangeString, "/")
325+
expectedSuffix, _ = strconv.Atoi(expectedCidrSplit[1])
326+
} else {
327+
// IPv4 logic
328+
expectedCidrRangeString = *vpcOutput.Vpcs[0].CidrBlock
329+
expectedCidrSplit := strings.Split(*vpcOutput.Vpcs[0].CidrBlock, "/")
316330
expectedSuffix, _ = strconv.Atoi(expectedCidrSplit[1])
317-
_, expectedCIDR, _ = net.ParseCIDR(cidrRangeString)
331+
_, expectedCIDR, _ = net.ParseCIDR(*vpcOutput.Vpcs[0].CidrBlock)
332+
333+
if expectNewCidr {
334+
expectedCidrRangeString = cidrRangeString
335+
expectedCidrSplit = strings.Split(cidrRangeString, "/")
336+
expectedSuffix, _ = strconv.Atoi(expectedCidrSplit[1])
337+
_, expectedCIDR, _ = net.ParseCIDR(cidrRangeString)
338+
}
318339
}
319340

320341
By(fmt.Sprintf("checking the secondary ENI subnets are in the CIDR %s", expectedCidrRangeString))

0 commit comments

Comments
 (0)