示例#1
0
    def configure_interfaces(self, device):
        LOG.debug("Configuring interfaces for %s" % self.network.fqdn(device))
        """Interface configuration"""
        lo_ip = self.network.lo_ip(device)
        interfaces = []

        interfaces.append({
            'id':          'lo0',
            'ip':           str(lo_ip.ip),
            'netmask':      str(lo_ip.netmask),
            'prefixlen':    str(lo_ip.prefixlen),
            'net_ent_title': ank.ip_to_net_ent_title(lo_ip.ip),
            'description': 'Loopback',
        })

        for src, dst, data in self.network.graph.edges(device, data=True):
            subnet = data['sn']
            int_id = self.int_id(data['id'])
            description = 'Interface %s -> %s' % (
                    ank.fqdn(self.network, src), 
                    ank.fqdn(self.network, dst))

# Interface information for router config
            interfaces.append({
                'id':          int_id,
                'ip':           str(data['ip']),
                'prefixlen':    str(subnet.prefixlen),
                'broadcast':    str(subnet.broadcast),
                'description':  description,
            })

        return interfaces
示例#2
0
    def configure_igp(self, router, igp_graph, ebgp_graph):
        """igp configuration"""
        LOG.debug("Configuring IGP for %s" % self.network.label(router))
        default_weight = 1
        igp_interfaces = []
        if igp_graph.degree(router) > 0:
            # Only start IGP process if IGP links
            igp_interfaces.append({ 'id': 'lo0', 'passive': True})
            for src, dst, data in igp_graph.edges(router, data=True):
                int_id = ank.junos_logical_int_id(self.int_id(data['id']))
                description = 'Interface %s -> %s' % (
                    ank.fqdn(self.network, src), 
                    ank.fqdn(self.network, dst))
                igp_interfaces.append({
                    'id':       int_id,
                    'weight':   data.get('weight', default_weight),
                    'description': description,
                    })

# Need to add eBGP edges as passive interfaces
            for src, dst in ebgp_graph.edges(router):
# Get relevant edges from ebgp_graph, and edge data from physical graph
                data = self.network.graph[src][dst]
                int_id = ank.junos_logical_int_id(self.int_id(data['id']))
                description = 'Interface %s -> %s' % (
                    ank.fqdn(self.network, src), 
                    ank.fqdn(self.network, dst))
                igp_interfaces.append({
                    'id':       int_id,
                    'weight':   data.get('weight', default_weight),
                    'description': description,
                    'passive': True,
                    })

        return igp_interfaces
示例#3
0
    def configure_igp(self, router, igp_graph, ebgp_graph):
        """igp configuration"""
        LOG.debug("Configuring IGP for %s" % self.network.label(router))
#TODO: get area from router
        default_area = 0
        igp_interfaces = []
        if igp_graph.degree(router) > 0:
            # Only start IGP process if IGP links
#TODO: make loopback a network mask so don't have to do "0.0.0.0"
            igp_interfaces.append({ 'id': 'lo0', 'wildcard': router.lo_ip.hostmask,
                'passive': False,
                'network': router.lo_ip.network,
                'area': default_area, 'weight': self.default_weight,
                })
            for src, dst, data in igp_graph.edges(router, data=True):
                int_id = self.int_id(data['id'])
                subnet = self.network.graph[src][dst]['sn']
                description = 'Interface %s -> %s' % (
                        ank.fqdn(self.network, src), 
                        ank.fqdn(self.network, dst))
                igp_interfaces.append({
                    'id':       int_id,
                    'weight':   data.get('weight', self.default_weight),
                    'area':   data.get('area', default_area),
                    'network': str(subnet.network),
                    'description': description,
                    'wildcard':      str(subnet.hostmask),
                    })

# Need to add eBGP edges as passive interfaces
            for src, dst in ebgp_graph.edges(router):
# Get relevant edges from ebgp_graph, and edge data from physical graph
                data = self.network.graph[src][dst]
                int_id = self.int_id(data['id'])
                subnet = self.network.graph[src][dst]['sn']
                description = 'Interface %s -> %s' % (
                    ank.fqdn(self.network, src), 
                    ank.fqdn(self.network, dst))
                igp_interfaces.append({
                    'id':       int_id,
                    'weight':   data.get('weight', self.default_weight),
                    'area':   data.get('area', default_area),
                    'description': description,
                    'passive': True,
                    'network': str(subnet.network),
                    'wildcard':      str(subnet.hostmask),
                    })

        return igp_interfaces
示例#4
0
    def configure_interfaces(self, device):
        LOG.debug("Configuring interfaces for %s" % self.network.fqdn(device))
        """Interface configuration"""
        lo_ip = self.network.lo_ip(device)
        interfaces = []
	static_routes = []
        interfaces.append({
            'id':          'lo0',
            'ip':           str(lo_ip.ip),
            'netmask':      str(lo_ip.netmask),
            'prefixlen':    str(lo_ip.prefixlen),
            'net_ent_title': ank.ip_to_net_ent_title(lo_ip.ip),
            'description': 'Loopback',
        })

        for src, dst, data in self.network.graph.edges(device, data=True):
	    neighbor = ank.fqdn(self.network, dst)
            subnet = data['sn']
            int_id = self.int_id(data['id'])
            description = 'Interface %s -> %s' % (
                    ank.fqdn(self.network, src), 
                    ank.fqdn(self.network, dst))

