Skip to content

Commit

Permalink
Support dynamic IPv4 EKS service CIDR
Browse files Browse the repository at this point in the history
Signed-off-by: Mikkel Oscar Lyderik Larsen <[email protected]>
  • Loading branch information
mikkeloscar committed Oct 4, 2024
1 parent e4d369d commit 5038b8e
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 21 deletions.
15 changes: 11 additions & 4 deletions provisioner/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@ type EKSClusterDetails struct {
Endpoint string
CertificateAuthority string
OIDCIssuerURL string
ServiceIPv6CIDR string
ServiceCIDR string
}

func (a *awsAdapter) GetEKSClusterDetails(cluster *api.Cluster) (*EKSClusterDetails, error) {
Expand All @@ -772,10 +772,17 @@ func (a *awsAdapter) GetEKSClusterDetails(cluster *api.Cluster) (*EKSClusterDeta
return nil, err
}

return &EKSClusterDetails{
clusterDetails := &EKSClusterDetails{
Endpoint: aws.StringValue(resp.Cluster.Endpoint),
CertificateAuthority: aws.StringValue(resp.Cluster.CertificateAuthority.Data),
OIDCIssuerURL: aws.StringValue(resp.Cluster.Identity.Oidc.Issuer),
ServiceIPv6CIDR: aws.StringValue(resp.Cluster.KubernetesNetworkConfig.ServiceIpv6Cidr),
}, nil
}

if aws.StringValue(resp.Cluster.KubernetesNetworkConfig.IpFamily) == "ipv4" {
clusterDetails.ServiceCIDR = aws.StringValue(resp.Cluster.KubernetesNetworkConfig.ServiceIpv4Cidr)
} else {
clusterDetails.ServiceCIDR = aws.StringValue(resp.Cluster.KubernetesNetworkConfig.ServiceIpv6Cidr)
}

return clusterDetails, nil
}
4 changes: 2 additions & 2 deletions provisioner/clusterpy.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,8 @@ func (p *clusterpyProvisioner) provision(
if postOptions.APIServerURL != "" {
cluster.APIServerURL = postOptions.APIServerURL
}
if postOptions.ServiceIPv6CIDR != "" {
cluster.ConfigItems["service_ipv6_cidr"] = postOptions.ServiceIPv6CIDR
if postOptions.ServiceCIDR != "" {
cluster.ConfigItems["service_cidr"] = postOptions.ServiceCIDR
}
}

Expand Down
6 changes: 3 additions & 3 deletions provisioner/provisioner.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ type (
// HookResponse contain configuration parameters that a provisioner can use
// at a later stage.
HookResponse struct {
APIServerURL string
CAData []byte
ServiceIPv6CIDR string
APIServerURL string
CAData []byte
ServiceCIDR string
}

// Options is the options that can be passed to a provisioner when initialized.
Expand Down
27 changes: 19 additions & 8 deletions provisioner/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func renderTemplate(context *templateContext, file string) (string, error) {
},
"nodeCIDRMaxNodesPodCIDR": nodeCIDRMaxNodes,
"nodeCIDRMaxPods": nodeCIDRMaxPods,
"addressNFromIPv6CIDR": addressNFromIPv6CIDR,
"nthAddressFromCIDR": nthAddressFromCIDR,
"parseInt64": parseInt64,
"generateJWKSDocument": generateJWKSDocument,
"generateOIDCDiscoveryDocument": generateOIDCDiscoveryDocument,
Expand Down Expand Up @@ -582,22 +582,33 @@ func nodeCIDRMaxPods(maskSize int64, extraCapacity int64) (int64, error) {
return maxPods, nil
}

// addressNFromIPv6CIDR takes an IPv6 CIDR and returns the Nth address in the
// subnet.
func addressNFromIPv6CIDR(cidr string, n int) (string, error) {
// nthAddressFromCIDR takes an IPv4 or IPv6 CIDR and returns the Nth address in
// the subnet.
func nthAddressFromCIDR(cidr string, n int) (string, error) {
_, ipNet, err := net.ParseCIDR(cidr)
if err != nil {
return "", err
}

ip := ipNet.IP
ip = ip.To16()
if ip == nil {
return "", fmt.Errorf("invalid IP address: %s", ipNet.IP)

nthByte := 0
if ip.To4() != nil {
// ipv4 address
nthByte = 3
ip = ip.To4()
} else {
// ipv6 address
ip = ip.To16()
if ip == nil {
return "", fmt.Errorf("invalid IP address: %s", ipNet.IP)
}
nthByte = 15
}

ip = ip.Mask(ipNet.Mask)
for i := 0; i < n; i++ {
ip[15]++
ip[nthByte]++
}
return ip.String(), nil
}
Expand Down
18 changes: 15 additions & 3 deletions provisioner/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1486,24 +1486,36 @@ func TestScalingTemplate(t *testing.T) {
}
}

func TestAddressNFromIPv6CIDR(t *testing.T) {
func TestNthAddressFromCIDR(t *testing.T) {
for _, tc := range []struct {
name string
cidr string
input string
expected string
err bool
}{
{
name: "50th address of IPv4 CIDR",
cidr: "172.20.0.0/16",
input: `{{ nthAddressFromCIDR .Values.data.cidr 50 }}`,
expected: "172.20.0.50",
},
{
name: "invalid CIDR causes error",
cidr: "172.20.0.0/100", // invalid CIDR
input: `{{ nthAddressFromCIDR .Values.data.cidr 50 }}`,
err: true,
},
{
name: "50th address of IPv6 CIDR",
cidr: "2a05:d014:9c0:bf05::/64",
input: `{{ addressNFromIPv6CIDR .Values.data.cidr 50 }}`,
input: `{{ nthAddressFromCIDR .Values.data.cidr 50 }}`,
expected: "2a05:d014:9c0:bf05::32",
},
{
name: "invalid CIDR causes error",
cidr: "2a05:d014:9c0:bf05::/2000", // invalid CIDR
input: `{{ addressNFromIPv6CIDR .Values.data.cidr 50 }}`,
input: `{{ nthAddressFromCIDR .Values.data.cidr 50 }}`,
err: true,
},
} {
Expand Down
2 changes: 1 addition & 1 deletion provisioner/zalando_eks.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ func (z *ZalandoEKSCreationHook) Execute(

res.APIServerURL = clusterDetails.Endpoint
res.CAData = decodedCA
res.ServiceIPv6CIDR = clusterDetails.ServiceIPv6CIDR
res.ServiceCIDR = clusterDetails.ServiceCIDR

return res, nil
}

0 comments on commit 5038b8e

Please sign in to comment.