From 45183569b1e0c90d46e861a800bf8f5f0470e9ca Mon Sep 17 00:00:00 2001 From: Pavani Panakanti Date: Thu, 26 Sep 2024 22:57:57 +0000 Subject: [PATCH 1/3] Filter for interfaces with no ip info --- pkg/awsutils/awsutils.go | 166 ++++++++++++++++++++++------------ pkg/awsutils/awsutils_test.go | 59 ++++++++---- pkg/awsutils/imds.go | 18 ++++ 3 files changed, 167 insertions(+), 76 deletions(-) diff --git a/pkg/awsutils/awsutils.go b/pkg/awsutils/awsutils.go index f9ba346915..cc2dbec621 100644 --- a/pkg/awsutils/awsutils.go +++ b/pkg/awsutils/awsutils.go @@ -603,89 +603,130 @@ func (cache *EC2InstanceMetadataCache) getENIMetadata(eniMAC string) (ENIMetadat } log.Debugf("Found ENI: %s, MAC %s, device %d", eniID, eniMAC, deviceNum) - - // Get IPv4 and IPv6 addresses assigned to interface - cidr, err := cache.imds.GetSubnetIPv4CIDRBlock(ctx, eniMAC) - if err != nil { - awsAPIErrInc("GetSubnetIPv4CIDRBlock", err) - return ENIMetadata{}, err - } - - imdsIPv4s, err := cache.imds.GetLocalIPv4s(ctx, eniMAC) + // Get IMDS fields for the interface + macImdsFields, err := cache.imds.GetMACImdsFields(ctx, eniMAC) if err != nil { - awsAPIErrInc("GetLocalIPv4s", err) + awsAPIErrInc("GetMACImdsFields", err) return ENIMetadata{}, err } - - ec2ip4s := make([]*ec2.NetworkInterfacePrivateIpAddress, len(imdsIPv4s)) - for i, ip4 := range imdsIPv4s { - ec2ip4s[i] = &ec2.NetworkInterfacePrivateIpAddress{ - Primary: aws.Bool(i == 0), - PrivateIpAddress: aws.String(ip4.String()), + isEFAOnlyInterface := true + // Efa-only interfaces do not have any ipv4s or ipv6s associated with it. If we don't find any local-ipv4 or ipv6 info in imds we assume it to be efa-only interface and validate this later via ec2 call n + for _, field := range macImdsFields { + if field == "local-ipv4s" { + imdsIPv4s, err := cache.imds.GetLocalIPv4s(ctx, eniMAC) + if err != nil { + awsAPIErrInc("GetLocalIPv4s", err) + return ENIMetadata{}, err + } + if len(imdsIPv4s) > 0 { + isEFAOnlyInterface = false + log.Debugf("Found IPv4 addresses associated with interface. This is not efa-only interface") + break + } + } + if field == "ipv6s" { + imdsIPv6s, err := cache.imds.GetIPv6s(ctx, eniMAC) + if err != nil { + awsAPIErrInc("GetIPv6s", err) + } else if len(imdsIPv6s) > 0 { + isEFAOnlyInterface = false + log.Debugf("Found IPv6 addresses associated with interface. This is not efa-only interface") + break + } } } + var subnetV4Cidr string + var ec2ip4s []*ec2.NetworkInterfacePrivateIpAddress var ec2ip6s []*ec2.NetworkInterfaceIpv6Address var subnetV6Cidr string - if cache.v6Enabled { - // For IPv6 ENIs, do not error on missing IPv6 information - v6cidr, err := cache.imds.GetSubnetIPv6CIDRBlocks(ctx, eniMAC) - if err != nil { - awsAPIErrInc("GetSubnetIPv6CIDRBlocks", err) - } else { - subnetV6Cidr = v6cidr.String() - } + var ec2ipv4Prefixes []*ec2.Ipv4PrefixSpecification + var ec2ipv6Prefixes []*ec2.Ipv6PrefixSpecification - imdsIPv6s, err := cache.imds.GetIPv6s(ctx, eniMAC) + // Do no fetch ip related info for Efa-only interfaces + if !isEFAOnlyInterface { + // Get IPv4 and IPv6 addresses assigned to interface + cidr, err := cache.imds.GetSubnetIPv4CIDRBlock(ctx, eniMAC) if err != nil { - awsAPIErrInc("GetIPv6s", err) + awsAPIErrInc("GetSubnetIPv4CIDRBlock", err) + return ENIMetadata{}, err } else { - ec2ip6s = make([]*ec2.NetworkInterfaceIpv6Address, len(imdsIPv6s)) - for i, ip6 := range imdsIPv6s { - ec2ip6s[i] = &ec2.NetworkInterfaceIpv6Address{ - Ipv6Address: aws.String(ip6.String()), - } - } + subnetV4Cidr = cidr.String() } - } - - var ec2ipv4Prefixes []*ec2.Ipv4PrefixSpecification - var ec2ipv6Prefixes []*ec2.Ipv6PrefixSpecification - // If IPv6 is enabled, get attached v6 prefixes. - if cache.v6Enabled { - imdsIPv6Prefixes, err := cache.imds.GetIPv6Prefixes(ctx, eniMAC) + imdsIPv4s, err := cache.imds.GetLocalIPv4s(ctx, eniMAC) if err != nil { - awsAPIErrInc("GetIPv6Prefixes", err) + awsAPIErrInc("GetLocalIPv4s", err) return ENIMetadata{}, err } - for _, ipv6prefix := range imdsIPv6Prefixes { - ec2ipv6Prefixes = append(ec2ipv6Prefixes, &ec2.Ipv6PrefixSpecification{ - Ipv6Prefix: aws.String(ipv6prefix.String()), - }) + + ec2ip4s = make([]*ec2.NetworkInterfacePrivateIpAddress, len(imdsIPv4s)) + for i, ip4 := range imdsIPv4s { + ec2ip4s[i] = &ec2.NetworkInterfacePrivateIpAddress{ + Primary: aws.Bool(i == 0), + PrivateIpAddress: aws.String(ip4.String()), + } } - } else if cache.v4Enabled && ((eniMAC == primaryMAC && !cache.useCustomNetworking) || (eniMAC != primaryMAC)) { - // Get prefix on primary ENI when custom networking is enabled is not needed. - // If primary ENI has prefixes attached and then we move to custom networking, we don't need to fetch - // the prefix since recommendation is to terminate the nodes and that would have deleted the prefix on the - // primary ENI. - imdsIPv4Prefixes, err := cache.imds.GetIPv4Prefixes(ctx, eniMAC) - if err != nil { - awsAPIErrInc("GetIPv4Prefixes", err) - return ENIMetadata{}, err + + if cache.v6Enabled { + // For IPv6 ENIs, do not error on missing IPv6 information + v6cidr, err := cache.imds.GetSubnetIPv6CIDRBlocks(ctx, eniMAC) + if err != nil { + awsAPIErrInc("GetSubnetIPv6CIDRBlocks", err) + } else { + subnetV6Cidr = v6cidr.String() + } + + imdsIPv6s, err := cache.imds.GetIPv6s(ctx, eniMAC) + if err != nil { + awsAPIErrInc("GetIPv6s", err) + } else { + ec2ip6s = make([]*ec2.NetworkInterfaceIpv6Address, len(imdsIPv6s)) + for i, ip6 := range imdsIPv6s { + ec2ip6s[i] = &ec2.NetworkInterfaceIpv6Address{ + Ipv6Address: aws.String(ip6.String()), + } + } + } } - for _, ipv4prefix := range imdsIPv4Prefixes { - ec2ipv4Prefixes = append(ec2ipv4Prefixes, &ec2.Ipv4PrefixSpecification{ - Ipv4Prefix: aws.String(ipv4prefix.String()), - }) + + // If IPv6 is enabled, get attached v6 prefixes. + if cache.v6Enabled { + imdsIPv6Prefixes, err := cache.imds.GetIPv6Prefixes(ctx, eniMAC) + if err != nil { + awsAPIErrInc("GetIPv6Prefixes", err) + return ENIMetadata{}, err + } + for _, ipv6prefix := range imdsIPv6Prefixes { + ec2ipv6Prefixes = append(ec2ipv6Prefixes, &ec2.Ipv6PrefixSpecification{ + Ipv6Prefix: aws.String(ipv6prefix.String()), + }) + } + } else if cache.v4Enabled && ((eniMAC == primaryMAC && !cache.useCustomNetworking) || (eniMAC != primaryMAC)) { + // Get prefix on primary ENI when custom networking is enabled is not needed. + // If primary ENI has prefixes attached and then we move to custom networking, we don't need to fetch + // the prefix since recommendation is to terminate the nodes and that would have deleted the prefix on the + // primary ENI. + imdsIPv4Prefixes, err := cache.imds.GetIPv4Prefixes(ctx, eniMAC) + if err != nil { + awsAPIErrInc("GetIPv4Prefixes", err) + return ENIMetadata{}, err + } + for _, ipv4prefix := range imdsIPv4Prefixes { + ec2ipv4Prefixes = append(ec2ipv4Prefixes, &ec2.Ipv4PrefixSpecification{ + Ipv4Prefix: aws.String(ipv4prefix.String()), + }) + } } + } else { + log.Debugf("No ipv4 or ipv6 info associated with this interface. This might be efa-only interface") } return ENIMetadata{ ENIID: eniID, MAC: eniMAC, DeviceNumber: deviceNum, - SubnetIPv4CIDR: cidr.String(), + SubnetIPv4CIDR: subnetV4Cidr, IPv4Addresses: ec2ip4s, IPv4Prefixes: ec2ipv4Prefixes, SubnetIPv6CIDR: subnetV6Cidr, @@ -1356,9 +1397,16 @@ func (cache *EC2InstanceMetadataCache) DescribeAllENIs() (DescribeAllENIsResult, if interfaceType == "trunk" { trunkENI = eniID } - if interfaceType == "efa" { + if interfaceType == "efa" || interfaceType == "efa-only" { efaENIs[eniID] = true } + if interfaceType != "efa-only" { + if len(eniMetadata.IPv4Addresses) == 0 && len(eniMetadata.IPv6Addresses) == 0 { + log.Errorf("Missing IP addresses from IMDS. Non efa-only interface should have IP address associated with it %s", eniID) + outOfSyncErr := errors.New("DescribeAllENIs: No IP addresses found") + return DescribeAllENIsResult{}, outOfSyncErr + } + } // Check IPv4 addresses logOutOfSyncState(eniID, eniMetadata.IPv4Addresses, ec2res.PrivateIpAddresses) tagMap[eniMetadata.ENIID] = convertSDKTagsToTags(ec2res.TagSet) diff --git a/pkg/awsutils/awsutils_test.go b/pkg/awsutils/awsutils_test.go index cf93040526..e923a82bcc 100644 --- a/pkg/awsutils/awsutils_test.go +++ b/pkg/awsutils/awsutils_test.go @@ -80,16 +80,19 @@ const ( eni2ID = "eni-12341234" metadataVPCIPv4CIDRs = "192.168.0.0/16 100.66.0.0/1" myNodeName = "testNodeName" + imdsMACFields = "security-group-ids subnet-id vpc-id vpc-ipv4-cidr-blocks device-number interface-id subnet-ipv4-cidr-block local-ipv4s ipv4-prefix ipv6-prefix" + imdsMACFieldsEfaOnly = "security-group-ids subnet-id vpc-id vpc-ipv4-cidr-blocks device-number interface-id subnet-ipv4-cidr-block ipv4-prefix ipv6-prefix" ) func testMetadata(overrides map[string]interface{}) FakeIMDS { data := map[string]interface{}{ - metadataAZ: az, - metadataLocalIP: localIP, - metadataInstanceID: instanceID, - metadataInstanceType: instanceType, - metadataMAC: primaryMAC, - metadataMACPath: primaryMAC, + metadataAZ: az, + metadataLocalIP: localIP, + metadataInstanceID: instanceID, + metadataInstanceType: instanceType, + metadataMAC: primaryMAC, + metadataMACPath: primaryMAC, + metadataMACPath + primaryMAC: imdsMACFields, metadataMACPath + primaryMAC + metadataDeviceNum: eni1Device, metadataMACPath + primaryMAC + metadataInterface: primaryeniID, metadataMACPath + primaryMAC + metadataSGs: sgs, @@ -109,12 +112,13 @@ func testMetadata(overrides map[string]interface{}) FakeIMDS { func testMetadataWithPrefixes(overrides map[string]interface{}) FakeIMDS { data := map[string]interface{}{ - metadataAZ: az, - metadataLocalIP: localIP, - metadataInstanceID: instanceID, - metadataInstanceType: instanceType, - metadataMAC: primaryMAC, - metadataMACPath: primaryMAC, + metadataAZ: az, + metadataLocalIP: localIP, + metadataInstanceID: instanceID, + metadataInstanceType: instanceType, + metadataMAC: primaryMAC, + metadataMACPath: primaryMAC, + metadataMACPath + primaryMAC: imdsMACFields, metadataMACPath + primaryMAC + metadataDeviceNum: eni1Device, metadataMACPath + primaryMAC + metadataInterface: primaryeniID, metadataMACPath + primaryMAC + metadataSGs: sgs, @@ -203,7 +207,8 @@ func TestInitWithEC2metadataErr(t *testing.T) { func TestGetAttachedENIs(t *testing.T) { mockMetadata := testMetadata(map[string]interface{}{ - metadataMACPath: primaryMAC + " " + eni2MAC, + metadataMACPath: primaryMAC + " " + eni2MAC, + metadataMACPath + eni2MAC: imdsMACFields, metadataMACPath + eni2MAC + metadataDeviceNum: eni2Device, metadataMACPath + eni2MAC + metadataInterface: eni2ID, metadataMACPath + eni2MAC + metadataSubnetCIDR: subnetCIDR, @@ -217,9 +222,26 @@ func TestGetAttachedENIs(t *testing.T) { } } +func TestGetAttachedENIsWithEfaOnly(t *testing.T) { + mockMetadata := testMetadata(map[string]interface{}{ + metadataMACPath: primaryMAC + " " + eni2MAC, + metadataMACPath + eni2MAC: imdsMACFieldsEfaOnly, + metadataMACPath + eni2MAC + metadataDeviceNum: eni2Device, + metadataMACPath + eni2MAC + metadataInterface: eni2ID, + metadataMACPath + eni2MAC + metadataSubnetCIDR: subnetCIDR, + }) + + cache := &EC2InstanceMetadataCache{imds: TypedIMDS{mockMetadata}} + ens, err := cache.GetAttachedENIs() + if assert.NoError(t, err) { + assert.Equal(t, len(ens), 2) + } +} + func TestGetAttachedENIsWithPrefixes(t *testing.T) { mockMetadata := testMetadata(map[string]interface{}{ - metadataMACPath: primaryMAC + " " + eni2MAC, + metadataMACPath: primaryMAC + " " + eni2MAC, + metadataMACPath + eni2MAC: imdsMACFields, metadataMACPath + eni2MAC + metadataDeviceNum: eni2Device, metadataMACPath + eni2MAC + metadataInterface: eni2ID, metadataMACPath + eni2MAC + metadataSubnetCIDR: subnetCIDR, @@ -343,6 +365,7 @@ func TestDescribeAllENIs(t *testing.T) { Attachment: &ec2.NetworkInterfaceAttachment{ NetworkCardIndex: aws.Int64(0), }, + NetworkInterfaceId: aws.String(primaryeniID), }}, } @@ -357,7 +380,7 @@ func TestDescribeAllENIs(t *testing.T) { awsErr error expErr error }{ - {"Success DescribeENI", map[string]TagMap{"": {"foo": "foo-value"}}, 1, nil, nil}, + {"Success DescribeENI", map[string]TagMap{"eni-00000000": {"foo": "foo-value"}}, 1, nil, nil}, {"Not found error", nil, maxENIEC2APIRetries, awserr.New("InvalidNetworkInterfaceID.NotFound", "no 'eni-xxx'", nil), expectedError}, {"Not found, no message", nil, maxENIEC2APIRetries, awserr.New("InvalidNetworkInterfaceID.NotFound", "no message", nil), noMessageError}, {"Other error", nil, maxENIEC2APIRetries, err, err}, @@ -1006,7 +1029,8 @@ func TestEC2InstanceMetadataCache_waitForENIAndIPsAttached(t *testing.T) { } fmt.Println("eniips", eniIPs) mockMetadata := testMetadata(map[string]interface{}{ - metadataMACPath: primaryMAC + " " + eni2MAC, + metadataMACPath: primaryMAC + " " + eni2MAC, + metadataMACPath + eni2MAC: imdsMACFields, metadataMACPath + eni2MAC + metadataDeviceNum: eni2Device, metadataMACPath + eni2MAC + metadataInterface: eni2ID, metadataMACPath + eni2MAC + metadataSubnetCIDR: subnetCIDR, @@ -1101,7 +1125,8 @@ func TestEC2InstanceMetadataCache_waitForENIAndPrefixesAttached(t *testing.T) { eniPrefixes = "" } mockMetadata := testMetadata(map[string]interface{}{ - metadataMACPath: primaryMAC + " " + eni2MAC, + metadataMACPath: primaryMAC + " " + eni2MAC, + metadataMACPath + eni2MAC: imdsMACFields, metadataMACPath + eni2MAC + metadataDeviceNum: eni2Device, metadataMACPath + eni2MAC + metadataInterface: eni2ID, metadataMACPath + eni2MAC + metadataSubnetCIDR: subnetCIDR, diff --git a/pkg/awsutils/imds.go b/pkg/awsutils/imds.go index 69c9343501..ab845eeb45 100644 --- a/pkg/awsutils/imds.go +++ b/pkg/awsutils/imds.go @@ -136,6 +136,24 @@ func (imds TypedIMDS) GetMACs(ctx context.Context) ([]string, error) { return list, err } +// GetMACImdsFields returns the imds fields present for a MAC +func (imds TypedIMDS) GetMACImdsFields(ctx context.Context, mac string) ([]string, error) { + key := fmt.Sprintf("network/interfaces/macs/%s", mac) + list, err := imds.getList(ctx, key) + if err != nil { + if imdsErr, ok := err.(*imdsRequestError); ok { + log.Warnf("%v", err) + return nil, imdsErr.err + } + return nil, err + } + // Remove trailing / + for i, item := range list { + list[i] = strings.TrimSuffix(item, "/") + } + return list, err +} + // GetInterfaceID returns the ID of the network interface. func (imds TypedIMDS) GetInterfaceID(ctx context.Context, mac string) (string, error) { key := fmt.Sprintf("network/interfaces/macs/%s/interface-id", mac) From 36a89916e2fbe75438273c624b6b91803979cb3f Mon Sep 17 00:00:00 2001 From: Pavani Panakanti Date: Fri, 27 Sep 2024 01:21:07 +0000 Subject: [PATCH 2/3] code refactor --- pkg/awsutils/awsutils.go | 158 ++++++++++++++++++++------------------- 1 file changed, 82 insertions(+), 76 deletions(-) diff --git a/pkg/awsutils/awsutils.go b/pkg/awsutils/awsutils.go index cc2dbec621..892b840756 100644 --- a/pkg/awsutils/awsutils.go +++ b/pkg/awsutils/awsutils.go @@ -603,14 +603,15 @@ func (cache *EC2InstanceMetadataCache) getENIMetadata(eniMAC string) (ENIMetadat } log.Debugf("Found ENI: %s, MAC %s, device %d", eniID, eniMAC, deviceNum) + // Get IMDS fields for the interface macImdsFields, err := cache.imds.GetMACImdsFields(ctx, eniMAC) if err != nil { awsAPIErrInc("GetMACImdsFields", err) return ENIMetadata{}, err } - isEFAOnlyInterface := true - // Efa-only interfaces do not have any ipv4s or ipv6s associated with it. If we don't find any local-ipv4 or ipv6 info in imds we assume it to be efa-only interface and validate this later via ec2 call n + ipInfoAvailable := false + // Efa-only interfaces do not have any ipv4s or ipv6s associated with it. If we don't find any local-ipv4 or ipv6 info in imds we assume it to be efa-only interface and validate this later via ec2 call for _, field := range macImdsFields { if field == "local-ipv4s" { imdsIPv4s, err := cache.imds.GetLocalIPv4s(ctx, eniMAC) @@ -619,7 +620,7 @@ func (cache *EC2InstanceMetadataCache) getENIMetadata(eniMAC string) (ENIMetadat return ENIMetadata{}, err } if len(imdsIPv4s) > 0 { - isEFAOnlyInterface = false + ipInfoAvailable = true log.Debugf("Found IPv4 addresses associated with interface. This is not efa-only interface") break } @@ -629,104 +630,109 @@ func (cache *EC2InstanceMetadataCache) getENIMetadata(eniMAC string) (ENIMetadat if err != nil { awsAPIErrInc("GetIPv6s", err) } else if len(imdsIPv6s) > 0 { - isEFAOnlyInterface = false + ipInfoAvailable = true log.Debugf("Found IPv6 addresses associated with interface. This is not efa-only interface") break } } } - var subnetV4Cidr string - var ec2ip4s []*ec2.NetworkInterfacePrivateIpAddress + if !ipInfoAvailable { + return ENIMetadata{ + ENIID: eniID, + MAC: eniMAC, + DeviceNumber: deviceNum, + SubnetIPv4CIDR: "", + IPv4Addresses: make([]*ec2.NetworkInterfacePrivateIpAddress, 0), + IPv4Prefixes: make([]*ec2.Ipv4PrefixSpecification, 0), + SubnetIPv6CIDR: "", + IPv6Addresses: make([]*ec2.NetworkInterfaceIpv6Address, 0), + IPv6Prefixes: make([]*ec2.Ipv6PrefixSpecification, 0), + }, nil + } + + // Get IPv4 and IPv6 addresses assigned to interface + cidr, err := cache.imds.GetSubnetIPv4CIDRBlock(ctx, eniMAC) + if err != nil { + awsAPIErrInc("GetSubnetIPv4CIDRBlock", err) + return ENIMetadata{}, err + } + + imdsIPv4s, err := cache.imds.GetLocalIPv4s(ctx, eniMAC) + if err != nil { + awsAPIErrInc("GetLocalIPv4s", err) + return ENIMetadata{}, err + } + + ec2ip4s := make([]*ec2.NetworkInterfacePrivateIpAddress, len(imdsIPv4s)) + for i, ip4 := range imdsIPv4s { + ec2ip4s[i] = &ec2.NetworkInterfacePrivateIpAddress{ + Primary: aws.Bool(i == 0), + PrivateIpAddress: aws.String(ip4.String()), + } + } + var ec2ip6s []*ec2.NetworkInterfaceIpv6Address var subnetV6Cidr string - var ec2ipv4Prefixes []*ec2.Ipv4PrefixSpecification - var ec2ipv6Prefixes []*ec2.Ipv6PrefixSpecification - - // Do no fetch ip related info for Efa-only interfaces - if !isEFAOnlyInterface { - // Get IPv4 and IPv6 addresses assigned to interface - cidr, err := cache.imds.GetSubnetIPv4CIDRBlock(ctx, eniMAC) + if cache.v6Enabled { + // For IPv6 ENIs, do not error on missing IPv6 information + v6cidr, err := cache.imds.GetSubnetIPv6CIDRBlocks(ctx, eniMAC) if err != nil { - awsAPIErrInc("GetSubnetIPv4CIDRBlock", err) - return ENIMetadata{}, err + awsAPIErrInc("GetSubnetIPv6CIDRBlocks", err) } else { - subnetV4Cidr = cidr.String() + subnetV6Cidr = v6cidr.String() } - imdsIPv4s, err := cache.imds.GetLocalIPv4s(ctx, eniMAC) + imdsIPv6s, err := cache.imds.GetIPv6s(ctx, eniMAC) if err != nil { - awsAPIErrInc("GetLocalIPv4s", err) - return ENIMetadata{}, err - } - - ec2ip4s = make([]*ec2.NetworkInterfacePrivateIpAddress, len(imdsIPv4s)) - for i, ip4 := range imdsIPv4s { - ec2ip4s[i] = &ec2.NetworkInterfacePrivateIpAddress{ - Primary: aws.Bool(i == 0), - PrivateIpAddress: aws.String(ip4.String()), + awsAPIErrInc("GetIPv6s", err) + } else { + ec2ip6s = make([]*ec2.NetworkInterfaceIpv6Address, len(imdsIPv6s)) + for i, ip6 := range imdsIPv6s { + ec2ip6s[i] = &ec2.NetworkInterfaceIpv6Address{ + Ipv6Address: aws.String(ip6.String()), + } } } + } - if cache.v6Enabled { - // For IPv6 ENIs, do not error on missing IPv6 information - v6cidr, err := cache.imds.GetSubnetIPv6CIDRBlocks(ctx, eniMAC) - if err != nil { - awsAPIErrInc("GetSubnetIPv6CIDRBlocks", err) - } else { - subnetV6Cidr = v6cidr.String() - } + var ec2ipv4Prefixes []*ec2.Ipv4PrefixSpecification + var ec2ipv6Prefixes []*ec2.Ipv6PrefixSpecification - imdsIPv6s, err := cache.imds.GetIPv6s(ctx, eniMAC) - if err != nil { - awsAPIErrInc("GetIPv6s", err) - } else { - ec2ip6s = make([]*ec2.NetworkInterfaceIpv6Address, len(imdsIPv6s)) - for i, ip6 := range imdsIPv6s { - ec2ip6s[i] = &ec2.NetworkInterfaceIpv6Address{ - Ipv6Address: aws.String(ip6.String()), - } - } - } + // If IPv6 is enabled, get attached v6 prefixes. + if cache.v6Enabled { + imdsIPv6Prefixes, err := cache.imds.GetIPv6Prefixes(ctx, eniMAC) + if err != nil { + awsAPIErrInc("GetIPv6Prefixes", err) + return ENIMetadata{}, err } - - // If IPv6 is enabled, get attached v6 prefixes. - if cache.v6Enabled { - imdsIPv6Prefixes, err := cache.imds.GetIPv6Prefixes(ctx, eniMAC) - if err != nil { - awsAPIErrInc("GetIPv6Prefixes", err) - return ENIMetadata{}, err - } - for _, ipv6prefix := range imdsIPv6Prefixes { - ec2ipv6Prefixes = append(ec2ipv6Prefixes, &ec2.Ipv6PrefixSpecification{ - Ipv6Prefix: aws.String(ipv6prefix.String()), - }) - } - } else if cache.v4Enabled && ((eniMAC == primaryMAC && !cache.useCustomNetworking) || (eniMAC != primaryMAC)) { - // Get prefix on primary ENI when custom networking is enabled is not needed. - // If primary ENI has prefixes attached and then we move to custom networking, we don't need to fetch - // the prefix since recommendation is to terminate the nodes and that would have deleted the prefix on the - // primary ENI. - imdsIPv4Prefixes, err := cache.imds.GetIPv4Prefixes(ctx, eniMAC) - if err != nil { - awsAPIErrInc("GetIPv4Prefixes", err) - return ENIMetadata{}, err - } - for _, ipv4prefix := range imdsIPv4Prefixes { - ec2ipv4Prefixes = append(ec2ipv4Prefixes, &ec2.Ipv4PrefixSpecification{ - Ipv4Prefix: aws.String(ipv4prefix.String()), - }) - } + for _, ipv6prefix := range imdsIPv6Prefixes { + ec2ipv6Prefixes = append(ec2ipv6Prefixes, &ec2.Ipv6PrefixSpecification{ + Ipv6Prefix: aws.String(ipv6prefix.String()), + }) + } + } else if cache.v4Enabled && ((eniMAC == primaryMAC && !cache.useCustomNetworking) || (eniMAC != primaryMAC)) { + // Get prefix on primary ENI when custom networking is enabled is not needed. + // If primary ENI has prefixes attached and then we move to custom networking, we don't need to fetch + // the prefix since recommendation is to terminate the nodes and that would have deleted the prefix on the + // primary ENI. + imdsIPv4Prefixes, err := cache.imds.GetIPv4Prefixes(ctx, eniMAC) + if err != nil { + awsAPIErrInc("GetIPv4Prefixes", err) + return ENIMetadata{}, err + } + for _, ipv4prefix := range imdsIPv4Prefixes { + ec2ipv4Prefixes = append(ec2ipv4Prefixes, &ec2.Ipv4PrefixSpecification{ + Ipv4Prefix: aws.String(ipv4prefix.String()), + }) } - } else { - log.Debugf("No ipv4 or ipv6 info associated with this interface. This might be efa-only interface") } return ENIMetadata{ ENIID: eniID, MAC: eniMAC, DeviceNumber: deviceNum, - SubnetIPv4CIDR: subnetV4Cidr, + SubnetIPv4CIDR: cidr.String(), IPv4Addresses: ec2ip4s, IPv4Prefixes: ec2ipv4Prefixes, SubnetIPv6CIDR: subnetV6Cidr, From c386ba9f80b73261ab63f69b69c752d54126caba Mon Sep 17 00:00:00 2001 From: Pavani Panakanti Date: Fri, 27 Sep 2024 06:30:38 +0000 Subject: [PATCH 3/3] Donot return for missing ipv6 --- pkg/awsutils/awsutils.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/awsutils/awsutils.go b/pkg/awsutils/awsutils.go index 892b840756..3fea1e189d 100644 --- a/pkg/awsutils/awsutils.go +++ b/pkg/awsutils/awsutils.go @@ -1407,9 +1407,9 @@ func (cache *EC2InstanceMetadataCache) DescribeAllENIs() (DescribeAllENIsResult, efaENIs[eniID] = true } if interfaceType != "efa-only" { - if len(eniMetadata.IPv4Addresses) == 0 && len(eniMetadata.IPv6Addresses) == 0 { + if len(eniMetadata.IPv4Addresses) == 0 { log.Errorf("Missing IP addresses from IMDS. Non efa-only interface should have IP address associated with it %s", eniID) - outOfSyncErr := errors.New("DescribeAllENIs: No IP addresses found") + outOfSyncErr := errors.New("DescribeAllENIs: No IPv4 address found") return DescribeAllENIsResult{}, outOfSyncErr } }