# Interface information for router config
            interfaces.append({
                'id':          int_id,
                'ip':           str(data['ip']),
                'prefixlen':    str(subnet.prefixlen),
		'netmask':	str(subnet.netmask),
                'broadcast':    str(subnet.broadcast),
                'description':  description,
            })
#static routes for the dummy nodes
	    for virtual in sorted(self.network.virtual_nodes(), key = lambda x: x.fqdn):
		virtual_hostname = virtual.hostname
		if neighbor == virtual_hostname:
		    subnet = data['sn']
		    static_routes.append({
		        'network':	str(subnet.network),
			'prefixlen':	str(subnet.prefixlen),
			'ip':		str(data['ip']),
		    })

        return interfaces,static_routes
示例#5
0
    def configure_interfaces(self, device):
        LOG.debug("Configuring interfaces for %s" % self.network.fqdn(device))
        """Interface configuration"""
        lo_ip = self.network.lo_ip(device)
        interfaces = []

        interfaces.append({
            'id':          'lo0',
            'ip':           lo_ip.ip,
            'netmask':      lo_ip.netmask,
            'wildcard':      lo_ip.hostmask,
            'prefixlen':    lo_ip.prefixlen,
            'network':       lo_ip.network,
            'description': 'Loopback',
        })

        for src, dst, data in self.network.graph.edges(device, data=True):
            subnet = data['sn']
            int_id = self.interface_id(data['id'])
            description = 'Interface %s -> %s' % (
                    ank.fqdn(self.network, src), 
                    ank.fqdn(self.network, dst))

# Interface information for router config
            interfaces.append({
                'id':          int_id,
                'ip':           data['ip'],
                'network':       subnet.network,
                'prefixlen':    subnet.prefixlen,
                'netmask':    subnet.netmask,
                'wildcard':      subnet.hostmask,
                'broadcast':    subnet.broadcast,
                'description':  description,
                'weight':   data.get('weight', self.default_weight),
            })

        return interfaces
示例#6
0
    def configure_bgp(self, router, physical_graph, ibgp_graph, ebgp_graph):
        LOG.debug("Configuring BGP for %s" % self.network.fqdn(router))
        """ BGP configuration"""
#TODO: Don't configure iBGP or eBGP if no eBGP edges
# need to pass correct blank dicts to templates then...

#TODO: put comments in for junos bgp peerings
        # route maps
        bgp_groups = {}
        route_maps = []
        if router in ibgp_graph:
            internal_peers = []
            for peer in ibgp_graph.neighbors(router):
                if not peer.is_router:
#no iBGP peering to non-routers
                    continue
                route_maps_in = [route_map for route_map in 
                        self.network.g_session[peer][router]['ingress']]
                route_maps_out = [route_map for route_map in 
                        self.network.g_session[router][peer]['egress']]
                route_maps += route_maps_in
                route_maps += route_maps_out   
                internal_peers.append({
                    'id': self.network.lo_ip(peer).ip,
                    'route_maps_in': [r.name for r in route_maps_in],
                    'route_maps_out': [r.name for r in route_maps_out],
                    })
            bgp_groups['internal_peers'] = {
                    'type': 'internal',
                    'neighbors': internal_peers
                    }

        ibgp_neighbor_list = []
        ibgp_rr_client_list = []
        if router in ibgp_graph:
            for src, neigh, data in ibgp_graph.edges(router, data=True):
                route_maps_in = [route_map for route_map in 
                        self.network.g_session[neigh][router]['ingress']]
                route_maps_out = [route_map for route_map in 
                        self.network.g_session[router][neigh]['egress']]
                route_maps += route_maps_in
                route_maps += route_maps_out     
                description = data.get("rr_dir") + " to " + ank.fqdn(self.network, neigh)
                if data.get('rr_dir') == 'down':
                    ibgp_rr_client_list.append(
                            {
                                'id':  self.network.lo_ip(neigh).ip,
                                'description':      description,
                                'route_maps_in': [r.name for r in route_maps_in],
                                'route_maps_out': [r.name for r in route_maps_out],
                                })
                elif (data.get('rr_dir') in set(['up', 'over', 'peer'])
                        or data.get('rr_dir') is None):
                    ibgp_neighbor_list.append(
                            {
                                'id':  self.network.lo_ip(neigh).ip,
                                'description':      description,
                                'route_maps_in': [r.name for r in route_maps_in],
                                'route_maps_out': [r.name for r in route_maps_out],
                                })

        bgp_groups['internal_peers'] = {
            'type': 'internal',
            'neighbors': ibgp_neighbor_list
            }
        if len(ibgp_rr_client_list):
            bgp_groups['internal_rr'] = {
                    'type': 'internal',
                    'neighbors': ibgp_rr_client_list,
                    'cluster': self.network.lo_ip(router).ip,
                    }

        if router in ebgp_graph:
            external_peers = []
            for peer in ebgp_graph.neighbors(router):
                if not peer.is_router:
#no eBGP peering to non-routers
                    continue
                route_maps_in = [route_map for route_map in 
                        self.network.g_session[peer][router]['ingress']]
                route_maps_out = [route_map for route_map in 
                        self.network.g_session[router][peer]['egress']]
                route_maps += route_maps_in
                route_maps += route_maps_out   
                peer_ip = physical_graph[peer][router]['ip']
                external_peers.append({
                    'id': peer_ip, 
                    'route_maps_in': [r.name for r in route_maps_in],
                    'route_maps_out': [r.name for r in route_maps_out],
                    'peer_as': self.network.asn(peer)})
            bgp_groups['external_peers'] = {
                    'type': 'external', 
                    'neighbors': external_peers}

