def compile_devices(self): g_phy = self.anm['phy'] to_memory, use_mgmt_interfaces, dst_folder = self._parameters() if use_mgmt_interfaces: log.debug("Allocating VIRL management interfaces") else: log.debug("Not allocating VIRL management interfaces") # TODO: need to copy across the interface name from edge to the interface # TODO: merge common router code, so end up with three loops: routers, ios # routers, ios_xr routers # TODO: Split out each device compiler into own function # TODO: look for unused code paths here - especially for interface # allocation # store autonetkit_cisco version log.debug("Generating device configurations") from pkg_resources import get_distribution # Copy across indices for external connectors (e.g may want to copy # configs) external_connectors = [ n for n in g_phy if n.host == self.host and n.device_type == "external_connector" ] for phy_node in external_connectors: DmNode = self.nidb.node(phy_node) DmNode.indices = phy_node.indices managed_switches = [ n for n in g_phy.switches() if n.host == self.host and n.device_subtype == "managed" ] for phy_node in managed_switches: DmNode = self.nidb.node(phy_node) DmNode.indices = phy_node.indices for phy_node in g_phy.l3devices(host=self.host): loopback_ids = self.loopback_interface_ids() # allocate loopbacks to routes (same for all ios variants) DmNode = self.nidb.node(phy_node) DmNode.add_stanza("render") DmNode.indices = phy_node.indices for interface in DmNode.loopback_interfaces(): if interface != DmNode.loopback_zero: interface.id = loopback_ids.next() # numeric ids numeric_int_ids = self.numeric_interface_ids() for interface in DmNode.physical_interfaces(): phy_numeric_id = phy_node.interface(interface).numeric_id if phy_numeric_id is None: # TODO: remove numeric ID code interface.numeric_id = numeric_int_ids.next() else: interface.numeric_id = int(phy_numeric_id) phy_specified_id = phy_node.interface(interface).specified_id if phy_specified_id is not None: interface.id = phy_specified_id #from autonetkit.compilers.device.ubuntu import UbuntuCompiler from autonetkit_cisco.compilers.device.ubuntu import UbuntuCompiler ubuntu_compiler = UbuntuCompiler(self.nidb, self.anm) for phy_node in g_phy.servers(host=self.host): DmNode = self.nidb.node(phy_node) DmNode.add_stanza("render") DmNode.add_stanza("ip") # TODO: look at server syntax also, same as for routers for interface in DmNode.physical_interfaces(): phy_specified_id = phy_node.interface(interface).specified_id if phy_specified_id is not None: interface.id = phy_specified_id #interface.id = self.numeric_to_interface_label_linux(interface.numeric_id) # print "numeric", interface.numeric_id, interface.id DmNode.ip.use_ipv4 = phy_node.use_ipv4 DmNode.ip.use_ipv6 = phy_node.use_ipv6 # TODO: clean up interface handling numeric_int_ids = self.numeric_interface_ids() for interface in DmNode.physical_interfaces(): phy_int = phy_node.interface(interface) phy_numeric_id = phy_node.interface(interface).numeric_id if phy_numeric_id is None: # TODO: remove numeric ID code interface.numeric_id = numeric_int_ids.next() else: interface.numeric_id = int(phy_numeric_id) phy_specified_id = phy_node.interface(interface).specified_id if phy_specified_id is not None: interface.id = phy_specified_id # TODO: make this part of the base device compiler, which # server/router inherits # not these are physical interfaces; configure after previous # config steps if use_mgmt_interfaces: mgmt_int = DmNode.add_interface(management=True, description="eth0") mgmt_int_id = "eth0" mgmt_int.id = mgmt_int_id # render route config DmNode = self.nidb.node(phy_node) ubuntu_compiler.compile(DmNode) if not phy_node.dont_configure_static_routing: DmNode.render.template = os.path.join("templates", "linux", "static_route.mako") if to_memory: DmNode.render.to_memory = True else: DmNode.render.dst_folder = dst_folder DmNode.render.dst_file = "%s.conf" % naming.network_hostname( phy_node) # TODO: refactor out common logic ios_compiler = IosClassicCompiler(self.nidb, self.anm) host_routers = g_phy.routers(host=self.host) ios_nodes = (n for n in host_routers if n.syntax in ("ios", "ios_xe")) for phy_node in ios_nodes: DmNode = self.nidb.node(phy_node) DmNode.add_stanza("render") DmNode.render.template = os.path.join("templates", "ios.mako") if to_memory: DmNode.render.to_memory = True else: DmNode.render.dst_folder = dst_folder DmNode.render.dst_file = "%s.conf" % naming.network_hostname( phy_node) # TODO: write function that assigns interface number excluding # those already taken # Assign interfaces if phy_node.device_subtype == "IOSv": int_ids = self.interface_ids_ios() numeric_to_interface_label = self.numeric_to_interface_label_ios elif phy_node.device_subtype == "CSR1000v": int_ids = self.interface_ids_csr1000v() numeric_to_interface_label = self.numeric_to_interface_label_ra else: # default if no subtype specified # TODO: need to set default in the load module log.warning("Unexpected subtype %s for %s" % (phy_node.device_subtype, phy_node)) int_ids = self.interface_ids_ios() numeric_to_interface_label = self.numeric_to_interface_label_ios if use_mgmt_interfaces: if phy_node.device_subtype == "IOSv": # TODO: make these configured in the internal config file # for platform/device_subtype keying mgmt_int_id = "GigabitEthernet0/0" if phy_node.device_subtype == "CSR1000v": mgmt_int_id = "GigabitEthernet1" for interface in DmNode.physical_interfaces(): # TODO: use this code block once for all routers if not interface.id: interface.id = numeric_to_interface_label( interface.numeric_id) ios_compiler.compile(DmNode) if use_mgmt_interfaces: mgmt_int = DmNode.add_interface(management=True) mgmt_int.id = mgmt_int_id try: from autonetkit_cisco.compilers.device.cisco import IosXrCompiler ios_xr_compiler = IosXrCompiler(self.nidb, self.anm) except ImportError: ios_xr_compiler = IosXrCompiler(self.nidb, self.anm) for phy_node in g_phy.routers(host=self.host, syntax='ios_xr'): DmNode = self.nidb.node(phy_node) DmNode.add_stanza("render") DmNode.render.template = os.path.join("templates", "ios_xr", "router.conf.mako") if to_memory: DmNode.render.to_memory = True else: DmNode.render.dst_folder = dst_folder DmNode.render.dst_file = "%s.conf" % naming.network_hostname( phy_node) # Assign interfaces int_ids = self.interface_ids_ios_xr() for interface in DmNode.physical_interfaces(): if not interface.id: interface.id = self.numeric_to_interface_label_ios_xr( interface.numeric_id) ios_xr_compiler.compile(DmNode) if use_mgmt_interfaces: mgmt_int_id = "mgmteth0/0/CPU0/0" mgmt_int = DmNode.add_interface(management=True) mgmt_int.id = mgmt_int_id nxos_compiler = NxOsCompiler(self.nidb, self.anm) for phy_node in g_phy.routers(host=self.host, syntax='nx_os'): DmNode = self.nidb.node(phy_node) DmNode.add_stanza("render") DmNode.render.template = os.path.join("templates", "nx_os.mako") if to_memory: DmNode.render.to_memory = True else: DmNode.render.dst_folder = dst_folder DmNode.render.dst_file = "%s.conf" % naming.network_hostname( phy_node) # Assign interfaces int_ids = self.interface_ids_nxos() for interface in DmNode.physical_interfaces(): if not interface.id: interface.id = self.numeric_to_interface_label_nxos( interface.numeric_id) DmNode.supported_features = ConfigStanza(mpls_te=False, mpls_oam=False, vrf=False) nxos_compiler.compile(DmNode) # TODO: make this work other way around if use_mgmt_interfaces: mgmt_int_id = "mgmt0" mgmt_int = DmNode.add_interface(management=True) mgmt_int.id = mgmt_int_id staros_compiler = StarOsCompiler(self.nidb, self.anm) for phy_node in g_phy.routers(host=self.host, syntax='StarOS'): DmNode = self.nidb.node(phy_node) DmNode.add_stanza("render") DmNode.render.template = os.path.join("templates", "staros.mako") if to_memory: DmNode.render.to_memory = True else: DmNode.render.dst_folder = dst_folder DmNode.render.dst_file = "%s.conf" % naming.network_hostname( phy_node) # Assign interfaces int_ids = self.interface_ids_nxos() for interface in DmNode.physical_interfaces(): if not interface.id: interface.id = self.numeric_to_interface_label_star_os( interface.numeric_id) staros_compiler.compile(DmNode) # TODO: make this work other way around if use_mgmt_interfaces: mgmt_int_id = "ethernet 1/1" mgmt_int = DmNode.add_interface(management=True) mgmt_int.id = mgmt_int_id
def compile_devices(self): import re g_phy = self.anm['phy'] to_memory, use_mgmt_interfaces, dst_folder = self._parameters() if use_mgmt_interfaces: log.debug("Allocating VIRL management interfaces") else: log.debug("Not allocating VIRL management interfaces") pc_only_config = False vxlan_global_config = None if g_phy.data.vxlan_global_config is not None: vxlan_global_config = g_phy.data.vxlan_global_config if g_phy.data.pc_only is not None: pc_only_config = g_phy.data.pc_only use_ignite_pool = False if g_phy.data.mgmt_block is not None: mgmt_address_block = netaddr.IPNetwork(g_phy.data.mgmt_block).iter_hosts() mgmt_address_mask = (netaddr.IPNetwork(g_phy.data.mgmt_block)).netmask else: pool = g_phy.data.ignite if pool is not None: if 'mgmt_pool_id' in pool and pool['mgmt_pool_id'] is not None: mgmt_pool_id = pool['mgmt_pool_id'] use_ignite_pool = True if g_phy.data.vpcid_block is not None: vpc_re = "([0-9]+)(-)([0-9]+)" #vpc_id_start = int(re.search(vpc_re, g_phy.data.vpcid_block).group(1)) #vpc_id_end = int(re.search(vpc_re, g_phy.data.vpcid_block).group(3)) #vpc_id_range = vpc_id_end-vpc_id_start vpc_id_range = 1000 # TODO: need to copy across the interface name from edge to the interface # TODO: merge common router code, so end up with three loops: routers, ios # routers, ios_xr routers # TODO: Split out each device compiler into own function # TODO: look for unused code paths here - especially for interface # allocation # store autonetkit_cisco version log.debug("Generating device configurations") from pkg_resources import get_distribution # Copy across indices for external connectors (e.g may want to copy # configs) external_connectors = [n for n in g_phy if n.host == self.host and n.device_type == "external_connector"] for phy_node in external_connectors: DmNode = self.nidb.node(phy_node) DmNode.indices = phy_node.indices g_input = self.anm['input'] managed_switches = [n for n in g_phy.switches() if n.host == self.host and n.device_subtype == "managed"] for phy_node in managed_switches: DmNode = self.nidb.node(phy_node) DmNode.indices = phy_node.indices for phy_node in g_phy.l3devices(host=self.host): loopback_ids = self.loopback_interface_ids() # allocate loopbacks to routes (same for all ios variants) DmNode = self.nidb.node(phy_node) DmNode.add_stanza("render") DmNode.indices = phy_node.indices DmNode.add_stanza("syslog") DmNode.add_stanza('mgmt') if use_ignite_pool == True: mgmt_ip = allocate_pool_entry(mgmt_pool_id,phy_node.name, None) pos_mask = mgmt_ip.find('/') if pos_mask != -1: network = mgmt_ip[:pos_mask] mask = int(mgmt_ip[pos_mask+1:]) else: network = mgmt_ip[:pos_mask] mask = 32 DmNode.mgmt.ip = network + '/' + str(mask) DmNode.mgmt.mask = "" elif g_phy.data.mgmt_block is not None: DmNode.mgmt.ip = mgmt_address_block.next() DmNode.mgmt.mask = mgmt_address_mask # for node_data in phy_node._graph.node: for interface in DmNode.loopback_interfaces(): if interface != DmNode.loopback_zero: interface.id = loopback_ids.next() # numeric ids numeric_int_ids = self.numeric_interface_ids() for interface in DmNode.physical_interfaces(): phy_numeric_id = phy_node.interface(interface).numeric_id if phy_numeric_id is None: # TODO: remove numeric ID code interface.numeric_id = numeric_int_ids.next() else: interface.numeric_id = int(phy_numeric_id) phy_specified_id = phy_node.interface(interface).specified_id if phy_specified_id is not None: interface.id = phy_specified_id # numeric ids numeric_po_ids = self.numeric_portchannel_ids() for interface in DmNode.portchannel_interfaces(): po_interface = phy_node.interface(interface) interface.numeric_id = int(po_interface.id[po_interface.id.rfind('_')+1:]) po_specified_id = phy_node.interface(interface).specified_id if po_specified_id is not None: interface.id = po_specified_id interface.pc = True for po_mem_int in DmNode.physical_interfaces(): po_mem_interface = phy_node.interface(po_mem_int) if po_mem_interface.id in po_interface.members: po_mem_int.channel_group = interface.numeric_id po_interface_int = po_interface._interface if po_interface_int.has_key('subcat_prot'): if po_interface.subcat_prot == "vpc": po_mem_int.keepalive_port_vpc = True# is a member port of VPC peer link interface.virt_port_channel = True# is a VPC interface DmNode.add_stanza('vpc') if po_interface.subcat_prot == "vpc-member": po_mem_int.member_port_vpc = True interface.vpc_member_id = interface.numeric_id interface.member_vpc = True ##adding rp's if vxlan_global_config is not None and 'rendezvous_point' in vxlan_global_config: for rp in vxlan_global_config['rendezvous_point']: for phy_node in g_phy.l3devices(host=self.host): DmNode = self.nidb.node(phy_node) if phy_node.id == rp['node_id']: rp['node_id'] = DmNode.interfaces[0]._port['ipv4_address'] #from autonetkit.compilers.device.ubuntu import UbuntuCompiler #from autonetkit_cisco.compilers.device.ubuntu import UbuntuCompiler #ubuntu_compiler = UbuntuCompiler(self.nidb, self.anm) for phy_node in g_phy.servers(host=self.host): DmNode = self.nidb.node(phy_node) DmNode.add_stanza("render") DmNode.add_stanza("ip") #interface.id = self.numeric_to_interface_label_linux(interface.numeric_id) # print "numeric", interface.numeric_id, interface.id DmNode.ip.use_ipv4 = phy_node.use_ipv4 DmNode.ip.use_ipv6 = phy_node.use_ipv6 # TODO: clean up interface handling numeric_int_ids = self.numeric_interface_ids() for interface in DmNode.physical_interfaces(): phy_numeric_id = phy_node.interface(interface).numeric_id if phy_numeric_id is None: # TODO: remove numeric ID code interface.numeric_id = numeric_int_ids.next() else: interface.numeric_id = int(phy_numeric_id) phy_specified_id = phy_node.interface(interface).specified_id if phy_specified_id is not None: interface.id = phy_specified_id # numeric ids numeric_po_ids = self.numeric_portchannel_ids() for interface in DmNode.portchannel_interfaces(): phy_numeric_id = phy_node.interface(interface).numeric_id if phy_numeric_id is None: # TODO: remove numeric ID code interface.numeric_id = numeric_po_ids.next() else: interface.numeric_id = int(phy_numeric_id) phy_specified_id = phy_node.interface(interface).specified_id if phy_specified_id is not None: interface.id = phy_specified_id # TODO: make this part of the base device compiler, which # server/router inherits # not these are physical interfaces; configure after previous # config steps if use_mgmt_interfaces: mgmt_int = DmNode.add_interface( management=True, description="eth0") mgmt_int_id = "eth0" mgmt_int.id = mgmt_int_id # render route config DmNode = self.nidb.node(phy_node) #ubuntu_compiler.compile(DmNode) if not phy_node.dont_configure_static_routing: DmNode.render.template = os.path.join( "templates", "linux", "static_route.mako") if to_memory: DmNode.render.to_memory = True else: DmNode.render.dst_folder = dst_folder DmNode.render.dst_file = "%s.conf" % naming.network_hostname( phy_node) # TODO: refactor out common logic ios_compiler = IosClassicCompiler(self.nidb, self.anm) host_routers = g_phy.routers(host=self.host) ios_nodes = (n for n in host_routers if n.syntax in ("ios", "ios_xe")) for phy_node in ios_nodes: if (phy_node.devsubtype == "core" or phy_node.devsubtype == "border"): continue DmNode = self.nidb.node(phy_node) DmNode.add_stanza("render") DmNode.render.template = os.path.join("templates", "ios.mako") to_memory = False if to_memory: DmNode.render.to_memory = True else: DmNode.render.dst_folder = dst_folder DmNode.render.dst_file = "%s.conf" % naming.network_hostname( phy_node) # TODO: write function that assigns interface number excluding # those already taken # Assign interfaces if phy_node.device_subtype == "IOSv": int_ids = self.interface_ids_ios() numeric_to_interface_label = self.numeric_to_interface_label_ios elif phy_node.device_subtype == "CSR1000v": int_ids = self.interface_ids_csr1000v() numeric_to_interface_label = self.numeric_to_interface_label_ra else: # default if no subtype specified # TODO: need to set default in the load module log.warning("Unexpected subtype %s for %s" % (phy_node.device_subtype, phy_node)) int_ids = self.interface_ids_ios() numeric_to_interface_label = self.numeric_to_interface_label_ios numeric_to_portchannel_interface_label = self.numeric_to_portchannel_interface_label_ios if use_mgmt_interfaces: if phy_node.device_subtype == "IOSv": # TODO: make these configured in the internal config file # for platform/device_subtype keying mgmt_int_id = "GigabitEthernet0/0" if phy_node.device_subtype == "CSR1000v": mgmt_int_id = "GigabitEthernet1" for interface in DmNode.physical_interfaces(): # TODO: use this code block once for all routers if not interface.id: interface.id = numeric_to_interface_label( interface.numeric_id) else: if interface.id[0] == 'e' or interface.id[0] == 'E': #import re port_re = "([a-zA-Z]+)([0-9]+/[0-9]+)" interface.id = "%s %s"%((re.search(port_re,interface.id)).group(1), (re.search(port_re,interface.id)).group(2)) for interface in DmNode.portchannel_interfaces(): # TODO: use this code block once for all routers #if not interface.id: interface.id = numeric_to_portchannel_interface_label( interface.numeric_id) ios_compiler.compile(DmNode) if use_mgmt_interfaces: mgmt_int = DmNode.add_interface(management=True) mgmt_int.id = mgmt_int_id nxos_compiler = NxOsCompiler(self.nidb, self.anm) for phy_node in g_phy.routers(host=self.host, syntax='nx_os'): if (phy_node.devsubtype == "core" or phy_node.devsubtype == "border"): continue DmNode = self.nidb.node(phy_node) DmNode.add_stanza("render") if pc_only_config == True: DmNode.render.template = os.path.join("templates", "nexus_os_pc_only.mako") else: DmNode.render.template = os.path.join("templates", "nexus_os.mako") #if to_memory: # DmNode.render.to_memory = True #else: DmNode.render.dst_folder = dst_folder DmNode.render.dst_file = "%s.conf" % phy_node.name # Assign interfaces int_ids = self.interface_ids_nxos() numeric_to_interface_label = self.numeric_to_interface_label_nxos numeric_to_portchannel_interface_label = self.numeric_to_portchannel_interface_label_nxos for interface in DmNode.physical_interfaces(): if not interface.id: interface.id = self.numeric_to_interface_label_nxos( interface.numeric_id) elif interface.id[0] == 'e' or interface.id[0] == 'E': import re port_re = "([a-zA-Z]+)([0-9]+/[0-9]+)" interface.id = "%s %s"%((re.search(port_re,interface.id)).group(1), (re.search(port_re,interface.id)).group(2)) else: interface.id = 'Ethernet ' + interface.id for interface in DmNode.portchannel_interfaces(): # TODO: use this code block once for all routers #if not interface.id: interface.id = numeric_to_portchannel_interface_label( interface.numeric_id) DmNode.supported_features = ConfigStanza( mpls_te=False, mpls_oam=False, vrf=False) nxos_compiler.compile(DmNode) # TODO: make this work other way around if use_mgmt_interfaces: mgmt_int_id = "mgmt0" mgmt_int = DmNode.add_interface(management=True) mgmt_int.id = mgmt_int_id staros_compiler = StarOsCompiler(self.nidb, self.anm) for phy_node in g_phy.routers(host=self.host, syntax='StarOS'): DmNode = self.nidb.node(phy_node) DmNode.add_stanza("render") DmNode.render.template = os.path.join("templates", "staros.mako") if to_memory: DmNode.render.to_memory = True else: DmNode.render.dst_folder = dst_folder DmNode.render.dst_file = "%s.conf" % naming.network_hostname( phy_node) # Assign interfaces int_ids = self.interface_ids_nxos() for interface in DmNode.physical_interfaces(): if not interface.id: interface.id = self.numeric_to_interface_label_star_os( interface.numeric_id) staros_compiler.compile(DmNode) # TODO: make this work other way around if use_mgmt_interfaces: mgmt_int_id = "ethernet 1/1" mgmt_int = DmNode.add_interface(management=True) mgmt_int.id = mgmt_int_id