Add netutils.get_my_ipv6()
Analog to netutils.get_my_ipv4(), except will return an IPv6 address on the local host. Change-Id: I26812ca6eaaeff70796bafa9f735d15d80f1bc30
This commit is contained in:
parent
439f39bdbf
commit
650b31f8ea
@ -414,6 +414,52 @@ def _get_my_ipv4_address():
|
||||
return LOCALHOST
|
||||
|
||||
|
||||
def get_my_ipv6():
|
||||
"""Returns the actual IPv6 address of the local machine.
|
||||
|
||||
This code figures out what source address would be used if some traffic
|
||||
were to be sent out to some well known address on the Internet. In this
|
||||
case, IPv6 from RFC3849 is used, but the specific address does not
|
||||
matter much. No traffic is actually sent.
|
||||
|
||||
.. versionadded:: 6.1
|
||||
Return ``'::1'`` if there is no default interface.
|
||||
"""
|
||||
try:
|
||||
csock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
||||
csock.connect(('2001:db8::1', 80))
|
||||
(addr, _, _, _) = csock.getsockname()
|
||||
csock.close()
|
||||
return addr
|
||||
except socket.error:
|
||||
return _get_my_ipv6_address()
|
||||
|
||||
|
||||
def _get_my_ipv6_address():
|
||||
"""Figure out the best IPv6 address
|
||||
"""
|
||||
LOCALHOST = '::1'
|
||||
gtw = netifaces.gateways()
|
||||
try:
|
||||
interface = gtw['default'][netifaces.AF_INET6][1]
|
||||
except (KeyError, IndexError):
|
||||
LOG.info('Could not determine default network interface, '
|
||||
'using %s for IPv6 address', LOCALHOST)
|
||||
return LOCALHOST
|
||||
|
||||
try:
|
||||
return netifaces.ifaddresses(interface)[netifaces.AF_INET6][0]['addr']
|
||||
except (KeyError, IndexError):
|
||||
LOG.info('Could not determine IPv6 address for interface '
|
||||
'%(interface)s, using %(address)s',
|
||||
{'interface': interface, 'address': LOCALHOST})
|
||||
except Exception as e:
|
||||
LOG.info('Could not determine IPv6 address for '
|
||||
'interface %(interface)s: %(error)s',
|
||||
{'interface': interface, 'error': e})
|
||||
return LOCALHOST
|
||||
|
||||
|
||||
class _ModifiedSplitResult(parse.SplitResult):
|
||||
"""Split results class for urlsplit."""
|
||||
|
||||
|
@ -276,13 +276,21 @@ class NetworkUtilsTest(test_base.BaseTestCase):
|
||||
for input_str in invalid_inputs:
|
||||
self.assertFalse(netutils.is_valid_port(input_str))
|
||||
|
||||
def test_get_my_ip(self):
|
||||
def test_get_my_ipv4(self):
|
||||
sock_attrs = {
|
||||
'return_value.getsockname.return_value': ['1.2.3.4', '']}
|
||||
with mock.patch('socket.socket', **sock_attrs):
|
||||
addr = netutils.get_my_ipv4()
|
||||
self.assertEqual(addr, '1.2.3.4')
|
||||
|
||||
def test_get_my_ipv6(self):
|
||||
sock_attrs = {
|
||||
'return_value.getsockname.return_value': ['2001:db8::2', '',
|
||||
'', '']}
|
||||
with mock.patch('socket.socket', **sock_attrs):
|
||||
addr = netutils.get_my_ipv6()
|
||||
self.assertEqual(addr, '2001:db8::2')
|
||||
|
||||
def test_is_int_in_range(self):
|
||||
valid_inputs = [(1, -100, 100),
|
||||
('1', -100, 100),
|
||||
@ -323,37 +331,44 @@ class NetworkUtilsTest(test_base.BaseTestCase):
|
||||
|
||||
@mock.patch('socket.socket')
|
||||
@mock.patch('oslo_utils.netutils._get_my_ipv4_address')
|
||||
def test_get_my_ip_socket_error(self, ip, mock_socket):
|
||||
def test_get_my_ipv4_socket_error(self, ip, mock_socket):
|
||||
mock_socket.side_effect = socket.error
|
||||
ip.return_value = '1.2.3.4'
|
||||
addr = netutils.get_my_ipv4()
|
||||
self.assertEqual(addr, '1.2.3.4')
|
||||
|
||||
@mock.patch('netifaces.gateways')
|
||||
@mock.patch('netifaces.ifaddresses')
|
||||
def test_get_my_ipv4_address_with_default_route(
|
||||
self, ifaddr, gateways):
|
||||
with mock.patch.dict(netifaces.__dict__, {'AF_INET': '0'}):
|
||||
ifaddr.return_value = {'0': [{'addr': '172.18.204.1'}]}
|
||||
addr = netutils._get_my_ipv4_address()
|
||||
self.assertEqual('172.18.204.1', addr)
|
||||
@mock.patch('socket.socket')
|
||||
@mock.patch('oslo_utils.netutils._get_my_ipv6_address')
|
||||
def test_get_my_ipv6_socket_error(self, ip, mock_socket):
|
||||
mock_socket.side_effect = socket.error
|
||||
ip.return_value = '2001:db8::2'
|
||||
addr = netutils.get_my_ipv6()
|
||||
self.assertEqual(addr, '2001:db8::2')
|
||||
|
||||
@mock.patch('netifaces.gateways')
|
||||
@mock.patch('netifaces.ifaddresses')
|
||||
def test_get_my_ipv4_address_without_default_route(
|
||||
def test_get_my_ip_address_with_default_route(
|
||||
self, ifaddr, gateways):
|
||||
with mock.patch.dict(netifaces.__dict__, {'AF_INET': '0'}):
|
||||
ifaddr.return_value = {}
|
||||
addr = netutils._get_my_ipv4_address()
|
||||
self.assertEqual('127.0.0.1', addr)
|
||||
ifaddr.return_value = {netifaces.AF_INET: [{'addr': '172.18.204.1'}],
|
||||
netifaces.AF_INET6: [{'addr': '2001:db8::2'}]}
|
||||
self.assertEqual('172.18.204.1', netutils._get_my_ipv4_address())
|
||||
self.assertEqual('2001:db8::2', netutils._get_my_ipv6_address())
|
||||
|
||||
@mock.patch('netifaces.gateways')
|
||||
@mock.patch('netifaces.ifaddresses')
|
||||
def test_get_my_ip_address_without_default_route(
|
||||
self, ifaddr, gateways):
|
||||
ifaddr.return_value = {}
|
||||
self.assertEqual('127.0.0.1', netutils._get_my_ipv4_address())
|
||||
self.assertEqual('::1', netutils._get_my_ipv6_address())
|
||||
|
||||
@mock.patch('netifaces.gateways')
|
||||
@mock.patch('netifaces.ifaddresses')
|
||||
def test_get_my_ipv4_address_without_default_interface(
|
||||
self, ifaddr, gateways):
|
||||
gateways.return_value = {}
|
||||
addr = netutils._get_my_ipv4_address()
|
||||
self.assertEqual('127.0.0.1', addr)
|
||||
self.assertEqual('127.0.0.1', netutils._get_my_ipv4_address())
|
||||
self.assertEqual('::1', netutils._get_my_ipv6_address())
|
||||
self.assertFalse(ifaddr.called)
|
||||
|
||||
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
New method ``netutils.get_my_ipv6()`` returns the IPv6 address
|
||||
of the local machine.
|
Loading…
x
Reference in New Issue
Block a user