# Ensure only one copy of each route map, can't use set due to list inside tuples (which won't hash)
# Use dict indexed by name, and then extract the dict items, dict hashing ensures only one route map per name
        route_maps = dict( (route_map.name, route_map) for route_map in route_maps).values()

        community_lists = {}
        prefix_lists = {}
        node_bgp_data = self.network.g_session.node.get(router)
        if node_bgp_data:
            community_lists = node_bgp_data.get('tags')
            prefix_lists = node_bgp_data.get('prefixes')
        policy_options = {
                'community_lists': community_lists,
                'prefix_lists': prefix_lists,
                'route_maps': route_maps,
                }

        return (bgp_groups, policy_options)
示例#7
0
    def configure_junosphere(self):
        """Configure Junosphere topology structure"""
        LOG.debug("Configuring Junosphere") 
        vmm_template = lookup.get_template("junos/topology_vmm.mako")
        topology_data = {}
        # Generator for private0, private1, etc
        collision_to_bridge_mapping = {}
        private_bridges = []
        junosphere_predefined_bridge_count = 124 # have to explicitly create bridges past 124

        image_tuple = namedtuple('image', "alias, basedisk")

        if self.junosphere_olive:
            image = image_tuple("MY_DISK", config.settings['Junosphere']['basedisk'])
        else:
            image = image_tuple("VJX1000_LATEST", None)


        bridge_id_generator = (i for i in itertools.count(0))
        def next_bridge_id():
            bridge_id = bridge_id_generator.next()
            retval = "private%s" % bridge_id
            if bridge_id > junosphere_predefined_bridge_count:
                private_bridges.append(retval)
            return retval

        for device in sorted(self.network.devices(), key = lambda x: x.fqdn):
            hostname = device.hostname
            topology_data[hostname] = {
                    'image': image.alias,
                    'config': router_conf_file(self.network, device),
                    'interfaces': [],
                    }
            for src, dst, data in sorted(self.network.graph.edges(device, data=True), key = lambda (s,t,d): t.fqdn):
                subnet = data['sn']
                description = 'Interface %s -> %s' % (
                        ank.fqdn(self.network, src), 
                        ank.fqdn(self.network, dst))
# Bridge information for topology config
                if subnet in collision_to_bridge_mapping:
# Use bridge allocated for this subnet
                    bridge_id = collision_to_bridge_mapping[subnet]
                else:
# Allocate a bridge for this subnet
                    bridge_id = next_bridge_id()
                    collision_to_bridge_mapping[subnet] = bridge_id

                if not self.junosphere_olive:
                    description += "(%s)" % self.int_id(data['id']) 

                topology_data[hostname]['interfaces'].append({
                    'description': description,
                    'id': self.int_id_em(data['id']),
                    'id_ge':  self.int_id(data['id']),
                    'bridge_id': bridge_id,
                    })

            if self.junosphere_olive:
# em2 is dead on Olive Junosphere platform
                topology_data[hostname]['interfaces'].append({
                    'description': "dead interface",
                    'id': "em2",
                    'bridge_id': "dead",
                    })
            
        vmm_file = os.path.join(lab_dir(), "topology.vmm")
        with open( vmm_file, 'wb') as f_vmm:
            f_vmm.write( vmm_template.render(
                topology_data = topology_data,
                private_bridges = private_bridges,
                image = image,
                olive_based = self.junosphere_olive,
                ))
示例#8
0
    def configure_bgp(self):
        """Generates BGP specific configuration files"""

        ip_as_allocs = ank.get_ip_as_allocs(self.network)

        LOG.debug("Configuring BGP")
        template = lookup.get_template("quagga/bgp.mako")

        route_maps = {}

        ibgp_graph = ank.get_ibgp_graph(self.network)
        ebgp_graph = ank.get_ebgp_graph(self.network)
        physical_graph = self.network.graph

        for my_as in ank.get_as_graphs(self.network):
            asn = my_as.asn
            LOG.debug("Configuring IGP for AS %s " % asn)
            # get nodes ie intersection
            #H = nx.intersection(my_as, ibgp_graph)
            # get ibgp graph that contains only nodes from this AS

            for router in self.network.routers(asn):
                bgp_groups = {}
                route_maps = []
                ibgp_neighbor_list = []
                ibgp_rr_client_list = []
                route_map_groups = {}

                if router in ibgp_graph:
                        for src, neigh, data in ibgp_graph.edges(router, data=True):
                            route_maps_in = self.network.g_session[neigh][router]['ingress']
                            rm_group_name_in = None
                            if len(route_maps_in):
                                rm_group_name_in = "rm_%s_in" % neigh.folder_name
                                route_map_groups[rm_group_name_in] = [match_tuple 
                                        for route_map in route_maps_in
                                        for match_tuple in route_map.match_tuples]

                            route_maps_out = self.network.g_session[router][neigh]['egress']
                            rm_group_name_out = None
                            if len(route_maps_out):
                                rm_group_name_in = "rm_%s_out" % neigh.folder_name
                                route_map_groups[rm_group_name_out] = [match_tuple 
                                        for route_map in route_maps_out
                                        for match_tuple in route_map.match_tuples]

                            description = data.get("rr_dir") + " to " + ank.fqdn(self.network, neigh)
                            if data.get('rr_dir') == 'down':
                                ibgp_rr_client_list.append(
                                        {
                                            'id':  self.network.lo_ip(neigh).ip,
                                            'description':      description,
                                            'route_maps_in': rm_group_name_in,
                                            'route_maps_out': rm_group_name_out,
                                            })
                            elif (data.get('rr_dir') in set(['up', 'over', 'peer'])
                                    or data.get('rr_dir') is None):
                                ibgp_neighbor_list.append(
                                        {
                                            'id':  self.network.lo_ip(neigh).ip,
                                            'description':      description,
                                            'route_maps_in': rm_group_name_in,
                                            'route_maps_out': rm_group_name_out,
                                            })

                        bgp_groups['internal_peers'] = {
                            'type': 'internal',
                            'neighbors': ibgp_neighbor_list
                            }
                        if len(ibgp_rr_client_list):
                            bgp_groups['internal_rr'] = {
                                    'type': 'internal',
                                    'neighbors': ibgp_rr_client_list,
                                    'cluster': self.network.lo_ip(router).ip,
                                    }

                if router in ebgp_graph:
                    external_peers = []
                    for peer in ebgp_graph.neighbors(router):
                        route_maps_in = self.network.g_session[peer][router]['ingress']
                        rm_group_name_in = None
                        if len(route_maps_in):
                            rm_group_name_in = "rm_%s_in" % peer.folder_name
                            route_map_groups[rm_group_name_in] = [match_tuple 
                                    for route_map in route_maps_in
                                    for match_tuple in route_map.match_tuples]

