All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

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