def diff(self, data=None): """ shortcut to netdiff.diff """ # if we get an instance of ``self.parser_class`` it means # ``self.get_topology_data`` has already been executed by ``receive`` if isinstance(data, self.parser_class): latest = data else: latest = self.get_topology_data(data) current = NetJsonParser(self.json(dict=True, omit_down=True)) return diff(current, latest)
def test_parse_exception3(self): with self.assertRaises(ParserError): NetJsonParser( { "type": "NetworkGraph", "protocol": "OLSR", "version": "0.6.3", "metric": "ETX", } )
def fetch_parameters_from_file(self, filename: str) -> NetJsonParser: """ Read the starting network from a file containing netjson Any node in the resulting graph which has a label matching ovs_regex is assumed to be a slave to this controller :param filename: NetJSON file to read :return: """ graph = NetJsonParser(file=filename) return graph
def compute_cut_block_tree(self): """ transform a given topology in a cut-block tree for better visualization of the critical nodes """ netjson = NetJsonParser(self.json(dict=True, omit_down=True)) p = ParsedGraph(netjson) p.condensate_graph() return json.dumps(to_netjson(p.netJSON.protocol, p.netJSON.version, p.netJSON.revision, p.netJSON.metric, p.condensed_graph.nodes(data=True), p.condensed_graph.edges(data=True), dict=True))
def test_parse_directed(self): p = NetJsonParser(links2, directed=True) self.assertIsInstance(p.graph, networkx.DiGraph) self.assertEqual(p.version, '0.6.6') self.assertEqual(p.revision, '5031a799fcbe17f61d57e387bc3806de') self.assertEqual(p.metric, 'ETX') # test additional properties in links of network graph properties = list(p.graph.edges(data=True))[0][2] self.assertIsInstance(properties['custom_property'], bool) # test additional properties in nodes of networkx graph properties = list(p.graph.nodes(data=True))[0][1] self.assertIsInstance(properties['local_addresses'], list) self.assertIsInstance(properties['hostname'], six.string_types)
def test_json_dict(self): p = NetJsonParser(links2) data = p.json(dict=True) self.assertIsInstance(data, dict) self.assertEqual(data['type'], 'NetworkGraph') self.assertEqual(data['protocol'], 'OLSR') self.assertEqual(data['version'], '0.6.6') self.assertEqual(data['revision'], '5031a799fcbe17f61d57e387bc3806de') self.assertEqual(data['metric'], 'ETX') self.assertIsInstance(data['nodes'], list) self.assertIsInstance(data['links'], list) self.assertEqual(len(data['nodes']), 3) self.assertEqual(len(data['links']), 2)
def netjson_import(self, req, **kwargs): incoming_json = req.body.decode(req.charset) importing_graph = NetJsonParser(incoming_json) # ASSUMPTION WARNING # I have conveniently used each node's IP address as its OSPF ID. That means, for me, it is # safe to convert the incoming labels back to dotted-quad form mapping = {} for id in importing_graph.graph.nodes: dotted_quad = ipaddress.IPv4Address(id) mapping[id] = str(dotted_quad) importing_graph.graph = networkx.relabel_nodes(importing_graph.graph, mapping) Te_controller.graph = importing_graph return Response(status=200, body="Yay")
def test_json_string(self): p = NetJsonParser(links2) data = p.json() self.assertIsInstance(data, six.string_types) self.assertIn('NetworkGraph', data) self.assertIn('protocol', data) self.assertIn('version', data) self.assertIn('revision', data) self.assertIn('metric', data) self.assertIn('OLSR', data) self.assertIn('0.6.6', data) self.assertIn('5031a799fcbe17f61d57e387bc3806de', data) self.assertIn('ETX', data) self.assertIn('links', data) self.assertIn('nodes', data)
def test_parse_exception4(self): with self.assertRaises(ParserError): NetJsonParser( { "type": "NetworkGraph", "protocol": "OLSR", "version": "0.6.3", "metric": "ETX", "nodes": [ {"id": "10.150.0.3"}, {"id": "10.150.0.2"}, {"id": "10.150.0.4"}, ], "links": [{"wrong": "10.150.0.3"}, {"wrong": "10.150.0.3"}], } )
def test_parse_forward_backward_directed_string_graph3(self): """ In directed mode, it should be possible to have a forward edge and a backward edge with different weights """ data = """{ "type": "NetworkGraph", "protocol": "OLSR", "version": "0.6.6", "revision": "5031a799fcbe17f61d57e387bc3806de", "metric": "ETX", "nodes": [ { "id": "10.150.0.3" }, { "id": "10.150.0.2" } ], "links": [ { "source": "10.150.0.3", "target": "10.150.0.2", "cost": 1.0 }, { "source": "10.150.0.2", "target": "10.150.0.3", "cost": 99.0 } ] }""" p = NetJsonParser(data, directed=True) self.assertEqual(len(p.graph.nodes()), 2) self.assertIn('10.150.0.3', p.graph.nodes()) self.assertIn('10.150.0.2', p.graph.nodes()) self.assertEqual(len(p.graph.edges()), 2) self.assertEqual( p.graph.edges[("10.150.0.3", "10.150.0.2")]['weight'], 1.0, msg="Forward edge weight was incorrectly overwritten!", ) self.assertEqual( p.graph.edges[("10.150.0.2", "10.150.0.3")]['weight'], 99.0, msg="Backward edge weight was not correctly assigned!", )
class Te_controller(ControllerBase): graph = NetJsonParser(data={"type": "NetworkGraph", "protocol": "static", "version": None, "metric": None, "nodes": [], "links": []}) def __init__(self, req, link, data, **config): super(Te_controller, self).__init__(req, link, data, **config) self.data = data def netjson_import(self, req, **kwargs): incoming_json = req.body.decode(req.charset) importing_graph = NetJsonParser(incoming_json) # ASSUMPTION WARNING # I have conveniently used each node's IP address as its OSPF ID. That means, for me, it is # safe to convert the incoming labels back to dotted-quad form mapping = {} for id in importing_graph.graph.nodes: dotted_quad = ipaddress.IPv4Address(id) mapping[id] = str(dotted_quad) importing_graph.graph = networkx.relabel_nodes(importing_graph.graph, mapping) Te_controller.graph = importing_graph return Response(status=200, body="Yay") #REST API - Return the topology graph, handle OPTIONS request in preflight request def handle_get_topology_OPTIONS(self, req, **_kwargs): headers = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST', 'Access-Control-Allow-Headers': 'Origin, Content-Type', 'Content-Type':'application/json'} return Response(content_type='application/json', headers=headers) def get_topology_netjson(self, req, **_kwargs): headers = { 'Access-Control-Allow-Origin': '*', # Anybody may request this resource 'Access-Control-Allow-Methods': 'GET', 'Access-Control-Allow-Headers': 'Origin, Content-Type', } return Response(content_type='application/json', json_body=Te_controller.graph.json(dict=True), headers=headers,)
def test_parse_one_way_directed_string_graph(self): """ In directed mode, it should be possible to have an edge in only one direction """ data = """{ "type": "NetworkGraph", "protocol": "OLSR", "version": "0.6.6", "revision": "5031a799fcbe17f61d57e387bc3806de", "metric": "ETX", "nodes": [ { "id": "10.150.0.3" }, { "id": "10.150.0.2" } ], "links": [ { "source": "10.150.0.3", "target": "10.150.0.2", "cost": 1.0 } ] }""" p = NetJsonParser(data, directed=True) self.assertEqual(len(p.graph.nodes()), 2) self.assertIn('10.150.0.3', p.graph.nodes()) self.assertIn('10.150.0.2', p.graph.nodes()) self.assertEqual(len(p.graph.edges()), 1) self.assertEqual( len(p.graph.adj["10.150.0.3"]), 1, msg="10.150.0.3 should have an edge" ) self.assertEqual( len(p.graph.adj["10.150.0.2"]), 0, msg="10.150.0.2 should have no edges" ) self.assertEqual( p.graph.edges[("10.150.0.3", "10.150.0.2")]['weight'], 1.0, msg="Expected directed edge does not exist!", )
def test_json_dict(self): p = NetJsonParser(links2) data = p.json(dict=True) self.assertIsInstance(data, dict) self.assertEqual(data['type'], 'NetworkGraph') self.assertEqual(data['protocol'], 'OLSR') self.assertEqual(data['version'], '0.6.6') self.assertEqual(data['revision'], '5031a799fcbe17f61d57e387bc3806de') self.assertEqual(data['metric'], 'ETX') self.assertIsInstance(data['nodes'], list) self.assertIsInstance(data['links'], list) self.assertEqual(len(data['nodes']), 3) self.assertEqual(len(data['links']), 2) # ensure additional node properties are present self.assertIn('properties', data['nodes'][0]) self.assertIn('hostname', data['nodes'][0]['properties']) # ensure local_addresses is present self.assertIn('local_addresses', data['nodes'][0]) # ensure additional link properties are present self.assertIn('properties', data['links'][0]) self.assertIn('custom_property', data['links'][0]['properties'])
def test_connected(self): self.obj = ParsedGraph(NetJsonParser(data=biconnected_graph)) self.obj.condensate_graph() self.assertTrue(nx.is_connected(self.obj.graph) == nx.is_connected(self.obj.condensed_graph))
def test_parse_exception(self): with self.assertRaises(NetParserException): NetJsonParser('{ "test": "test" }')
def test_parse(self): p = NetJsonParser(links2) self.assertIsInstance(p.graph, networkx.Graph) self.assertEqual(p.version, '0.6.6') self.assertEqual(p.revision, '5031a799fcbe17f61d57e387bc3806de') self.assertEqual(p.metric, 'ETX')
def ReadGrafoDaJson(): netJSON = NetJsonParser(file='topology.json') grafo = netJSON.graph return grafo
#!/bin/python3 import json import os from netdiff import NetJsonParser import networkx as nx import time destination = "192.168.254.3" data = os.popen('echo "/netjsoninfo filter graph ipv4_0" | nc %s 2009' % (destination)).read() json = json.loads(data) graph = NetJsonParser(data=data).graph.to_undirected() graph2 = nx.Graph() networks = [] for link in graph.edges(data=True): if link[2]["type"] not in ["node", "local"]: networks.append(link[1]) for net in networks: graph.remove_node(net) cp = nx.articulation_points(graph) cent = nx.betweenness_centrality(graph, endpoints=True, weight='cost') for x in list(cp): del (cent[x]) sorted(cent, key=cent.__getitem__) print(cent) node = list(cent.keys())[0] node_ip = node[3:]
def test_disconnected_graph(self): self.obj = ParsedGraph(NetJsonParser(data=disconnected_graph)) self.obj.condensate_graph() self.assertFalse(nx.is_connected(self.obj.condensed_graph))
def setUp(self): self.obj = ParsedGraph(NetJsonParser(data=biconnected_graph))
def diff(self): """ shortcut to netdiff.diff """ latest = self.latest current = NetJsonParser(self.json()) return diff(current, latest)
def test_empty(self): self.obj = ParsedGraph(NetJsonParser(data=empty_graph)) self.obj.condensate_graph() self.assertEqual(len(self.obj.condensed_graph), 0)
#! /usr/bin/env python """ A simple main documenting how to use thhis python package """ from netdiff import NetJsonParser from netdiff.utils import _netjson_networkgraph as to_netjson from netjson_robustness.analyser import ParsedGraph import sys import json NetJSON = sys.argv[1] # a NetJSON graph file nj = NetJsonParser(file=NetJSON) pg = ParsedGraph(nj) pg.condensate_graph() js = to_netjson(pg.netJSON.protocol, pg.netJSON.version, pg.netJSON.revision, pg.netJSON.metric, pg.condensed_graph.nodes(data=True), pg.condensed_graph.edges(data=True), dict=True) print json.dumps(js, indent=4)
def test_type(self): self.obj = ParsedGraph(NetJsonParser(data=biconnected_graph)) self.obj.condensate_graph() for node, data in self.obj.condensed_graph.nodes(data=True): self.assertTrue(data["type"] in ("cutpoint", "block"))