Commit 9c4ac85c authored by Simon Redman's avatar Simon Redman

Add NetJSON to topomap_parser

parent b39675a9
......@@ -16,6 +16,7 @@
# limitations under the License.
import argparse
import copy
from collections import namedtuple
import json
......@@ -76,13 +77,14 @@ def parse_link_line(line):
return name, Lan(*parameters)
def parse_topomap(topomap):
"""
Parse the passed topomap string into a Python dictionary
It shall contain one key per datatype defined in TMCD's topomap, currently 'nodes' and 'lans'
'nodes' shall map to a dictionary of node names -> parameters
'lans' shall map to a dictionary of lan names -> parameters
:param topomap: File to open and parse
:return: Dictionary as defined above
"""
......@@ -110,8 +112,79 @@ def parse_topomap(topomap):
return to_return
def parse_topomap_to_netjson(topomap):
"""
Convert the Emulab topomap file into NetJSON [http://netjson.org/]
:param topomap: File to open and parse
:return: Python dictionary in NetJSON format
"""
netjson = {}
nodes = []
links = []
netjson['type'] = "NetworkGraph"
netjson['protocol'] = "static"
netjson['version'] = None
netjson['metric'] = None
netjson['nodes'] = nodes
netjson['links'] = links
topodict = parse_topomap(topomap)
for node_name in topodict['nodes']:
node = {}
interfaces = topodict['nodes'][node_name]
local_addresses = []
properties = {}
node['id'] = node_name # This might more usefully be the node's management IP
node['label'] = node_name
node['local_addresses'] = local_addresses
node['properties'] = properties
lans = [] # List of LANs configured in Emulab
properties['lans'] = lans
for lan in interfaces:
lans.append(lan)
local_addresses.append(interfaces[lan])
nodes.append(node)
# Construct NetJSON link objects
for lan_name in topodict['lans']:
link = {}
properties = {}
lan = topodict['lans'][lan_name]
link['cost'] = lan.cost
link['properties'] = properties
properties['netmask'] = lan.netmask
# Since Emulab does not, to my knowledge, present link information in a convenient way we have to parse
# each node to look for two on the same LAN
for node1_idx in range(0, len(netjson['nodes'])):
node1 = netjson['nodes'][node1_idx]
if lan_name in node1['properties']['lans']:
# We have found one node, look for a second
for node2_idx in range(node1_idx + 1, len(netjson['nodes'])):
node2 = netjson['nodes'][node2_idx]
if lan_name in node2['properties']['lans']:
# We have found two nodes. Make a link
link['source'] = node1['id']
link['target'] = node2['id']
links.append(copy.deepcopy(link))
# Make the reverse link, since there are only bi-directional links in Emulab
link['source'] = node2['id']
link['target'] = node1['id']
links.append(copy.deepcopy(link))
return netjson
if __name__ == "__main__":
parser = argparse.ArgumentParser("Parse Emulab's topomap into a Python dictionary")
parser = argparse.ArgumentParser("Parse Emulab's topomap into netjson")
parser.add_argument("--in-file", action='store', default='/var/emulab/boot/topomap', type=str,
help="Path to the netinfo file to parse")
parser.add_argument("--out-file", action='store', default='./netinfo.json', type=str,
......@@ -119,7 +192,7 @@ if __name__ == "__main__":
args = parser.parse_args()
dict = parse_topomap(args.in_file)
netjson = parse_topomap_to_netjson(args.in_file)
with open(args.out_file, 'w') as out_file:
out_file.write(json.dumps(dict))
out_file.write(json.dumps(netjson))
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