Detect internal_ip interface from default gateway

Add the option to specify `interface='default_gateway'` to the
`internal_ip` segment, which displays the IP address of the interface
connected to the default gateway.
This commit is contained in:
Sean Fisk 2015-09-04 16:12:20 -04:00
parent f91fb141de
commit 105cf6666f
2 changed files with 36 additions and 1 deletions

View File

@ -101,15 +101,22 @@ else:
return 0
def internal_ip(pl, interface='auto', ipv=4):
family = netifaces.AF_INET6 if ipv == 6 else netifaces.AF_INET
if interface == 'auto':
try:
interface = next(iter(sorted(netifaces.interfaces(), key=_interface_key, reverse=True)))
except StopIteration:
pl.info('No network interfaces found')
return None
elif interface == 'default_gateway':
try:
interface = netifaces.gateways()['default'][family][1]
except KeyError:
pl.info('No default gateway found for IPv{0}', ipv)
return None
addrs = netifaces.ifaddresses(interface)
try:
return addrs[netifaces.AF_INET6 if ipv == 6 else netifaces.AF_INET][0]['addr']
return addrs[family][0]['addr']
except (KeyError, IndexError):
return None
@ -130,6 +137,11 @@ Requires ``netifaces`` module to work properly.
#. ``teredo`` followed by number or the end of string.
#. Any other interface that is not ``lo*``.
#. ``lo`` followed by number or the end of string.
Use ``default_gateway`` to detect the interface based on the machine's
`default gateway <https://en.wikipedia.org/wiki/Default_gateway>`_ (i.e.,
the router to which it is connected).
:param int ipv:
4 or 6 for ipv4 and ipv6 respectively, depending on which IP address you
need exactly.

View File

@ -397,6 +397,29 @@ class TestNet(TestCommon):
interfaces[:] = ()
self.assertEqual(self.module.internal_ip(pl=pl, ipv=6), None)
gateways = {
'default': {
netifaces.AF_INET: ('192.168.100.1', 'enp2s0'),
netifaces.AF_INET6: ('feff::5446:5eff:fe5a:0001', 'enp2s0')
}
}
with replace_module_module(
self.module, 'netifaces',
interfaces=(lambda: interfaces),
ifaddresses=(lambda interface: addr[interface]),
gateways=(lambda: gateways),
AF_INET=netifaces.AF_INET,
AF_INET6=netifaces.AF_INET6,
):
# default gateway has specified address family
self.assertEqual(self.module.internal_ip(pl=pl, interface='default_gateway', ipv=4), '192.168.100.200')
self.assertEqual(self.module.internal_ip(pl=pl, interface='default_gateway', ipv=6), 'feff::5446:5eff:fe5a:7777%enp2s0')
# default gateway doesn't have specified address family
gateways['default'] = {}
self.assertEqual(self.module.internal_ip(pl=pl, interface='default_gateway', ipv=4), None)
self.assertEqual(self.module.internal_ip(pl=pl, interface='default_gateway', ipv=6), None)
def test_network_load(self):
def gb(interface):
return None