Exemple #1
0
    def read_porttab_mappings(self, porttabfile):
        logical = []
        logical_to_physical = {}
        physical_to_logical = {}
        last_fp_port_index = 0
        last_portname = ""
        first = 1
        port_pos_in_file = 0
        parse_fmt_port_config_ini = False
        parse_fmt_platform_json = False

        parse_fmt_port_config_ini = (os.path.basename(porttabfile) == PORT_CONFIG_INI)
        parse_fmt_platform_json = (os.path.basename(porttabfile) == PLATFORM_JSON)

        (platform, hwsku) =  DaemonBase().get_platform_and_hwsku()
        if(parse_fmt_platform_json):
            ports, _ = get_port_config(hwsku, platform)
            if not ports:
                print('Failed to get port config', file=sys.stderr)
                sys.exit(1)
            else:
                logical_list = []
                for intf in ports.keys():
                    logical_list.append(intf)

                logical = natsorted(logical_list, key=lambda y: y.lower())
                logical_to_physical, physical_to_logical = OrderedDict(),  OrderedDict()

                for intf_name in logical:
                    bcm_port = str(port_pos_in_file)

                    if 'index' in ports[intf_name].keys():
                        fp_port_index = ports[intf_name]['index']
                        logical_to_physical[intf_name] = [fp_port_index]

                    if physical_to_logical.get(fp_port_index) is None:
                        physical_to_logical[fp_port_index] = [intf_name]
                    else:
                        physical_to_logical[fp_port_index].append(intf_name)

                    port_pos_in_file +=1

                self.logical = logical
                self.logical_to_physical = logical_to_physical
                self.physical_to_logical = physical_to_logical

                """
                print("logical: {}".format(self.logical))
                print("logical to physical: {}".format(self.logical_to_physical))
                print("physical to logical: {}".format( self.physical_to_logical))
                """
                return None


        try:
            f = open(porttabfile)
        except:
            raise

        # Read the porttab file and generate dicts
        # with mapping for future reference.
        #
        # TODO: Refactor this to use the portconfig.py module that now
        # exists as part of the sonic-config-engine package.
        title = []
        for line in f:
            line.strip()
            if re.search("^#", line) is not None:
                # The current format is: # name lanes alias index speed
                # Where the ordering of the columns can vary
                title = line.split()[1:]
                continue

            # Parsing logic for 'port_config.ini' file
            if (parse_fmt_port_config_ini):
                # bcm_port is not explicitly listed in port_config.ini format
                # Currently we assume ports are listed in numerical order according to bcm_port
                # so we use the port's position in the file (zero-based) as bcm_port
                portname = line.split()[0]

                bcm_port = str(port_pos_in_file)

                if "index" in title:
                    fp_port_index = int(line.split()[title.index("index")])
                # Leave the old code for backward compatibility
                elif len(line.split()) >= 4:
                    fp_port_index = int(line.split()[3])
                else:
                    fp_port_index = portname.split("Ethernet").pop()
                    fp_port_index = int(fp_port_index.split("s").pop(0))/4
            else:  # Parsing logic for older 'portmap.ini' file
                (portname, bcm_port) = line.split("=")[1].split(",")[:2]

                fp_port_index = portname.split("Ethernet").pop()
                fp_port_index = int(fp_port_index.split("s").pop(0))/4

            if ((len(self.sfp_ports) > 0) and (fp_port_index not in self.sfp_ports)):
                continue

            if first == 1:
                # Initialize last_[physical|logical]_port
                # to the first valid port
                last_fp_port_index = fp_port_index
                last_portname = portname
                first = 0

            logical.append(portname)

            logical_to_physical[portname] = [fp_port_index]
            if physical_to_logical.get(fp_port_index) is None:
                physical_to_logical[fp_port_index] = [portname]
            else:
                physical_to_logical[fp_port_index].append(portname)

            last_fp_port_index = fp_port_index
            last_portname = portname

            port_pos_in_file += 1

        self.logical = logical
        self.logical_to_physical = logical_to_physical
        self.physical_to_logical = physical_to_logical

        """
Exemple #2
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
    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")
    for child in root:
        if child.tag == str(hwsku_qn):
            hwsku = child.text
        if child.tag == str(hostname_qn):
            hostname = 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) = 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,
            '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_INTERFACE'] = mgmt_intf
    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] = {}
        elif vlan_invert_mapping.has_key(intf[0]):
            vlan_intfs[(vlan_invert_mapping[intf[0]], intf[1])] = {}
        elif intf[0][0:11] == 'PortChannel':
            pc_intfs[intf] = {}
        else:
            phyport_intfs[intf] = {}

    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'

    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]

    # set default port MTU as 9100
    for port in ports.itervalues():
        port['mtu'] = '9100'

    # set physical port default admin status up
    for port in phyport_intfs:
        if port[0] in ports:
            ports.get(port[0])['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 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]

    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

    return results
Exemple #3
0
 def test_platform_json_no_interfaces(self):
     (ports, _, _) = get_port_config(port_config_file=self.platform_json)
     self.assertNotEqual(ports, None)
     self.assertEqual(ports, {})
Exemple #4
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
    port_speeds = {}
    port_descriptions = {}
    syslog_servers = []
    dhcp_servers = []
    ntp_servers = []
    mgmt_routes = []
    erspan_dst = []
    bgp_peers_with_range = None
    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

    (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,
             acls) = 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, dhcp_servers, ntp_servers, mgmt_routes,
             erspan_dst, deployment_id) = parse_meta(child, hostname)
        elif child.tag == str(QName(ns, "DeviceInfos")):
            (port_speeds, port_descriptions) = parse_deviceinfo(child, hwsku)

    results = {}
    results['DEVICE_METADATA'] = {
        'localhost': {
            'bgp_asn': bgp_asn,
            'deployment_id': deployment_id,
            'hostname': hostname,
            'hwsku': hwsku,
            'type': devices[hostname]['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_INTERFACE'] = mgmt_intf
    results['LOOPBACK_INTERFACE'] = lo_intfs

    phyport_intfs = {}
    vlan_intfs = {}
    pc_intfs = {}
    for intf in intfs:
        if intf[0][0:4] == 'Vlan':
            vlan_intfs[intf] = {}
        elif intf[0][0:11] == 'PortChannel':
            pc_intfs[intf] = {}
        else:
            phyport_intfs[intf] = {}

    results['INTERFACE'] = phyport_intfs
    results['VLAN_INTERFACE'] = vlan_intfs
    results['PORTCHANNEL_INTERFACE'] = pc_intfs

    for port_name in port_speeds:
        ports.setdefault(port_name, {})['speed'] = port_speeds[port_name]
    for port_name in port_descriptions:
        ports.setdefault(port_name,
                         {})['description'] = port_descriptions[port_name]

    results['PORT'] = ports
    results['PORTCHANNEL'] = pcs
    results['VLAN'] = vlans
    results['VLAN_MEMBER'] = vlan_members

    results['DEVICE_NEIGHBOR'] = neighbors
    results['DEVICE_NEIGHBOR_METADATA'] = {
        key: devices[key]
        for key in devices if key != hostname
    }
    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['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

    return results
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_monitors = []
    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, 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) = 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_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'] = lo_intfs
    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 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:
            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'] = filter_acl_mirror_table_bindings(
        acls, neighbors, pcs)
    results['FEATURE'] = {'telemetry': {'status': 'enabled'}}

    # 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
Exemple #6
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 = "unified"
    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) = 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'}
        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] = {}
        elif vlan_invert_mapping.has_key(intf[0]):
            vlan_intfs[(vlan_invert_mapping[intf[0]], intf[1])] = {}
        elif intf[0][0:11] == 'PortChannel':
            pc_intfs[intf] = {}
        else:
            phyport_intfs[intf] = {}

    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 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]

    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

    return results
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
    port_speeds_default = {}
    port_speed_png = {}
    port_descriptions = {}
    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")
    for child in root:
        if child.tag == str(hwsku_qn):
            hwsku = child.text
        if child.tag == str(hostname_qn):
            hostname = 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,
             acls) = 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) = 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,
            '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_INTERFACE'] = mgmt_intf
    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] = {}
        elif vlan_invert_mapping.has_key(intf[0]):
            vlan_intfs[(vlan_invert_mapping[intf[0]], intf[1])] = {}
        elif intf[0][0:11] == 'PortChannel':
            pc_intfs[intf] = {}
        else:
            phyport_intfs[intf] = {}

    results['INTERFACE'] = phyport_intfs
    results['VLAN_INTERFACE'] = vlan_intfs
    results['PORTCHANNEL_INTERFACE'] = pc_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:
        # if port_name is not in port_config.ini, still consider it.
        # and later swss will pick up and behave on-demand port break-up.
        # if on-deman port break-up is not supported on a specific platform, swss will return error.
        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'

    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]

    results['PORT'] = ports
    results['PORTCHANNEL'] = pcs
    results['VLAN'] = vlans
    results['VLAN_MEMBER'] = vlan_members

    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

    return results