Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setup: add type and default_ipv{4,6} to linux network facts #866

Merged
merged 1 commit into from
Aug 14, 2012
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
88 changes: 64 additions & 24 deletions library/setup
Original file line number Diff line number Diff line change
Expand Up @@ -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):
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']
)
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 = [],
ips = dict(
all_ipv4_addresses = [],
all_ipv6_addresses = [],
ipv4_address = None,
ipv6_address = None
)
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]
output = subprocess.Popen([ip_path, 'addr', 'show'], stdout=subprocess.PIPE).communicate()[0]
for line in output.split('\n'):
if line:
words = line.split()
Expand All @@ -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('/')
Expand All @@ -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

Expand Down