# Now need to update the sequence numbers for the flattened route maps

                        route_maps_out = self.network.g_session[router][peer]['egress']
                        rm_group_name_out = None
                        if len(route_maps_out):
                            rm_group_name_out = "rm_%s_out" % peer.folder_name
                            route_map_groups[rm_group_name_out] = [match_tuple 
                                    for route_map in route_maps_out
                                    for match_tuple in route_map.match_tuples]

                        peer_ip = physical_graph[peer][router]['ip'] 

                        external_peers.append({
                            'id': peer_ip, 
                            'route_maps_in': rm_group_name_in,
                            'route_maps_out': rm_group_name_out,
                            'peer_as': self.network.asn(peer)})
                    bgp_groups['external_peers'] = {
                            'type': 'external', 
                            'neighbors': external_peers}

# Ensure only one copy of each route map, can't use set due to list inside tuples (which won't hash)
# Use dict indexed by name, and then extract the dict items, dict hashing ensures only one route map per name
                community_lists = {}
                prefix_lists = {}
                node_bgp_data = self.network.g_session.node.get(router)
                if node_bgp_data:
                    community_lists = node_bgp_data.get('tags')
                    prefix_lists = node_bgp_data.get('prefixes')
                policy_options = {
                'community_lists': community_lists,
                'prefix_lists': prefix_lists,
                'route_maps': route_map_groups,
                }
            
                f_handle = open(os.path.join(zebra_dir(self.network, router),
                                                "bgpd.conf"),'wb')

                #TODO: remove community_lists and prefix_lists as they are put into policy_options
                f_handle.write(template.render(
                        hostname = router.device_hostname,
                        asn = self.network.asn(router),
                        password = self.zebra_password,
                        enable_password = self.zebra_password,
                        router_id = self.network.lo_ip(router).ip,
                        community_lists = community_lists,
                        policy_options = policy_options,
                        prefix_lists = prefix_lists,
                        #TODO: see how this differs to router_id
                        identifying_loopback = self.network.lo_ip(router),
                        bgp_groups = bgp_groups,
                        ibgp_neighbor_list = ibgp_neighbor_list,
                        ibgp_rr_client_list = ibgp_rr_client_list,
                        route_maps = route_maps,
                        logfile = "/var/log/zebra/bgpd.log",
                        debug=True,
                        use_debug=True,
                        dump=False,
                        snmp=False,
                        interfaces = self.configure_interfaces(router)
                ))
示例#9
0
    def collect_data(self, commands):
        shell = self.server.get_shell()
        shell.setecho(False)

        collected_data_dir = config.collected_data_dir
        netkit_data_dir = os.path.join(collected_data_dir, "netkit")
        if not os.path.isdir(netkit_data_dir):
                os.mkdir(netkit_data_dir)
        host_data_dir = os.path.join(netkit_data_dir, self.host_alias)
        if not os.path.isdir(host_data_dir):
                os.mkdir(host_data_dir)
        collect_timestamp_dir = os.path.join(host_data_dir, time.strftime("%Y%m%d_%H%M%S", time.localtime()))
        if not os.path.isdir(collect_timestamp_dir):
            os.mkdir(collect_timestamp_dir)

        servers = set(self.network.servers())

        #TODO: need to have way to allow privexec.... or just disable enable password?
#TODO: Put term len 0 into configs

        for node in self.network.devices():
            routername = ank.fqdn(self.network, node)
            full_routername = ank.rtr_folder_name(self.network, node)
            user_exec_prompt = "%s>" % node.dns_hostname
            priv_exec_prompt = "%s#" % node.dns_hostname
            for port_command in commands:
                LOG.info("%s: running %s" % (routername, port_command))
                telnet_port, command = port_command.split(":")
                if telnet_port == 'ssh':
                    self.server.connect_vm(node.tap_ip, shell)
                    shell.sendline(command)
                    shell.expect(self.server.NETKIT_PROMPT)
                    command_output = shell.before
                    self.server.disconnect_vm(shell)
                    shell.prompt()
