From 3cbf25233d3aea813ef5f97120b1167169e9863b Mon Sep 17 00:00:00 2001 From: Jason Zhao Date: Wed, 19 Apr 2017 17:49:22 -0400 Subject: [PATCH 1/2] handle multiple internal ip in aws provider --- pkg/cloudprovider/providers/aws/aws.go | 42 +++++++++++++++----------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/pkg/cloudprovider/providers/aws/aws.go b/pkg/cloudprovider/providers/aws/aws.go index 151938d6730cc..166d5b9cf26af 100644 --- a/pkg/cloudprovider/providers/aws/aws.go +++ b/pkg/cloudprovider/providers/aws/aws.go @@ -947,20 +947,6 @@ func (c *Cloud) NodeAddresses(name types.NodeName) ([]v1.NodeAddress, error) { } addresses := []v1.NodeAddress{} - - if !isNilOrEmpty(instance.PrivateIpAddress) { - ipAddress := *instance.PrivateIpAddress - ip := net.ParseIP(ipAddress) - if ip == nil { - return nil, fmt.Errorf("EC2 instance had invalid private address: %s (%s)", orEmpty(instance.InstanceId), ipAddress) - } - addresses = append(addresses, v1.NodeAddress{Type: v1.NodeInternalIP, Address: ip.String()}) - - // Legacy compatibility: the private ip was the legacy host ip - addresses = append(addresses, v1.NodeAddress{Type: v1.NodeLegacyHostIP, Address: ip.String()}) - } - - // TODO: Other IP addresses (multiple ips)? if !isNilOrEmpty(instance.PublicIpAddress) { ipAddress := *instance.PublicIpAddress ip := net.ParseIP(ipAddress) @@ -970,14 +956,36 @@ func (c *Cloud) NodeAddresses(name types.NodeName) ([]v1.NodeAddress, error) { addresses = append(addresses, v1.NodeAddress{Type: v1.NodeExternalIP, Address: ip.String()}) } - if !isNilOrEmpty(instance.PrivateDnsName) { - addresses = append(addresses, v1.NodeAddress{Type: v1.NodeInternalDNS, Address: *instance.PrivateDnsName}) - } if !isNilOrEmpty(instance.PublicDnsName) { addresses = append(addresses, v1.NodeAddress{Type: v1.NodeExternalDNS, Address: *instance.PublicDnsName}) } + // handle internal network interfaces + for _, networkInterface := range instance.NetworkInterfaces { + // skip network interfaces that are not currently in use + if isNilOrEmpty(networkInterface.Status) || *networkInterface.Status != ec2.NetworkInterfaceStatusInUse { + continue + } + + for _, internalIP := range networkInterface.PrivateIpAddresses { + if !isNilOrEmpty(internalIP.PrivateIpAddress) { + ipAddress := *internalIP.PrivateIpAddress + ip := net.ParseIP(ipAddress) + if ip == nil { + return nil, fmt.Errorf("EC2 instance had invalid private address: %s (%s)", orEmpty(instance.InstanceId), ipAddress) + } + addresses = append(addresses, v1.NodeAddress{Type: v1.NodeInternalIP, Address: ip.String()}) + + // Legacy compatibility: the private ip was the legacy host ip + addresses = append(addresses, v1.NodeAddress{Type: v1.NodeLegacyHostIP, Address: ip.String()}) + } + if !isNilOrEmpty(internalIP.PrivateDnsName) { + addresses = append(addresses, v1.NodeAddress{Type: v1.NodeInternalDNS, Address: *internalIP.PrivateDnsName}) + } + } + } + return addresses, nil } From 0ea7ec67df9511e401057635c07cec58f639b149 Mon Sep 17 00:00:00 2001 From: Jason Zhao Date: Fri, 21 Apr 2017 11:15:04 -0700 Subject: [PATCH 2/2] handle metdata case as well --- pkg/cloudprovider/providers/aws/aws.go | 39 +++++++++++++-------- pkg/cloudprovider/providers/aws/aws_test.go | 4 +++ 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/pkg/cloudprovider/providers/aws/aws.go b/pkg/cloudprovider/providers/aws/aws.go index 166d5b9cf26af..40c6cedab73ff 100644 --- a/pkg/cloudprovider/providers/aws/aws.go +++ b/pkg/cloudprovider/providers/aws/aws.go @@ -904,13 +904,33 @@ func (c *Cloud) NodeAddresses(name types.NodeName) ([]v1.NodeAddress, error) { if c.selfAWSInstance.nodeName == name || len(name) == 0 { addresses := []v1.NodeAddress{} - internalIP, err := c.metadata.GetMetadata("local-ipv4") - if err != nil { + macs, err := c.metadata.GetMetadata("network/interfaces/macs/") + if err != nil || len(macs) == 0 { return nil, err } - addresses = append(addresses, v1.NodeAddress{Type: v1.NodeInternalIP, Address: internalIP}) - // Legacy compatibility: the private ip was the legacy host ip - addresses = append(addresses, v1.NodeAddress{Type: v1.NodeLegacyHostIP, Address: internalIP}) + glog.V(2).Infof("Retrieved macs from metadata %s", macs) + for _, macID := range strings.Split(macs, "\n") { + glog.V(2).Infof("Processing mac ID %s", macID) + internalDNS, err := c.metadata.GetMetadata(fmt.Sprintf("network/interfaces/macs/%s/local-hostname", macID)) + if err != nil || len(internalDNS) == 0 { + //TODO: It would be nice to be able to determine the reason for the failure, + // but the AWS client masks all failures with the same error description. + glog.V(2).Info("Could not determine private DNS from AWS metadata.") + } else { + addresses = append(addresses, v1.NodeAddress{Type: v1.NodeInternalDNS, Address: internalDNS}) + } + internalIPs, err := c.metadata.GetMetadata(fmt.Sprintf("network/interfaces/macs/%s/local-ipv4s", macID)) + if err != nil || len(internalIPs) == 0 { + return nil, err + } + glog.V(2).Infof("Got internal ips %s", internalIPs) + for _, internalIP := range strings.Split(internalIPs, "\n") { + glog.V(2).Infof("Adding internal IP %s", internalIP) + addresses = append(addresses, v1.NodeAddress{Type: v1.NodeInternalIP, Address: internalIP}) + // Legacy compatibility: the private ip was the legacy host ip + addresses = append(addresses, v1.NodeAddress{Type: v1.NodeLegacyHostIP, Address: internalIP}) + } + } externalIP, err := c.metadata.GetMetadata("public-ipv4") if err != nil { @@ -921,15 +941,6 @@ func (c *Cloud) NodeAddresses(name types.NodeName) ([]v1.NodeAddress, error) { addresses = append(addresses, v1.NodeAddress{Type: v1.NodeExternalIP, Address: externalIP}) } - internalDNS, err := c.metadata.GetMetadata("local-hostname") - if err != nil || len(internalDNS) == 0 { - //TODO: It would be nice to be able to determine the reason for the failure, - // but the AWS client masks all failures with the same error description. - glog.V(2).Info("Could not determine private DNS from AWS metadata.") - } else { - addresses = append(addresses, v1.NodeAddress{Type: v1.NodeInternalDNS, Address: internalDNS}) - } - externalDNS, err := c.metadata.GetMetadata("public-hostname") if err != nil || len(externalDNS) == 0 { //TODO: It would be nice to be able to determine the reason for the failure, diff --git a/pkg/cloudprovider/providers/aws/aws_test.go b/pkg/cloudprovider/providers/aws/aws_test.go index c04545e1f6779..3d0ad901f68b8 100644 --- a/pkg/cloudprovider/providers/aws/aws_test.go +++ b/pkg/cloudprovider/providers/aws/aws_test.go @@ -621,6 +621,10 @@ func TestNodeAddresses(t *testing.T) { testHasNodeAddress(t, addrs4, v1.NodeExternalIP, "2.3.4.5") } +func TestNodeAddressWithMetadata(t *testing.T) { + // TODO refactor and add more tests +} + func TestGetRegion(t *testing.T) { aws := mockAvailabilityZone("us-west-2e") zones, ok := aws.Zones()