Skip to content

Commit 46b06b1

Browse files
authored
Add utils to get all IP addresses (aws#4642)
* Add utils to get all IP addresses * Update comments
1 parent 284d18e commit 46b06b1

File tree

12 files changed

+256
-0
lines changed

12 files changed

+256
-0
lines changed

agent/vendor/github.com/aws/amazon-ecs-agent/ecs-agent/tmds/utils/netconfig/netconfig_linux.go

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

agent/vendor/github.com/aws/amazon-ecs-agent/ecs-agent/tmds/utils/netconfig/netconfig_unsupported.go

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

agent/vendor/github.com/aws/amazon-ecs-agent/ecs-agent/tmds/utils/netconfig/netconfig_windows.go

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

agent/vendor/github.com/aws/amazon-ecs-agent/ecs-agent/utils/netwrapper/generate_mocks.go

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

agent/vendor/github.com/aws/amazon-ecs-agent/ecs-agent/utils/netwrapper/net.go

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

agent/vendor/modules.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ github.com/aws/amazon-ecs-agent/ecs-agent/utils/execwrapper/mocks
8383
github.com/aws/amazon-ecs-agent/ecs-agent/utils/httpproxy
8484
github.com/aws/amazon-ecs-agent/ecs-agent/utils/netlinkwrapper
8585
github.com/aws/amazon-ecs-agent/ecs-agent/utils/netlinkwrapper/mocks
86+
github.com/aws/amazon-ecs-agent/ecs-agent/utils/netwrapper
8687
github.com/aws/amazon-ecs-agent/ecs-agent/utils/retry
8788
github.com/aws/amazon-ecs-agent/ecs-agent/utils/retry/mock
8889
github.com/aws/amazon-ecs-agent/ecs-agent/utils/ttime

ecs-agent/tmds/utils/netconfig/netconfig_linux.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717
package netconfig
1818

1919
import (
20+
"net"
21+
2022
"github.com/aws/amazon-ecs-agent/ecs-agent/logger"
2123
"github.com/aws/amazon-ecs-agent/ecs-agent/logger/field"
2224
"github.com/aws/amazon-ecs-agent/ecs-agent/utils/netlinkwrapper"
25+
"github.com/aws/amazon-ecs-agent/ecs-agent/utils/netwrapper"
2326

2427
"github.com/vishvananda/netlink"
2528
)
@@ -69,3 +72,32 @@ func DefaultNetInterfaceName(netlinkClient netlinkwrapper.NetLink) (string, erro
6972
}
7073
return "", nil
7174
}
75+
76+
// GetInterfaceGlobalIPAddresses returns all global unicast IP addresses (both IPv4 and IPv6)
77+
// assigned to the given network interface. It excludes link-local, loopback, multicast,
78+
// and unspecified addresses. Returns an empty list if no global unicast addresses are found,
79+
// or an error if the interface cannot be accessed.
80+
func GetInterfaceGlobalIPAddresses(nw netwrapper.Net, ifaceName string) ([]string, error) {
81+
iface, err := nw.InterfaceByName(ifaceName)
82+
if err != nil {
83+
return nil, err
84+
}
85+
86+
allAddrs, err := nw.Addrs(iface)
87+
if err != nil {
88+
return nil, err
89+
}
90+
91+
ipAddrs := make([]string, 0)
92+
for _, addr := range allAddrs {
93+
ipNet, ok := addr.(*net.IPNet)
94+
if !ok {
95+
continue
96+
}
97+
98+
if ipNet.IP.IsGlobalUnicast() {
99+
ipAddrs = append(ipAddrs, ipNet.IP.String())
100+
}
101+
}
102+
return ipAddrs, nil
103+
}

ecs-agent/tmds/utils/netconfig/netconfig_linux_test.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717
package netconfig
1818