# need to ssh into this machine
                else:
                    if node in servers:
# don't try telnet into as zebra not running
                        continue
# use telnet
                    shell.sendline("telnet %s %s" % (node.tap_ip, telnet_port))
                    shell.expect("Password:"******"1234")
                    shell.expect(user_exec_prompt)
                    shell.sendline("en")
                    i = shell.expect(["Password:"******"1234")
                    else:
# all good, in priv exec
                        pass
# just to be sure
                    set_term_length = "term len 0"
                    shell.sendline(set_term_length)
                    shell.expect(priv_exec_prompt)
                    shell.sendline(command)
                    shell.expect(priv_exec_prompt)
# Can be an issue with the telnet x zebra command (not for bgpd it seems)
                    command_output = shell.before
# If no command output, captured the previous command, try again
                    if command_output.strip() == set_term_length:
                        shell.expect(priv_exec_prompt)
                        command_output = shell.before
                    shell.sendline("exit")
                    shell.prompt() 
# from http://stackoverflow.com/q/295135/
                command_filename_format = (re.sub('[^\w\s-]', '', command).strip().lower())
                filename = "%s_%s_%s.txt" % (full_routername,
                        command_filename_format,
                        time.strftime("%Y%m%d_%H%M%S", time.localtime()))
                filename = os.path.join(collect_timestamp_dir, filename)
                
                with open( filename, 'w') as f_out:
                    f_out.write(command_output)
示例#10
0
 def fqdn(self, node):
     """Shortcut to fqdn"""
     return ank.fqdn(self, node)
示例#11
0
    def configure_dynagen(self):  
        """Generates dynagen specific configuration files."""
        LOG.info("Configuring Dynagen")

        # Location of IOS binary

        # Set up routers
        lab_template = lookup.get_template("dynagen/topology.mako")

        # Counter starting at 2000, eg 2000, 2001, 2002, etc
        console_ports = itertools.count(2000)

        #NOTE this must be a full path!
        server_config_dir = os.path.join(config.settings['Dynagen']['working dir'], lab_dir())
        working_dir ="/tmp"

        #TODO: need nice way to map ANK graph into feasible hardware graph

#TODO: see what chassis is used for
        chassis = config.settings['Dynagen']['model']
        model = config.settings['Dynagen']['model']
        slots = config.settings['Dynagen']['Slots']
        options = config.settings['Dynagen']['Options']

        # ugly alias
#TODO: remove this
        graph = self.network.graph

        all_router_info = {}

        #TODO: make this use dynagen tagged nodes
        for router in sorted(self.network.routers()):
            router_info = {}

            data = graph.node[router]
            router_info['hostname'] = router.fqdn

            rtr_console_port = console_ports.next()
            router_info['console'] =  rtr_console_port
            self.network.graph.node[router]['dynagen_console_port'] = rtr_console_port
            #TODO: tidy this up - want relative reference to config dir
            rtr_conf_file = os.path.join("configs", "%s.conf" % router.folder_name)
            #router_info['cnfg'] = rtr_conf_file
            # Absolute configs for remote dynagen deployment
#TODO: make this dependent on remote host - if localhost then don't use
# and if do use, then 
            rtr_conf_file_with_path = os.path.join(server_config_dir, rtr_conf_file)
            #router_info['cnfg'] = os.path.abspath(rtr_conf_file_with_path)
            router_info['cnfg'] = rtr_conf_file_with_path

            # Max of 3 connections out
            # todo: check symmetric
            router_links = []
            router_info['slot1'] = "NM-4E"
            for src, dst, data in sorted(graph.edges(router, data=True)):
                if dst.is_router:
                    # Src is node, dst is router connected to. Link data in data
                    local_id = data['id']
                    remote_id = graph.edge[dst][src]['id']
                    local_cisco_id = self.dynagen_interface_name(self.int_id(local_id))
                    remote_cisco_id = self.dynagen_interface_name(self.int_id(remote_id))
                    remote_hostname = ank.fqdn(self.network, dst)
                    router_links.append( (local_cisco_id, remote_cisco_id,
                                            remote_hostname))

            # Store links
            router_info['links'] = router_links

            # and store info
            all_router_info[router] = router_info

        #pprint.pprint(all_router_info)
        lab_file = os.path.join(lab_dir(), "lab.net")
        with open( lab_file, 'wb') as f_lab:
            f_lab.write( lab_template.render(
                image = self.image,
                hypervisor_port = self.hypervisor_port,
                hypervisor_server = self.hypervisor_server,
                all_router_info = all_router_info,   
                working_dir = working_dir,
                chassis = chassis,
                model = model,
                slots = slots,
                options = options,
                ))

        return
示例#12
0
    def configure_bgp(self, router, physical_graph, ibgp_graph, ebgp_graph):
        LOG.debug("Configuring BGP for %s" % self.network.fqdn(router))
        """ BGP configuration"""
#TODO: Don't configure iBGP or eBGP if no eBGP edges
# need to pass correct blank dicts to templates then...

#TODO: put comments in for IOS bgp peerings
        # route maps
        bgp_groups = {}
        route_maps = []
        ibgp_neighbor_list = []
        ibgp_rr_client_list = []
        route_map_groups = {}

        if router in ibgp_graph:
            for src, neigh, data in ibgp_graph.edges(router, data=True):
                route_maps_in = self.network.g_session[neigh][router]['ingress']
                rm_group_name_in = None
                if len(route_maps_in):
                    rm_group_name_in = "rm_%s_in" % neigh.folder_name
                    route_map_groups[rm_group_name_in] = [match_tuple 
                            for route_map in route_maps_in
                            for match_tuple in route_map.match_tuples]

                route_maps_out = self.network.g_session[router][neigh]['egress']
                rm_group_name_out = None
                if len(route_maps_out):
                    rm_group_name_in = "rm_%s_out" % neigh.folder_name
                    route_map_groups[rm_group_name_out] = [match_tuple 
                            for route_map in route_maps_out
                            for match_tuple in route_map.match_tuples]

                description = data.get("rr_dir") + " to " + ank.fqdn(self.network, neigh)
                if data.get('rr_dir') == 'down':
                    ibgp_rr_client_list.append(
                            {
                                'id':  self.network.lo_ip(neigh).ip,
                                'description':      description,
                                'route_maps_in': rm_group_name_in,
                                'route_maps_out': rm_group_name_out,
                                })
                elif (data.get('rr_dir') in set(['up', 'over', 'peer'])
                        or data.get('rr_dir') is None):
                    ibgp_neighbor_list.append(
                            {
                                'id':  self.network.lo_ip(neigh).ip,
                                'description':      description,
                                'route_maps_in': rm_group_name_in,
                                'route_maps_out': rm_group_name_out,
                                })

        bgp_groups['internal_peers'] = {
            'type': 'internal',
            'neighbors': ibgp_neighbor_list
            }
        if len(ibgp_rr_client_list):
            bgp_groups['internal_rr'] = {
                    'type': 'internal',
                    'neighbors': ibgp_rr_client_list,
                    'cluster': self.network.lo_ip(router).ip,
                    }

        if router in ebgp_graph:
            external_peers = []
            for peer in ebgp_graph.neighbors(router):
                route_maps_in = self.network.g_session[peer][router]['ingress']
                rm_group_name_in = None
                if len(route_maps_in):
                    rm_group_name_in = "rm_%s_in" % peer.folder_name
                    route_map_groups[rm_group_name_in] = [match_tuple 
                            for route_map in route_maps_in
                            for match_tuple in route_map.match_tuples]

# Now need to update the sequence numbers for the flattened route maps

                route_maps_out = self.network.g_session[router][peer]['egress']
                rm_group_name_out = None
                if len(route_maps_out):
                    rm_group_name_out = "rm_%s_out" % peer.folder_name
                    route_map_groups[rm_group_name_out] = [match_tuple 
                            for route_map in route_maps_out
                            for match_tuple in route_map.match_tuples]

                peer_ip = physical_graph[peer][router]['ip'] 

                external_peers.append({
                    'id': peer_ip, 
                    'route_maps_in': rm_group_name_in,
                    'route_maps_out': rm_group_name_out,
                    'peer_as': self.network.asn(peer)})
            bgp_groups['external_peers'] = {
                    'type': 'external', 
                    'neighbors': external_peers}

# Ensure only one copy of each route map, can't use set due to list inside tuples (which won't hash)
# Use dict indexed by name, and then extract the dict items, dict hashing ensures only one route map per name
        community_lists = {}
        prefix_lists = {}
        node_bgp_data = self.network.g_session.node.get(router)
        if node_bgp_data:
            community_lists = node_bgp_data.get('tags')
            prefix_lists = node_bgp_data.get('prefixes')
        policy_options = {
                'community_lists': community_lists,
                'prefix_lists': prefix_lists,
                'route_maps': route_map_groups,
                }

        return (bgp_groups, policy_options)
示例#13
0
文件: jsplot.py 项目: coaj/autonetkit
def jsplot(network):
    """ Plot the network """
    plot_dir = config.plot_dir
    if not os.path.isdir(plot_dir):
        os.mkdir(plot_dir)
    jsplot_dir = os.path.join(plot_dir, "jsplot")
    if not os.path.isdir(jsplot_dir):
        os.mkdir(jsplot_dir)

    js_template = lookup.get_template("arborjs/main_js.mako")
    css_template = lookup.get_template("arborjs/style_css.mako")
    html_template = lookup.get_template("arborjs/index_html.mako")
    ank_css_template = lookup.get_template("autonetkit/style_css.mako")
#TODO: tidy these up with the embedded network in node name

    node_list = ( (node.fqdn, {'label': network.fqdn(node)}) for node in network.graph.nodes())
    edge_list = list( (src.fqdn, dst.fqdn, {}) 
            for (src, dst, data) in network.graph.edges(data=True))


    js_files = []
    timestamp = time.strftime("%Y/%m/%d %H:%M:%S", time.localtime())

    js_filename = os.path.join(jsplot_dir, "main.js")
    js_files.append("main.js")
    with open( js_filename, 'w') as f_js:
            f_js.write( js_template.render(
                node_list = node_list,
                edge_list = edge_list,
                physical_graph = True,
                ))

    js_filename = os.path.join(jsplot_dir, "ip.js")
    js_files.append("ip.js")
    node_list = []
    for node in network.graph.nodes():
# Set label to be FQDN, so don't have multiple "Router A" nodes etc
        data = { 'label': "%s %s" % (ank.fqdn(network, node), network.lo_ip(node).ip)}
        node_list.append( (node.fqdn, data))
    edge_list = list( (src.fqdn, dst.fqdn, data['sn']) 
            for (src, dst, data) in network.graph.edges(data=True))
    with open( js_filename, 'w') as f_js:
            f_js.write( js_template.render(
                node_list = node_list,
                edge_list = edge_list,
                physical_graph = True,
                ))

    js_filename = os.path.join(jsplot_dir, "igp.js")
    js_files.append("igp.js")
    node_list = []
    for node in network.graph.nodes():
        if not node.igp_link_count:
# no IGP links, don't add to plot
            continue
# Set label to be FQDN, so don't have multiple "Router A" nodes etc
        data = { 'label': "%s" % node.fqdn}
        node_list.append( (node.fqdn, data))
    edge_list = list( (src.fqdn, dst.fqdn, data.get('weight')) 
            for (src, dst, data) in network.graph.edges(data=True)
            if src.asn == dst.asn)
    with open( js_filename, 'w') as f_js:
            f_js.write( js_template.render(
                node_list = node_list,
                edge_list = edge_list,
                physical_graph = True,
                ))
    
    #TODO: work out how to do multiple on one page
    ebgp_graph = ank.get_ebgp_graph(network)
    labels = dict( (n, network.label(n)) for n in ebgp_graph)
    nx.relabel_nodes(ebgp_graph, labels, copy=False)
    ebgp_filename = os.path.join(jsplot_dir, "ebgp.js")
    js_files.append("ebgp.js")
    with open( ebgp_filename, 'w') as f_js:
            f_js.write( js_template.render(
                node_list = ebgp_graph.nodes(data=True),
                edge_list = ebgp_graph.edges(data=True),
                overlay_graph = True,
                ))

    ibgp_graph = ank.get_ibgp_graph(network)
    node_list = []
    for node in ibgp_graph.nodes():
# Set label to be FQDN, so don't have multiple "Router A" nodes etc
        data = { 'label': "%s (%s)" % (node.fqdn, network.graph.node[node].get("ibgp_level"))}
        node_list.append( (node.fqdn, data))
    edge_list = ibgp_graph.edges(data=True)
    edge_list = list( (src.fqdn, dst.fqdn, data.get("rr_dir")) for (src, dst, data) in edge_list)

    ibgp_filename = os.path.join(jsplot_dir, "ibgp.js")
    js_files.append("ibgp.js")
    with open( ibgp_filename, 'w') as f_js:
            f_js.write( js_template.render(
                node_list = node_list,
                edge_list = edge_list,
                physical_graph = True,
                ))

    #TODO: clarify difference of physical_graph and overlay_graph

#TODO: see if js_files ever used

    dns_graph = ank.get_dns_graph(network)
    node_list = []
    for node in dns_graph.nodes():
# Set label to be FQDN, so don't have multiple "Router A" nodes etc
        data = { 'label': "%s (%s)" % (node.fqdn, dns_graph.node[node].get("level"))}
        node_list.append( (node.fqdn, data))
    dns_filename = os.path.join(jsplot_dir, "dns.js")
    edge_list = dns_graph.edges(data=True)
    #edge_list = list( (src.fqdn, dst.fqdn, data.get('dns_dir')) for (src, dst, data) in edge_list)
    edge_list = list( (src.fqdn, dst.fqdn, '') for (src, dst, data) in edge_list)
    js_files.append("dns.js")
    with open( dns_filename, 'w') as f_js:
            f_js.write( js_template.render(
                node_list = node_list,
                edge_list = edge_list,
                physical_graph = True,
                ))


    dns_auth_graph = ank.get_dns_auth_graph(network)
    node_list = []
    for node in dns_auth_graph.nodes():
# Set label to be FQDN, so don't have multiple "Router A" nodes etc
        data = { 'label': "%s" % node.label}
        node_list.append( (node.fqdn, data))
    dns_filename = os.path.join(jsplot_dir, "dns_auth.js")
    edge_list = dns_auth_graph.edges(data=True)
    edge_list = list( (src.fqdn, dst.fqdn, data) for (src, dst, data) in edge_list)
    js_files.append("dns_auth.js")
    with open( dns_filename, 'w') as f_js:
            f_js.write( js_template.render(
                node_list = node_list,
                edge_list = edge_list,
                physical_graph = True,
                ))

    #TODO: add timestamps to plots
    # put html file in main plot directory
#TODO: parameterised/variable the css location
    plot_width = config.settings['Plotting']['jsplot width']
    plot_height = config.settings['Plotting']['jsplot height']
    html_filename = os.path.join(plot_dir, "plot.html")
    with open( html_filename, 'w') as f_html:
            f_html.write( html_template.render( js_file = "main.js",
                timestamp=timestamp,
                plot_width = plot_width,
                plot_height = plot_height,
                title = "Physical Network",
                css_filename = "./ank_style.css",))

    html_filename = os.path.join(plot_dir, "ip.html")
    with open( html_filename, 'w') as f_html:
            f_html.write( html_template.render( js_file = "ip.js",
                timestamp=timestamp,
                plot_width = plot_width,
                plot_height = plot_height,
                title = "IP",
                css_filename = "./ank_style.css",))

    html_filename = os.path.join(plot_dir, "igp.html")
    with open( html_filename, 'w') as f_html:
            f_html.write( html_template.render( js_file = "igp.js",
                timestamp=timestamp,
                plot_width = plot_width,
                plot_height = plot_height,
                title = "IGP",
                css_filename = "./ank_style.css",))

    html_filename = os.path.join(plot_dir, "ibgp.html")
    with open( html_filename, 'w') as f_html:
            f_html.write( html_template.render( js_file = "ibgp.js",
                timestamp=timestamp,
                plot_width = plot_width,
                plot_height = plot_height,
                title = "iBGP",
                css_filename = "./ank_style.css",))

    html_filename = os.path.join(plot_dir, "ebgp.html")
    with open( html_filename, 'w') as f_html:
            f_html.write( html_template.render( js_file = "ebgp.js",
                timestamp=timestamp,
                plot_width = plot_width,
                plot_height = plot_height,
                title = "eBGP",
                css_filename = "./ank_style.css",))

    html_filename = os.path.join(plot_dir, "dns.html")
    with open( html_filename, 'w') as f_html:
            f_html.write( html_template.render( js_file = "dns.js",
                timestamp=timestamp,
                plot_width = plot_width,
                plot_height = plot_height,
                title = "DNS Hierarchy",
                css_filename = "./ank_style.css",))

    html_filename = os.path.join(plot_dir, "dns_auth.html")
    with open( html_filename, 'w') as f_html:
            f_html.write( html_template.render( js_file = "dns_auth.js",
                timestamp=timestamp,
                plot_width = plot_width,
                plot_height = plot_height,
                title = "DNS Authority",
                css_filename = "./ank_style.css",))

    css_filename = os.path.join(jsplot_dir, "style.css")
    with open( css_filename, 'w') as f_css:
            f_css.write( css_template.render())

    # and ank css_template
    css_filename = os.path.join(plot_dir, "ank_style.css")
    with open( css_filename, 'w') as f_css:
            f_css.write( ank_css_template.render())

    arbor_js_src_filename = os.path.join(template_dir, "arborjs", "arbor.js")
    arbor_js_dst_filename = os.path.join(jsplot_dir, "arbor.js")
    shutil.copy(arbor_js_src_filename, arbor_js_dst_filename)
示例#14
0
def summarydoc(network):
    """ Plot the network """
    ank_main_dir = config.ank_main_dir

    html_template = lookup.get_template("autonetkit/summary_html.mako")
    ank_css_template = lookup.get_template("autonetkit/style_css.mako")
    
    ebgp_graph = ank.get_ebgp_graph(network)
    ibgp_graph = ank.get_ibgp_graph(network)

# Network wide stats
    network_stats = {}
    network_stats['device_count'] = len(list(network.devices()))
    network_stats['router_count'] = len(list(network.routers()))
    network_stats['server_count'] = len(list(network.servers()))
    network_stats['edge_count'] = network.graph.number_of_edges()
    as_graphs = ank.get_as_graphs(network)
    network_stats['as_count'] = len(as_graphs)

    as_stats = {}

    for my_as in as_graphs:
        #print single_as.nodes(data=True)
# Get ASN of first node
        asn = my_as.asn
        #print asn
        node_list = {}
        loopbacks = []
        virtual_nodes = {}
        for router in network.routers(asn):
            node_label = network.fqdn(router)
            loopbacks.append( (node_label, network.lo_ip(router).ip))
            node_list[node_label] = {}
            interface_list = []
            ibgp_list = []
            ebgp_list = []
            for _, dst, data in network.graph.edges(router, data=True):
                interface_list.append( (ank.fqdn(network, dst), data['sn']))
            node_list[node_label]['interface_list'] = interface_list
            for _, dst, data in ebgp_graph.edges(router, data=True):
                ebgp_list.append( (ank.fqdn(network, dst), network.lo_ip(dst).ip))
            node_list[node_label]['ebgp_list'] = ebgp_list
            for _, dst, data in ibgp_graph.edges(router, data=True):
                ibgp_list.append( (ank.fqdn(network, dst), network.lo_ip(dst).ip))
            node_list[node_label]['ibgp_list'] = ibgp_list

        for virtual_node in network.virtual_nodes(asn):
            links = []
            for link in network.links(virtual_node):
                links.append( (link.local_ip, link.remote_ip, link.dst))
            virtual_nodes[virtual_node] = {
                'links': links,
                }

        as_stats[my_as.name] = {
                'asn': asn,
                'loopbacks': loopbacks,
                'node_list': node_list,
                'virtual_nodes': virtual_nodes,
                }

    plot_dir = config.plot_dir
    if not os.path.isdir(plot_dir):
        os.mkdir(plot_dir)

    timestamp = time.strftime("%Y/%m/%d %H:%M:%S", time.localtime())
    
    css_filename = os.path.join(plot_dir, "ank_style.css")
    with open( css_filename, 'w') as f_css:
            f_css.write( ank_css_template.render())

    # put html file in main plot directory
    html_filename = os.path.join(plot_dir, "summary.html")
    #print html_filename
    with open( html_filename, 'w') as f_html:
            f_html.write( html_template.render(
                network_stats = network_stats,
                as_stats = as_stats,
                timestamp=timestamp,
                css_filename = "./ank_style.css",
                    )
                    )