def apply_design_rules(anm): """Applies appropriate design rules to ANM""" g_in = anm['input'] build_phy(anm) g_phy = anm['phy'] import autonetkit autonetkit.update_http(anm) build_l3_connectivity(anm) check_server_asns(anm) autonetkit.update_http(anm) build_vrf(anm) # need to do before to add loopbacks before ip allocations from autonetkit.design.ip import build_ip, build_ipv4,build_ipv6 build_ip(anm) # ip infrastructure topology #TODO: set defaults at the start, rather than inline, ie set g_in.data.address_family then use later address_family = g_in.data.address_family or "v4" # default is v4 #TODO: can remove the infrastructure now create g_ip seperately if address_family == "None": log.info("IP addressing disabled, disabling routing protocol configuration") anm['phy'].data.enable_routing = False if address_family == "None": log.info("IP addressing disabled, skipping IPv4") anm.add_overlay("ipv4") # create empty so rest of code follows through g_phy.update(g_phy, use_ipv4 = False) elif address_family in ("v4", "dual_stack"): build_ipv4(anm, infrastructure = True) g_phy.update(g_phy, use_ipv4 = True) elif address_family == "v6": # Allocate v4 loopbacks for router ids build_ipv4(anm, infrastructure = False) g_phy.update(g_phy, use_ipv4 = False) #TODO: Create a collision domain overlay for ip addressing - l2 overlay? if address_family == "None": log.info("IP addressing disabled, not allocating IPv6") anm.add_overlay("ipv6") # create empty so rest of code follows through g_phy.update(g_phy, use_ipv6 = False) elif address_family in ("v6", "dual_stack"): build_ipv6(anm) g_phy.update(g_phy, use_ipv6 = True) else: anm.add_overlay("ipv6") # placeholder for compiler logic default_igp = g_in.data.igp or "ospf" non_igp_nodes = [n for n in g_in if not n.igp] #TODO: should this be modifying g_in? g_in.update(non_igp_nodes, igp=default_igp) # store igp onto each node ank_utils.copy_attr_from(g_in, g_phy, "include_csr") try: from autonetkit_cisco import build_network as cisco_build_network except ImportError, e: log.debug("Unable to load autonetkit_cisco %s" % e)
def manage_network(input_graph_string, timestamp, build_options, reload_build=False, grid=None): """Build, compile, render network as appropriate""" # import build_network_simple as build_network import autonetkit.build_network as build_network if reload_build: # remap? build_network = reload(build_network) if build_options['build']: if input_graph_string: graph = build_network.load(input_graph_string) elif grid: graph = build_network.grid_2d(grid) anm = build_network.build(graph) if not build_options['compile']: update_http(anm) if build_options['validate']: import autonetkit.ank_validate try: autonetkit.ank_validate.validate(anm) except Exception, e: log.warning("Unable to validate topologies: %s" % e) log.debug("Unable to validate topologies", exc_info=True)
def collect_sh_ip_route(anm, nidb, start_node = None): if not start_node: start_node = random.choice([n for n in nidb.nodes("is_router")]) #TODO: move this to another module, eg measure import autonetkit.measure as measure import autonetkit.verify as verify import autonetkit command = 'vtysh -c "show ip route"' #TODO: make auto take tap ip if netkit platform node #TODO: auto make put into list if isinstance(remote_hosts, nidb_node) remote_hosts = [start_node.tap.ip] result = measure.send(nidb, command, remote_hosts) processed = [] for line in result: processed.append([anm['ipv4'].node(n) for n in line]) #TODO: move this into verify module verification_results = verify.igp_routes(anm, processed) processed_with_results = [] for line in processed: prefix = str(line[-1].subnet) try: result = verification_results[prefix] except KeyError: result = False # couldn't find prefix processed_with_results.append({ 'path': line, 'verified': result, }) autonetkit.update_http(anm, nidb) ank_messaging.highlight([], [], processed_with_results)
def collect_sh_ip_route(anm, nidb, start_node=None): if not start_node: start_node = random.choice([n for n in nidb.nodes("is_router")]) #TODO: move this to another module, eg measure import autonetkit.measure as measure import autonetkit.verify as verify import autonetkit command = 'vtysh -c "show ip route"' #TODO: make auto take tap ip if netkit platform node #TODO: auto make put into list if isinstance(remote_hosts, nidb_node) remote_hosts = [start_node.tap.ip] result = measure.send(nidb, command, remote_hosts) processed = [] for line in result: processed.append([anm['ipv4'].node(n) for n in line]) #TODO: move this into verify module verification_results = verify.igp_routes(anm, processed) processed_with_results = [] for line in processed: prefix = str(line[-1].subnet) try: result = verification_results[prefix] except KeyError: result = False # couldn't find prefix processed_with_results.append({ 'path': line, 'verified': result, }) autonetkit.update_http(anm, nidb) ank_messaging.highlight([], [], processed_with_results)
def build(input_graph): """Main function to build network overlay topologies""" anm = None try: anm = initialise(input_graph) anm = apply_design_rules(anm) #print {str(node): {'x': node.x, 'y': node.y} for node in anm['input']} import autonetkit autonetkit.update_http(anm) except Exception, e: # Send the visualisation to help debugging import autonetkit try: autonetkit.update_http(anm) except Exception, e: # problem with vis -> could be coupled with original exception - raise original log.warning("Unable to visualise: %s" % e)
def manual_ipv4_infrastructure_allocation(anm): """Applies manual IPv4 allocation""" import netaddr g_ipv4 = anm['ipv4'] for node in g_ipv4.nodes("is_l3device"): for interface in node.physical_interfaces: if not interface['input'].is_bound: continue # unbound interface ip_address = netaddr.IPAddress(interface['input'].ipv4_address) prefixlen = interface['input'].ipv4_prefixlen interface.ip_address = ip_address interface.prefixlen = prefixlen cidr_string = "%s/%s" % (ip_address, prefixlen) interface.subnet = netaddr.IPNetwork(cidr_string) collision_domains = [d for d in g_ipv4 if d.collision_domain] #TODO: allow this to work with specified ip_address/subnet as well as ip_address/prefixlen from netaddr import IPNetwork for cd in collision_domains: connected_interfaces = [edge.dst_int for edge in cd.edges()] cd_subnets = [IPNetwork("%s/%s" % (i.subnet.network, i.prefixlen)) for i in connected_interfaces] try: assert(len(set(cd_subnets)) == 1) except AssertionError: log.warning("Non matching subnets from collision domain %s" % cd) else: cd.subnet = cd_subnets[0] # take first entry # apply to remote interfaces for edge in cd.edges(): remote_interface = edge.dst_int edge.dst_int.subnet = cd.subnet # also need to form aggregated IP blocks (used for e.g. routing prefix # advertisement) autonetkit.update_http(anm) infra_blocks = {} for asn, devices in g_ipv4.groupby("asn").items(): collision_domains = [d for d in devices if d.collision_domain] subnets = [cd.subnet for cd in collision_domains] infra_blocks[asn] = netaddr.cidr_merge(subnets) g_ipv4.data.infra_blocks = infra_blocks
def build(input_graph): """Main function to build network overlay topologies""" anm = None try: anm = initialise(input_graph) anm = apply_design_rules(anm) # print {str(node): {'x': node.x, 'y': node.y} for node in # anm['input']} autonetkit.update_http(anm) except Exception, e: # Send the visualisation to help debugging try: autonetkit.update_http(anm) except Exception, e: # problem with vis -> could be coupled with original exception - # raise original log.warning("Unable to visualise: %s" % e)
def apply_design_rules(anm): g_in = anm['input'] build_phy(anm) g_phy = anm['phy'] autonetkit.update_http(anm) build_l3_connectivity(anm) build_vrf(anm) # need to do before to add loopbacks before ip allocations build_ip(anm) # ip infrastructure topology #TODO: set defaults at the start, rather than inline, ie set g_in.data.address_family then use later address_family = g_in.data.address_family or "v4" # default is v4 #TODO: can remove the infrastructure now create g_ip seperately if address_family in ("v4", "dual_stack"): build_ipv4(anm, infrastructure = True) g_phy.update(g_phy, use_ipv4 = True) else: build_ipv4(anm, infrastructure = False) #TODO: Create a collision domain overlay for ip addressing - l2 overlay? if address_family in ("v6", "dual_stack"): build_ipv6(anm) g_phy.update(g_phy, use_ipv6 = True) else: anm.add_overlay("ipv6") # placeholder for compiler logic default_igp = g_in.data.igp or "ospf" non_igp_nodes = [n for n in g_in if not n.igp] #TODO: should this be modifying g_in? g_in.update(non_igp_nodes, igp=default_igp) # store igp onto each node ank_utils.copy_attr_from(g_in, g_phy, "include_csr") build_ospf(anm) build_isis(anm) build_bgp(anm) autonetkit.update_http(anm) # post-processing mark_ebgp_vrf(anm) build_ibgp_vpn_v4(anm) # build after bgp as is based on #autonetkit.update_http(anm) return anm
def apply_design_rules(anm): g_in = anm['input'] build_phy(anm) g_phy = anm['phy'] build_vrf(anm) # need to do before to add loopbacks before ip allocations build_ip(anm) # ip infrastructure topology #TODO: set defaults at the start, rather than inline, ie set g_in.data.address_family then use later address_family = g_in.data.address_family or "v4" # default is v4 #TODO: can remove the infrastructure now create g_ip seperately if address_family in ("v4", "dual_stack"): build_ipv4(anm, infrastructure=True) g_phy.update(g_phy, use_ipv4=True) else: build_ipv4(anm, infrastructure=False) #TODO: Create a collision domain overlay for ip addressing - l2 overlay? if address_family in ("v6", "dual_stack"): build_ipv6(anm) g_phy.update(g_phy, use_ipv6=True) else: anm.add_overlay("ipv6") # placeholder for compiler logic default_igp = g_in.data.igp or "ospf" non_igp_nodes = [n for n in g_in if not n.igp] #TODO: should this be modifying g_in? g_in.update(non_igp_nodes, igp=default_igp) # store igp onto each node ank_utils.copy_attr_from(g_in, g_phy, "include_csr") build_ospf(anm) build_isis(anm) build_bgp(anm) autonetkit.update_http(anm) # post-processing mark_ebgp_vrf(anm) build_ibgp_vpn_v4(anm) # build after bgp as is based on #autonetkit.update_http(anm) return anm
def manage_network(input_graph_string, timestamp, build_options, reload_build=False, grid = None): """Build, compile, render network as appropriate""" # import build_network_simple as build_network import autonetkit.build_network as build_network if reload_build: # remap? build_network = reload(build_network) if build_options['build']: if input_graph_string: graph = build_network.load(input_graph_string) elif grid: graph = build_network.grid_2d(grid) anm = build_network.build(graph) if not build_options['compile']: update_http(anm) if build_options['validate']: import autonetkit.ank_validate autonetkit.ank_validate.validate(anm) if build_options['compile']: if build_options['archive']: anm.save() nidb = compile_network(anm) update_http(anm, nidb) log.debug("Sent ANM to web server") if build_options['archive']: nidb.save() # render.remove_dirs(["rendered"]) if build_options['render']: render.render(nidb) if not(build_options['build'] or build_options['compile']): # Load from last run import autonetkit.anm anm = autonetkit.anm.AbstractNetworkModel() anm.restore_latest() nidb = NIDB() nidb.restore_latest() update_http(anm, nidb) if build_options['diff']: import autonetkit.diff nidb_diff = autonetkit.diff.nidb_diff() import json data = json.dumps(nidb_diff, cls=ank_json.AnkEncoder, indent=4) log.info("Wrote diff to diff.json") with open("diff.json", "w") as fh: # TODO: make file specified in config fh.write(data) if build_options['deploy']: deploy_network(anm, nidb, input_graph_string) if build_options['measure']: measure_network(anm, nidb) log.info("Finished")
def build_ipv6(anm): """Builds IPv6 graph, using nodes and edges from IPv4 graph""" import autonetkit.plugins.ipv6 as ipv6 # uses the nodes and edges from ipv4 g_ipv6 = anm.add_overlay("ipv6") g_ip = anm["ip"] g_ipv6.add_nodes_from(g_ip, retain="collision_domain") # retain if collision domain or not g_ipv6.add_edges_from(g_ip.edges()) autonetkit.update_http(anm) ipv6.allocate_ips(g_ipv6) # TODO: replace this with direct allocation to interfaces in ip alloc plugin for node in g_ipv6.nodes("is_l3device"): node.loopback_zero.ip_address = node.loopback for interface in node: edges = list(interface.edges()) if len(edges): edge = edges[0] # first (only) edge interface.ip_address = edge.ip # TODO: make this consistent interface.subnet = edge.dst.subnet # from collision domain
def initialise(input_graph): """Initialises the input graph with from a NetworkX graph""" anm = autonetkit.anm.AbstractNetworkModel() input_undirected = nx.Graph(input_graph) g_in = anm.add_overlay("input", graph=input_undirected) anm.add_overlay("input_directed", graph=input_graph, directed=True) # set defaults if not g_in.data.specified_int_names: # if not specified then automatically assign interface names g_in.data.specified_int_names = False import autonetkit.plugins.graph_product as graph_product graph_product.expand(g_in) # apply graph products if relevant expand_fqdn = False # TODO: make this set from config and also in the input file if expand_fqdn and len(ank_utils.unique_attr(g_in, "asn")) > 1: # Multiple ASNs set, use label format device.asn anm.set_node_label(".", ['label', 'pop', 'asn']) g_in.update( g_in.nodes("is_router", platform="junosphere"), syntax="junos") g_in.update(g_in.nodes("is_router", platform="dynagen"), syntax="ios") g_in.update(g_in.nodes("is_router", platform="netkit"), syntax="quagga") g_in.update(g_in.nodes("is_server", platform="netkit"), syntax="quagga") g_graphics = anm.add_overlay("graphics") # plotting data g_graphics.add_nodes_from(g_in, retain=['x', 'y', 'device_type', 'label', 'device_subtype', 'pop', 'asn']) if g_in.data.Creator == "Maestro": # Multiple ASNs set, use label format device.asn anm.set_node_label(".", ['label_full']) autonetkit.update_http(anm) return anm
def manage_network(input_graph_string, timestamp, build_options, reload_build=False, grid=None): """Build, compile, render network as appropriate""" # import build_network_simple as build_network import autonetkit.build_network as build_network if reload_build: # remap? build_network = reload(build_network) if build_options['build']: if input_graph_string: graph = build_network.load(input_graph_string) elif grid: graph = build_network.grid_2d(grid) anm = build_network.build(graph) if not build_options['compile']: update_http(anm) if build_options['validate']: import autonetkit.ank_validate try: autonetkit.ank_validate.validate(anm) except Exception, e: log.warning("Unable to validate topologies: %s" % e)
def build_ipv4(anm, infrastructure=True): """Builds IPv4 graph""" g_ipv4 = anm.add_overlay("ipv4") g_ip = anm["ip"] g_in = anm["input"] g_ipv4.add_nodes_from(g_ip, retain="collision_domain") # retain if collision domain or not # Copy ASN attribute chosen for collision domains (used in alloc algorithm) ank_utils.copy_attr_from(g_ip, g_ipv4, "asn", nbunch=g_ipv4.nodes("collision_domain")) g_ipv4.add_edges_from(g_ip.edges()) autonetkit.update_http(anm) # TODO: need to set allocate_ipv4 by default in the readers if g_in.data.alloc_ipv4_infrastructure is False: manual_ipv4_infrastructure_allocation(anm) else: import autonetkit.plugins.ipv4 as ipv4 ipv4.allocate_ips(g_ipv4, infrastructure=True, loopbacks=False) # ank_utils.save(g_ipv4) if g_in.data.alloc_ipv4_loopbacks is False: manual_ipv4_loopback_allocation(anm) else: import autonetkit.plugins.ipv4 as ipv4 ipv4.allocate_ips(g_ipv4, infrastructure=False, loopbacks=True) # ank_utils.save(g_ipv4) # TODO: need to also support secondary_loopbacks for IPv6 ipv4.allocate_ips(g_ipv4, infrastructure=False, loopbacks=False, secondary_loopbacks=True) autonetkit.update_http(anm) # TODO: replace this with direct allocation to interfaces in ip alloc plugin for node in g_ipv4.nodes("is_l3device"): node.loopback_zero.ip_address = node.loopback for interface in node: edges = list(interface.edges()) if len(edges): edge = edges[0] # first (only) edge interface.ip_address = edge.ip_address interface.subnet = edge.dst.subnet # from collision domain # TODO: also map loopbacks to loopback interface 0 autonetkit.update_http(anm)
g_dir = anm.add_overlay("dir", directed=True) g_dir.add_nodes_from(g_phy) g_dir.add_edges_from(([("r1", "r2")])) g_dir.add_edges_from(([("r2", "r1")])) g_dir.add_edges_from(([("r1", "r3")])) g_dir_multi = anm.add_overlay("dir_multi", directed=True, multi_edge=True) g_dir_multi.add_nodes_from(g_phy) g_dir_multi.add_edges_from(([("r1", "r2")])) g_dir_multi.add_edges_from(([("r1", "r2")])) g_dir_multi.add_edges_from(([("r1", "r2")])) g_dir_multi.add_edges_from(([("r1", "r2")])) g_dir_multi.add_edges_from(([("r2", "r1")])) g_dir_multi.add_edges_from(([("r2", "r1")])) g_dir_multi.add_edges_from(([("r2", "r1")])) g_dir_multi.add_edges_from(([("r2", "r1")])) g_dir_multi.add_edges_from(([("r2", "r1")])) g_dir_multi.add_edges_from(([("r1", "r3")])) for index, edge in enumerate(g_dir_multi.edges()): #print index, edge edge.index = "i_%s" % index from networkx.readwrite import json_graph import json data = json_graph.node_link_data(graph) with open("multi.json", "w") as fh: fh.write(json.dumps(data, indent=2)) autonetkit.update_http(anm)
if build_options['validate']: import autonetkit.ank_validate try: autonetkit.ank_validate.validate(anm) except Exception, e: log.warning("Unable to validate topologies: %s" % e) log.debug("Unable to validate topologies", exc_info=True) if build_options['compile']: if build_options['archive']: anm.save() nidb = compile_network(anm) update_http(anm, nidb) log.debug("Sent ANM to web server") if build_options['archive']: nidb.save() # render.remove_dirs(["rendered"]) if build_options['render']: render.render(nidb) if not(build_options['build'] or build_options['compile']): # Load from last run import autonetkit.anm anm = autonetkit.anm.NetworkModel() anm.restore_latest() nidb = DeviceModel() nidb.restore_latest() update_http(anm, nidb)
if not build_options['compile']: update_http(anm) if build_options['validate']: import autonetkit.ank_validate try: autonetkit.ank_validate.validate(anm) except Exception, e: log.warning("Unable to validate topologies: %s" % e) if build_options['compile']: if build_options['archive']: anm.save() nidb = compile_network(anm) update_http(anm, nidb) log.debug("Sent ANM to web server") if build_options['archive']: nidb.save() # render.remove_dirs(["rendered"]) if build_options['render']: render.render(nidb) if not(build_options['build'] or build_options['compile']): # Load from last run import autonetkit.anm anm = autonetkit.anm.AbstractNetworkModel() anm.restore_latest() nidb = NIDB() nidb.restore_latest() update_http(anm, nidb)
import autonetkit.collection.process as ank_process import autonetkit.ank_messaging as ank_messaging import autonetkit import pkg_resources parse_template = pkg_resources.resource_filename("autonetkit", "textfsm/linux/traceroute") anm = autonetkit.ANM() anm.restore_latest() nidb = autonetkit.NIDB() nidb.restore_latest() print list(nidb.nodes()) autonetkit.update_http(anm, nidb) emulation_server = "115.146.93.18" command_list = [] import autonetkit.collection.process as ank_process reverse_mappings = ank_process.build_reverse_mappings_from_nidb(nidb) import random dest_node = random.choice(list(nidb.routers())) #dest_node = nidb.node("as1r1") #dest_node = nidb.node("as40r1") #dest_label = random.choice(["as1r1", "as30r1", "as20r3"]) #dest_node = nidb.node(dest_label) dest_ip = dest_node.interfaces[1].ipv4_address command = "traceroute -n -a -U -w 0.5 %s" % dest_ip
def test(): log.info("Testing ANM") anm = autonetkit.NetworkModel() g_in = anm.add_overlay("input") router_ids = ["r1", "r2", "r3", "r4", "r5"] g_in.add_nodes_from(router_ids) g_in.update(device_type="router") g_in.update(asn=1) positions = { 'r3': (107, 250), 'r5': (380, 290), 'r1': (22, 50), 'r2': (377, 9), 'r4': (571, 229) } for node in g_in: node.x = positions[node][0] node.y = positions[node][1] eth0 = node.add_interface("eth0") eth0.speed = 100 # node->node edges input_edges = [("r1", "r2"), ("r2", "r4"), ("r3", "r4"), ("r3", "r5"), ("r1", "r3")] input_interface_edges = [(g_in.node(src).interface(1), g_in.node(dst).interface(1)) for src, dst in input_edges] g_in.add_edges_from(input_interface_edges) g_phy = anm['phy'] g_phy.add_nodes_from(g_in, retain=["device_type", "x", "y", "asn"]) g_phy.add_edges_from(g_in.edges()) g_test = anm.add_overlay("test") g_test.add_node("test_node") # test interfaces for node in g_phy: pass test_node = g_phy.node("r1") #TODO: assert here node_interfaces = list(test_node.interfaces()) # test equality #TODO: check why == uses eq() but != doesn't... assert (not node_interfaces[0] == node_interfaces[1]) print list(test_node.interfaces()) for i in test_node.interfaces(): print i, i.dump() print[i.description for i in sorted(node_interfaces)] assert ([i.description for i in sorted(node_interfaces)] == ['loopback', 'eth0']) for interface in test_node: # test exists assert (interface is not None) # test __nonzero__ assert (interface) set_value = 123 interface.test = set_value get_value = interface.test assert (set_value == get_value ) # TODO: could check is indeed same object reference loopback0 = test_node.interface(0) assert (not loopback0.is_bound) assert (loopback0.is_loopback) assert (not loopback0.is_physical) assert (loopback0.is_loopback_zero) #TODO: need to add more loopbacks to test print loopback0 assert (str(loopback0) == "loopback.r1") eth0 = test_node.interface(1) assert (eth0.is_bound) assert (not eth0.is_loopback) assert (not eth0.is_loopback_zero) assert (eth0.is_physical) assert (eth0.phy == eth0) # should be itself as phy overlay #print eth0.dump() #Cross-layer access assert (eth0['input'] is not None) assert (sorted(eth0.neighbors()) == [ g_phy.node("r2").interface(1), g_phy.node("r3").interface(1) ]) # access non existent overlay #TODO: decide if worth trying to assert the logged item eth0["non_existent_overlay"] # Need to test cross-layer interface access to phy #test accessing overlay for node that doesnt exist in that overlay test_overlay_node = g_test.node("test_node") test_overlay_interface = test_overlay_node.add_interface() test_overlay_interface['phy'] #Want to assertRaises # Test edges autonetkit.update_http(anm) test_edge = g_in.edge("r1", "r2") assert (test_edge is not None) # test overlays # test ANM test_node = g_phy.node("r1") assert (test_node.asn == 1) assert (test_node.device_type == "router") #TODO: also need to test for servers assert (test_node.is_l3device()) assert (test_node.is_router()) assert (not test_node.is_switch()) assert (not test_node.is_server()) assert (str(sorted(list(test_node.neighbors()))) == "[r2, r3]") assert (str(sorted(list( test_node.neighbor_interfaces()))) == "[eth0.r2, eth0.r3]") # Test getting from another overlay assert (test_node['input'].asn == 1) assert (str(sorted(g_phy.nodes())) == "[r1, r2, r3, r4, r5]") assert (test_node.label == "r1") """ g_in.update("r4", asn = 2) g_in.update(["r1", "r2", "r3"], asn = 1) test = g_in.node("r5") """ # More graph level tests #TODO: need to allow searching for interface by .interface("eth1", "r1") #TODO: need to provide remove_nodes_from test_node = g_phy.node("r1") search_int = list(test_node.interfaces())[0] result_int = g_phy.interface(search_int) assert (search_int == result_int) search_int = list(test_node.interfaces())[1] result_int = g_phy.interface(search_int) assert (search_int == result_int) assert (g_phy.node("r1").degree() == 2) assert (g_phy.node("r3").degree() == 3) g_phy.add_edge("r1", "r4") assert (g_phy.edge("r1", "r4") is not None) edges_to_remove = g_phy.edge("r1", "r4") #TODO: remove_edges_from needs to support single/list g_phy.remove_edges_from([edges_to_remove]) assert (g_phy.edge("r1", "r4") is None) src_int = g_phy.node("r1").add_interface("eth1") dst_int = g_phy.node("r5").add_interface("eth1") g_phy.add_edges_from([(src_int, dst_int)]) edge = g_phy.edge("r1", "r5") assert ((edge.src_int, edge.dst_int) == (src_int, dst_int)) edge_a1 = g_phy.edge("r1", "r2") edge_a2 = g_phy.edge("r1", "r2") assert (edge_a1 == edge_a2) edge_b = g_phy.edge("r1", "r2") assert (edge_a1 != edge_b) # compare to string assert (edge_a1 == ("r1", "r2")) assert (edge_a1 != ("r1", "r3")) assert (bool(edge_a1) is True) #exists edge_non_existent = g_phy.edge("r1", "r8") #TODO: need to document API to check exists/doesn't exist for nodes, edges, interfaces, graphs,.... assert (bool(edge_non_existent) is False) #doesn't exist # add node #TODO: better handling of nodes with no x,y, asn, etc in jsonify r6 = g_phy.add_node("r6") assert (r6 in g_phy) del g_phy[r6] assert (r6 not in g_phy) # graph data g_phy.data.test = 123 assert (g_phy.data.test == 123) assert (g_phy.data['test'] == 123) # test adding a node with not attributes for jsonify #TODO: test for directed graph autonetkit.update_http(anm)
def test(): automated = True # whether to open ksdiff, log to file... if __name__ == "__main__": automated = False dirname, filename = os.path.split(os.path.abspath(__file__)) parent_dir = os.path.abspath(os.path.join(dirname, os.pardir)) anm = autonetkit.NetworkModel() input_file = os.path.join(parent_dir, "small_internet.graphml") input_graph = graphml.load_graphml(input_file) import autonetkit.build_network as build_network anm = build_network.initialise(input_graph) anm = build_network.apply_design_rules(anm) try: from websocket import create_connection except ImportError: print "websocket-client package not installed" else: autonetkit.update_http(anm) ws = create_connection("ws://localhost:8000/ws") ws.send("overlay_list") result = ws.recv() expected = '{"overlay_list": ["bgp", "ebgp", "ebgp_v4", "ebgp_v6", "eigrp", graphics", "ibgp_v4", "ibgp_v6", "ibgp_vpn_v4", "input", "input_directed", "ip", "ipv4", "ipv6", "isis", "l3_conn", "ospf", "phy", "vrf"]}' assert(result == expected) overlay_id = "phy" ws.send("overlay_id=" + overlay_id) result = ws.recv() with open(os.path.join(dirname, "expected_phy.json"), "r") as fh: expected = fh.read() assert(result == expected) ws.close() import autonetkit.console_script as console_script render_hostname = "localhost" nidb = console_script.create_nidb(anm) nidb._graph.graph['timestamp'] = "123456" import autonetkit.compilers.platform.netkit as pl_netkit nk_compiler = pl_netkit.NetkitCompiler(nidb, anm, render_hostname) nk_compiler.compile() autonetkit.update_http(anm, nidb) ws = create_connection("ws://localhost:8000/ws") ws.send("overlay_list") result = ws.recv() expected = '{"overlay_list": ["bgp", "ebgp", "ebgp_v4", "ebgp_v6", "eigrp", graphics", "ibgp_v4", "ibgp_v6", "ibgp_vpn_v4", "input", "input_directed", "ip", "ipv4", "ipv6", "isis", "l3_conn", "nidb", "ospf", "phy", "vrf"]}' assert(result == expected) overlay_id = "nidb" ws.send("overlay_id=" + overlay_id) result = ws.recv() with open(os.path.join(dirname, "expected_nidb.json"), "r") as fh: expected = fh.read() assert(result == expected) ws.close()
def test(): anm = autonetkit.NetworkModel() g_phy = anm['phy'] g_phy.add_nodes_from(["r1", "r2", "r3", "r4", "r5"]) for node in g_phy: node.device_type = "router" g_phy.node("r1").x = 100 g_phy.node("r1").y = 100 g_phy.node("r2").x = 250 g_phy.node("r2").y = 250 g_phy.node("r3").x = 100 g_phy.node("r3").y = 300 g_phy.node("r4").x = 600 g_phy.node("r4").y = 600 g_phy.node("r5").x = 600 g_phy.node("r5").y = 300 g_phy.add_edges_from(([("r1", "r2")])) g_phy.add_edges_from(([("r1", "r3")])) #g_phy.add_edges_from(([("r2", "r3")])) #g_phy.add_edges_from(([("r2", "r4")])) #g_phy.add_edges_from(([("r4", "r3")])) #g_phy.add_edges_from(([("r4", "r5")])) g_simple = anm.add_overlay("simple") g_simple.add_nodes_from(g_phy) g_simple.add_edges_from(([("r1", "r2")])) g_simple.add_edges_from(([("r4", "r3")])) g_me = anm.add_overlay("multi", multi_edge = True) graph = g_me._graph g_me.add_nodes_from(g_phy) # add two edges g_me.add_edges_from(([("r1", "r2")])) g_me.add_edges_from(([("r1", "r2")])) g_me.add_edges_from(([("r1", "r2")])) g_me.add_edges_from(([("r1", "r2")])) g_me.add_edges_from(([("r1", "r2")])) g_me.add_edges_from(([("r1", "r3")])) g_me.add_edges_from(([("r2", "r3")])) g_me.add_edges_from(([("r2", "r3")])) r1 = g_me.node("r1") for index, edge in enumerate(g_me.edges()): #print index, edge edge.index = "i_%s" % index for edge in r1.edges(): #print edge, edge.index pass """ e1 = r1.edges()[0] e1a = g_me.edge(e1) assert(e1 == e1a) e2 = r1.edges()[1] assert(e1 != e2) #TODO: check why neq != also returns true for e1 != e1a """ #print g_me.edge("r1", "r2", 0).index #print g_me.edge("r1", "r2", 1).index print "edges" for edge in g_me.edges(): print edge out_of_order = [g_me.edge("r1", "r2", x) for x in [4, 1, 3, 2, 0]] #print [e.index for e in out_of_order] in_order = sorted(out_of_order) #print in_order #print [e.index for e in in_order] # test adding to another mutli edge graph print "adding" g_me2 = anm.add_overlay("multi2", multi_edge = True) g_me2.add_nodes_from(g_me) print "add", len(g_me.edges()) g_me2.add_edges_from(g_me.edges(), retain = "index") for edge in g_me2.edges(): print edge, edge.index # examine underlying nx structure #print graph #print type(graph) for u, v, k in graph.edges(keys=True): pass #print u, v, k #print graph[u][v][k].items() #graph[u][v][k]['test'] = 123 g_dir = anm.add_overlay("dir", directed=True) g_dir.add_nodes_from(g_phy) g_dir.add_edges_from(([("r1", "r2")])) g_dir.add_edges_from(([("r2", "r1")])) g_dir.add_edges_from(([("r1", "r3")])) g_dir_multi = anm.add_overlay("dir_multi", directed = True, multi_edge = True) g_dir_multi.add_nodes_from(g_phy) g_dir_multi.add_edges_from(([("r1", "r2")])) g_dir_multi.add_edges_from(([("r1", "r2")])) g_dir_multi.add_edges_from(([("r1", "r2")])) g_dir_multi.add_edges_from(([("r1", "r2")])) g_dir_multi.add_edges_from(([("r2", "r1")])) g_dir_multi.add_edges_from(([("r2", "r1")])) g_dir_multi.add_edges_from(([("r2", "r1")])) g_dir_multi.add_edges_from(([("r2", "r1")])) g_dir_multi.add_edges_from(([("r2", "r1")])) g_dir_multi.add_edges_from(([("r1", "r3")])) for index, edge in enumerate(g_dir_multi.edges()): #print index, edge edge.index = "i_%s" % index from networkx.readwrite import json_graph import json data = json_graph.node_link_data(graph) with open("multi.json", "w") as fh: fh.write(json.dumps(data, indent=2)) autonetkit.update_http(anm)
# test overlays # test ANM test_node = g_phy.node("r1") assert test_node.asn == 1 assert test_node.device_type == "router" # TODO: also need to test for servers assert test_node.is_l3device() assert test_node.is_router() assert not test_node.is_switch() assert not test_node.is_server() assert str(list(test_node.neighbors())) == "[r2, r3]" assert str(list(test_node.neighbor_interfaces())) == "[eth0.r2, eth0.r3]" # Test getting from another overlay assert test_node["input"].asn == 1 assert str(sorted(g_phy.nodes())) == "[r1, r2, r3, r4, r5]" assert test_node.label == "r1" """ g_in.update("r4", asn = 2) g_in.update(["r1", "r2", "r3"], asn = 1) test = g_in.node("r5") """ autonetkit.update_http(anm)
def build(input_graph): """Main function to build network overlay topologies""" anm = autonetkit.anm.AbstractNetworkModel() input_undirected = nx.Graph(input_graph) g_in = anm.add_overlay("input", graph=input_undirected) anm.add_overlay("input_directed", graph=input_graph, directed=True) # set defaults if not g_in.data.specified_int_names: # if not specified then automatically assign interface names g_in.data.specified_int_names = False import autonetkit.plugins.graph_product as graph_product graph_product.expand(g_in) # apply graph products if relevant expand_fqdn = False # TODO: make this set from config and also in the input file if expand_fqdn and len(ank_utils.unique_attr(g_in, "asn")) > 1: # Multiple ASNs set, use label format device.asn anm.set_node_label(".", ["label", "pop", "asn"]) g_in.update(g_in.nodes("is_router", platform="junosphere"), syntax="junos") g_in.update(g_in.nodes("is_router", platform="dynagen"), syntax="ios") g_in.update(g_in.nodes("is_router", platform="netkit"), syntax="quagga") g_graphics = anm.add_overlay("graphics") # plotting data g_graphics.add_nodes_from(g_in, retain=["x", "y", "device_type", "device_subtype", "pop", "asn"]) build_phy(anm) autonetkit.update_http(anm) g_phy = anm["phy"] build_vrf(anm) # need to do before to add loopbacks before ip allocations build_ip(anm) # ip infrastructure topology autonetkit.update_http(anm) address_family = g_in.data.address_family or "v4" # default is v4 # TODO: can remove the infrastructure now create g_ip seperately if address_family in ("v4", "dual_stack"): build_ipv4(anm, infrastructure=True) g_phy.update(g_phy, use_ipv4=True) else: build_ipv4(anm, infrastructure=False) # TODO: Create a collision domain overlay for ip addressing - l2 overlay? if address_family in ("v6", "dual_stack"): build_ipv6(anm) g_phy.update(g_phy, use_ipv6=True) default_igp = g_in.data.igp or "ospf" non_igp_nodes = [n for n in g_in if not n.igp] # TODO: should this be modifying g_in? g_in.update(non_igp_nodes, igp=default_igp) # store igp onto each node anm.add_overlay("ospf") anm.add_overlay("isis") ank_utils.copy_attr_from(g_in, g_phy, "include_csr") build_ospf(anm) build_isis(anm) build_bgp(anm) autonetkit.update_http(anm) return anm
def test(): anm = autonetkit.NetworkModel() g_phy = anm['phy'] g_phy.add_nodes_from(["r1", "r2", "r3", "r4", "r5"]) for node in g_phy: node.device_type = "router" g_phy.node("r1").x = 100 g_phy.node("r1").y = 100 g_phy.node("r2").x = 250 g_phy.node("r2").y = 250 g_phy.node("r3").x = 100 g_phy.node("r3").y = 300 g_phy.node("r4").x = 600 g_phy.node("r4").y = 600 g_phy.node("r5").x = 600 g_phy.node("r5").y = 300 g_phy.add_edges_from(([("r1", "r2")])) g_phy.add_edges_from(([("r1", "r3")])) #g_phy.add_edges_from(([("r2", "r3")])) #g_phy.add_edges_from(([("r2", "r4")])) #g_phy.add_edges_from(([("r4", "r3")])) #g_phy.add_edges_from(([("r4", "r5")])) g_simple = anm.add_overlay("simple") g_simple.add_nodes_from(g_phy) g_simple.add_edges_from(([("r1", "r2")])) g_simple.add_edges_from(([("r4", "r3")])) g_me = anm.add_overlay("multi", multi_edge=True) graph = g_me._graph g_me.add_nodes_from(g_phy) # add two edges g_me.add_edges_from(([("r1", "r2")])) g_me.add_edges_from(([("r1", "r2")])) g_me.add_edges_from(([("r1", "r2")])) g_me.add_edges_from(([("r1", "r2")])) g_me.add_edges_from(([("r1", "r2")])) g_me.add_edges_from(([("r1", "r3")])) g_me.add_edges_from(([("r2", "r3")])) g_me.add_edges_from(([("r2", "r3")])) r1 = g_me.node("r1") for index, edge in enumerate(g_me.edges()): #print index, edge edge.index = "i_%s" % index for edge in r1.edges(): #print edge, edge.index pass """ e1 = r1.edges()[0] e1a = g_me.edge(e1) assert(e1 == e1a) e2 = r1.edges()[1] assert(e1 != e2) #TODO: check why neq != also returns true for e1 != e1a """ #print g_me.edge("r1", "r2", 0).index #print g_me.edge("r1", "r2", 1).index print "edges" for edge in g_me.edges(): print edge out_of_order = [g_me.edge("r1", "r2", x) for x in [4, 1, 3, 2, 0]] #print [e.index for e in out_of_order] in_order = sorted(out_of_order) #print in_order #print [e.index for e in in_order] # test adding to another mutli edge graph print "adding" g_me2 = anm.add_overlay("multi2", multi_edge=True) g_me2.add_nodes_from(g_me) print "add", len(g_me.edges()) g_me2.add_edges_from(g_me.edges(), retain="index") for edge in g_me2.edges(): print edge, edge.index # examine underlying nx structure #print graph #print type(graph) for u, v, k in graph.edges(keys=True): pass #print u, v, k #print graph[u][v][k].items() #graph[u][v][k]['test'] = 123 g_dir = anm.add_overlay("dir", directed=True) g_dir.add_nodes_from(g_phy) g_dir.add_edges_from(([("r1", "r2")])) g_dir.add_edges_from(([("r2", "r1")])) g_dir.add_edges_from(([("r1", "r3")])) g_dir_multi = anm.add_overlay("dir_multi", directed=True, multi_edge=True) g_dir_multi.add_nodes_from(g_phy) g_dir_multi.add_edges_from(([("r1", "r2")])) g_dir_multi.add_edges_from(([("r1", "r2")])) g_dir_multi.add_edges_from(([("r1", "r2")])) g_dir_multi.add_edges_from(([("r1", "r2")])) g_dir_multi.add_edges_from(([("r2", "r1")])) g_dir_multi.add_edges_from(([("r2", "r1")])) g_dir_multi.add_edges_from(([("r2", "r1")])) g_dir_multi.add_edges_from(([("r2", "r1")])) g_dir_multi.add_edges_from(([("r2", "r1")])) g_dir_multi.add_edges_from(([("r1", "r3")])) for index, edge in enumerate(g_dir_multi.edges()): #print index, edge edge.index = "i_%s" % index from networkx.readwrite import json_graph import json data = json_graph.node_link_data(graph) with open("multi.json", "w") as fh: fh.write(json.dumps(data, indent=2)) autonetkit.update_http(anm)
def manage_network(input_graph_string, timestamp, build_options, reload_build=False, grid=None): """Build, compile, render network as appropriate""" # import build_network_simple as build_network import autonetkit.build_network as build_network if reload_build: # remap? build_network = reload(build_network) if build_options['build']: if input_graph_string: graph = build_network.load(input_graph_string) elif grid: graph = build_network.grid_2d(grid) anm = build_network.build(graph) if not build_options['compile']: update_http(anm) if build_options['validate']: import ank_validate ank_validate.validate(anm) if build_options['compile']: if build_options['archive']: anm.save() nidb = compile_network(anm) update_http(anm, nidb) log.debug("Sent ANM to web server") if build_options['archive']: nidb.save() # render.remove_dirs(["rendered"]) if build_options['render']: render.render(nidb) if not (build_options['build'] or build_options['compile']): # Load from last run import autonetkit.anm anm = autonetkit.anm.AbstractNetworkModel() anm.restore_latest() nidb = NIDB() nidb.restore_latest() update_http(anm, nidb) if build_options['diff']: import autonetkit.diff nidb_diff = autonetkit.diff.nidb_diff() import json data = json.dumps(nidb_diff, cls=ank_json.AnkEncoder, indent=4) log.info("Wrote diff to diff.json") with open("diff.json", "w") as fh: # TODO: make file specified in config fh.write(data) # Note: this clobbers command line options # build_options.update(settings['General']) # update in case build has updated, eg for deploy # build_options.update(settings['General']) # update in case build has # updated, eg for deploy if build_options['deploy']: deploy_network(anm, nidb, input_graph_string) if build_options['measure']: measure_network(anm, nidb) log.info("Finished")
import autonetkit.ank_messaging as ank_messaging import autonetkit import json import random import pkg_resources parse_template = pkg_resources.resource_filename("autonetkit", "textfsm/quagga/sh_ip_route") anm = autonetkit.ANM() anm.restore_latest() nidb = autonetkit.DeviceModel() nidb.restore_latest() print list(nidb.nodes()) autonetkit.update_http(anm, nidb) emulation_server = "115.146.93.18" command_list = [] import autonetkit.collection.process as ank_process reverse_mappings = ank_process.build_reverse_mappings_from_nidb(nidb) print reverse_mappings command = "show ip route" node = nidb.node("5") #node = random.choice(list(nidb.routers())) while True: #for node in nidb.routers():
def build(input_graph): """Main function to build network overlay topologies""" anm = autonetkit.anm.AbstractNetworkModel() input_undirected = nx.Graph(input_graph) g_in = anm.add_overlay("input", graph=input_undirected) anm.add_overlay("input_directed", graph=input_graph, directed=True) # set defaults if not g_in.data.specified_int_names: # if not specified then automatically assign interface names g_in.data.specified_int_names = False import autonetkit.plugins.graph_product as graph_product graph_product.expand(g_in) # apply graph products if relevant expand_fqdn = False # TODO: make this set from config and also in the input file if expand_fqdn and len(ank_utils.unique_attr(g_in, "asn")) > 1: # Multiple ASNs set, use label format device.asn anm.set_node_label(".", ['label', 'pop', 'asn']) g_in.update( g_in.nodes("is_router", platform="junosphere"), syntax="junos") g_in.update(g_in.nodes("is_router", platform="dynagen"), syntax="ios") g_in.update(g_in.nodes("is_router", platform="netkit"), syntax="quagga") g_graphics = anm.add_overlay("graphics") # plotting data g_graphics.add_nodes_from(g_in, retain=['x', 'y', 'device_type', 'device_subtype', 'pop', 'asn']) build_phy(anm) autonetkit.update_http(anm) g_phy = anm['phy'] build_vrf(anm) address_family = g_in.data.address_family or "v4" allocate_ipv4_infrastructure = False if address_family in ("v4", "dual_stack"): allocate_ipv4_infrastructure = True build_ipv4(anm, infrastructure=allocate_ipv4_infrastructure) #TODO: Create a collision domain overlay for ip addressing - l2 overlay? allocate_ipv6 = False if address_family in ("v6", "dual_stack"): allocate_ipv6 = True build_ipv4(anm, infrastructure=True) build_ip6(anm) for node in g_phy: node.use_ipv4 = allocate_ipv4_infrastructure node.use_ipv6 = allocate_ipv6 default_igp = g_in.data.igp or "ospf" non_igp_nodes = [n for n in g_in if not node.igp] g_in.update(non_igp_nodes, igp=default_igp) anm.add_overlay("ospf") anm.add_overlay("isis") ank_utils.copy_attr_from(g_in, g_phy, "include_csr") build_ospf(anm) build_isis(anm) build_bgp(anm) autonetkit.update_http(anm) return anm