Skip to content

Commit

Permalink
Provisioning IPv6 prefix to LT if clustter is IPv6
Browse files Browse the repository at this point in the history
  • Loading branch information
haouc committed Nov 7, 2024
1 parent 655d473 commit d4187f7
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 0 deletions.
6 changes: 6 additions & 0 deletions pkg/providers/launchtemplate/launchtemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ type DefaultProvider struct {
CABundle *string
ClusterEndpoint string
ClusterCIDR atomic.Pointer[string]
ClusterIPFamily corev1.IPFamily
}

func NewDefaultProvider(ctx context.Context, cache *cache.Cache, ec2api sdk.EC2API, eksapi sdk.EKSAPI, amiFamily amifamily.Resolver,
Expand All @@ -95,6 +96,7 @@ func NewDefaultProvider(ctx context.Context, cache *cache.Cache, ec2api sdk.EC2A
cm: pretty.NewChangeMonitor(),
KubeDNSIP: kubeDNSIP,
ClusterEndpoint: clusterEndpoint,
ClusterIPFamily: lo.Ternary(kubeDNSIP != nil && kubeDNSIP.To4() == nil, corev1.IPv6Protocol, corev1.IPv4Protocol),
}
l.cache.OnEvicted(l.cachedEvictedFunc(ctx))
go func() {
Expand Down Expand Up @@ -284,6 +286,8 @@ func (p *DefaultProvider) generateNetworkInterfaces(options *amifamily.LaunchTem
// Instances launched with multiple pre-configured network interfaces cannot set AssociatePublicIPAddress to true. This is an EC2 limitation. However, this does not apply for instances
// with a single EFA network interface, and we should support those use cases. Launch failures with multiple enis should be considered user misconfiguration.
AssociatePublicIpAddress: options.AssociatePublicIPAddress,
PrimaryIpv6: lo.Ternary(p.ClusterIPFamily == corev1.IPv6Protocol, lo.ToPtr(true), nil),
Ipv6PrefixCount: lo.Ternary(p.ClusterIPFamily == corev1.IPv6Protocol, lo.ToPtr(int32(1)), nil),
}
})
}
Expand All @@ -296,6 +300,8 @@ func (p *DefaultProvider) generateNetworkInterfaces(options *amifamily.LaunchTem
Groups: lo.Map(options.SecurityGroups, func(s v1.SecurityGroup, _ int) string {
return s.ID
}),
PrimaryIpv6: lo.Ternary(p.ClusterIPFamily == corev1.IPv6Protocol, lo.ToPtr(true), nil),
Ipv6PrefixCount: lo.Ternary(p.ClusterIPFamily == corev1.IPv6Protocol, lo.ToPtr(int32(1)), nil),
},
}
}
Expand Down
9 changes: 9 additions & 0 deletions pkg/providers/launchtemplate/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2245,6 +2245,15 @@ func ExpectLaunchTemplatesCreatedWithUserDataContaining(substrings ...string) {
})
}

func ExpectLaunchTemplatesCreatedWithIPv6PrefixAndPrimaryIPv6() {
GinkgoHelper()
Expect(awsEnv.EC2API.CalledWithCreateLaunchTemplateInput.Len()).To(BeNumerically(">=", 1))
awsEnv.EC2API.CalledWithCreateLaunchTemplateInput.ForEach(func(input *ec2.CreateLaunchTemplateInput) {
Expect(lo.FromPtr(input.LaunchTemplateData.NetworkInterfaces[0].Ipv6PrefixCount)).To(Equal(1))
Expect(lo.FromPtr(input.LaunchTemplateData.NetworkInterfaces[0].PrimaryIpv6)).To(BeTrue())
})
}

func ExpectLaunchTemplatesCreatedWithUserDataNotContaining(substrings ...string) {
GinkgoHelper()
Expect(awsEnv.EC2API.CalledWithCreateLaunchTemplateInput.Len()).To(BeNumerically(">=", 1))
Expand Down
17 changes: 17 additions & 0 deletions test/suites/ipv6/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import (
karpv1 "sigs.k8s.io/karpenter/pkg/apis/v1"
coretest "sigs.k8s.io/karpenter/pkg/test"

"github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/aws/aws-sdk-go-v2/service/ec2/types"

v1 "github.com/aws/karpenter-provider-aws/pkg/apis/v1"
"github.com/aws/karpenter-provider-aws/test/pkg/environment/aws"

Expand Down Expand Up @@ -94,4 +97,18 @@ var _ = Describe("IPv6", func() {
})
Expect(internalIPv6Addrs).To(HaveLen(1))
})
It("should provision a static IPv6 prefix with node launch and set IPv6 as primary in the primary network interface", func() {
output, err := env.EC2API.DescribeInstances(env.Context, &ec2.DescribeInstancesInput{
InstanceIds: []string{coretest.Pod().Spec.NodeName},
})
Expect(err).ShouldNot(HaveOccurred())
Expect(output.Reservations[0].Instances[0].NetworkInterfaces[0].Ipv6Prefixes).To(HaveLen(1))
ipv6IsPrimary := func(ips []types.InstanceIpv6Address) bool {
_, yes := lo.Find(ips, func(ip types.InstanceIpv6Address) bool {
return lo.FromPtr(ip.IsPrimaryIpv6)
})
return yes
}
Expect(ipv6IsPrimary(output.Reservations[0].Instances[0].NetworkInterfaces[0].Ipv6Addresses)).To(BeTrue())
})
})

0 comments on commit d4187f7

Please sign in to comment.