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 ""
Esempio n. 2
0
 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
Esempio n. 3
0
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
Esempio n. 4
0
        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)
Esempio n. 5
0
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
Esempio n. 6
0
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)
Esempio n. 7
0
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
Esempio n. 8
0
    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)
Esempio n. 9
0
    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),
            ]
        )
Esempio n. 10
0
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"))
Esempio n. 11
0
 def setUp(self):
     self.parser = XmlParser()
     self.parser.index = 10
     self.parser.objects = [(QName(x), x) for x in "abcde"]
Esempio n. 12
0
    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)
Esempio n. 13
0
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
Esempio n. 14
0
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
Esempio n. 15
0
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)
Esempio n. 16
0
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
Esempio n. 17
0
    def SubElement(self, parent, name):

        ns, tag = name.split(':')
        return etree.SubElement(parent, QName(self.ns[ns], tag))
Esempio n. 18
0
 def test_next_node(self):
     ctx = XmlContext()
     with self.assertRaises(NotImplementedError):
         XmlNode(0).next_node(QName("foo"), 0, ctx)
Esempio n. 19
0
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]|&#0;")


def encode_pdf_date(d: datetime) -> str:
    """Encode Python datetime object as PDF date string
Esempio n. 20
0
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)
Esempio n. 21
0
def is_text_property(property):
    tag = QName(property).localname
    return tag in ['bstr', 'lpstr', 'lpwstr']
Esempio n. 22
0
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
Esempio n. 23
0
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
Esempio n. 24
0
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
Esempio n. 25
0
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
Esempio n. 26
0
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
Esempio n. 27
0
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)
Esempio n. 28
0
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)
Esempio n. 29
0
def test_compose(composer, data_dict, schema):
    delivery = composer.compose(data_dict)

    assert delivery.tag == QName(NS.fe, "Delivery").text

    schema.assertValid(delivery)
Esempio n. 30
0
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))
Esempio n. 31
0
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
Esempio n. 32
0
    def Element(self, name):

        ns, tag = name.split(':')
        return etree.Element(QName(self.ns[ns], tag), nsmap=self.ns)