1919
import (
20+
"errors"
2021
"net"
22+
"reflect"
2123
"testing"
2224

2325
mock_netlinkwrapper "github.com/aws/amazon-ecs-agent/ecs-agent/utils/netlinkwrapper/mocks"
26+
mock_nw "github.com/aws/amazon-ecs-agent/ecs-agent/utils/netwrapper/mocks"
2427

2528
"github.com/golang/mock/gomock"
2629
"github.com/stretchr/testify/assert"
@@ -167,3 +170,83 @@ func TestDefaultNetInterfaceName(t *testing.T) {
167170
})
168171
}
169172
}
173+
174+
func TestGetInterfaceGlobalIPAddresses(t *testing.T) {
175+
ctrl := gomock.NewController(t)
176+
defer ctrl.Finish()
177+
178+
tests := []struct {
179+
name string
180+
addrs []net.Addr
181+
ifaceErrMsg string
182+
ifaceAddrErrMsg string
183+
expectedAddrs []string
184+
expectedErrMsg string
185+
}{
186+
{
187+
name: "success with mixed IPs",
188+
addrs: []net.Addr{
189+
&net.IPNet{IP: net.ParseIP("192.168.1.100"), Mask: net.CIDRMask(24, 32)},
190+
&net.IPNet{IP: net.ParseIP("fe80::1"), Mask: net.CIDRMask(64, 128)},
191+
&net.IPNet{IP: net.ParseIP("2001:db8::1"), Mask: net.CIDRMask(64, 128)},
192+
&net.IPNet{IP: net.ParseIP("127.0.0.1"), Mask: net.CIDRMask(8, 32)},
193+
&net.IPNet{IP: net.ParseIP("::1"), Mask: net.CIDRMask(128, 128)},
194+
},
195+
expectedAddrs: []string{"192.168.1.100", "2001:db8::1"},
196+
expectedErrMsg: "",
197+
},
198+
{
199+
name: "empty address list",
200+
addrs: nil,
201+
expectedAddrs: []string{},
202+
expectedErrMsg: "",
203+
},
204+
{
205+
name: "interface error",
206+
ifaceErrMsg: "fail to get the interface",
207+
expectedErrMsg: "fail to get the interface",
208+
},
209+
{
210+
name: "addrs error",
211+
ifaceAddrErrMsg: "fail to get the IP address",
212+
expectedErrMsg: "fail to get the IP address",
213+
},
214+
{
215+
name: "invalid addr",
216+
addrs: []net.Addr{
217+
&net.TCPAddr{IP: net.ParseIP("192.168.1.100"), Port: 80},
218+
},
219+
expectedAddrs: []string{},
220+
expectedErrMsg: "",
221+
},
222+
}
223+
224+
for _, tc := range tests {
225+
tc := tc
226+
t.Run(tc.name, func(t *testing.T) {
227+
t.Parallel()
228+
229+
nw := mock_nw.NewMockNet(ctrl)
230+
if tc.ifaceErrMsg != "" {
231+
nw.EXPECT().InterfaceByName("test0").Return(nil, errors.New(tc.ifaceErrMsg))
232+
} else {
233+
nw.EXPECT().InterfaceByName("test0").Return(nil, nil)
234+
if tc.ifaceAddrErrMsg != "" {
235+
nw.EXPECT().Addrs(nil).Return(nil, errors.New(tc.ifaceAddrErrMsg))
236+
} else {
237+
nw.EXPECT().Addrs(nil).Return(tc.addrs, nil)
238+
}
239+
}
240+
241+
got, err := GetInterfaceGlobalIPAddresses(nw, "test0")
242+
if err != nil {
243+
assert.EqualValues(t, tc.expectedErrMsg, err.Error())
244+
return
245+
}
246+
247+
if !reflect.DeepEqual(got, tc.expectedAddrs) {
248+
t.Errorf("GetInterfaceGlobalIPAddresses() = %v, want %v", got, tc.expectedAddrs)
249+
}
250+
})
251+
}
252+
}

ecs-agent/tmds/utils/netconfig/netconfig_unsupported.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,9 @@ func NewNetworkConfigClient() *NetworkConfigClient {
3030
func DefaultNetInterfaceName(unknown interface{}) (string, error) {
3131
return "", errors.New("not supported on unknown platform")
3232
}
33+
34+
// GetInterfaceGlobalIPAddresses returns all global unicast IP addresses (both IPv4 and IPv6)
35+
// assigned to the given network interface. This is only supported on linux as of now.
36+
func GetInterfaceGlobalIPAddresses(unknown interface{}, ifaceName string) ([]string, error) {
37+
return nil, errors.New("not supported on windows")
38+
}

ecs-agent/tmds/utils/netconfig/netconfig_windows.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,9 @@ func NewNetworkConfigClient() *NetworkConfigClient {
3333
func DefaultNetInterfaceName(unknown interface{}) (string, error) {
3434
return "", errors.New("not supported on windows")
3535
}
36+
37+
// GetInterfaceGlobalIPAddresses returns all global unicast IP addresses (both IPv4 and IPv6)
38+
// assigned to the given network interface. This is only supported on linux as of now.
39+
func GetInterfaceGlobalIPAddresses(unknown interface{}, ifaceName string) ([]string, error) {
40+
return nil, errors.New("not supported on windows")
41+
}

0 commit comments

Comments
 (0)