diff --git a/pkg/providers/v1/aws.go b/pkg/providers/v1/aws.go index 1e276f237a..3e71cd9fe9 100644 --- a/pkg/providers/v1/aws.go +++ b/pkg/providers/v1/aws.go @@ -1542,6 +1542,19 @@ func extractIPv4NodeAddresses(instance *ec2.Instance) ([]v1.NodeAddress, error) addresses := []v1.NodeAddress{} + // sort by device index so that the first address added to the addresses list is from the first (primary) device + sort.Slice(instance.NetworkInterfaces, func(i, j int) bool { + // These nil checks should cause interfaces with non-nil attachments to sort before those with nil attachments + if instance.NetworkInterfaces[i].Attachment == nil { + return false + } + if instance.NetworkInterfaces[j].Attachment == nil { + return true + } + + return aws.Int64Value(instance.NetworkInterfaces[i].Attachment.DeviceIndex) < aws.Int64Value(instance.NetworkInterfaces[j].Attachment.DeviceIndex) + }) + // handle internal network interfaces for _, networkInterface := range instance.NetworkInterfaces { // skip network interfaces that are not currently in use diff --git a/pkg/providers/v1/aws_fakes.go b/pkg/providers/v1/aws_fakes.go index a4e45a1f29..fa57928076 100644 --- a/pkg/providers/v1/aws_fakes.go +++ b/pkg/providers/v1/aws_fakes.go @@ -77,6 +77,45 @@ func NewFakeAWSServices(clusterID string) *FakeAWSServices { s.selfInstance = selfInstance s.instances = []*ec2.Instance{selfInstance} + selfInstance.NetworkInterfaces = []*ec2.InstanceNetworkInterface{ + { + Attachment: &ec2.InstanceNetworkInterfaceAttachment{ + DeviceIndex: aws.Int64(1), + }, + PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ + { + Primary: aws.Bool(true), + PrivateDnsName: aws.String("ip-172-20-1-100.ec2.internal"), + PrivateIpAddress: aws.String("172.20.1.1"), + }, + { + Primary: aws.Bool(false), + PrivateDnsName: aws.String("ip-172-20-1-101.ec2.internal"), + PrivateIpAddress: aws.String("172.20.1.2"), + }, + }, + Status: aws.String(ec2.NetworkInterfaceStatusInUse), + }, + { + Attachment: &ec2.InstanceNetworkInterfaceAttachment{ + DeviceIndex: aws.Int64(0), + }, + PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ + { + Primary: aws.Bool(true), + PrivateDnsName: aws.String("ip-172-20-0-100.ec2.internal"), + PrivateIpAddress: aws.String("172.20.0.100"), + }, + { + Primary: aws.Bool(false), + PrivateDnsName: aws.String("ip-172-20-0-101.ec2.internal"), + PrivateIpAddress: aws.String("172.20.0.101"), + }, + }, + Status: aws.String(ec2.NetworkInterfaceStatusInUse), + }, + } + var tag ec2.Tag tag.Key = aws.String(TagNameKubernetesClusterLegacy) tag.Value = aws.String(clusterID) diff --git a/pkg/providers/v1/aws_test.go b/pkg/providers/v1/aws_test.go index e3f4145a98..d04cbca790 100644 --- a/pkg/providers/v1/aws_test.go +++ b/pkg/providers/v1/aws_test.go @@ -3790,6 +3790,23 @@ func verifyNodeAddressesForFargate(t *testing.T, ipFamily string, verifyPublicIP assert.Equal(t, v1.NodeInternalIP, nodeAddresses[0].Type) } +func TestNodeAddressesOrderedByDeviceIndex(t *testing.T) { + awsServices := newMockedFakeAWSServices(TestClusterID) + c, _ := newAWSCloud(CloudConfig{}, awsServices) + + nodeAddresses, _ := c.NodeAddressesByProviderID(context.TODO(), "aws:///us-west-2a/i-self") + expectedAddresses := []v1.NodeAddress{ + {Type: v1.NodeInternalIP, Address: "172.20.0.100"}, + {Type: v1.NodeInternalIP, Address: "172.20.0.101"}, + {Type: v1.NodeInternalIP, Address: "172.20.1.1"}, + {Type: v1.NodeInternalIP, Address: "172.20.1.2"}, + {Type: v1.NodeExternalIP, Address: "1.2.3.4"}, + {Type: v1.NodeInternalDNS, Address: "ip-172-20-0-100.ec2.internal"}, + {Type: v1.NodeHostName, Address: "ip-172-20-0-100.ec2.internal"}, + } + assert.Equal(t, expectedAddresses, nodeAddresses) +} + func TestInstanceExistsByProviderIDForFargate(t *testing.T) { awsServices := newMockedFakeAWSServices(TestClusterID) c, _ := newAWSCloud(CloudConfig{}, awsServices)