def server_method(self, unused_session, rpc, *unused_params): args = {} for element in rpc.iterchildren(): if QName(element.tag).localname == rpcname: for rpcarg in element.iterchildren(): name = QName(rpcarg.tag).localname args[name.replace("-", "_")] = rpcarg.text result = method(minstance, **args) return str(result) if result is not None else ""
def from_element(cls, root): self = cls(**cls.root_from_element(root)) for elm in root.findall("*"): key = QName(elm.tag).localname fn = getattr(self, "{0}_from_element".format(key.replace("-", "_")), None) val = fn(key, elm) if fn else elm.text if val is not self.NoInsert: self[key] = val return self
def parse_dpg(dpg, hname): for child in dpg: hostname = child.find(str(QName(ns, "Hostname"))) if hostname.text.lower() != hname.lower(): continue vni = vni_default vni_element = child.find(str(QName(ns, "VNI"))) if vni_element != None: if vni_element.text.isdigit(): vni = int(vni_element.text) else: print >> sys.stderr, "VNI must be an integer (use default VNI %d instead)" % vni_default ipintfs = child.find(str(QName(ns, "IPInterfaces"))) intfs = {} for ipintf in ipintfs.findall(str(QName(ns, "IPInterface"))): intfalias = ipintf.find(str(QName(ns, "AttachTo"))).text intfname = port_alias_map.get(intfalias, intfalias) ipprefix = ipintf.find(str(QName(ns, "Prefix"))).text intfs[(intfname, ipprefix)] = {} lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) lo_intfs = {} for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): intfname = lointf.find(str(QName(ns, "AttachTo"))).text ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text lo_intfs[(intfname, ipprefix)] = {} mvrfConfigs = child.find(str(QName(ns, "MgmtVrfConfigs"))) mvrf = {} if mvrfConfigs != None: mv = mvrfConfigs.find(str(QName(ns1, "MgmtVrfGlobal"))) if mv != None: mvrf_en_flag = mv.find(str(QName(ns, "mgmtVrfEnabled"))).text mvrf["vrf_global"] = {"mgmtVrfEnabled": mvrf_en_flag} mgmtintfs = child.find(str(QName(ns, "ManagementIPInterfaces"))) mgmt_intf = {} for mgmtintf in mgmtintfs.findall( str(QName(ns1, "ManagementIPInterface"))): intfname = mgmtintf.find(str(QName(ns, "AttachTo"))).text ipprefix = mgmtintf.find(str(QName(ns1, "PrefixStr"))).text mgmtipn = ipaddress.IPNetwork(ipprefix) gwaddr = ipaddress.IPAddress(int(mgmtipn.network) + 1) mgmt_intf[(intfname, ipprefix)] = {'gwaddr': gwaddr} pcintfs = child.find(str(QName(ns, "PortChannelInterfaces"))) pc_intfs = [] pcs = {} pc_members = {} intfs_inpc = [] # List to hold all the LAG member interfaces for pcintf in pcintfs.findall(str(QName(ns, "PortChannel"))): pcintfname = pcintf.find(str(QName(ns, "Name"))).text pcintfmbr = pcintf.find(str(QName(ns, "AttachTo"))).text pcmbr_list = pcintfmbr.split(';') pc_intfs.append(pcintfname) for i, member in enumerate(pcmbr_list): pcmbr_list[i] = port_alias_map.get(member, member) intfs_inpc.append(pcmbr_list[i]) pc_members[(pcintfname, pcmbr_list[i])] = {'NULL': 'NULL'} if pcintf.find(str(QName(ns, "Fallback"))) != None: pcs[pcintfname] = { 'members': pcmbr_list, 'fallback': pcintf.find(str(QName(ns, "Fallback"))).text, 'min_links': str(int(math.ceil(len() * 0.75))) } else: pcs[pcintfname] = { 'members': pcmbr_list, 'min_links': str(int(math.ceil(len(pcmbr_list) * 0.75))) } vlanintfs = child.find(str(QName(ns, "VlanInterfaces"))) vlan_intfs = [] vlans = {} vlan_members = {} for vintf in vlanintfs.findall(str(QName(ns, "VlanInterface"))): vintfname = vintf.find(str(QName(ns, "Name"))).text vlanid = vintf.find(str(QName(ns, "VlanID"))).text vintfmbr = vintf.find(str(QName(ns, "AttachTo"))).text vmbr_list = vintfmbr.split(';') for i, member in enumerate(vmbr_list): vmbr_list[i] = port_alias_map.get(member, member) sonic_vlan_member_name = "Vlan%s" % (vlanid) vlan_members[(sonic_vlan_member_name, vmbr_list[i])] = { 'tagging_mode': 'untagged' } vlan_attributes = {'vlanid': vlanid} # If this VLAN requires a DHCP relay agent, it will contain a <DhcpRelays> element # containing a list of DHCP server IPs vintf_node = vintf.find(str(QName(ns, "DhcpRelays"))) if vintf_node is not None and vintf_node.text is not None: vintfdhcpservers = vintf_node.text vdhcpserver_list = vintfdhcpservers.split(';') vlan_attributes['dhcp_servers'] = vdhcpserver_list sonic_vlan_name = "Vlan%s" % vlanid if sonic_vlan_name != vintfname: vlan_attributes['alias'] = vintfname vlans[sonic_vlan_name] = vlan_attributes aclintfs = child.find(str(QName(ns, "AclInterfaces"))) acls = {} for aclintf in aclintfs.findall(str(QName(ns, "AclInterface"))): aclname = aclintf.find(str(QName(ns, "InAcl"))).text.upper().replace( " ", "_").replace("-", "_") aclattach = aclintf.find(str(QName(ns, "AttachTo"))).text.split(';') acl_intfs = [] is_mirror = False is_mirror_v6 = False # TODO: Ensure that acl_intfs will only ever contain front-panel interfaces (e.g., # maybe we should explicity ignore management and loopback interfaces?) because we # decide an ACL is a Control Plane ACL if acl_intfs is empty below. for member in aclattach: member = member.strip() if pcs.has_key(member): # If try to attach ACL to a LAG interface then we shall add the LAG to # to acl_intfs directly instead of break it into member ports, ACL attach # to LAG will be applied to all the LAG members internally by SAI/SDK acl_intfs.append(member) elif vlans.has_key(member): print >> sys.stderr, "Warning: ACL " + aclname + " is attached to a Vlan interface, which is currently not supported" elif port_alias_map.has_key(member): acl_intfs.append(port_alias_map[member]) # Give a warning if trying to attach ACL to a LAG member interface, correct way is to attach ACL to the LAG interface if port_alias_map[member] in intfs_inpc: print >> sys.stderr, "Warning: ACL " + aclname + " is attached to a LAG member interface " + port_alias_map[ member] + ", instead of LAG interface" elif member.lower().startswith('erspan'): if member.lower().startswith('erspanv6'): is_mirror_v6 = True else: is_mirror = True # Erspan session will be attached to all front panel ports # initially. If panel ports is a member port of LAG, then # the LAG will be added to acl table instead of the panel # ports. Non-active ports will be removed from this list # later after the rest of the minigraph has been parsed. acl_intfs = pc_intfs[:] for panel_port in port_alias_map.values(): if panel_port not in intfs_inpc: acl_intfs.append(panel_port) break if acl_intfs: acls[aclname] = {'policy_desc': aclname, 'ports': acl_intfs} if is_mirror: acls[aclname]['type'] = 'MIRROR' elif is_mirror_v6: acls[aclname]['type'] = 'MIRRORV6' else: acls[aclname]['type'] = 'L3' else: # This ACL has no interfaces to attach to -- consider this a control plane ACL try: aclservice = aclintf.find(str(QName(ns, "Type"))).text # If we already have an ACL with this name and this ACL is bound to a different service, # append the service to our list of services if aclname in acls: if acls[aclname]['type'] != 'CTRLPLANE': print >> sys.stderr, "Warning: ACL '%s' type mismatch. Not updating ACL." % aclname elif acls[aclname]['services'] == aclservice: print >> sys.stderr, "Warning: ACL '%s' already contains service '%s'. Not updating ACL." % ( aclname, aclservice) else: acls[aclname]['services'].append(aclservice) else: acls[aclname] = { 'policy_desc': aclname, 'type': 'CTRLPLANE', 'services': [aclservice] } except: print >> sys.stderr, "Warning: Ignoring Control Plane ACL %s without type" % aclname return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni return None, None, None, None, None, None, None, None, None, None
id = elem.findtext(QName(PNR, 'paikkaID')) type = elem.findtext(QName(PNR, 'paikkatyyppiKoodi')) uri = PAIKAT["P" + id] g.add((uri, RDF.type, PAIKAT['T' + type])) g.add((uri, RDF.type, SKOS.Concept)) point = URIRef(uri + "_point") g.add((uri, GEO.hasGeometry, point)) g.add((point, RDF.type, GEO.Point)) coords = elem.findtext("{%s}paikkaSijainti//{%s}pos" % (PNR, GML)) wkt = "<http://www.opengis.net/def/crs/EPSG/0/3067> POINT(%s)" % coords g.add((point, GEO.asWKT, Literal(wkt, datatype=GEO.wktLiteral))) for name in elem.findall("{%s}nimi/{%s}PaikanNimi" % (PNR, PNR)): label = name.findtext(QName(PNR, 'kirjoitusasu')) lang = name.findtext(QName(PNR, 'kieliKoodi')) lang = LANGMAP.get(lang, lang) g.add((uri, SKOS.prefLabel, Literal(label, lang))) g = Graph() g.namespace_manager.bind('skos', SKOS) g.namespace_manager.bind('paikat', PAIKAT) g.namespace_manager.bind('geo', GEO) paikat = etree.iterparse('paikka.xml', events=('end', ), tag=QName(PNR, 'Paikka')) fast_iter(paikat, convert) g.serialize(format='turtle', destination=sys.stdout)
def parse_xml(filename, hostname): mini_graph_path, root = reconcile_mini_graph_locations(filename, hostname) u_neighbors = None u_devices = None hwsku = None bgp_sessions = None bgp_asn = None intfs = None vlan_intfs = None pc_intfs = None mgmt_intf = None lo_intf = None neighbors = None devices = None hwsku_qn = QName(ns, "HwSku") for child in root: if child.tag == str(hwsku_qn): hwsku = child.text # port_alias_map maps ngs port name to sonic port name if hwsku == "Force10-S6000": for i in range(0, 128, 4): port_alias_map["fortyGigE0/%d" % i] = "Ethernet%d" % i elif hwsku == "Force10-S6100": for i in range(0, 4): for j in range(0, 16): port_alias_map["fortyGigE1/%d/%d" % (i+1, j+1)] = "Ethernet%d" % (i * 16 + j + 1) elif hwsku == "Arista-7050-QX32": for i in range(1, 25): port_alias_map["Ethernet%d/1" % i] = "Ethernet%d" % ((i - 1) * 4) for i in range(25, 33): port_alias_map["Ethernet%d" % i] = "Ethernet%d" % ((i - 1) * 4) else: for i in range(0, 128, 4): port_alias_map["Ethernet%d" % i] = "Ethernet%d" % i for child in root: if child.tag == str(QName(ns, "DpgDec")): (intfs, lo_intfs, mgmt_intf, vlan_intfs, pc_intfs) = parse_dpg(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_asn) = parse_cpg(child, hostname) elif child.tag == str(QName(ns, "PngDec")): (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port) = parse_png(child, hostname) elif child.tag == str(QName(ns, "UngDec")): (u_neighbors, u_devices, _, _, _, _) = parse_png(child, hostname) # Replace port with alias in Vlan interfaces members if vlan_intfs is not None: for vlan in vlan_intfs: for i,member in enumerate(vlan['members']): vlan['members'][i] = port_alias_map[member] # Convert vlan members into a space-delimited string vlan['members'] = " ".join(vlan['members']) # Replace port with alias in port channel interfaces members if pc_intfs is not None: for pc in pc_intfs: for i,member in enumerate(pc['members']): pc['members'][i] = port_alias_map[member] Tree = lambda: defaultdict(Tree) results = Tree() results['minigraph_hwsku'] = hwsku # sorting by lambdas are not easily done without custom filters. # TODO: add jinja2 filter to accept a lambda to sort a list of dictionaries by attribute. # TODO: alternatively (preferred), implement class containers for multiple-attribute entries, enabling sort by attr results['minigraph_bgp'] = sorted(bgp_sessions, key=lambda x: x['addr']) results['minigraph_bgp_asn'] = bgp_asn # TODO: sort does not work properly on all interfaces of varying lengths. Need to sort by integer group(s). results['minigraph_interfaces'] = sorted(intfs, key=lambda x: x['name']) results['minigraph_vlan_interfaces'] = vlan_intfs results['minigraph_portchannel_interfaces'] = pc_intfs results['minigraph_mgmt_interface'] = mgmt_intf results['minigraph_lo_interfaces'] = lo_intfs results['minigraph_neighbors'] = neighbors results['minigraph_devices'] = devices results['minigraph_underlay_neighbors'] = u_neighbors results['minigraph_underlay_devices'] = u_devices # note - this may include files under acs/ansible/minigraph, or those under the default cache folder. # (see ANSIBLE_USER_MINIGRAPH_PATH at the top of the module) results['minigraph_as_xml'] = mini_graph_path results['minigraph_console'] = get_console_info(devices, console_dev, console_port) results['minigraph_mgmt'] = get_mgmt_info(devices, mgmt_dev, mgmt_port) return results
def parse_png(png, hname): neighbors = {} devices = {} console_dev = '' console_port = '' mgmt_dev = '' mgmt_port = '' port_speeds = {} console_ports = {} for child in png: if child.tag == str(QName(ns, "DeviceInterfaceLinks")): for link in child.findall(str(QName(ns, "DeviceLinkBase"))): linktype = link.find(str(QName(ns, "ElementType"))).text if linktype == "DeviceSerialLink": enddevice = link.find(str(QName(ns, "EndDevice"))).text endport = link.find(str(QName(ns, "EndPort"))).text startdevice = link.find(str(QName(ns, "StartDevice"))).text startport = link.find(str(QName(ns, "StartPort"))).text baudrate = link.find(str(QName(ns, "Bandwidth"))).text flowcontrol = 1 if link.find(str(QName( ns, "FlowControl"))) is not None and link.find( str(QName(ns, "FlowControl"))).text == 'true' else 0 if enddevice.lower() == hname.lower(): console_ports[endport] = { 'remote_device': startdevice, 'baud_rate': baudrate, 'flow_control': flowcontrol } else: console_ports[startport] = { 'remote_device': enddevice, 'baud_rate': baudrate, 'flow_control': flowcontrol } continue if linktype != "DeviceInterfaceLink" and linktype != "UnderlayInterfaceLink": continue enddevice = link.find(str(QName(ns, "EndDevice"))).text endport = link.find(str(QName(ns, "EndPort"))).text startdevice = link.find(str(QName(ns, "StartDevice"))).text startport = link.find(str(QName(ns, "StartPort"))).text bandwidth_node = link.find(str(QName(ns, "Bandwidth"))) bandwidth = bandwidth_node.text if bandwidth_node is not None else None if enddevice.lower() == hname.lower(): if port_alias_map.has_key(endport): endport = port_alias_map[endport] neighbors[endport] = { 'name': startdevice, 'port': startport } if bandwidth: port_speeds[endport] = bandwidth else: if port_alias_map.has_key(startport): startport = port_alias_map[startport] neighbors[startport] = {'name': enddevice, 'port': endport} if bandwidth: port_speeds[startport] = bandwidth if child.tag == str(QName(ns, "Devices")): for device in child.findall(str(QName(ns, "Device"))): (lo_prefix, mgmt_prefix, name, hwsku, d_type, deployment_id) = parse_device(device) device_data = { 'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku } if deployment_id: device_data['deployment_id'] = deployment_id devices[name] = device_data if child.tag == str(QName(ns, "DeviceInterfaceLinks")): for if_link in child.findall(str(QName(ns, 'DeviceLinkBase'))): if str(QName(ns3, "type")) in if_link.attrib: link_type = if_link.attrib[str(QName(ns3, "type"))] if link_type == 'DeviceSerialLink': for node in if_link: if node.tag == str(QName(ns, "EndPort")): console_port = node.text.split()[-1] elif node.tag == str(QName(ns, "EndDevice")): console_dev = node.text elif link_type == 'DeviceMgmtLink': for node in if_link: if node.tag == str(QName(ns, "EndPort")): mgmt_port = node.text.split()[-1] elif node.tag == str(QName(ns, "EndDevice")): mgmt_dev = node.text return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speeds, console_ports)
def process_step_xml(**kwargs): step_node = Element(QName(_nsmap['prov'], 'processStep'), nsmap=_nsmap) program_node = Element(QName(_nsmap['prov'], 'program'), nsmap=_nsmap) program_node.text = kwargs['program'] if kwargs.has_key('program_version'): program_node.set('version', kwargs['program_version']) if kwargs.has_key('program_arguments'): program_node.set('arguments', kwargs['program_arguments']) step_node.append(program_node) timestamp_node = Element(QName(_nsmap['prov'], 'timestamp'), nsmap=_nsmap) timestamp_node.text = kwargs['timestamp'] step_node.append(timestamp_node) if kwargs.has_key('cvs'): cvs_node = Element(QName(_nsmap['prov'], 'cvs'), nsmap=_nsmap) cvs_node.text = kwargs['cvs'] step_node.append(cvs_node) user_node = Element(QName(_nsmap['prov'], 'user'), nsmap=_nsmap) user_node.text = kwargs['user'] step_node.append(user_node) machine_node = Element(QName(_nsmap['prov'], 'machine'), nsmap=_nsmap) machine_node.text = kwargs['machine'] step_node.append(machine_node) platform_node = Element(QName(_nsmap['prov'], 'platform'), nsmap=_nsmap) platform_node.text = kwargs['platform'] if kwargs.has_key('platform_version'): platform_node.set('version', kwargs['platform_version']) step_node.append(platform_node) if kwargs.has_key('compiler'): compiler_node = Element(QName(_nsmap['prov'], 'compiler'), nsmap=_nsmap) compiler_node.text = kwargs['compiler'] if kwargs.has_key('compiler_version'): compiler_node.set('version', kwargs['compiler_version']) step_node.append(compiler_node) if kwargs.has_key('library'): library_node = Element(QName(_nsmap['prov'], 'library'), nsmap=_nsmap) library_node.text = kwargs['library'] if kwargs.has_key('library_version'): library_node.set('version', kwargs['library_version']) step_node.append(library_node) return step_node
def __setitem__(self, key, val): if not self._updating: raise RuntimeError( "Metadata not opened for editing, use with block") def clean(s): return re_xml_illegal_chars.sub('', s) def add_array(node, items): rdf_type = next(c.rdf_type for c in XMP_CONTAINERS if isinstance(items, c.py_type)) seq = etree.SubElement(node, QName(XMP_NS_RDF, rdf_type)) if rdf_type == 'Alt': attrib = {QName(XMP_NS_XML, 'lang'): 'x-default'} else: attrib = None for item in items: el = etree.SubElement(seq, QName(XMP_NS_RDF, 'li'), attrib=attrib) el.text = clean(item) try: # Locate existing node to replace node, attrib, _oldval, _parent = next(self._get_elements(key)) if attrib: if not isinstance(val, str): raise TypeError(val) node.set(attrib, clean(val)) elif isinstance(val, (list, set)): for child in node.findall('*'): node.remove(child) add_array(node, val) elif isinstance(val, str): for child in node.findall('*'): node.remove(child) if str(self._qname(key)) in LANG_ALTS: add_array(node, AltList([clean(val)])) else: node.text = clean(val) else: raise TypeError(val) except StopIteration: # Insert a new node rdf = self._get_rdf_root() if str(self._qname(key)) in LANG_ALTS: val = AltList([clean(val)]) if isinstance(val, (list, set)): rdfdesc = etree.SubElement( rdf, QName(XMP_NS_RDF, 'Description'), attrib={QName(XMP_NS_RDF, 'about'): ''}, ) node = etree.SubElement(rdfdesc, self._qname(key)) add_array(node, val) elif isinstance(val, str): rdfdesc = etree.SubElement( rdf, QName(XMP_NS_RDF, 'Description'), attrib={ QName(XMP_NS_RDF, 'about'): '', self._qname(key): clean(val), }, ) else: raise TypeError(val)
def test_class_depends_on(self, mock_dependencies, mock_find_class): source = ClassFactory.create() target = ClassFactory.create() another = ClassFactory.create() find_classes = {QName("a"): another, QName("b"): target} mock_find_class.side_effect = lambda x, condition: find_classes.get(x) mock_dependencies.side_effect = [ [QName(x) for x in "cde"], [QName(x) for x in "abc"], [QName(x) for x in "xy"], ] self.assertFalse(self.analyzer.class_depends_on(source, target)) self.assertTrue(self.analyzer.class_depends_on(source, target)) mock_find_class.assert_has_calls( [ mock.call(QName("c"), condition=None), mock.call(QName("d"), condition=None), mock.call(QName("e"), condition=None), mock.call(QName("a"), condition=None), mock.call(QName("x"), condition=None), mock.call(QName("y"), condition=None), mock.call(QName("b"), condition=None), ] )
def sign_envelope(envelope, public_cert, private_key, certfile, password): reference_id = "Reference" security = get_security_header(envelope) security.set(QName(ns.SOAP_ENV_11, "mustUnderstand"), "1") x509type = ( "http://docs.oasis-open.org/wss/2004/01/" "oasis-200401-wss-x509-token-profile-1.0#X509v3" ) encoding_type = ( "http://docs.oasis-open.org/wss/2004/01/" "oasis-200401-wss-soap-message-security-1.0#Base64Binary" ) binary_token = etree.SubElement( security, QName(ns.WSSE, "BinarySecurityToken"), attrib={ QName(ns.WSU, "Id"): reference_id, "ValueType": x509type, "EncodingType": encoding_type, }, ) binary_token.text = base64.b64encode( public_cert.public_bytes(encoding=serialization.Encoding.DER) ) signature = xmlsig.template.create( c14n_method=xmlsig.constants.TransformExclC14N, sign_method=xmlsig.constants.TransformRsaSha1, ns="ds", ) envelope.append(signature) # Add a KeyInfo node with X509Data child to the Signature. XMLSec will fill # in this template with the actual certificate details when it signs. key_info = xmlsig.template.ensure_key_info(signature) sec_token_ref = etree.SubElement(key_info, QName(ns.WSSE, "SecurityTokenReference")) etree.SubElement( sec_token_ref, QName(ns.WSSE, "Reference"), attrib={"URI": "#" + reference_id, "ValueType": x509type}, ) # Insert the Signature node in the wsse:Security header. security.append(signature) # Perform the actual signing. ctx = xmlsig.SignatureContext() ctx.x509 = public_cert ctx.public_key = public_cert.public_key() ctx.private_key = private_key timestamp = etree.SubElement(security, QName(ns.WSU, "Timestamp")) now = datetime.now() etree.SubElement(timestamp, QName(ns.WSU, "Created")).text = now.strftime( "%Y-%m-%dT%H:%M:%SZ" ) exp = now + timedelta(hours=1) etree.SubElement(timestamp, QName(ns.WSU, "Expires")).text = exp.strftime( "%Y-%m-%dT%H:%M:%SZ" ) soap_env = detect_soap_env(envelope) _sign_node(ctx, signature, envelope.find(QName(soap_env, "Body"))) _sign_node(ctx, signature, security.find(QName(ns.WSU, "Timestamp"))) ctx.sign(signature) return etree.fromstring(etree.tostring(envelope, method="c14n"))
def setUp(self): self.parser = XmlParser() self.parser.index = 10 self.parser.objects = [(QName(x), x) for x in "abcde"]
def test_create_wildcard_queue_item(self): parent_qname = QName("parent") actual = self.parser.create_wildcard_queue_item(parent_qname) expected = WildcardQueueItem(index=10, position=5, qname=parent_qname) self.assertEqual(expected, actual)
def parse_xml(filename, hostname, asic_name=None): mini_graph_path, root = reconcile_mini_graph_locations(filename, hostname) u_neighbors = None u_devices = None hwsku = None bgp_sessions = None bgp_asn = None intfs = None vlan_intfs = None pc_intfs = None vlans = None pcs = None mgmt_intf = None lo_intfs = None host_lo_intfs = None neighbors = None devices = None hostname = None resource_type = None syslog_servers = [] dhcp_servers = [] dhcpv6_servers = [] ntp_servers = [] mgmt_routes = [] bgp_peers_with_range = [] deployment_id = None is_storage_device = None if asic_name is not None: asic_id = asic_name[len('asic'):] else: asic_id = None hwsku_qn = QName(ns, "HwSku") hostname_qn = QName(ns, "Hostname") for child in root: if child.tag == str(hwsku_qn): hwsku = child.text if child.tag == str(hostname_qn): hostname = child.text global port_alias_to_name_map global port_name_to_alias_map global port_alias_asic_map global port_alias_to_port_asic_alias_map global port_name_to_index_map port_alias_to_name_map, port_alias_asic_map, port_name_to_index_map = get_port_alias_to_name_map( hwsku, asic_name) # Create inverse mapping between port name and alias port_name_to_alias_map = {v: k for k, v in port_alias_to_name_map.items()} for k, v in port_alias_to_name_map.items(): for i, j in port_alias_asic_map.items(): if v == j: port_alias_to_port_asic_alias_map[k] = i for child in root: if asic_name is None: if child.tag == str(QName(ns, "DpgDec")): (intfs, lo_intfs, mgmt_intf, vlans, pcs, acls, dhcp_servers, dhcpv6_servers) = parse_dpg(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_asn, bgp_peers_with_range) = parse_cpg(child, hostname) elif child.tag == str(QName(ns, "PngDec")): (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port) = parse_png(child, hostname) elif child.tag == str(QName(ns, "UngDec")): (u_neighbors, u_devices, _, _, _, _) = parse_png(child, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): (syslog_servers, ntp_servers, mgmt_routes, deployment_id, resource_type) = parse_meta(child, hostname) else: if child.tag == str(QName(ns, "DpgDec")): (intfs, lo_intfs, mgmt_intf, vlans, pcs, acls, dhcp_servers, dhcpv6_servers) = parse_dpg(child, asic_name) host_lo_intfs = parse_host_loopback(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_asn, bgp_peers_with_range) = parse_cpg(child, asic_name) elif child.tag == str(QName(ns, "PngDec")): (neighbors, devices, _) = parse_asic_png(child, asic_name, hostname) current_device = [ devices[key] for key in devices if key.lower() == hostname.lower() ][0] device_type = current_device['type'] # Associate Port Channel to namespace try: for pckey, pcval in pcs.items(): pcval['namespace'] = neighbors[pcval['members'][0]]['namespace'] except Exception as e: print("Warning: PortChannel " + pckey + " has no member ports.", file=sys.stderr) # TODO: Move all alias-related code out of minigraph_facts.py and into # its own module to be used as another layer after parsing the minigraph. # Create a map of SONiC port name to physical port index # Start by creating a list of all port names port_name_list = port_name_to_alias_map.keys() # Sort the list in natural order, because SONiC port names, when # sorted in natural sort order, match the phyical port index order port_name_list_sorted = natsorted(port_name_list) # Create mapping between port alias and physical index port_index_map = port_name_to_index_map if port_name_to_index_map else get_port_indices_for_asic( asic_id, port_name_list_sorted) # Generate results Tree = lambda: defaultdict(Tree) results = Tree() results['minigraph_hwsku'] = hwsku # sorting by lambdas are not easily done without custom filters. # TODO: add jinja2 filter to accept a lambda to sort a list of dictionaries by attribute. # TODO: alternatively (preferred), implement class containers for multiple-attribute entries, enabling sort by attr results['minigraph_bgp'] = sorted(bgp_sessions, key=lambda x: x['addr']) results['minigraph_bgp_asn'] = bgp_asn results['minigraph_bgp_peers_with_range'] = bgp_peers_with_range # TODO: sort does not work properly on all interfaces of varying lengths. Need to sort by integer group(s). phyport_intfs = [] vlan_intfs = [] pc_intfs = [] vlan_sub_intfs = [] for intf in intfs: intfname = intf['attachto'] if intfname[0:4] == 'Vlan': vlan_intfs.append(intf) elif intfname[0:11] == 'PortChannel': pc_intfs.append(intf) elif VLAN_SUB_INTERFACE_SEPARATOR in intfname: vlan_sub_intfs.append(intf) else: phyport_intfs.append(intf) if host_lo_intfs: lo_intfs += host_lo_intfs results['minigraph_device_metadata'] = { 'bgp_asn': bgp_asn, 'deployment_id': deployment_id, 'hostname': hostname, 'hwsku': hwsku, 'device_type': device_type } if resource_type is not None: results['minigraph_device_metadata']['resource_type'] = resource_type results['minigraph_interfaces'] = sorted(phyport_intfs, key=lambda x: x['attachto']) results['minigraph_vlan_interfaces'] = sorted(vlan_intfs, key=lambda x: x['attachto']) results['minigraph_portchannel_interfaces'] = sorted( pc_intfs, key=lambda x: x['attachto']) results['minigraph_ports'] = ports results['minigraph_vlans'] = vlans results['minigraph_portchannels'] = pcs results['minigraph_mgmt_interface'] = mgmt_intf results['minigraph_lo_interfaces'] = lo_intfs results['minigraph_acls'] = acls results['minigraph_neighbors'] = neighbors results['minigraph_devices'] = devices results['minigraph_underlay_neighbors'] = u_neighbors results['minigraph_underlay_devices'] = u_devices results['minigraph_port_indices'] = port_index_map results['minigraph_port_name_to_alias_map'] = port_name_to_alias_map results['minigraph_port_alias_to_name_map'] = port_alias_to_name_map results['minigraph_as_xml'] = mini_graph_path results['minigraph_hostname'] = hostname results['inventory_hostname'] = hostname if asic_name is None: if devices is not None: results['minigraph_console'] = get_console_info( devices, console_dev, console_port) results['minigraph_mgmt'] = get_mgmt_info(devices, mgmt_dev, mgmt_port) results['syslog_servers'] = syslog_servers results['dhcp_servers'] = dhcp_servers results['dhcpv6_servers'] = dhcpv6_servers results['ntp_servers'] = ntp_servers results['forced_mgmt_routes'] = mgmt_routes results['deployment_id'] = deployment_id if device_type in backend_device_types and vlan_sub_intfs: results['minigraph_interfaces'] = [] results['minigraph_portchannel_interfaces'] = [] is_storage_device = True results['minigraph_vlan_sub_interfaces'] = sorted( vlan_sub_intfs, key=lambda x: x['attachto']) elif device_type in backend_device_types and (resource_type is None or 'Storage' in resource_type): results['minigraph_interfaces'] = [] results['minigraph_portchannel_interfaces'] = [] is_storage_device = True for intf in phyport_intfs: intf['attachto'] = intf[ 'attachto'] + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID intf['vlan'] = VLAN_SUB_INTERFACE_VLAN_ID vlan_sub_intfs.append(intf) for pc_intf in pc_intfs: pc_intf['attachto'] = pc_intf[ 'attachto'] + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID pc_intf['vlan'] = VLAN_SUB_INTERFACE_VLAN_ID vlan_sub_intfs.append(pc_intf) results['minigraph_vlan_sub_interfaces'] = sorted( vlan_sub_intfs, key=lambda x: x['attachto']) elif resource_type is not None and 'Storage' in resource_type: is_storage_device = True if is_storage_device: results['minigraph_device_metadata']['storage_device'] = "true" return results
def parse_dpg(dpg, hname): def _parse_intf(intfname, ipprefix): ipn = ipaddress.IPNetwork(ipprefix) ipaddr, prefix_len, addr_bits = ipn.ip, ipn.prefixlen, ipn.max_prefixlen subnet = ipaddress.IPNetwork(str(ipn.network) + '/' + str(prefix_len)) ipmask = ipn.netmask intf = { 'addr': ipaddr, 'subnet': subnet, 'attachto': intfname, 'prefixlen': int(prefix_len) } if isinstance(ipn, ipaddress.IPv4Network): intf['mask'] = ipmask else: intf['mask'] = str(prefix_len) # TODO: remove peer_addr after dependency removed ipaddr_val = int(ipn.ip) peer_addr_val = None if int(prefix_len) == addr_bits - 2: if ipaddr_val & 0x3 == 1: peer_addr_val = ipaddr_val + 1 else: peer_addr_val = ipaddr_val - 1 elif int(prefix_len) == addr_bits - 1: if ipaddr_val & 0x1 == 0: peer_addr_val = ipaddr_val + 1 else: peer_addr_val = ipaddr_val - 1 if peer_addr_val is not None: intf['peer_addr'] = ipaddress.IPAddress(peer_addr_val) return intf for child in dpg: hostname = child.find(str(QName(ns, "Hostname"))) if hostname.text.lower() != hname.lower(): continue ipintfs = child.find(str(QName(ns, "IPInterfaces"))) intfs = [] for ipintf in ipintfs.findall(str(QName(ns, "IPInterface"))): intfalias = ipintf.find(str(QName(ns, "AttachTo"))).text if intfalias in port_alias_to_name_map: intfname = port_alias_to_name_map[intfalias] elif intfalias in port_alias_asic_map: intfname = port_alias_asic_map[intfalias] else: intfname = intfalias ipprefix = ipintf.find(str(QName(ns, "Prefix"))).text intfs.append(_parse_intf(intfname, ipprefix)) ports[intfname] = {'name': intfname, 'alias': intfalias} lo_intfs = parse_loopback_intf(child) subintfs = child.find(str(QName(ns, "SubInterfaces"))) if subintfs is not None: for subintf in subintfs.findall(str(QName(ns, "SubInterface"))): intfalias = subintf.find(str(QName(ns, "AttachTo"))).text intfname = port_alias_to_name_map.get(intfalias, intfalias) ipprefix = subintf.find(str(QName(ns, "Prefix"))).text subintfvlan = subintf.find(str(QName(ns, "Vlan"))).text subintfname = intfname + VLAN_SUB_INTERFACE_SEPARATOR + subintfvlan intfs.append(_parse_intf(subintfname, ipprefix)) mgmtintfs = child.find(str(QName(ns, "ManagementIPInterfaces"))) mgmt_intf = None for mgmtintf in mgmtintfs.findall( str(QName(ns1, "ManagementIPInterface"))): intfname = mgmtintf.find(str(QName(ns, "AttachTo"))).text ipprefix = mgmtintf.find(str(QName(ns1, "PrefixStr"))).text mgmtipn = ipaddress.IPNetwork(ipprefix) # Ignore IPv6 management address if mgmtipn.version == 6: continue ipaddr = mgmtipn.ip prefix_len = str(mgmtipn.prefixlen) ipmask = mgmtipn.netmask gwaddr = ipaddress.IPAddress(int(mgmtipn.network) + 1) mgmt_intf = { 'addr': ipaddr, 'alias': intfname, 'prefixlen': prefix_len, 'mask': ipmask, 'gwaddr': gwaddr } pcintfs = child.find(str(QName(ns, "PortChannelInterfaces"))) pcs = {} for pcintf in pcintfs.findall(str(QName(ns, "PortChannel"))): pcintfname = pcintf.find(str(QName(ns, "Name"))).text pcintfmbr = pcintf.find(str(QName(ns, "AttachTo"))).text pcmbr_list = pcintfmbr.split(';') for i, member in enumerate(pcmbr_list): if member in port_alias_to_name_map: pcmbr_list[i] = port_alias_to_name_map[member] ports[port_alias_to_name_map[member]] = { 'name': port_alias_to_name_map[member], 'alias': member } elif member in port_alias_asic_map: pcmbr_list[i] = port_alias_asic_map[member] ports[port_alias_asic_map[member]] = { 'name': port_alias_asic_map[member], 'alias': port_name_to_alias_map[port_alias_asic_map[member]] } pcs[pcintfname] = {'name': pcintfname, 'members': pcmbr_list} pcs[pcintfname] = { 'name': pcintfname, 'members': pcmbr_list, 'namespace': '' } fallback_node = pcintf.find(str(QName(ns, "Fallback"))) if fallback_node is not None: pcs[pcintfname]['fallback'] = fallback_node.text ports.pop(pcintfname, None) vlanintfs = child.find(str(QName(ns, "VlanInterfaces"))) dhcp_servers = [] dhcpv6_servers = [] vlans = {} for vintf in vlanintfs.findall(str(QName(ns, "VlanInterface"))): vintfname = vintf.find(str(QName(ns, "Name"))).text vlanid = vintf.find(str(QName(ns, "VlanID"))).text vintfmbr = vintf.find(str(QName(ns, "AttachTo"))).text vintftype = vintf.find(str(QName(ns, "Type"))) vmbr_list = vintfmbr.split(';') vintf_node = vintf.find(str(QName(ns, "DhcpRelays"))) if vintf_node is not None and vintf_node.text is not None: vlandhcpservers = vintf_node.text else: vlandhcpservers = "" dhcp_servers = vlandhcpservers.split(";") vintf_node = vintf.find(str(QName(ns, "Dhcpv6Relays"))) if vintf_node is not None and vintf_node.text is not None: vlandhcpservers = vintf_node.text else: vlandhcpservers = "" dhcpv6_servers = vlandhcpservers.split(";") for i, member in enumerate(vmbr_list): # Skip PortChannel inside Vlan if member in pcs: continue vmbr_list[i] = port_alias_to_name_map[member] ports[port_alias_to_name_map[member]] = { 'name': port_alias_to_name_map[member], 'alias': member } vlan_attributes = { 'name': vintfname, 'members': vmbr_list, 'vlanid': vlanid } if vintftype is not None: vlan_attributes['type'] = vintftype.text vlans[vintfname] = vlan_attributes ports.pop(vintfname) aclintfs = child.find(str(QName(ns, "AclInterfaces"))) acls = {} for aclintf in aclintfs.findall(str(QName(ns, "AclInterface"))): aclname = aclintf.find(str(QName(ns, "InAcl"))).text aclattach = aclintf.find(str(QName(ns, "AttachTo"))).text.split(';') acl_intfs = [] for member in aclattach: member = member.strip() if member in pcs: acl_intfs.extend( pcs[member]['members'] ) # For ACL attaching to port channels, we break them into port channel members elif member in vlans: print( "Warning: ACL " + aclname + " is attached to a Vlan interface, which is currently not supported", file=sys.stderr) elif member in port_alias_to_name_map: acl_intfs.append(port_alias_to_name_map[member]) if acl_intfs: acls[aclname] = acl_intfs return intfs, lo_intfs, mgmt_intf, vlans, pcs, acls, dhcp_servers, dhcpv6_servers return None, None, None, None, None, None, None
def parse_asic_png(png, asic_name, hostname): neighbors = {} devices = {} port_speeds = {} for child in png: if child.tag == str(QName(ns, "DeviceInterfaceLinks")): for link in child.findall(str(QName(ns, "DeviceLinkBase"))): # Chassis internal node is used in multi-asic device or chassis minigraph # where the minigraph will contain the internal asic connectivity and # external neighbor information. The ChassisInternal node will be used to # determine if the link is internal to the device or chassis. chassis_internal_node = link.find( str(QName(ns, "ChassisInternal"))) chassis_internal = chassis_internal_node.text if chassis_internal_node is not None else "false" # If the link is an external link include the external neighbor # information in ASIC ports table if chassis_internal.lower() == "false": ext_neighbors, ext_port_speeds = parse_asic_external_link( link, asic_name, hostname) neighbors.update(ext_neighbors) port_speeds.update(ext_port_speeds) else: int_neighbors, int_port_speeds = parse_asic_internal_link( link, asic_name, hostname) neighbors.update(int_neighbors) port_speeds.update(int_port_speeds) if child.tag == str(QName(ns, "Devices")): for device in child.findall(str(QName(ns, "Device"))): lo_addr = None # don't shadow type() d_type = None mgmt_addr = None hwsku = None if str(QName(ns3, "type")) in device.attrib: d_type = device.attrib[str(QName(ns3, "type"))] for node in device: if node.tag == str(QName(ns, "Address")): lo_addr = node.find(str(QName( ns2, "IPPrefix"))).text.split('/')[0] elif node.tag == str(QName(ns, "ManagementAddress")): mgmt_addr = node.find(str(QName( ns2, "IPPrefix"))).text.split('/')[0] elif node.tag == str(QName(ns, "Hostname")): name = node.text elif node.tag == str(QName(ns, "HwSku")): hwsku = node.text devices[name] = { 'lo_addr': lo_addr, 'type': d_type, 'mgmt_addr': mgmt_addr, 'hwsku': hwsku } for k, v in neighbors.items(): v['namespace'] = asic_name return (neighbors, devices, port_speeds)
def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): """ Parse minigraph xml file. Keyword arguments: filename -- minigraph file name platform -- device platform port_config_file -- port config file name asic_name -- asic name; to parse multi-asic device minigraph to generate asic specific configuration. """ root = ET.parse(filename).getroot() mini_graph_path = filename u_neighbors = None u_devices = None hwsku = None bgp_sessions = None bgp_monitors = [] bgp_asn = None intfs = None vlan_intfs = None pc_intfs = None vlans = None vlan_members = None pcs = None mgmt_intf = None lo_intfs = None neighbors = None devices = None sub_role = None docker_routing_config_mode = "separated" port_speeds_default = {} port_speed_png = {} port_descriptions = {} console_ports = {} syslog_servers = [] dhcp_servers = [] ntp_servers = [] tacacs_servers = [] mgmt_routes = [] erspan_dst = [] bgp_peers_with_range = None deployment_id = None region = None hostname = None #hostname is the asic_name, get the asic_id from the asic_name if asic_name is not None: asic_id = get_npu_id_from_name(asic_name) else: asic_id = None hwsku_qn = QName(ns, "HwSku") hostname_qn = QName(ns, "Hostname") docker_routing_config_mode_qn = QName(ns, "DockerRoutingConfigMode") for child in root: if child.tag == str(hwsku_qn): hwsku = child.text if child.tag == str(hostname_qn): hostname = child.text if child.tag == str(docker_routing_config_mode_qn): docker_routing_config_mode = child.text (ports, alias_map, alias_asic_map) = get_port_config(hwsku=hwsku, platform=platform, port_config_file=port_config_file, asic=asic_id) port_alias_map.update(alias_map) port_alias_asic_map.update(alias_asic_map) for child in root: if asic_name is None: if child.tag == str(QName(ns, "DpgDec")): (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname) elif child.tag == str(QName(ns, "PngDec")): (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports) = parse_png(child, hostname) elif child.tag == str(QName(ns, "UngDec")): (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region) = parse_meta(child, hostname) elif child.tag == str(QName(ns, "DeviceInfos")): (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) else: if child.tag == str(QName(ns, "DpgDec")): (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, asic_name) elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name) elif child.tag == str(QName(ns, "PngDec")): (neighbors, devices, port_speed_png) = parse_asic_png(child, asic_name, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): (sub_role) = parse_asic_meta(child, asic_name) elif child.tag == str(QName(ns, "DeviceInfos")): (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) if asic_name is None: current_device = [ devices[key] for key in devices if key.lower() == hostname.lower() ][0] name = hostname else: current_device = [ devices[key] for key in devices if key.lower() == asic_name.lower() ][0] name = asic_name results = {} results['DEVICE_METADATA'] = { 'localhost': { 'bgp_asn': bgp_asn, 'deployment_id': deployment_id, 'region': region, 'docker_routing_config_mode': docker_routing_config_mode, 'hostname': name, 'hwsku': hwsku, 'type': current_device['type'] } } # for this hostname, if sub_role is defined, add sub_role in # device_metadata if sub_role is not None: current_device['sub_role'] = sub_role results['DEVICE_METADATA']['localhost']['sub_role'] = sub_role results['BGP_NEIGHBOR'] = bgp_sessions results['BGP_MONITORS'] = bgp_monitors results['BGP_PEER_RANGE'] = bgp_peers_with_range if mgmt_routes: # TODO: differentiate v4 and v6 mgmt_intf.itervalues().next()['forced_mgmt_routes'] = mgmt_routes results['MGMT_PORT'] = {} results['MGMT_INTERFACE'] = {} mgmt_intf_count = 0 mgmt_alias_reverse_mapping = {} for key in mgmt_intf: alias = key[0] if mgmt_alias_reverse_mapping.has_key(alias): name = mgmt_alias_reverse_mapping[alias] else: name = 'eth' + str(mgmt_intf_count) mgmt_intf_count += 1 mgmt_alias_reverse_mapping[alias] = name results['MGMT_PORT'][name] = {'alias': alias, 'admin_status': 'up'} if alias in port_speeds_default: results['MGMT_PORT'][name]['speed'] = port_speeds_default[alias] results['MGMT_INTERFACE'][(name, key[1])] = mgmt_intf[key] results['LOOPBACK_INTERFACE'] = {} for lo_intf in lo_intfs: results['LOOPBACK_INTERFACE'][lo_intf] = lo_intfs[lo_intf] results['LOOPBACK_INTERFACE'][lo_intf[0]] = {} results['MGMT_VRF_CONFIG'] = mvrf phyport_intfs = {} vlan_intfs = {} pc_intfs = {} vlan_invert_mapping = { v['alias']: k for k, v in vlans.items() if v.has_key('alias') } vlan_sub_intfs = {} for intf in intfs: if intf[0][0:4] == 'Vlan': vlan_intfs[intf] = {} vlan_intfs[intf[0]] = {} elif vlan_invert_mapping.has_key(intf[0]): vlan_intfs[(vlan_invert_mapping[intf[0]], intf[1])] = {} vlan_intfs[vlan_invert_mapping[intf[0]]] = {} elif intf[0][0:11] == 'PortChannel': pc_intfs[intf] = {} pc_intfs[intf[0]] = {} else: phyport_intfs[intf] = {} phyport_intfs[intf[0]] = {} results['INTERFACE'] = phyport_intfs results['VLAN_INTERFACE'] = vlan_intfs for port_name in port_speeds_default: # ignore port not in port_config.ini if not ports.has_key(port_name): continue ports.setdefault(port_name, {})['speed'] = port_speeds_default[port_name] for port_name in port_speed_png: # not consider port not in port_config.ini #If no port_config_file is found ports is empty so ignore this error if port_config_file is not None: if port_name not in ports: print >> sys.stderr, "Warning: ignore interface '%s' as it is not in the port_config.ini" % port_name continue ports.setdefault(port_name, {})['speed'] = port_speed_png[port_name] for port_name, port in ports.items(): if port.get('speed') == '100000': port['fec'] = 'rs' # set port description if parsed from deviceinfo for port_name in port_descriptions: # ignore port not in port_config.ini if not ports.has_key(port_name): continue ports.setdefault(port_name, {})['description'] = port_descriptions[port_name] for port_name, port in ports.items(): if not port.get('description'): if neighbors.has_key(port_name): # for the ports w/o description set it to neighbor name:port port['description'] = "%s:%s" % (neighbors[port_name]['name'], neighbors[port_name]['port']) else: # for the ports w/o neighbor info, set it to port alias port['description'] = port.get('alias', port_name) # set default port MTU as 9100 for port in ports.itervalues(): port['mtu'] = '9100' # asymmetric PFC is disabled by default for port in ports.itervalues(): port['pfc_asym'] = 'off' # set physical port default admin status up for port in phyport_intfs: if port[0] in ports: ports.get(port[0])['admin_status'] = 'up' for member in pc_members.keys() + vlan_members.keys(): port = ports.get(member[1]) if port: port['admin_status'] = 'up' results['PORT'] = ports results['CONSOLE_PORT'] = console_ports if port_config_file: port_set = set(ports.keys()) for (pc_name, mbr_map) in pcs.items(): # remove portchannels that contain ports not existing in port_config.ini # when port_config.ini exists if not set(mbr_map['members']).issubset(port_set): print >> sys.stderr, "Warning: ignore '%s' as part of its member interfaces is not in the port_config.ini" % pc_name del pcs[pc_name] # set default port channel MTU as 9100 and admin status up for pc in pcs.itervalues(): pc['mtu'] = '9100' pc['admin_status'] = 'up' results['PORTCHANNEL'] = pcs results['PORTCHANNEL_MEMBER'] = pc_members for pc_intf in pc_intfs.keys(): # remove portchannels not in PORTCHANNEL dictionary if isinstance(pc_intf, tuple) and pc_intf[0] not in pcs: print >> sys.stderr, "Warning: ignore '%s' interface '%s' as '%s' is not in the valid PortChannel list" % ( pc_intf[0], pc_intf[1], pc_intf[0]) del pc_intfs[pc_intf] pc_intfs.pop(pc_intf[0], None) results['PORTCHANNEL_INTERFACE'] = pc_intfs if current_device['type'] in backend_device_types: del results['INTERFACE'] del results['PORTCHANNEL_INTERFACE'] for intf in phyport_intfs.keys(): if isinstance(intf, tuple): intf_info = list(intf) intf_info[0] = intf_info[ 0] + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID sub_intf = tuple(intf_info) vlan_sub_intfs[sub_intf] = {} else: sub_intf = intf + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID vlan_sub_intfs[sub_intf] = {"admin_status": "up"} for pc_intf in pc_intfs.keys(): if isinstance(pc_intf, tuple): pc_intf_info = list(pc_intf) pc_intf_info[0] = pc_intf_info[ 0] + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID sub_intf = tuple(pc_intf_info) vlan_sub_intfs[sub_intf] = {} else: sub_intf = pc_intf + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID vlan_sub_intfs[sub_intf] = {"admin_status": "up"} results['VLAN_SUB_INTERFACE'] = vlan_sub_intfs results['VLAN'] = vlans results['VLAN_MEMBER'] = vlan_members for nghbr in neighbors.keys(): # remove port not in port_config.ini if nghbr not in ports: if port_config_file is not None: print >> sys.stderr, "Warning: ignore interface '%s' in DEVICE_NEIGHBOR as it is not in the port_config.ini" % nghbr del neighbors[nghbr] results['DEVICE_NEIGHBOR'] = neighbors if asic_name is None: results['DEVICE_NEIGHBOR_METADATA'] = { key: devices[key] for key in devices if key.lower() != hostname.lower() } else: results['DEVICE_NEIGHBOR_METADATA'] = { key: devices[key] for key in devices if key in {device['name'] for device in neighbors.values()} } results['SYSLOG_SERVER'] = dict((item, {}) for item in syslog_servers) results['DHCP_SERVER'] = dict((item, {}) for item in dhcp_servers) results['NTP_SERVER'] = dict((item, {}) for item in ntp_servers) results['TACPLUS_SERVER'] = dict((item, { 'priority': '1', 'tcp_port': '49' }) for item in tacacs_servers) results['ACL_TABLE'] = filter_acl_mirror_table_bindings( acls, neighbors, pcs) results['FEATURE'] = {'telemetry': {'status': 'enabled'}} results['TELEMETRY'] = { 'gnmi': { 'client_auth': 'true', 'port': '50051', 'log_level': '2' }, 'certs': { 'server_crt': '/etc/sonic/telemetry/streamingtelemetryserver.cer', 'server_key': '/etc/sonic/telemetry/streamingtelemetryserver.key', 'ca_crt': '/etc/sonic/telemetry/dsmsroot.cer' } } results['RESTAPI'] = { 'config': { 'client_auth': 'true', 'allow_insecure': 'false', 'log_level': 'trace' }, 'certs': { 'server_crt': '/etc/sonic/credentials/restapiserver.crt', 'server_key': '/etc/sonic/credentials/restapiserver.key', 'client_ca_crt': '/etc/sonic/credentials/restapiclient.crt', 'client_crt_cname': 'client.restapi.sonic' } } # Do not configure the minigraph's mirror session, which is currently unused # mirror_sessions = {} # if erspan_dst: # lo_addr = '0.0.0.0' # for lo in lo_intfs: # lo_network = ipaddress.IPNetwork(lo[1]) # if lo_network.version == 4: # lo_addr = str(lo_network.ip) # break # count = 0 # for dst in erspan_dst: # mirror_sessions['everflow{}'.format(count)] = {"dst_ip": dst, "src_ip": lo_addr} # count += 1 # results['MIRROR_SESSION'] = mirror_sessions # Special parsing for spine chassis frontend routers if current_device['type'] == spine_chassis_frontend_role: parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_members, devices) return results
def SubElement(self, parent, name): ns, tag = name.split(':') return etree.SubElement(parent, QName(self.ns[ns], tag))
def test_next_node(self): ctx = XmlContext() with self.assertRaises(NotImplementedError): XmlNode(0).next_node(QName("foo"), 0, ctx)
XmpContainer = namedtuple('XmpContainer', ['rdf_type', 'py_type', 'insert_fn']) class AltList(list): pass XMP_CONTAINERS = [ XmpContainer('Alt', AltList, AltList.append), XmpContainer('Bag', set, set.add), XmpContainer('Seq', list, list.append), ] LANG_ALTS = frozenset([ str(QName(XMP_NS_DC, 'title')), str(QName(XMP_NS_DC, 'description')), str(QName(XMP_NS_DC, 'rights')), str(QName(XMP_NS_XMP_RIGHTS, 'UsageTerms')), ]) # These are the illegal characters in XML 1.0. (XML 1.1 is a bit more permissive, # but we'll be strict to ensure wider compatibility.) re_xml_illegal_chars = re.compile( r"(?u)[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u10000-\u10FFFF]") re_xml_illegal_bytes = re.compile(br"[^\x09\x0A\x0D\x20-\xFF]|�") def encode_pdf_date(d: datetime) -> str: """Encode Python datetime object as PDF date string
class ElementNodeTests(TestCase): @mock.patch.object(ParserUtils, "bind_element_wild_text") @mock.patch.object(ParserUtils, "bind_element_children") @mock.patch.object(ParserUtils, "bind_element_text") @mock.patch.object(ParserUtils, "bind_element_attrs") def test_parse_element( self, mock_bind_element_attrs, mock_bind_element_text, mock_bind_element_children, mock_bind_element_wild_text, ): def add_attr(x, *args): x["a"] = 1 def add_text(x, *args): x["b"] = 2 def add_child(x, *args): x["c"] = 3 def add_wild_text(x, *args): x["d"] = 4 mock_bind_element_attrs.side_effect = add_attr mock_bind_element_text.side_effect = add_text mock_bind_element_children.side_effect = add_child mock_bind_element_wild_text.side_effect = add_wild_text ctx = XmlContext() meta = ctx.build(Foo) ele = Element("foo") pool = [1, 2, 3] node = ElementNode(position=0, meta=meta, config=ParserConfig()) qname, obj = node.parse_element(ele, pool) self.assertEqual(QName(ele.tag), qname) self.assertEqual(Foo(1, 2, 3, 4), obj) mock_bind_element_attrs.assert_called_once_with(mock.ANY, meta, ele) mock_bind_element_text.assert_called_once_with(mock.ANY, meta, ele) mock_bind_element_children.assert_called_once_with( mock.ANY, meta, 0, pool) mock_bind_element_wild_text.assert_called_once_with( mock.ANY, meta, ele) @mock.patch.object(ParserUtils, "parse_xsi_type", return_value=QName("foo")) @mock.patch.object(XmlContext, "fetch") def test_next_node_when_given_qname_matches_dataclass_var( self, mock_ctx_fetch, mock_element_xsi_type): ele = Element("a") ctx = XmlContext() cfg = ParserConfig() var = XmlElement(name="a", qname=QName("a"), types=[Foo], dataclass=True) meta = XmlMeta( name="foo", clazz=None, qname=QName("foo"), source_qname=QName("foo"), nillable=False, vars=[var], ) xsi_type = QName("foo") namespace = meta.qname.namespace mock_ctx_fetch.return_value = replace(meta) mock_element_xsi_type.return_value = xsi_type node = ElementNode(position=0, meta=meta, config=cfg) actual = node.next_node(ele, 10, ctx) self.assertIsInstance(actual, ElementNode) self.assertEqual(10, actual.position) self.assertIs(mock_ctx_fetch.return_value, actual.meta) mock_ctx_fetch.assert_called_once_with(var.clazz, namespace, xsi_type) def test_next_node_when_given_qname_matches_any_element_var(self): ele = Element("a") ctx = XmlContext() cfg = ParserConfig() var = XmlWildcard(name="a", qname=QName("a"), types=[], dataclass=False) meta = XmlMeta( name="foo", clazz=None, qname=QName("foo"), source_qname=QName("foo"), nillable=False, vars=[var], ) node = ElementNode(position=0, meta=meta, config=cfg) actual = node.next_node(ele, 10, ctx) self.assertIsInstance(actual, WildcardNode) self.assertEqual(10, actual.position) self.assertEqual(var.qname, actual.qname) def test_next_node_when_given_qname_matches_primitive_var(self): ele = Element("a") ctx = XmlContext() cfg = ParserConfig() var = XmlText(name="a", qname=QName("a"), types=[int], default=100) meta = XmlMeta( name="foo", clazz=None, qname=QName("foo"), source_qname=QName("foo"), nillable=False, vars=[var], ) node = ElementNode(position=0, meta=meta, config=cfg) actual = node.next_node(ele, 10, ctx) self.assertIsInstance(actual, PrimitiveNode) self.assertEqual(10, actual.position) self.assertEqual(var, actual.var) def test_next_node_when_given_qname_does_not_match_any_var(self): ele = Element("nope") ctx = XmlContext() cfg = ParserConfig() meta = XmlMeta( name="foo", clazz=None, qname=QName("foo"), source_qname=QName("foo"), nillable=False, ) node = ElementNode(position=0, meta=meta, config=cfg) with self.assertRaises(XmlContextError) as cm: node.next_node(ele, 10, ctx) self.assertEqual("foo does not support mixed content: nope", str(cm.exception)) def test_next_node_when_config_fail_on_unknown_properties_is_false(self): ele = Element("nope") ctx = XmlContext() cfg = ParserConfig(fail_on_unknown_properties=False) meta = XmlMeta( name="foo", clazz=None, qname=QName("foo"), source_qname=QName("foo"), nillable=False, ) node = ElementNode(position=0, meta=meta, config=cfg) actual = node.next_node(ele, 10, ctx) self.assertEqual(SkipNode(position=10), actual)
def is_text_property(property): tag = QName(property).localname return tag in ['bstr', 'lpstr', 'lpwstr']
def parse_dpg(dpg, hname): for child in dpg: hostname = child.find(str(QName(ns, "Hostname"))) if hostname.text != hname: continue ipintfs = child.find(str(QName(ns, "IPInterfaces"))) intfs = [] for ipintf in ipintfs.findall(str(QName(ns, "IPInterface"))): intfalias = ipintf.find(str(QName(ns, "AttachTo"))).text if port_alias_to_name_map.has_key(intfalias): intfname = port_alias_to_name_map[intfalias] else: intfname = intfalias ipprefix = ipintf.find(str(QName(ns, "Prefix"))).text ipn = ipaddress.IPNetwork(ipprefix) ipaddr = ipn.ip prefix_len = ipn.prefixlen addr_bits = ipn.max_prefixlen subnet = ipaddress.IPNetwork( str(ipn.network) + '/' + str(prefix_len)) ipmask = ipn.netmask intf = {'addr': ipaddr, 'subnet': subnet} if isinstance(ipn, ipaddress.IPv4Network): intf['mask'] = ipmask else: intf['mask'] = str(prefix_len) intf.update({'attachto': intfname, 'prefixlen': int(prefix_len)}) # TODO: remove peer_addr after dependency removed ipaddr_val = int(ipn.ip) peer_addr_val = None if int(prefix_len) == addr_bits - 2: if ipaddr_val & 0x3 == 1: peer_addr_val = ipaddr_val + 1 else: peer_addr_val = ipaddr_val - 1 elif int(prefix_len) == addr_bits - 1: if ipaddr_val & 0x1 == 0: peer_addr_val = ipaddr_val + 1 else: peer_addr_val = ipaddr_val - 1 if peer_addr_val is not None: intf['peer_addr'] = ipaddress.IPAddress(peer_addr_val) intfs.append(intf) ports[intfname] = {'name': intfname, 'alias': intfalias} lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) lo_intfs = [] for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): intfname = lointf.find(str(QName(ns, "AttachTo"))).text ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text ipn = ipaddress.IPNetwork(ipprefix) ipaddr = ipn.ip prefix_len = ipn.prefixlen ipmask = ipn.netmask lo_intf = { 'name': intfname, 'addr': ipaddr, 'prefixlen': prefix_len } if isinstance(ipn, ipaddress.IPv4Network): lo_intf['mask'] = ipmask else: lo_intf['mask'] = str(prefix_len) lo_intfs.append(lo_intf) mgmtintfs = child.find(str(QName(ns, "ManagementIPInterfaces"))) mgmt_intf = None for mgmtintf in mgmtintfs.findall( str(QName(ns1, "ManagementIPInterface"))): intfname = mgmtintf.find(str(QName(ns, "AttachTo"))).text ipprefix = mgmtintf.find(str(QName(ns1, "PrefixStr"))).text mgmtipn = ipaddress.IPNetwork(ipprefix) # Ignore IPv6 management address if mgmtipn.version == 6: continue ipaddr = mgmtipn.ip prefix_len = str(mgmtipn.prefixlen) ipmask = mgmtipn.netmask gwaddr = ipaddress.IPAddress(int(mgmtipn.network) + 1) mgmt_intf = { 'addr': ipaddr, 'alias': intfname, 'prefixlen': prefix_len, 'mask': ipmask, 'gwaddr': gwaddr } pcintfs = child.find(str(QName(ns, "PortChannelInterfaces"))) pc_intfs = [] pcs = {} for pcintf in pcintfs.findall(str(QName(ns, "PortChannel"))): pcintfname = pcintf.find(str(QName(ns, "Name"))).text pcintfmbr = pcintf.find(str(QName(ns, "AttachTo"))).text pcmbr_list = pcintfmbr.split(';', 1) for i, member in enumerate(pcmbr_list): pcmbr_list[i] = port_alias_to_name_map[member] ports[port_alias_to_name_map[member]] = { 'name': port_alias_to_name_map[member], 'alias': member } pcs[pcintfname] = {'name': pcintfname, 'members': pcmbr_list} fallback_node = pcintf.find(str(QName(ns, "Fallback"))) if fallback_node is not None: pcs[pcintfname]['fallback'] = fallback_node.text ports.pop(pcintfname) vlanintfs = child.find(str(QName(ns, "VlanInterfaces"))) vlan_intfs = [] dhcp_servers = [] vlans = {} for vintf in vlanintfs.findall(str(QName(ns, "VlanInterface"))): vintfname = vintf.find(str(QName(ns, "Name"))).text vlanid = vintf.find(str(QName(ns, "VlanID"))).text vintfmbr = vintf.find(str(QName(ns, "AttachTo"))).text vmbr_list = vintfmbr.split(';') vintf_node = vintf.find(str(QName(ns, "DhcpRelays"))) if vintf_node is not None and vintf_node.text is not None: vlandhcpservers = vintf_node.text else: vlandhcpservers = "" dhcp_servers = vlandhcpservers.split(";") for i, member in enumerate(vmbr_list): vmbr_list[i] = port_alias_to_name_map[member] ports[port_alias_to_name_map[member]] = { 'name': port_alias_to_name_map[member], 'alias': member } vlan_attributes = { 'name': vintfname, 'members': vmbr_list, 'vlanid': vlanid } vlans[vintfname] = vlan_attributes ports.pop(vintfname) aclintfs = child.find(str(QName(ns, "AclInterfaces"))) acls = {} for aclintf in aclintfs.findall(str(QName(ns, "AclInterface"))): aclname = aclintf.find(str(QName(ns, "InAcl"))).text aclattach = aclintf.find(str(QName(ns, "AttachTo"))).text.split(';') acl_intfs = [] for member in aclattach: member = member.strip() if pcs.has_key(member): acl_intfs.extend( pcs[member]['members'] ) # For ACL attaching to port channels, we break them into port channel members elif vlans.has_key(member): print >> sys.stderr, "Warning: ACL " + aclname + " is attached to a Vlan interface, which is currently not supported" elif port_alias_to_name_map.has_key(member): acl_intfs.append(port_alias_to_name_map[member]) if acl_intfs: acls[aclname] = acl_intfs return intfs, lo_intfs, mgmt_intf, vlans, pcs, acls, dhcp_servers return None, None, None, None, None, None
def parse_xml(filename, platform=None, port_config_file=None): root = ET.parse(filename).getroot() mini_graph_path = filename u_neighbors = None u_devices = None hwsku = None bgp_sessions = None bgp_asn = None intfs = None vlan_intfs = None pc_intfs = None vlans = None vlan_members = None pcs = None mgmt_intf = None lo_intf = None neighbors = None devices = None hostname = None docker_routing_config_mode = "separated" port_speeds_default = {} port_speed_png = {} port_descriptions = {} console_ports = {} syslog_servers = [] dhcp_servers = [] ntp_servers = [] tacacs_servers = [] mgmt_routes = [] erspan_dst = [] bgp_peers_with_range = None deployment_id = None hwsku_qn = QName(ns, "HwSku") hostname_qn = QName(ns, "Hostname") docker_routing_config_mode_qn = QName(ns, "DockerRoutingConfigMode") for child in root: if child.tag == str(hwsku_qn): hwsku = child.text if child.tag == str(hostname_qn): hostname = child.text if child.tag == str(docker_routing_config_mode_qn): docker_routing_config_mode = child.text (ports, alias_map) = get_port_config(hwsku, platform, port_config_file) port_alias_map.update(alias_map) for child in root: if child.tag == str(QName(ns, "DpgDec")): (intfs, lo_intfs, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_asn, bgp_peers_with_range) = parse_cpg(child, hostname) elif child.tag == str(QName(ns, "PngDec")): (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports) = parse_png(child, hostname) elif child.tag == str(QName(ns, "UngDec")): (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id) = parse_meta(child, hostname) elif child.tag == str(QName(ns, "DeviceInfos")): (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) current_device = [ devices[key] for key in devices if key.lower() == hostname.lower() ][0] results = {} results['DEVICE_METADATA'] = { 'localhost': { 'bgp_asn': bgp_asn, 'deployment_id': deployment_id, 'docker_routing_config_mode': docker_routing_config_mode, 'hostname': hostname, 'hwsku': hwsku, 'type': current_device['type'] } } results['BGP_NEIGHBOR'] = bgp_sessions results['BGP_PEER_RANGE'] = bgp_peers_with_range if mgmt_routes: # TODO: differentiate v4 and v6 mgmt_intf.itervalues().next()['forced_mgmt_routes'] = mgmt_routes results['MGMT_PORT'] = {} results['MGMT_INTERFACE'] = {} mgmt_intf_count = 0 mgmt_alias_reverse_mapping = {} for key in mgmt_intf: alias = key[0] if mgmt_alias_reverse_mapping.has_key(alias): name = mgmt_alias_reverse_mapping[alias] else: name = 'eth' + str(mgmt_intf_count) mgmt_intf_count += 1 mgmt_alias_reverse_mapping[alias] = name results['MGMT_PORT'][name] = {'alias': alias, 'admin_status': 'up'} if alias in port_speeds_default: results['MGMT_PORT'][name]['speed'] = port_speeds_default[alias] results['MGMT_INTERFACE'][(name, key[1])] = mgmt_intf[key] results['LOOPBACK_INTERFACE'] = lo_intfs phyport_intfs = {} vlan_intfs = {} pc_intfs = {} vlan_invert_mapping = { v['alias']: k for k, v in vlans.items() if v.has_key('alias') } for intf in intfs: if intf[0][0:4] == 'Vlan': vlan_intfs[intf] = {} vlan_intfs[intf[0]] = {} elif vlan_invert_mapping.has_key(intf[0]): vlan_intfs[(vlan_invert_mapping[intf[0]], intf[1])] = {} vlan_intfs[vlan_invert_mapping[intf[0]]] = {} elif intf[0][0:11] == 'PortChannel': pc_intfs[intf] = {} pc_intfs[intf[0]] = {} else: phyport_intfs[intf] = {} phyport_intfs[intf[0]] = {} results['INTERFACE'] = phyport_intfs results['VLAN_INTERFACE'] = vlan_intfs for port_name in port_speeds_default: # ignore port not in port_config.ini if not ports.has_key(port_name): continue ports.setdefault(port_name, {})['speed'] = port_speeds_default[port_name] for port_name in port_speed_png: # not consider port not in port_config.ini if port_name not in ports: print >> sys.stderr, "Warning: ignore interface '%s' as it is not in the port_config.ini" % port_name continue ports.setdefault(port_name, {})['speed'] = port_speed_png[port_name] for port_name, port in ports.items(): if port.get('speed') == '100000': port['fec'] = 'rs' # set port description if parsed from deviceinfo for port_name in port_descriptions: # ignore port not in port_config.ini if not ports.has_key(port_name): continue ports.setdefault(port_name, {})['description'] = port_descriptions[port_name] for port_name, port in ports.items(): if not port.get('description'): if neighbors.has_key(port_name): # for the ports w/o description set it to neighbor name:port port['description'] = "%s:%s" % (neighbors[port_name]['name'], neighbors[port_name]['port']) else: # for the ports w/o neighbor info, set it to port alias port['description'] = port.get('alias', port_name) # set default port MTU as 9100 for port in ports.itervalues(): port['mtu'] = '9100' # asymmetric PFC is disabled by default for port in ports.itervalues(): port['pfc_asym'] = 'off' # set physical port default admin status up for port in phyport_intfs: if port[0] in ports: ports.get(port[0])['admin_status'] = 'up' for member in pc_members.keys() + vlan_members.keys(): port = ports.get(member[1]) if port: port['admin_status'] = 'up' results['PORT'] = ports results['CONSOLE_PORT'] = console_ports if port_config_file: port_set = set(ports.keys()) for (pc_name, mbr_map) in pcs.items(): # remove portchannels that contain ports not existing in port_config.ini # when port_config.ini exists if not set(mbr_map['members']).issubset(port_set): print >> sys.stderr, "Warning: ignore '%s' as part of its member interfaces is not in the port_config.ini" % pc_name del pcs[pc_name] # set default port channel MTU as 9100 and admin status up for pc in pcs.itervalues(): pc['mtu'] = '9100' pc['admin_status'] = 'up' results['PORTCHANNEL'] = pcs results['PORTCHANNEL_MEMBER'] = pc_members for pc_intf in pc_intfs.keys(): # remove portchannels not in PORTCHANNEL dictionary if isinstance(pc_intf, tuple) and pc_intf[0] not in pcs: print >> sys.stderr, "Warning: ignore '%s' interface '%s' as '%s' is not in the valid PortChannel list" % ( pc_intf[0], pc_intf[1], pc_intf[0]) del pc_intfs[pc_intf] pc_intfs.pop(pc_intf[0], None) results['PORTCHANNEL_INTERFACE'] = pc_intfs results['VLAN'] = vlans results['VLAN_MEMBER'] = vlan_members for nghbr in neighbors.keys(): # remove port not in port_config.ini if nghbr not in ports: print >> sys.stderr, "Warning: ignore interface '%s' in DEVICE_NEIGHBOR as it is not in the port_config.ini" % nghbr del neighbors[nghbr] results['DEVICE_NEIGHBOR'] = neighbors results['DEVICE_NEIGHBOR_METADATA'] = { key: devices[key] for key in devices if key.lower() != hostname.lower() } results['SYSLOG_SERVER'] = dict((item, {}) for item in syslog_servers) results['DHCP_SERVER'] = dict((item, {}) for item in dhcp_servers) results['NTP_SERVER'] = dict((item, {}) for item in ntp_servers) results['TACPLUS_SERVER'] = dict((item, { 'priority': '1', 'tcp_port': '49' }) for item in tacacs_servers) results['ACL_TABLE'] = acls mirror_sessions = {} if erspan_dst: lo_addr = '0.0.0.0' for lo in lo_intfs: lo_network = ipaddress.IPNetwork(lo[1]) if lo_network.version == 4: lo_addr = str(lo_network.ip) break count = 0 for dst in erspan_dst: mirror_sessions['everflow{}'.format(count)] = { "dst_ip": dst, "src_ip": lo_addr } count += 1 results['MIRROR_SESSION'] = mirror_sessions # Special parsing for spine chassis frontend routers if current_device['type'] == spine_chassis_frontend_role: parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_members, devices) return results
def parse_cpg(cpg, hname): bgp_sessions = [] myasn = None bgp_peers_with_range = [] for child in cpg: tag = child.tag if tag == str(QName(ns, "PeeringSessions")): for session in child.findall(str(QName(ns, "BGPSession"))): start_router = session.find(str(QName(ns, "StartRouter"))).text start_peer = session.find(str(QName(ns, "StartPeer"))).text end_router = session.find(str(QName(ns, "EndRouter"))).text end_peer = session.find(str(QName(ns, "EndPeer"))).text if end_router == hname: bgp_sessions.append({ 'name': start_router, 'addr': start_peer, 'peer_addr': end_peer }) else: bgp_sessions.append({ 'name': end_router, 'addr': end_peer, 'peer_addr': start_peer }) elif child.tag == str(QName(ns, "Routers")): for router in child.findall(str(QName(ns1, "BGPRouterDeclaration"))): asn = router.find(str(QName(ns1, "ASN"))).text hostname = router.find(str(QName(ns1, "Hostname"))).text if hostname == hname: myasn = int(asn) peers = router.find(str(QName(ns1, "Peers"))) for bgpPeer in peers.findall(str(QName(ns, "BGPPeer"))): addr = bgpPeer.find(str(QName(ns, "Address"))).text if bgpPeer.find(str(QName(ns1, "PeersRange"))) is not None: name = bgpPeer.find(str(QName(ns1, "Name"))).text ip_range = bgpPeer.find( str(QName(ns1, "PeersRange"))).text ip_range_group = ip_range.split( ';') if ip_range and ip_range != "" else [] bgp_peers_with_range.append({ 'name': name, 'ip_range': ip_range_group }) else: for bgp_session in bgp_sessions: if hostname == bgp_session['name']: bgp_session['asn'] = int(asn) return bgp_sessions, myasn, bgp_peers_with_range
def parse_dpg(dpg, hname): for child in dpg: hostname = child.find(str(QName(ns, "Hostname"))) if hostname.text != hname: continue ipintfs = child.find(str(QName(ns, "IPInterfaces"))) intfs = [] vlan_map = {} for ipintf in ipintfs.findall(str(QName(ns, "IPInterface"))): intfname = ipintf.find(str(QName(ns, "AttachTo"))).text ipprefix = ipintf.find(str(QName(ns, "Prefix"))).text ipn = ipaddress.IPNetwork(ipprefix) ipaddr = ipn.ip prefix_len = ipn.prefixlen addr_bits = ipn.max_prefixlen subnet = ipaddress.IPNetwork(str(ipn.network) + '/' + str(prefix_len)) ipmask = ipn.netmask intf = {'addr': ipaddr, 'subnet': subnet} if isinstance(ipn, ipaddress.IPv4Network): intf['mask'] = ipmask else: intf['mask'] = str(prefix_len) if intfname[0:4] == "Vlan": if intfname in vlan_map: vlan_map[intfname].append(intf) else: vlan_map[intfname] = [intf] else: intf.update({'name': intfname, 'prefixlen': int(prefix_len)}) if port_alias_map.has_key(intfname): intf['alias'] = port_alias_map[intfname] else: intf['alias'] = intfname # TODO: remove peer_addr after dependency removed ipaddr_val = int(ipn.ip) peer_addr_val = None if int(prefix_len) == addr_bits - 2: if ipaddr_val & 0x3 == 1: peer_addr_val = ipaddr_val + 1 else: peer_addr_val = ipaddr_val - 1 elif int(prefix_len) == addr_bits - 1: if ipaddr_val & 0x1 == 0: peer_addr_val = ipaddr_val + 1 else: peer_addr_val = ipaddr_val - 1 if peer_addr_val is not None: intf['peer_addr'] = ipaddress.IPAddress(peer_addr_val) intfs.append(intf) pcintfs = child.find(str(QName(ns, "PortChannelInterfaces"))) pc_intfs = [] for pcintf in pcintfs.findall(str(QName(ns, "PortChannel"))): pcintfname = pcintf.find(str(QName(ns, "Name"))).text pcintfmbr = pcintf.find(str(QName(ns, "AttachTo"))).text pcmbr_list = pcintfmbr.split(';', 1) pc_intfs.append({'name': pcintfname, 'members': pcmbr_list}) lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) lo_intfs = [] for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): intfname = lointf.find(str(QName(ns, "AttachTo"))).text ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text ipn = ipaddress.IPNetwork(ipprefix) ipaddr = ipn.ip prefix_len = ipn.prefixlen ipmask = ipn.netmask lo_intf = {'name': intfname, 'addr': ipaddr, 'prefixlen': prefix_len} if isinstance(ipn, ipaddress.IPv4Network): lo_intf['mask'] = ipmask else: lo_intf['mask'] = str(prefix_len) lo_intfs.append(lo_intf) mgmtintfs = child.find(str(QName(ns, "ManagementIPInterfaces"))) mgmt_intf = None for mgmtintf in mgmtintfs.findall(str(QName(ns1, "ManagementIPInterface"))): ipprefix = mgmtintf.find(str(QName(ns1, "PrefixStr"))).text mgmtipn = ipaddress.IPNetwork(ipprefix) ipaddr = mgmtipn.ip prefix_len = str(mgmtipn.prefixlen) ipmask = mgmtipn.netmask gwaddr = ipaddress.IPAddress(int(mgmtipn.network) + 1) mgmt_intf = {'addr': ipaddr, 'prefixlen': prefix_len, 'mask': ipmask, 'gwaddr': gwaddr} vlanintfs = child.find(str(QName(ns, "VlanInterfaces"))) vlan_intfs = [] for vintf in vlanintfs.findall(str(QName(ns, "VlanInterface"))): vintfname = vintf.find(str(QName(ns, "Name"))).text vlanid = vintf.find(str(QName(ns, "VlanID"))).text vintfmbr = vintf.find(str(QName(ns, "AttachTo"))).text vmbr_list = vintfmbr.split(';') vlan_attributes = {'name': vintfname, 'members': vmbr_list, 'vlanid': vlanid} for addrtuple in vlan_map.get(vintfname, []): vlan_attributes.update(addrtuple) vlan_intfs.append(copy.deepcopy(vlan_attributes)) return intfs, lo_intfs, mgmt_intf, vlan_intfs, pc_intfs return None, None, None, None, None
def parse_xml(filename, hostname): mini_graph_path, root = reconcile_mini_graph_locations(filename, hostname) u_neighbors = None u_devices = None hwsku = None bgp_sessions = None bgp_asn = None intfs = None vlan_intfs = None pc_intfs = None vlans = None pcs = None mgmt_intf = None lo_intf = None neighbors = None devices = None hostname = None syslog_servers = [] dhcp_servers = [] ntp_servers = [] mgmt_routes = [] bgp_peers_with_range = [] deployment_id = None hwsku_qn = QName(ns, "HwSku") hostname_qn = QName(ns, "Hostname") for child in root: if child.tag == str(hwsku_qn): hwsku = child.text if child.tag == str(hostname_qn): hostname = child.text global port_alias_to_name_map if hwsku == "Force10-S6000": for i in range(0, 128, 4): port_alias_to_name_map["fortyGigE0/%d" % i] = "Ethernet%d" % i elif hwsku == "Force10-S6100": for i in range(0, 4): for j in range(0, 16): port_alias_to_name_map["fortyGigE1/%d/%d" % (i + 1, j + 1)] = "Ethernet%d" % (i * 16 + j) elif hwsku == "Force10-Z9100": for i in range(0, 128, 4): port_alias_to_name_map["hundredGigE1/%d" % (i / 4 + 1)] = "Ethernet%d" % i elif hwsku == "Arista-7050-QX32": for i in range(1, 25): port_alias_to_name_map["Ethernet%d/1" % i] = "Ethernet%d" % ((i - 1) * 4) for i in range(25, 33): port_alias_to_name_map["Ethernet%d" % i] = "Ethernet%d" % ((i - 1) * 4) elif hwsku == "Arista-7050-QX-32S": for i in range(5, 29): port_alias_to_name_map["Ethernet%d/1" % i] = "Ethernet%d" % ((i - 5) * 4) for i in range(29, 37): port_alias_to_name_map["Ethernet%d" % i] = "Ethernet%d" % ((i - 5) * 4) elif hwsku == "Arista-7260CX3-C64" or hwsku == "Arista-7170-64C": for i in range(1, 65): port_alias_to_name_map["Ethernet%d/1" % i] = "Ethernet%d" % ((i - 1) * 4) elif hwsku == "Arista-7060CX-32S-C32" or hwsku == "Arista-7060CX-32S-Q32" or hwsku == "Arista-7060CX-32S-C32-T1" or hwsku == "Arista-7170-32CD-C32": for i in range(1, 33): port_alias_to_name_map["Ethernet%d/1" % i] = "Ethernet%d" % ((i - 1) * 4) elif hwsku == "Mellanox-SN2700-D48C8": # 50G ports s50G_ports = [x for x in range(0, 24, 2)] + [ x for x in range(40, 88, 2) ] + [x for x in range(104, 128, 2)] # 100G ports s100G_ports = [x for x in range(24, 40, 4) ] + [x for x in range(88, 104, 4)] for i in s50G_ports: alias = "etp%d" % (i / 4 + 1) + ("a" if i % 4 == 0 else "b") port_alias_to_name_map[alias] = "Ethernet%d" % i for i in s100G_ports: alias = "etp%d" % (i / 4 + 1) port_alias_to_name_map[alias] = "Ethernet%d" % i elif hwsku == "Mellanox-SN2700" or hwsku == "ACS-MSN2700": for i in range(1, 33): port_alias_to_name_map["etp%d" % i] = "Ethernet%d" % ((i - 1) * 4) elif hwsku == "Arista-7060CX-32S-D48C8": # All possible breakout 50G port numbers: all_ports = [x for x in range(1, 33)] # 100G ports s100G_ports = [x for x in range(7, 11)] s100G_ports += [x for x in range(23, 27)] port_alias_to_name_map = port_alias_to_name_map_50G( all_ports, s100G_ports) elif hwsku == "Arista-7260CX3-D108C8": # All possible breakout 50G port numbers: all_ports = [x for x in range(1, 65)] # 100G ports s100G_ports = [x for x in range(13, 21)] port_alias_to_name_map = port_alias_to_name_map_50G( all_ports, s100G_ports) elif hwsku == "INGRASYS-S9100-C32": for i in range(1, 33): port_alias_to_name_map["Ethernet%d/1" % i] = "Ethernet%d" % ((i - 1) * 4) elif hwsku == "INGRASYS-S9100-C32" or hwsku == "INGRASYS-S9130-32X" or hwsku == "INGRASYS-S8810-32Q": for i in range(1, 33): port_alias_to_name_map["Ethernet%d/1" % i] = "Ethernet%d" % ((i - 1) * 4) elif hwsku == "INGRASYS-S8900-54XC": for i in range(1, 49): port_alias_to_name_map["Ethernet%d" % i] = "Ethernet%d" % (i - 1) for i in range(49, 55): port_alias_to_name_map["Ethernet%d/1" % i] = "Ethernet%d" % ((i - 49) * 4 + 48) elif hwsku == "INGRASYS-S8900-64XC": for i in range(1, 49): port_alias_to_name_map["Ethernet%d" % i] = "Ethernet%d" % (i - 1) for i in range(49, 65): port_alias_to_name_map["Ethernet%d/1" % i] = "Ethernet%d" % ((i - 49) * 4 + 48) elif hwsku == "Accton-AS7712-32X": for i in range(1, 33): port_alias_to_name_map["hundredGigE%d" % i] = "Ethernet%d" % ((i - 1) * 4) elif hwsku == "Celestica-DX010-C32": for i in range(1, 33): port_alias_to_name_map["etp%d" % i] = "Ethernet%d" % ((i - 1) * 4) elif hwsku == "Seastone-DX010": for i in range(1, 33): port_alias_to_name_map["Eth%d" % i] = "Ethernet%d" % ((i - 1) * 4) elif hwsku == "Celestica-E1031-T48S4": for i in range(1, 53): port_alias_to_name_map["etp%d" % i] = "Ethernet%d" % ((i - 1)) elif hwsku == "et6448m": for i in range(0, 52): port_alias_to_name_map["Ethernet%d" % i] = "Ethernet%d" % i elif hwsku == "newport": for i in range(0, 256, 8): port_alias_to_name_map["Ethernet%d" % i] = "Ethernet%d" % i else: for i in range(0, 128, 4): port_alias_to_name_map["Ethernet%d" % i] = "Ethernet%d" % i for child in root: if child.tag == str(QName(ns, "DpgDec")): (intfs, lo_intfs, mgmt_intf, vlans, pcs, acls, dhcp_servers) = parse_dpg(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_asn, bgp_peers_with_range) = parse_cpg(child, hostname) elif child.tag == str(QName(ns, "PngDec")): (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port) = parse_png(child, hostname) elif child.tag == str(QName(ns, "UngDec")): (u_neighbors, u_devices, _, _, _, _) = parse_png(child, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): (syslog_servers, ntp_servers, mgmt_routes, deployment_id) = parse_meta(child, hostname) # TODO: Move all alias-related code out of minigraph_facts.py and into # its own module to be used as another layer after parsing the minigraph. # Create inverse mapping between port name and alias port_name_to_alias_map = { v: k for k, v in port_alias_to_name_map.iteritems() } # Create a map of SONiC port name to physical port index # Start by creating a list of all port names port_name_list = port_name_to_alias_map.keys() # Sort the list in natural order, because SONiC port names, when # sorted in natural sort order, match the phyical port index order port_name_list_sorted = natsorted(port_name_list) # Create mapping between port alias and physical index port_index_map = {} for idx, val in enumerate(port_name_list_sorted): port_index_map[val] = idx # Generate results Tree = lambda: defaultdict(Tree) results = Tree() results['minigraph_hwsku'] = hwsku # sorting by lambdas are not easily done without custom filters. # TODO: add jinja2 filter to accept a lambda to sort a list of dictionaries by attribute. # TODO: alternatively (preferred), implement class containers for multiple-attribute entries, enabling sort by attr results['minigraph_bgp'] = sorted(bgp_sessions, key=lambda x: x['addr']) results['minigraph_bgp_asn'] = bgp_asn results['minigraph_bgp_peers_with_range'] = bgp_peers_with_range # TODO: sort does not work properly on all interfaces of varying lengths. Need to sort by integer group(s). phyport_intfs = [] vlan_intfs = [] pc_intfs = [] for intf in intfs: intfname = intf['attachto'] if intfname[0:4] == 'Vlan': vlan_intfs.append(intf) elif intfname[0:11] == 'PortChannel': pc_intfs.append(intf) else: phyport_intfs.append(intf) results['minigraph_interfaces'] = sorted(phyport_intfs, key=lambda x: x['attachto']) results['minigraph_vlan_interfaces'] = sorted(vlan_intfs, key=lambda x: x['attachto']) results['minigraph_portchannel_interfaces'] = sorted( pc_intfs, key=lambda x: x['attachto']) results['minigraph_ports'] = ports results['minigraph_vlans'] = vlans results['minigraph_portchannels'] = pcs results['minigraph_mgmt_interface'] = mgmt_intf results['minigraph_lo_interfaces'] = lo_intfs results['minigraph_acls'] = acls results['minigraph_neighbors'] = neighbors results['minigraph_devices'] = devices results['minigraph_underlay_neighbors'] = u_neighbors results['minigraph_underlay_devices'] = u_devices results['minigraph_port_indices'] = port_index_map results['minigraph_port_name_to_alias_map'] = port_name_to_alias_map results['minigraph_port_alias_to_name_map'] = port_alias_to_name_map results['minigraph_as_xml'] = mini_graph_path if devices != None: results['minigraph_console'] = get_console_info( devices, console_dev, console_port) results['minigraph_mgmt'] = get_mgmt_info(devices, mgmt_dev, mgmt_port) results['minigraph_hostname'] = hostname results['inventory_hostname'] = hostname results['syslog_servers'] = syslog_servers results['dhcp_servers'] = dhcp_servers results['ntp_servers'] = ntp_servers results['forced_mgmt_routes'] = mgmt_routes results['deployment_id'] = deployment_id return results
def parse_png(png, hname): neighbors = {} devices = {} console_dev = '' console_port = '' mgmt_dev = '' mgmt_port = '' for child in png: if child.tag == str(QName(ns, "DeviceInterfaceLinks")): for link in child.findall(str(QName(ns, "DeviceLinkBase"))): linktype = link.find(str(QName(ns, "ElementType"))).text if linktype != "DeviceInterfaceLink" and linktype != "UnderlayInterfaceLink": continue enddevice = link.find(str(QName(ns, "EndDevice"))).text endport = link.find(str(QName(ns, "EndPort"))).text startdevice = link.find(str(QName(ns, "StartDevice"))).text startport = link.find(str(QName(ns, "StartPort"))).text if enddevice == hname: neighbors[endport] = {'name': startdevice, 'port': startport} else: neighbors[startport] = {'name': enddevice, 'port': endport} if child.tag == str(QName(ns, "Devices")): for device in child.findall(str(QName(ns, "Device"))): lo_addr = None # don't shadow type() d_type = None mgmt_addr = None hwsku = None if str(QName(ns3, "type")) in device.attrib: d_type = device.attrib[str(QName(ns3, "type"))] for node in device: if node.tag == str(QName(ns, "Address")): lo_addr = node.find(str(QName(ns2, "IPPrefix"))).text.split('/')[0] elif node.tag == str(QName(ns, "ManagementAddress")): mgmt_addr = node.find(str(QName(ns2, "IPPrefix"))).text.split('/')[0] elif node.tag == str(QName(ns, "Hostname")): name = node.text elif node.tag == str(QName(ns, "HwSku")): hwsku = node.text devices[name] = {'lo_addr': lo_addr, 'type': d_type, 'mgmt_addr': mgmt_addr, 'hwsku': hwsku} if child.tag == str(QName(ns, "DeviceInterfaceLinks")): for if_link in child.findall(str(QName(ns, 'DeviceLinkBase'))): if str(QName(ns3, "type")) in if_link.attrib: link_type = if_link.attrib[str(QName(ns3, "type"))] if link_type == 'DeviceSerialLink': for node in if_link: if node.tag == str(QName(ns, "EndPort")): console_port = node.text.split()[-1] elif node.tag == str(QName(ns, "EndDevice")): console_dev = node.text elif link_type == 'DeviceMgmtLink': for node in if_link: if node.tag == str(QName(ns, "EndPort")): mgmt_port = node.text.split()[-1] elif node.tag == str(QName(ns, "EndDevice")): mgmt_dev = node.text return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port)
def parse_png(png, hname): neighbors = {} devices = {} neighbors_namespace = defaultdict(str) console_dev = '' console_port = '' mgmt_dev = '' mgmt_port = '' try: from sonic_py_common import multi_asic namespace_list = multi_asic.get_namespace_list() except ImportError: namespace_list = [''] for child in png: if child.tag == str(QName(ns, "DeviceInterfaceLinks")): for link in child.findall(str(QName(ns, "DeviceLinkBase"))): linktype = link.find(str(QName(ns, "ElementType"))).text if linktype != "DeviceInterfaceLink" and linktype != "UnderlayInterfaceLink": continue enddevice = link.find(str(QName(ns, "EndDevice"))).text endport = link.find(str(QName(ns, "EndPort"))).text startdevice = link.find(str(QName(ns, "StartDevice"))).text startport = link.find(str(QName(ns, "StartPort"))).text if enddevice == hname: if port_alias_to_name_map.has_key(endport): endport = port_alias_to_name_map[endport] if startdevice.lower() in namespace_list: neighbors_namespace[endport] = startdevice.lower() else: neighbors[endport] = { 'name': startdevice, 'port': startport, 'namespace': '' } elif startdevice == hname: if port_alias_to_name_map.has_key(startport): startport = port_alias_to_name_map[startport] if enddevice.lower() in namespace_list: neighbors_namespace[startport] = enddevice.lower() else: neighbors[startport] = { 'name': enddevice, 'port': endport, 'namespace': '' } if child.tag == str(QName(ns, "Devices")): for device in child.findall(str(QName(ns, "Device"))): lo_addr = None # don't shadow type() d_type = None mgmt_addr = None hwsku = None if str(QName(ns3, "type")) in device.attrib: d_type = device.attrib[str(QName(ns3, "type"))] for node in device: if node.tag == str(QName(ns, "Address")): lo_addr = node.find(str(QName( ns2, "IPPrefix"))).text.split('/')[0] elif node.tag == str(QName(ns, "ManagementAddress")): mgmt_addr = node.find(str(QName( ns2, "IPPrefix"))).text.split('/')[0] elif node.tag == str(QName(ns, "Hostname")): name = node.text elif node.tag == str(QName(ns, "HwSku")): hwsku = node.text if name.lower() in namespace_list: continue devices[name] = { 'lo_addr': lo_addr, 'type': d_type, 'mgmt_addr': mgmt_addr, 'hwsku': hwsku } if child.tag == str(QName(ns, "DeviceInterfaceLinks")): for if_link in child.findall(str(QName(ns, 'DeviceLinkBase'))): if str(QName(ns3, "type")) in if_link.attrib: link_type = if_link.attrib[str(QName(ns3, "type"))] if link_type == 'DeviceSerialLink': for node in if_link: if node.tag == str(QName(ns, "EndPort")): console_port = node.text.split()[-1] elif node.tag == str(QName(ns, "EndDevice")): console_dev = node.text elif link_type == 'DeviceMgmtLink': for node in if_link: if node.tag == str(QName(ns, "EndPort")): mgmt_port = node.text.split()[-1] elif node.tag == str(QName(ns, "EndDevice")): mgmt_dev = node.text for k, v in neighbors.iteritems(): v['namespace'] = neighbors_namespace[k] return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port)
def test_compose(composer, data_dict, schema): delivery = composer.compose(data_dict) assert delivery.tag == QName(NS.fe, "Delivery").text schema.assertValid(delivery)
def _get_wsa_header(client: Client, address: str) -> AnyObject: """Get WSA header from the client.""" applies_type = client.get_element(QName(WSP, 'AppliesTo')) reference_type = client.get_element(QName(WSA, 'EndpointReference')) reference = AnyObject(reference_type, reference_type(Address=address)) return AnyObject(applies_type, applies_type(_value_1=reference))
def parse_cpg(cpg, hname): bgp_sessions = {} myasn = None bgp_peers_with_range = {} for child in cpg: tag = child.tag if tag == str(QName(ns, "PeeringSessions")): for session in child.findall(str(QName(ns, "BGPSession"))): start_router = session.find(str(QName(ns, "StartRouter"))).text start_peer = session.find(str(QName(ns, "StartPeer"))).text end_router = session.find(str(QName(ns, "EndRouter"))).text end_peer = session.find(str(QName(ns, "EndPeer"))).text rrclient = 1 if session.find(str(QName( ns, "RRClient"))) is not None else 0 if session.find(str(QName(ns, "HoldTime"))) is not None: holdtime = session.find(str(QName(ns, "HoldTime"))).text else: holdtime = 180 if session.find(str(QName(ns, "KeepAliveTime"))) is not None: keepalive = session.find(str(QName(ns, "KeepAliveTime"))).text else: keepalive = 60 nhopself = 1 if session.find(str(QName( ns, "NextHopSelf"))) is not None else 0 if end_router.lower() == hname.lower(): bgp_sessions[start_peer.lower()] = { 'name': start_router, 'local_addr': end_peer.lower(), 'rrclient': rrclient, 'holdtime': holdtime, 'keepalive': keepalive, 'nhopself': nhopself } else: bgp_sessions[end_peer.lower()] = { 'name': end_router, 'local_addr': start_peer.lower(), 'rrclient': rrclient, 'holdtime': holdtime, 'keepalive': keepalive, 'nhopself': nhopself } elif child.tag == str(QName(ns, "Routers")): for router in child.findall(str(QName(ns1, "BGPRouterDeclaration"))): asn = router.find(str(QName(ns1, "ASN"))).text hostname = router.find(str(QName(ns1, "Hostname"))).text if hostname.lower() == hname.lower(): myasn = asn peers = router.find(str(QName(ns1, "Peers"))) for bgpPeer in peers.findall(str(QName(ns, "BGPPeer"))): addr = bgpPeer.find(str(QName(ns, "Address"))).text if bgpPeer.find( str(QName(ns1, "PeersRange")) ) is not None: # FIXME: is better to check for type BGPPeerPassive name = bgpPeer.find(str(QName(ns1, "Name"))).text ip_range = bgpPeer.find( str(QName(ns1, "PeersRange"))).text ip_range_group = ip_range.split( ';') if ip_range and ip_range != "" else [] bgp_peers_with_range[name] = { 'name': name, 'ip_range': ip_range_group } if bgpPeer.find(str(QName(ns1, "Address"))) is not None: bgp_peers_with_range[name][ 'src_address'] = bgpPeer.find( str(QName(ns1, "Address"))).text if bgpPeer.find(str(QName(ns1, "PeerAsn"))) is not None: bgp_peers_with_range[name][ 'peer_asn'] = bgpPeer.find( str(QName(ns1, "PeerAsn"))).text else: for peer in bgp_sessions: bgp_session = bgp_sessions[peer] if hostname.lower() == bgp_session['name'].lower(): bgp_session['asn'] = asn bgp_monitors = { key: bgp_sessions[key] for key in bgp_sessions if bgp_sessions[key].has_key('asn') and bgp_sessions[key]['name'] == 'BGPMonitor' } bgp_sessions = { key: bgp_sessions[key] for key in bgp_sessions if bgp_sessions[key].has_key('asn') and int(bgp_sessions[key]['asn']) != 0 } return bgp_sessions, myasn, bgp_peers_with_range, bgp_monitors
def Element(self, name): ns, tag = name.split(':') return etree.Element(QName(self.ns[ns], tag), nsmap=self.ns)