def parse_xml()

in src/sonic-config-engine/minigraph.py [0:0]


def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hwsku_config_file=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()

    u_neighbors = None
    u_devices = None
    acls = {}
    acl_table_types = {}
    hwsku = None
    bgp_sessions = None
    bgp_monitors = []
    bgp_asn = None
    intfs = None
    dpg_ecmp_content = {}
    png_ecmp_content = {}
    vlan_intfs = None
    pc_intfs = None
    tunnel_intfs = None
    tunnel_intfs_qos_remap_config = None
    vlans = None
    vlan_members = None
    dhcp_relay_table = None
    pcs = None
    mgmt_intf = None
    voq_inband_intfs = None
    lo_intfs = None
    neighbors = None
    devices = None
    sub_role = None
    resource_type = None
    downstream_subrole = None
    docker_routing_config_mode = "separated"
    port_speeds_default = {}
    port_speed_png = {}
    port_descriptions = {}
    sys_ports = {}
    console_ports = {}
    mux_cable_ports = {}
    syslog_servers = []
    dhcp_servers = []
    dhcpv6_servers = []
    ntp_servers = []
    tacacs_servers = []
    mgmt_routes = []
    erspan_dst = []
    bgp_peers_with_range = None
    deployment_id = None
    region = None
    cloudtype = None
    switch_id = None
    switch_type = None
    max_cores = None
    hostname = None
    linkmetas = {}
    host_lo_intfs = None
    is_storage_device = False
    local_devices = []
    kube_data = {}
    static_routes = {}
    system_defaults = {}
    macsec_profile = {}
    downstream_redundancy_types = None
    redundancy_type = None
    qos_profile = None
    rack_mgmt_map = 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_name=asic_name, hwsku_config_file=hwsku_config_file)
    
    port_names_map.update(ports)
    port_alias_map.update(alias_map)
    port_alias_asic_map.update(alias_asic_map)

    # Get the local device node from DeviceMetadata
    local_devices = parse_asic_meta_get_devices(root)

    for child in root:
        if asic_name is None:
            if child.tag == str(QName(ns, "DpgDec")):
                (intfs, lo_intfs, mvrf, mgmt_intf, voq_inband_intfs, vlans, vlan_members, dhcp_relay_table, pcs, pc_members, acls, acl_table_types, vni, tunnel_intfs, dpg_ecmp_content, static_routes, tunnel_intfs_qos_remap_config) = parse_dpg(child, hostname)
            elif child.tag == str(QName(ns, "CpgDec")):
                (bgp_sessions, bgp_internal_sessions, bgp_voq_chassis_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, mux_cable_ports, png_ecmp_content) = parse_png(child, hostname, dpg_ecmp_content)
            elif child.tag == str(QName(ns, "UngDec")):
                (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname, None)
            elif child.tag == str(QName(ns, "MetadataDeclaration")):
                (syslog_servers, dhcp_servers, dhcpv6_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, downstream_subrole, switch_id, switch_type, max_cores, kube_data, macsec_profile, downstream_redundancy_types, redundancy_type, qos_profile, rack_mgmt_map) = parse_meta(child, hostname)
            elif child.tag == str(QName(ns, "LinkMetadataDeclaration")):
                linkmetas = parse_linkmeta(child, hostname)
            elif child.tag == str(QName(ns, "DeviceInfos")):
                (port_speeds_default, port_descriptions, sys_ports) = parse_deviceinfo(child, hwsku)
        else:
            if child.tag == str(QName(ns, "DpgDec")):
                (intfs, lo_intfs, mvrf, mgmt_intf, voq_inband_intfs, vlans, vlan_members, dhcp_relay_table, pcs, pc_members, acls, acl_table_types, vni, tunnel_intfs, dpg_ecmp_content, static_routes, tunnel_intfs_qos_remap_config) = parse_dpg(child, asic_name)
                host_lo_intfs = parse_host_loopback(child, hostname)
            elif child.tag == str(QName(ns, "CpgDec")):
                (bgp_sessions, bgp_internal_sessions, bgp_voq_chassis_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name, local_devices)
            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, switch_id, switch_type, max_cores, deployment_id, macsec_profile) = parse_asic_meta(child, asic_name)
            elif child.tag == str(QName(ns, "LinkMetadataDeclaration")):
                linkmetas = parse_linkmeta(child, hostname)
            elif child.tag == str(QName(ns, "DeviceInfos")):
                (port_speeds_default, port_descriptions, sys_ports) = parse_deviceinfo(child, hwsku)

    select_mmu_profiles(qos_profile, platform, hwsku)
    # set the host device type in asic metadata also
    device_type = [devices[key]['type'] for key in devices if key.lower() == hostname.lower()][0]
    if asic_name is None:
        current_device = [devices[key] for key in devices if key.lower() == hostname.lower()][0]
    else:
        try:
            current_device = [devices[key] for key in devices if key.lower() == asic_name.lower()][0]
        except:
            print("Warning: no asic configuration found for {} in minigraph".format(asic_name), file=sys.stderr)
            current_device = {}

    results = {}
    results['DEVICE_METADATA'] = {'localhost': {
        'bgp_asn': bgp_asn,
        'region': region,
        'cloudtype': cloudtype,
        'docker_routing_config_mode': docker_routing_config_mode,
        'hostname': hostname,
        'hwsku': hwsku,
        'type': device_type,
        'synchronous_mode': 'enable',
        'yang_config_validation': 'disable'
        }
    }

    if deployment_id is not None:
        results['DEVICE_METADATA']['localhost']['deployment_id'] = deployment_id

    if rack_mgmt_map is not None:
        results['DEVICE_METADATA']['localhost']['rack_mgmt_map'] = rack_mgmt_map

    cluster = [devices[key] for key in devices if key.lower() == hostname.lower()][0].get('cluster', "")
    if cluster:
        results['DEVICE_METADATA']['localhost']['cluster'] = cluster

    if kube_data:
        results['KUBERNETES_MASTER'] = {
            'SERVER': {
                'disable': str(kube_data.get('enable', '0') == '0'),
                'ip': kube_data.get('ip', '')
            }
        }

    results['PEER_SWITCH'], mux_tunnel_name, peer_switch_ip = get_peer_switch_info(linkmetas, devices)

    if bool(results['PEER_SWITCH']):
        results['DEVICE_METADATA']['localhost']['subtype'] = 'DualToR'
        if len(results['PEER_SWITCH'].keys()) > 1:
            print("Warning: more than one peer switch was found. Only the first will be parsed: {}".format(results['PEER_SWITCH'].keys()[0]))

        results['DEVICE_METADATA']['localhost']['peer_switch'] = list(results['PEER_SWITCH'].keys())[0]
    
    # Enable tunnel_qos_remap if downstream_redundancy_types(T1) or redundancy_type(T0) = Gemini/Libra
    enable_tunnel_qos_map = False
    if platform and 'kvm' in platform:
        enable_tunnel_qos_map = False
    elif results['DEVICE_METADATA']['localhost']['type'].lower() == 'leafrouter' and ('gemini' in str(downstream_redundancy_types).lower() or 'libra' in str(downstream_redundancy_types).lower()):
        enable_tunnel_qos_map = True
    elif results['DEVICE_METADATA']['localhost']['type'].lower() == 'torrouter' and ('gemini' in str(redundancy_type).lower() or 'libra' in str(redundancy_type).lower()):
        enable_tunnel_qos_map = True

    if enable_tunnel_qos_map:
        system_defaults['tunnel_qos_remap'] = {"status": "enabled"}

    if len(system_defaults) > 0:
        results['SYSTEM_DEFAULTS'] = system_defaults
    
    # 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['DEVICE_METADATA']['localhost']['asic_name'] =  asic_name
    elif switch_type == "voq":
       # On Voq switches asic_name is mandatory even on single-asic devices
       results['DEVICE_METADATA']['localhost']['asic_name'] = 'Asic0'

    # on Voq system each asic has a switch_id
    if switch_id is not None:
        results['DEVICE_METADATA']['localhost']['switch_id'] = switch_id
    # on Voq system each asic has a switch_type
    if switch_type is not None:
        results['DEVICE_METADATA']['localhost']['switch_type'] = switch_type
    # on Voq system each asic has a max_cores
    if max_cores is not None:
        results['DEVICE_METADATA']['localhost']['max_cores'] = max_cores

    # Voq systems have an inband interface
    if voq_inband_intfs is not None:
        results['VOQ_INBAND_INTERFACE'] = {}
        for key in voq_inband_intfs:
           results['VOQ_INBAND_INTERFACE'][key] = voq_inband_intfs[key]


    if resource_type is not None:
        results['DEVICE_METADATA']['localhost']['resource_type'] = resource_type

    if downstream_subrole is not None:
        results['DEVICE_METADATA']['localhost']['downstream_subrole'] = downstream_subrole

    results['BGP_NEIGHBOR'] = bgp_sessions
    results['BGP_MONITORS'] = bgp_monitors
    results['BGP_PEER_RANGE'] = bgp_peers_with_range
    results['BGP_INTERNAL_NEIGHBOR'] = bgp_internal_sessions
    results['BGP_VOQ_CHASSIS_NEIGHBOR'] = bgp_voq_chassis_sessions
    if mgmt_routes:
        # TODO: differentiate v4 and v6
        next(iter(mgmt_intf.values()))['forced_mgmt_routes'] = mgmt_routes
    results['MGMT_PORT'] = {}
    results['MGMT_INTERFACE'] = {}
    mgmt_intf_count = 0
    mgmt_alias_reverse_mapping = {}
    sorted_keys = natsorted(mgmt_intf.keys(), alg=natsortns.IGNORECASE, key=lambda x : "|".join(x))
    for key in sorted_keys:
        alias = key[0]
        if alias in mgmt_alias_reverse_mapping:
            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]] = {}

    if host_lo_intfs is not None:
        for host_lo_intf in host_lo_intfs:
            results['LOOPBACK_INTERFACE'][host_lo_intf] = host_lo_intfs[host_lo_intf]
            results['LOOPBACK_INTERFACE'][host_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 'alias' in v }
    vlan_sub_intfs = {}

    for intf in intfs:
        if intf[0][0:4] == 'Vlan':
            vlan_intfs[intf] = {}

            if bool(results['PEER_SWITCH']):
                vlan_intfs[intf[0]] = {
                    'proxy_arp': 'enabled',
                    'grat_arp': 'enabled'
                }
            else:
                vlan_intfs[intf[0]] = {}
        elif intf[0] in vlan_invert_mapping:
            vlan_intfs[(vlan_invert_mapping[intf[0]], intf[1])] = {}

            if bool(results['PEER_SWITCH']):
                vlan_intfs[vlan_invert_mapping[intf[0]]] = {
                    'proxy_arp': 'enabled',
                    'grat_arp': 'enabled'
                }
            else:
                vlan_intfs[vlan_invert_mapping[intf[0]]] = {}
        elif VLAN_SUB_INTERFACE_SEPARATOR in intf[0]:
            vlan_sub_intfs[intf] = {}
            vlan_sub_intfs[intf[0]] = {'admin_status': 'up'}
        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

    if sys_ports:
       results['SYSTEM_PORT'] = sys_ports

    for port_name in port_speeds_default:
        # ignore port not in port_config.ini
        if port_name not in ports:
            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("Warning: ignore interface '%s' as it is not in the port_config.ini" % port_name, file=sys.stderr)
                continue

        # skip management ports
        if port_name in mgmt_alias_reverse_mapping.keys():
            continue

        port_default_speed =  port_speeds_default.get(port_name, None)
        port_png_speed = port_speed_png[port_name]

        # when the port speed is changes from 400g to 100g/40g 
        # update the port lanes, use the first 4 lanes of the 400G port to support 100G/40G port
        if port_default_speed == '400000' and (port_png_speed == '100000' or port_png_speed == '40000'):
            port_lanes =  ports[port_name].get('lanes', '').split(',')
            # check if the 400g port has only 8 lanes
            if len(port_lanes) != 8:
                continue
            updated_lanes = ",".join(port_lanes[:4])
            ports[port_name]['lanes'] = updated_lanes

        ports.setdefault(port_name, {})['speed'] = port_speed_png[port_name]

    for port_name, port in list(ports.items()):
        # get port alias from port_config.ini
        alias = port.get('alias', port_name)
        # generate default 100G FEC only if FECDisabled is not true and 'fec' is not defined in port_config.ini
        # Note: FECDisabled only be effective on 100G port right now
        if linkmetas.get(alias, {}).get('FECDisabled', '').lower() == 'true':
            port['fec'] = 'none'
        elif not port.get('fec') and port.get('speed') == '100000':
            port['fec'] = 'rs'

        # If AutoNegotiation is available in the minigraph, we override any value we may have received from port_config.ini
        autoneg = linkmetas.get(alias, {}).get('AutoNegotiation')
        if autoneg:
            port['autoneg'] = 'on' if autoneg.lower() == 'true' else 'off'

        # If macsec is enabled on interface, and profile is valid, add the profile to port
        macsec_enabled = linkmetas.get(alias, {}).get('MacSecEnabled')
        if macsec_enabled and 'PrimaryKey' in macsec_profile:
            port['macsec'] = macsec_profile['PrimaryKey']

        tx_power = linkmetas.get(alias, {}).get('tx_power')
        if tx_power:
            port['tx_power'] = tx_power

        laser_freq = linkmetas.get(alias, {}).get('laser_freq')
        if laser_freq:
            port['laser_freq'] = laser_freq

    # set port description if parsed from deviceinfo
    for port_name in port_descriptions:
        # ignore port not in port_config.ini
        if port_name not in ports:
            continue

        ports.setdefault(port_name, {})['description'] = port_descriptions[port_name]

    for port_name, port in ports.items():
        if not port.get('description'):
            if port_name in neighbors:
                # 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 and default TPID 0x8100
    for port in ports.values():
        port['mtu'] = '9100'
        port['tpid'] = '0x8100'

    # asymmetric PFC is disabled by default
    for port in ports.values():
        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'

    if len(vlan_sub_intfs):
        for subintf in vlan_sub_intfs:
            if not isinstance(subintf, tuple):
                parent_port = subintf.split(".")[0]
                if parent_port in ports:
                     ports.get(parent_port)['admin_status'] = 'up'

    for member in list(pc_members.keys()) + list(vlan_members.keys()):
        port = ports.get(member[1])
        if port:
            port['admin_status'] = 'up'

    for port in neighbors.keys():
        if port in ports.keys():
            # make all neighbors connected ports to 'admin_up'
            ports[port]['admin_status'] = 'up'

    # bring up the inband voq interfaces
    for inband_port in voq_inband_intfs:
        if inband_port in ports.keys():
            ports[inband_port]['admin_status'] = 'up'

    # bring up the recirc port for voq chassis, Set it as routed interface
    for port, port_attributes in ports.items():
        port_role = port_attributes.get('role', None)
        if port_role == 'Rec':
            ports[port]['admin_status'] = 'up'

            #Add the Recirc ports to the INTERFACES table to make it routed intf
            results['INTERFACE'].update({port : {}})

    results['PORT'] = ports
    results['CONSOLE_PORT'] = console_ports

    if port_config_file:
        port_set = set(ports.keys())
        for (pc_name, pc_member) in list(pc_members.keys()):
            # remove portchannels that contain ports not existing in port_config.ini
            # when port_config.ini exists
            if (pc_name, pc_member) in pc_members and pc_member not in port_set:
                print("Warning: ignore '%s' as at least one of its member interfaces ('%s') is not in the port_config.ini" % (pc_name, pc_member), file=sys.stderr)
                del pcs[pc_name]
                pc_mbr_del_keys = [f for f in list(pc_members.keys()) if f[0] == pc_name]
                for pc_mbr_del_key in pc_mbr_del_keys:
                    del pc_members[pc_mbr_del_key]

    # set default port channel MTU as 9100 and admin status up and default TPID 0x8100
    for pc in pcs.values():
        pc['mtu'] = '9100'
        pc['tpid'] = '0x8100'
        pc['admin_status'] = 'up'

    results['PORTCHANNEL'] = pcs
    results['PORTCHANNEL_MEMBER'] = pc_members

    for pc_intf in list(pc_intfs.keys()):
        # remove portchannels not in PORTCHANNEL dictionary
        if isinstance(pc_intf, tuple) and pc_intf[0] not in pcs:
            print("Warning: ignore '%s' interface '%s' as '%s' is not in the valid PortChannel list" % (pc_intf[0], pc_intf[1], pc_intf[0]), file=sys.stderr)
            del pc_intfs[pc_intf]
            pc_intfs.pop(pc_intf[0], None)

    results['PORTCHANNEL_INTERFACE'] = pc_intfs

    # for storage backend subinterface info present in minigraph takes precedence over ResourceType
    if current_device and current_device['type'] in backend_device_types and bool(vlan_sub_intfs):
        del results['INTERFACE']
        del results['PORTCHANNEL_INTERFACE']
        is_storage_device = True
        results['VLAN_SUB_INTERFACE'] = vlan_sub_intfs
        # storage backend T0 have all vlan members tagged
        for vlan in vlan_members:
            vlan_members[vlan]["tagging_mode"] = "tagged"
    elif current_device and current_device['type'] in backend_device_types and (resource_type is None or 'Storage' in resource_type):
        del results['INTERFACE']
        del results['PORTCHANNEL_INTERFACE']
        is_storage_device = True

        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
        # storage backend T0 have all vlan members tagged
        for vlan in vlan_members:
            vlan_members[vlan]["tagging_mode"] = "tagged"
    elif resource_type is not None and 'Storage' in resource_type:
        is_storage_device = True
    elif bool(vlan_sub_intfs):
        results['VLAN_SUB_INTERFACE'] = vlan_sub_intfs


    if is_storage_device:
        results['DEVICE_METADATA']['localhost']['storage_device'] = "true"

    # remove bgp monitor and slb peers for storage backend
    if is_storage_device and 'BackEnd' in current_device['type']:
        results['BGP_MONITORS'] = {}
        results['BGP_PEER_RANGE'] = {}

    results['VLAN'] = vlans
    results['VLAN_MEMBER'] = vlan_members

    # Add src_ip and qos remapping config into TUNNEL table if tunnel_qos_remap is enabled
    results['TUNNEL'] = get_tunnel_entries(tunnel_intfs, tunnel_intfs_qos_remap_config, lo_intfs, system_defaults.get('tunnel_qos_remap', {}), mux_tunnel_name, peer_switch_ip)

    active_active_ports = get_ports_in_active_active(root, devices, neighbors)
    results['MUX_CABLE'] = get_mux_cable_entries(ports, mux_cable_ports, active_active_ports, neighbors, devices, redundancy_type)

    # If connected to a smart cable, get the connection position
    for port_name, port in results['PORT'].items():
        if port_name in results['MUX_CABLE']:
            port['mux_cable'] = "true"

    if static_routes:
        results['STATIC_ROUTE'] = static_routes

    for nghbr in list(neighbors.keys()):
        # remove port not in port_config.ini
        if nghbr not in ports:
            if port_config_file is not None:
                print("Warning: ignore interface '%s' in DEVICE_NEIGHBOR as it is not in the port_config.ini" % nghbr, file=sys.stderr)
            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['DHCP_RELAY'] = dhcp_relay_table
    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)
    if len(acl_table_types) > 0:
        results['ACL_TABLE_TYPE'] = acl_table_types
    results['ACL_TABLE'] = filter_acl_table_bindings(acls, neighbors, pcs, pc_members, sub_role, current_device['type'] if current_device else None, is_storage_device, vlan_members)
    results['FEATURE'] = {
        'telemetry': {
            'state': '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': 'info'
        },
        'certs': {
            'server_crt': '/etc/sonic/credentials/restapiserver.crt',
            'server_key': '/etc/sonic/credentials/restapiserver.key',
            'ca_crt': '/etc/sonic/credentials/restapica.crt',
            'client_crt_cname': 'client.restapi.sonic'
        }
    }

    if len(png_ecmp_content):
        results['FG_NHG_MEMBER'] = png_ecmp_content['FG_NHG_MEMBER']
        results['FG_NHG'] = png_ecmp_content['FG_NHG']
        results['NEIGH'] = png_ecmp_content['NEIGH']

    # 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.ip_network(UNICODE_TYPE(lo[1]), False)
    #         if lo_network.version == 4:
    #             lo_addr = str(lo_network.network_address)
    #             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 and current_device['type'] == spine_chassis_frontend_role:
        parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_members, devices)

    # Enable console management feature for console swtich
    results['CONSOLE_SWITCH'] = {
        'console_mgmt' : {
            'enabled' : 'yes' if current_device and current_device['type'] in console_device_types else 'no'
        }
    }

    # Enable DHCP Server feature for specific device type
    if current_device and current_device['type'] in dhcp_server_enabled_device_types:
        results['DEVICE_METADATA']['localhost']['dhcp_server'] = 'enabled'

    return results