Commit ec6160eb authored by Simon Redman's avatar Simon Redman

Add helper for parsing ipv4 addresses

parent ea9bd892
......@@ -23,10 +23,11 @@ import ipaddress
from netdiff import NetJsonParser
import re
INTERFACE_ID_COMMAND = "ip -6 address list"
LINK_LOCAL_COMMAND = "ip -6 address list"
IPV4_COMMAND = "ip -4 address list"
def parse_local_interface_addresses(netgraph):
def parse_ipv4_networks(netgraph):
"""
For each ssh session, query the remote for its interfaces, then parse that for its IPv6 interface ID on each interface
......@@ -43,7 +44,47 @@ def parse_local_interface_addresses(netgraph):
# Build an ordered list of hosts, sessions, and commands
hosts.append(host)
sessions.append(netgraph.graph._node[host]['session'])
commands.append(INTERFACE_ID_COMMAND)
commands.append(IPV4_COMMAND)
outputs = ssh_helper.run_commands_on_many_hosts(sessions, commands)
for host_idx in range(len(hostnames)):
# Split the output of the `ip` command per-interface. It comes in as a numbered list, so split on the numbers
interface_lines = re.split(r'\s[0-9]+:\s', outputs[host_idx])
# Dump the first line since it is the echo of the command we sent
interface_lines = interface_lines[1:]
for line in interface_lines:
# The first token, ending with a colon, is the name of the interface
interface_name, *remainder = re.split(r':', line, 1)
assert len(remainder) == 1, "Error when splitting for interface name. More than one regex match found!"
if interface_name == 'lo':
# Don't mess with the loopback interface
continue
# Parse out the ipv4 address. There should be only one.
ipaddr = re.findall(r'\sinet\s+(.*?)\s+brd.*scope global', remainder[0])
assert len(ipaddr) == 1, "Should only have found one link-local address!"
ipaddr = ipaddress.ip_interface(ipaddr[0])
interface_map[hostnames[host_idx]][interface_name] = ipaddr
return interface_map
def parse_local_interface_addresses(netgraph):
"""
For each ssh session, query the remote for its interfaces, then parse that for its IPv4 address
:param netgraph: topology map, annotated with logged-in ssh sessions
:return: mapping of hosts to map of interfaces to that interface's IPv4 address
"""
hosts = []
sessions = []
commands = []
interface_map = {}
for host in netgraph.graph.nodes:
interface_map[host] = {}
# Build an ordered list of hosts, sessions, and commands
hosts.append(host)
sessions.append(netgraph.graph._node[host]['session'])
commands.append(LINK_LOCAL_COMMAND)
outputs = ssh_helper.run_commands_on_many_hosts(sessions, commands)
for host_idx in range(len(hostnames)):
......@@ -85,5 +126,14 @@ if __name__ == "__main__":
sessions, passwords = ssh_helper.log_in_many_sessions(hostnames, usernames)
for host_idx in range(len(hostnames)):
netgraph.graph._node[hostnames[host_idx]]['session'] = sessions[host_idx]
interface_map = parse_local_interface_addresses(netgraph)
link_local_map = parse_local_interface_addresses(netgraph)
ipv4_map = parse_ipv4_networks(netgraph)
site_local_map = {}
for host in link_local_map:
site_local_map[host] = {}
for interface in link_local_map[host]:
link_local_addr = link_local_map[host][interface]
ipv4_addr = ipv4_map[host][interface]
site_local_map[host][interface] = convert_link_local_addr_to_site_local(link_local_addr, ipv4_addr)
pass
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment