mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Merge pull request #866 from akhayyat/devel
setup: add type and default_ipv{4,6} to linux network facts
This commit is contained in:
commit
731adc0eaf
1 changed files with 66 additions and 26 deletions
|
@ -434,32 +434,58 @@ class LinuxNetwork(Network):
|
|||
Network.__init__(self)
|
||||
|
||||
def populate(self):
|
||||
interfaces, ips = self.parse_ip_addr()
|
||||
|
||||
ip_path = self.get_ip_path()
|
||||
default_ipv4, default_ipv6 = self.get_default_interfaces(ip_path)
|
||||
interfaces, ips = self.get_interfaces_info(ip_path, default_ipv4, default_ipv6)
|
||||
self.facts['interfaces'] = interfaces.keys()
|
||||
for iface in interfaces:
|
||||
self.facts[iface] = interfaces[iface]
|
||||
|
||||
for key in ips:
|
||||
self.facts[key] = ips[key]
|
||||
|
||||
self.facts['default_ipv4'] = default_ipv4
|
||||
self.facts['default_ipv6'] = default_ipv6
|
||||
self.facts['all_ipv4_addresses'] = ips['all_ipv4_addresses']
|
||||
self.facts['all_ipv6_addresses'] = ips['all_ipv6_addresses']
|
||||
return self.facts
|
||||
|
||||
def parse_ip_addr(self):
|
||||
interfaces = {}
|
||||
ips = dict(
|
||||
all_ipv4_addresses = [],
|
||||
all_ipv6_addresses = [],
|
||||
ipv4_address = None,
|
||||
ipv6_address = None
|
||||
def get_ip_path(self):
|
||||
paths = ['/sbin/ip', '/usr/sbin/ip']
|
||||
ip_path = None
|
||||
for path in paths:
|
||||
if os.path.exists(path):
|
||||
ip_path = path
|
||||
break
|
||||
return ip_path
|
||||
|
||||
def get_default_interfaces(self, ip_path):
|
||||
# Use the commands:
|
||||
# ip -4 route get 8.8.8.8 -> Google public DNS
|
||||
# ip -6 route get 2404:6800:400a:800::1012 -> ipv6.google.com
|
||||
# to find out the default outgoing interface, address, and gateway
|
||||
command = dict(
|
||||
v4 = [ip_path, '-4', 'route', 'get', '8.8.8.8'],
|
||||
v6 = [ip_path, '-6', 'route', 'get', '2404:6800:400a:800::1012']
|
||||
)
|
||||
ipbin = '/sbin/ip'
|
||||
if not os.path.exists(ipbin):
|
||||
if os.path.exists('/usr/sbin/ip'):
|
||||
ipbin = '/usr/sbin/ip'
|
||||
else:
|
||||
return interfaces, ips
|
||||
output = subprocess.Popen([ipbin, 'addr', 'show'], stdout=subprocess.PIPE).communicate()[0]
|
||||
interface = dict(v4 = {}, v6 = {})
|
||||
for v in 'v4', 'v6':
|
||||
output = subprocess.Popen(command[v], stdout=subprocess.PIPE).communicate()[0]
|
||||
words = output.split('\n')[0].split()
|
||||
# A valid output starts with the queried address on the first line
|
||||
if words[0] == command[v][-1]:
|
||||
for i in range(len(words) - 1):
|
||||
if words[i] == 'dev':
|
||||
interface[v]['interface'] = words[i+1]
|
||||
elif words[i] == 'src':
|
||||
interface[v]['address'] = words[i+1]
|
||||
elif words[i] == 'via' and words[i+1] != command[v][-1]:
|
||||
interface[v]['gateway'] = words[i+1]
|
||||
return interface['v4'], interface['v6']
|
||||
|
||||
def get_interfaces_info(self, ip_path, default_ipv4, default_ipv6):
|
||||
interfaces = {}
|
||||
ips = dict(
|
||||
all_ipv4_addresses = [],
|
||||
all_ipv6_addresses = [],
|
||||
)
|
||||
output = subprocess.Popen([ip_path, 'addr', 'show'], stdout=subprocess.PIPE).communicate()[0]
|
||||
for line in output.split('\n'):
|
||||
if line:
|
||||
words = line.split()
|
||||
|
@ -486,22 +512,30 @@ class LinuxNetwork(Network):
|
|||
# interface name for each address
|
||||
if iface in interfaces:
|
||||
i = 0
|
||||
while '{0}:{1}'.format(iface, i) in interfaces:
|
||||
while '{0}_{1}'.format(iface, i) in interfaces:
|
||||
i += 1
|
||||
iface = '{0}:{1}'.format(iface, i)
|
||||
iface = '{0}_{1}'.format(iface, i)
|
||||
|
||||
interfaces[iface] = {}
|
||||
interfaces[iface]['macaddress'] = macaddress
|
||||
interfaces[iface]['mtu'] = mtu
|
||||
interfaces[iface]['type'] = iface_type
|
||||
interfaces[iface]['device'] = device
|
||||
interfaces[iface]['ipv4'] = {'address': address,
|
||||
'netmask': netmask,
|
||||
'network': network}
|
||||
|
||||
# If this is the default address, update default_ipv4
|
||||
if 'address' in default_ipv4 and default_ipv4['address'] == address:
|
||||
default_ipv4['netmask'] = netmask
|
||||
default_ipv4['network'] = network
|
||||
default_ipv4['macaddress'] = macaddress
|
||||
default_ipv4['mtu'] = mtu
|
||||
default_ipv4['type'] = iface_type
|
||||
default_ipv4['alias'] = words[-1]
|
||||
|
||||
if not address.startswith('127.'):
|
||||
ips['all_ipv4_addresses'].append(address)
|
||||
if not ips['ipv4_address'] or ips['ipv4_address'].startswith('127.'):
|
||||
ips['ipv4_address'] = address
|
||||
|
||||
elif words[0] == 'inet6':
|
||||
address, prefix = words[1].split('/')
|
||||
|
@ -520,10 +554,16 @@ class LinuxNetwork(Network):
|
|||
'prefix': prefix,
|
||||
'scope': scope} )
|
||||
|
||||
# If this is the default address, update default_ipv6
|
||||
if 'address' in default_ipv6 and default_ipv6['address'] == address:
|
||||
default_ipv6['prefix'] = prefix
|
||||
default_ipv6['scope'] = scope
|
||||
default_ipv6['macaddress'] = macaddress
|
||||
default_ipv6['mtu'] = mtu
|
||||
default_ipv6['type'] = iface_type
|
||||
|
||||
if not address == '::1':
|
||||
ips['all_ipv6_addresses'].append(address)
|
||||
if not ips['ipv6_address'] or ips['ipv6_address'] == '::1':
|
||||
ips['ipv6_address'] = address
|
||||
|
||||
return interfaces, ips
|
||||
|
||||
|
|
Loading…
Reference in a new issue