Skip to content

Commit

Permalink
Add ipv6 support. (#1024)
Browse files Browse the repository at this point in the history
* IPv6 infrastructure changes for terraform.

* Request IPv6 addresses in case of IPv6 shoots.

* Set NodeIPFamily to IPv6 for IPv6 shoots.

* Add IPv6 to flow based deploy.

Adapt tests.

* Address review comments.

* Adapt validation.

* Fix after rebase.

* Fix integration tests.

* Fix terraform after rebase.

* fix format

* Address review comments.

* Add comment to getSubnetKey.

* Make generate.

* Fix integration test.

IPv6 addresses of subnets were different for terraform and flow.
This resulted in a subnet changes after migration.

* Check the eogw that belongs to the vpc.
  • Loading branch information
axel7born authored Oct 9, 2024
1 parent 329b188 commit 8975d72
Show file tree
Hide file tree
Showing 22 changed files with 1,023 additions and 286 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,10 @@ data:
KubernetesClusterTag="{{ .Values.clusterName }}"
KubernetesClusterID="{{ .Values.clusterName }}"
Zone="{{ .Values.zone }}"
# https://github.com/kubernetes/cloud-provider-aws/issues/638
{{- if .Values.nodeIPFamilyIPv4 }}
NodeIPFamilies="{{ .Values.nodeIPFamilyIPv4 }}"
{{- end }}
{{- if .Values.nodeIPFamilyIPv6 }}
NodeIPFamilies="{{ .Values.nodeIPFamilyIPv6 }}"
{{- end }}
2 changes: 1 addition & 1 deletion pkg/admission/validator/shoot.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (s *shoot) validateShoot(_ context.Context, shoot *core.Shoot) error {
}

if shoot.Spec.Networking != nil {
if errList := awsvalidation.ValidateInfrastructureConfig(infraConfig, shoot.Spec.Networking.Nodes, shoot.Spec.Networking.Pods, shoot.Spec.Networking.Services); len(errList) != 0 {
if errList := awsvalidation.ValidateInfrastructureConfig(infraConfig, shoot.Spec.Networking.IPFamilies, shoot.Spec.Networking.Nodes, shoot.Spec.Networking.Pods, shoot.Spec.Networking.Services); len(errList) != 0 {
return errList.ToAggregate()
}
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/admission/validator/shoot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ var _ = Describe("Shoot validator", func() {
},
Region: regionName,
Networking: &core.Networking{
Nodes: ptr.To("10.250.0.0/16"),
Nodes: ptr.To("10.250.0.0/16"),
IPFamilies: []core.IPFamily{core.IPFamilyIPv4},
},
},
}
Expand Down
21 changes: 12 additions & 9 deletions pkg/apis/aws/validation/infrastructure.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package validation
import (
"fmt"
"regexp"
"slices"
"strings"

"github.com/gardener/gardener/pkg/apis/core"
Expand Down Expand Up @@ -66,7 +67,7 @@ func validateInfrastructureConfigZones(oldInfra, infra *apisaws.InfrastructureCo
}

// ValidateInfrastructureConfig validates a InfrastructureConfig object.
func ValidateInfrastructureConfig(infra *apisaws.InfrastructureConfig, nodesCIDR, podsCIDR, servicesCIDR *string) field.ErrorList {
func ValidateInfrastructureConfig(infra *apisaws.InfrastructureConfig, ipFamilies []core.IPFamily, nodesCIDR, podsCIDR, servicesCIDR *string) field.ErrorList {
allErrs := field.ErrorList{}

var (
Expand Down Expand Up @@ -109,18 +110,20 @@ func ValidateInfrastructureConfig(infra *apisaws.InfrastructureConfig, nodesCIDR
for i, zone := range infra.Networks.Zones {
zonePath := networksPath.Child("zones").Index(i)

internalPath := zonePath.Child("internal")
cidrs = append(cidrs, cidrvalidation.NewCIDR(zone.Internal, internalPath))
allErrs = append(allErrs, cidrvalidation.ValidateCIDRIsCanonical(internalPath, zone.Internal)...)

publicPath := zonePath.Child("public")
cidrs = append(cidrs, cidrvalidation.NewCIDR(zone.Public, publicPath))
allErrs = append(allErrs, cidrvalidation.ValidateCIDRIsCanonical(publicPath, zone.Public)...)

workerPath := zonePath.Child("workers")
cidrs = append(cidrs, cidrvalidation.NewCIDR(zone.Workers, workerPath))
allErrs = append(allErrs, cidrvalidation.ValidateCIDRIsCanonical(workerPath, zone.Workers)...)
workerCIDRs = append(workerCIDRs, cidrvalidation.NewCIDR(zone.Workers, workerPath))
if ipFamilies == nil || slices.Contains(ipFamilies, core.IPFamilyIPv4) {
internalPath := zonePath.Child("internal")
cidrs = append(cidrs, cidrvalidation.NewCIDR(zone.Internal, internalPath))
allErrs = append(allErrs, cidrvalidation.ValidateCIDRIsCanonical(internalPath, zone.Internal)...)

workerPath := zonePath.Child("workers")
cidrs = append(cidrs, cidrvalidation.NewCIDR(zone.Workers, workerPath))
allErrs = append(allErrs, cidrvalidation.ValidateCIDRIsCanonical(workerPath, zone.Workers)...)
workerCIDRs = append(workerCIDRs, cidrvalidation.NewCIDR(zone.Workers, workerPath))
}

if zone.ElasticIPAllocationID != nil {
for _, eIP := range referencedElasticIPAllocationIDs {
Expand Down
51 changes: 26 additions & 25 deletions pkg/apis/aws/validation/infrastructure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ var _ = Describe("InfrastructureConfig validation", func() {
Public: "10.250.5.0/24",
Workers: "10.250.6.0/24",
}
familyIPv4 = []core.IPFamily{core.IPFamilyIPv4}
)

BeforeEach(func() {
Expand Down Expand Up @@ -165,7 +166,7 @@ var _ = Describe("InfrastructureConfig validation", func() {
It("should forbid empty zones", func() {
infrastructureConfig.Networks.Zones = nil

errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)

Expect(errorList).To(ConsistOfFields(Fields{
"Type": Equal(field.ErrorTypeRequired),
Expand All @@ -175,20 +176,20 @@ var _ = Describe("InfrastructureConfig validation", func() {
})

It("should allow specifying valid config", func() {
errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)
Expect(errorList).To(BeEmpty())
})

It("should allow specifying valid config with podsCIDR=nil and servicesCIDR=nil", func() {
errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, nil, nil)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, nil, nil)
Expect(errorList).To(BeEmpty())
})

It("should allow adding the same zone", func() {
infrastructureConfig.Networks.Zones = append(infrastructureConfig.Networks.Zones, awsZone2)
infrastructureConfig.Networks.Zones[1].Name = zone

errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)

Expect(errorList).To(BeEmpty())
})
Expand All @@ -197,7 +198,7 @@ var _ = Describe("InfrastructureConfig validation", func() {
It("should forbid invalid VPC CIDRs", func() {
infrastructureConfig.Networks.VPC.CIDR = &invalidCIDR

errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)

Expect(errorList).To(ConsistOfFields(Fields{
"Type": Equal(field.ErrorTypeInvalid),
Expand All @@ -209,7 +210,7 @@ var _ = Describe("InfrastructureConfig validation", func() {
It("should forbid invalid internal CIDR", func() {
infrastructureConfig.Networks.Zones[0].Internal = invalidCIDR

errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)

Expect(errorList).To(ConsistOfFields(Fields{
"Type": Equal(field.ErrorTypeInvalid),
Expand All @@ -221,7 +222,7 @@ var _ = Describe("InfrastructureConfig validation", func() {
It("should forbid invalid public CIDR", func() {
infrastructureConfig.Networks.Zones[0].Public = invalidCIDR

errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)

Expect(errorList).To(ConsistOfFields(Fields{
"Type": Equal(field.ErrorTypeInvalid),
Expand All @@ -233,7 +234,7 @@ var _ = Describe("InfrastructureConfig validation", func() {
It("should forbid invalid workers CIDR", func() {
infrastructureConfig.Networks.Zones[0].Workers = invalidCIDR

errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)

Expect(errorList).To(ConsistOfFields(Fields{
"Type": Equal(field.ErrorTypeInvalid),
Expand All @@ -245,7 +246,7 @@ var _ = Describe("InfrastructureConfig validation", func() {
It("should forbid internal CIDR which is not in VPC CIDR", func() {
infrastructureConfig.Networks.Zones[0].Internal = "1.1.1.1/32"

errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)

Expect(errorList).To(ConsistOfFields(Fields{
"Type": Equal(field.ErrorTypeInvalid),
Expand All @@ -257,7 +258,7 @@ var _ = Describe("InfrastructureConfig validation", func() {
It("should forbid public CIDR which is not in VPC CIDR", func() {
infrastructureConfig.Networks.Zones[0].Public = "1.1.1.1/32"

errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)

Expect(errorList).To(ConsistOfFields(Fields{
"Type": Equal(field.ErrorTypeInvalid),
Expand All @@ -269,7 +270,7 @@ var _ = Describe("InfrastructureConfig validation", func() {
It("should forbid workers CIDR which are not in VPC and Nodes CIDR", func() {
infrastructureConfig.Networks.Zones[0].Workers = "1.1.1.1/32"

errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)

Expect(errorList).To(ConsistOfFields(Fields{
"Type": Equal(field.ErrorTypeInvalid),
Expand All @@ -285,7 +286,7 @@ var _ = Describe("InfrastructureConfig validation", func() {
It("should forbid Pod CIDR to overlap with VPC CIDR", func() {
podCIDR := "10.0.0.1/32"

errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &podCIDR, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &podCIDR, &services)

Expect(errorList).To(ConsistOfFields(Fields{
"Type": Equal(field.ErrorTypeInvalid),
Expand All @@ -296,7 +297,7 @@ var _ = Describe("InfrastructureConfig validation", func() {
It("should forbid Services CIDR to overlap with VPC CIDR", func() {
servicesCIDR := "10.0.0.1/32"

errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &servicesCIDR)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &servicesCIDR)

Expect(errorList).To(ConsistOfFields(Fields{
"Type": Equal(field.ErrorTypeInvalid),
Expand All @@ -310,12 +311,12 @@ var _ = Describe("InfrastructureConfig validation", func() {
infrastructureConfig.Networks.Zones[0].Public = overlappingCIDR
infrastructureConfig.Networks.Zones[0].Workers = overlappingCIDR

errorList := ValidateInfrastructureConfig(infrastructureConfig, &overlappingCIDR, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &overlappingCIDR, &pods, &services)

Expect(errorList).To(ConsistOfFields(Fields{
"Type": Equal(field.ErrorTypeInvalid),
"Field": Equal("networks.zones[0].public"),
"Detail": Equal(`must not overlap with "networks.zones[0].internal" ("10.250.0.1/32")`),
"Field": Equal("networks.zones[0].internal"),
"Detail": Equal(`must not overlap with "networks.zones[0].public" ("10.250.0.1/32")`),
}, Fields{
"Type": Equal(field.ErrorTypeInvalid),
"Field": Equal("networks.zones[0].workers"),
Expand All @@ -334,7 +335,7 @@ var _ = Describe("InfrastructureConfig validation", func() {
infrastructureConfig.Networks.Zones[0].Workers = "10.250.3.8/24"
infrastructureConfig.Networks.VPC = apisaws.VPC{CIDR: &vpcCIDR}

errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)

Expect(errorList).To(HaveLen(4))
Expect(errorList).To(ConsistOfFields(Fields{
Expand All @@ -359,14 +360,14 @@ var _ = Describe("InfrastructureConfig validation", func() {

It("should ensure that the elastic IP allocation id starts with `eipalloc-`", func() {
infrastructureConfig.Networks.Zones[0].ElasticIPAllocationID = ptr.To("foo")
errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)
Expect(errorList).To(ConsistOfFields(Fields{
"Type": Equal(field.ErrorTypeInvalid),
"Field": Equal("networks.zones[0].elasticIPAllocationID"),
}))

infrastructureConfig.Networks.Zones[0].ElasticIPAllocationID = ptr.To("eipalloc-123456")
errorList = ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList = ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)
Expect(errorList).To(BeEmpty())
})

Expand All @@ -375,27 +376,27 @@ var _ = Describe("InfrastructureConfig validation", func() {
infrastructureConfig.Networks.Zones[0].ElasticIPAllocationID = ptr.To("eipalloc-123456")
infrastructureConfig.Networks.Zones[1].ElasticIPAllocationID = ptr.To("eipalloc-123456")

errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)
Expect(errorList).To(ConsistOfFields(Fields{
"Type": Equal(field.ErrorTypeDuplicate),
"Field": Equal("networks.zones[1].elasticIPAllocationID"),
}))

infrastructureConfig.Networks.Zones[1].ElasticIPAllocationID = ptr.To("eipalloc-654321")
errorList = ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList = ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)
Expect(errorList).To(BeEmpty())
})
})

Context("gatewayEndpoints", func() {
It("should accept empty list", func() {
errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)
Expect(errorList).To(BeEmpty())
})

It("should reject non-alphanumeric endpoints", func() {
infrastructureConfig.Networks.VPC.GatewayEndpoints = []string{"s3", "my-endpoint"}
errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)
Expect(errorList).To(ConsistOfFields(Fields{
"Type": Equal(field.ErrorTypeInvalid),
"Field": Equal("networks.vpc.gatewayEndpoints[1]"),
Expand All @@ -406,7 +407,7 @@ var _ = Describe("InfrastructureConfig validation", func() {

It("should accept all-valid lists", func() {
infrastructureConfig.Networks.VPC.GatewayEndpoints = []string{"myservice", "s3", "my.other.service"}
errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)
Expect(errorList).To(BeEmpty())
})
})
Expand All @@ -417,7 +418,7 @@ var _ = Describe("InfrastructureConfig validation", func() {
Keys: []string{"Name"},
KeyPrefixes: []string{"kubernetes.io/", "gardener.cloud/"},
}
errorList := ValidateInfrastructureConfig(infrastructureConfig, &nodes, &pods, &services)
errorList := ValidateInfrastructureConfig(infrastructureConfig, familyIPv4, &nodes, &pods, &services)
Expect(errorList).NotTo(BeEmpty())
})
})
Expand Down
3 changes: 2 additions & 1 deletion pkg/apis/aws/validation/shoot.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package validation

import (
"fmt"
"slices"

"github.com/gardener/gardener/pkg/apis/core"
validationutils "github.com/gardener/gardener/pkg/utils/validation"
Expand All @@ -20,7 +21,7 @@ import (
func ValidateNetworking(networking *core.Networking, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if networking.Nodes == nil {
if networking.Nodes == nil && (networking.IPFamilies == nil || slices.Contains(networking.IPFamilies, core.IPFamilyIPv4)) {
allErrs = append(allErrs, field.Required(fldPath.Child("nodes"), "a nodes CIDR must be provided for AWS shoots"))
}

Expand Down
1 change: 1 addition & 0 deletions pkg/apis/aws/validation/shoot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ var _ = Describe("Shoot validation", func() {

It("should return an error because no nodes CIDR was provided", func() {
networking := &core.Networking{}
networking.IPFamilies = []core.IPFamily{core.IPFamilyIPv4}

errorList := ValidateNetworking(networking, networkingPath)

Expand Down
Loading

0 comments on commit 8975d72

Please sign in to comment.