Commit cecb3a6d authored by Pedro Duarte's avatar Pedro Duarte
Browse files

use translation in openconfig handler

parent ef7f44ea
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -167,9 +167,9 @@ class SamplesCache:
            try:
                now = datetime.timestamp(datetime.utcnow())
                if self.__timestamp is not None and (now - self.__timestamp) < SAMPLE_EVICTION_SECONDS: return
                str_filter = get_filter(SAMPLE_RESOURCE_KEY)
                str_filter = get_filter(SAMPLE_RESOURCE_KEY, device_type=self.__netconf_handler.vendor)
                xml_data = self.__netconf_handler.get(filter=str_filter).data_ele
                interface_samples = parse(SAMPLE_RESOURCE_KEY, xml_data)
                interface_samples = parse(SAMPLE_RESOURCE_KEY, xml_data, device_type=self.__netconf_handler.vendor)
                for interface,samples in interface_samples:
                    match = RE_GET_ENDPOINT_FROM_INTERFACE_KEY.match(interface)
                    if match is None: continue
@@ -228,7 +228,7 @@ def edit_config(
                resource_key,resource_value = resource
                chk_string(str_resource_name + '.key', resource_key, allow_empty=False)
                str_config_messages = compose_config(                                                                          # get template for configuration
                    resource_key, resource_value, delete=delete, vendor=netconf_handler.vendor, message_renderer=netconf_handler.message_renderer)
                    resource_key, resource_value, delete=delete, vendor=netconf_handler.vendor, message_renderer=netconf_handler.message_renderer, device_type=netconf_handler.vendor)
                for str_config_message in str_config_messages:                                                                 # configuration of the received templates 
                    if str_config_message is None: raise UnsupportedResourceKeyException(resource_key)
                    logger.debug('[{:s}] str_config_message[{:d}] = {:s}'.format(
@@ -318,12 +318,12 @@ class OpenConfigDriver(_Driver):
                str_resource_name = 'resource_key[#{:d}]'.format(i)
                try:
                    chk_string(str_resource_name, resource_key, allow_empty=False)
                    str_filter = get_filter(resource_key)
                    str_filter = get_filter(resource_key, device_type=self.__netconf_handler.vendor)
                    #self.__logger.debug('[GetConfig] str_filter = {:s}'.format(str(str_filter)))
                    if str_filter is None: str_filter = resource_key
                    xml_data = self.__netconf_handler.get(filter=str_filter).data_ele
                    if isinstance(xml_data, Exception): raise xml_data
                    results.extend(parse(resource_key, xml_data))
                    results.extend(parse(resource_key, xml_data, device_type=self.__netconf_handler.vendor))
                except Exception as e: # pylint: disable=broad-except
                    MSG = 'Exception retrieving {:s}: {:s}'
                    self.__logger.exception(MSG.format(str_resource_name, str(resource_key)))
+45 −43
Original line number Diff line number Diff line
@@ -16,110 +16,112 @@ import logging, lxml.etree as ET
from typing import Any, Dict, List, Tuple
from .Namespace import NAMESPACES
from .Tools import add_value_from_tag
from inter_device_translation import get_dict_helper
from . import find_element, get_resource_key

LOGGER = logging.getLogger(__name__)

XPATH_ACL_SET     = "//ocacl:acl/ocacl:acl-sets/ocacl:acl-set"
XPATH_A_ACL_ENTRY = ".//ocacl:acl-entries/ocacl:acl-entry"
XPATH_A_IPv4      = ".//ocacl:ipv4/ocacl:config"
XPATH_A_TRANSPORT = ".//ocacl:transport/ocacl:config"
XPATH_A_ACTIONS   = ".//ocacl:actions/ocacl:config"

XPATH_INTERFACE   = "//ocacl:acl/ocacl:interfaces/ocacl:interface"
XPATH_I_INGRESS   = ".//ocacl:ingress-acl-sets/ocacl:ingress-acl-set"
XPATH_I_EGRESS    = ".//ocacl:egress-acl-sets/ocacl:egress-acl-set"

def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
def parse(xml_data : ET.Element, device_type : str = None) -> List[Tuple[str, Dict[str, Any]]]:
    # Get device-specific paths
    dict_helper = get_dict_helper(device_type)
    xpath_acl_set = "//" + dict_helper.get_path('acl_set')
    xpath_acl_entry = ".//" + dict_helper.get_path('acl_entry')
    xpath_acl_ipv4 = ".//" + dict_helper.get_path('acl_ipv4')
    xpath_acl_transport = ".//" + dict_helper.get_path('acl_transport')
    xpath_acl_actions = ".//" + dict_helper.get_path('acl_actions')
    xpath_acl_interface = "//" + dict_helper.get_path('acl_interface')
    xpath_acl_ingress = ".//" + dict_helper.get_path('acl_ingress')
    xpath_acl_egress = ".//" + dict_helper.get_path('acl_egress')
    #LOGGER.info('[ACL] xml_data = {:s}'.format(str(ET.tostring(xml_data))))

    response = []
    acl = {}
    name = {}

    for xml_acl in xml_data.xpath(XPATH_ACL_SET, namespaces=NAMESPACES):
    for xml_acl in xml_data.xpath(xpath_acl_set, namespaces=NAMESPACES):
        #LOGGER.info('xml_acl = {:s}'.format(str(ET.tostring(xml_acl))))

        acl_name = xml_acl.find('ocacl:name', namespaces=NAMESPACES)
        acl_name = find_element(xml_acl, 'acl_name', device_type, NAMESPACES)
        if acl_name is None or acl_name.text is None: continue
        add_value_from_tag(name, 'name', acl_name)

        acl_type = xml_acl.find('ocacl:type', namespaces=NAMESPACES)
        acl_type = find_element(xml_acl, 'acl_type', device_type, NAMESPACES)
        add_value_from_tag(acl, 'type', acl_type)

        for xml_acl_entries in xml_acl.xpath(XPATH_A_ACL_ENTRY, namespaces=NAMESPACES):
        for xml_acl_entries in xml_acl.xpath(xpath_acl_entry, namespaces=NAMESPACES):

            acl_id = xml_acl_entries.find('ocacl:sequence-id', namespaces=NAMESPACES)
            acl_id = find_element(xml_acl_entries, 'acl_sequence_id', device_type, NAMESPACES)
            add_value_from_tag(acl, 'sequence-id', acl_id)
            LOGGER.info('xml_acl_id = {:s}'.format(str(ET.tostring(acl_id))))

            for xml_ipv4 in xml_acl_entries.xpath(XPATH_A_IPv4, namespaces=NAMESPACES):
            for xml_ipv4 in xml_acl_entries.xpath(xpath_acl_ipv4, namespaces=NAMESPACES):

                ipv4_source = xml_ipv4.find('ocacl:source-address', namespaces=NAMESPACES)
                ipv4_source = find_element(xml_ipv4, 'acl_source_address', device_type, NAMESPACES)
                add_value_from_tag(acl, 'source-address' , ipv4_source)

                ipv4_destination = xml_ipv4.find('ocacl:destination-address', namespaces=NAMESPACES)
                ipv4_destination = find_element(xml_ipv4, 'acl_destination_address', device_type, NAMESPACES)
                add_value_from_tag(acl, 'destination-address' , ipv4_destination)

                ipv4_protocol = xml_ipv4.find('ocacl:protocol', namespaces=NAMESPACES)
                ipv4_protocol = find_element(xml_ipv4, 'acl_protocol', device_type, NAMESPACES)
                add_value_from_tag(acl, 'protocol' , ipv4_protocol)

                ipv4_dscp = xml_ipv4.find('ocacl:dscp', namespaces=NAMESPACES)
                ipv4_dscp = find_element(xml_ipv4, 'acl_dscp', device_type, NAMESPACES)
                add_value_from_tag(acl, 'dscp' , ipv4_dscp)

                ipv4_hop_limit = xml_ipv4.find('ocacl:hop-limit', namespaces=NAMESPACES)
                ipv4_hop_limit = find_element(xml_ipv4, 'acl_hop_limit', device_type, NAMESPACES)
                add_value_from_tag(acl, 'hop-limit' , ipv4_hop_limit)

            for xml_transport in xml_acl_entries.xpath(XPATH_A_TRANSPORT, namespaces=NAMESPACES):
            for xml_transport in xml_acl_entries.xpath(xpath_acl_transport, namespaces=NAMESPACES):

                transport_source = xml_transport.find('ocacl:source-port', namespaces=NAMESPACES)
                transport_source = find_element(xml_transport, 'acl_source_port', device_type, NAMESPACES)
                add_value_from_tag(acl, 'source-port' ,transport_source)

                transport_destination = xml_transport.find('ocacl:destination-port', namespaces=NAMESPACES)
                transport_destination = find_element(xml_transport, 'acl_destination_port', device_type, NAMESPACES)
                add_value_from_tag(acl, 'destination-port' ,transport_destination)

                transport_tcp_flags = xml_transport.find('ocacl:tcp-flags', namespaces=NAMESPACES)
                transport_tcp_flags = find_element(xml_transport, 'acl_tcp_flags', device_type, NAMESPACES)
                add_value_from_tag(acl, 'tcp-flags' ,transport_tcp_flags)

            for xml_action in xml_acl_entries.xpath(XPATH_A_ACTIONS, namespaces=NAMESPACES):
            for xml_action in xml_acl_entries.xpath(xpath_acl_actions, namespaces=NAMESPACES):

                action = xml_action.find('ocacl:forwarding-action', namespaces=NAMESPACES)
                action = find_element(xml_action, 'acl_forwarding_action', device_type, NAMESPACES)
                add_value_from_tag(acl, 'forwarding-action' ,action)

                log_action = xml_action.find('ocacl:log-action', namespaces=NAMESPACES)
                log_action = find_element(xml_action, 'acl_log_action', device_type, NAMESPACES)
                add_value_from_tag(acl, 'log-action' ,log_action)

            resource_key =  '/acl/acl-set[{:s}][{:s}]/acl-entry[{:s}]'.format(
                name['name'], acl['type'], acl['sequence-id'])
            resource_key = get_resource_key('acl_set_entry', device_type,
                                          name=name['name'], type=acl['type'], sequence_id=acl['sequence-id'])
            response.append((resource_key,acl))

    for xml_interface in xml_data.xpath(XPATH_INTERFACE, namespaces=NAMESPACES):
    for xml_interface in xml_data.xpath(xpath_acl_interface, namespaces=NAMESPACES):

        interface = {}

        interface_id = xml_interface.find('ocacl:id', namespaces=NAMESPACES)
        interface_id = find_element(xml_interface, 'acl_interface_id', device_type, NAMESPACES)
        add_value_from_tag(interface, 'id' , interface_id)

        for xml_ingress in xml_interface.xpath(XPATH_I_INGRESS, namespaces=NAMESPACES):
        for xml_ingress in xml_interface.xpath(xpath_acl_ingress, namespaces=NAMESPACES):

            i_name = xml_ingress.find('ocacl:set-name-ingress', namespaces=NAMESPACES)
            i_name = find_element(xml_ingress, 'acl_set_name_ingress', device_type, NAMESPACES)
            add_value_from_tag(interface, 'ingress-set-name' , i_name)

            i_type = xml_ingress.find('ocacl:type-ingress', namespaces=NAMESPACES)
            i_type = find_element(xml_ingress, 'acl_type_ingress', device_type, NAMESPACES)
            add_value_from_tag(interface, 'ingress-type' , i_type)

            resource_key =  '/acl/interfaces/ingress[{:s}][{:s}]'.format(
                name['name'], acl['type'])
            resource_key = get_resource_key('acl_interfaces_ingress', device_type,
                                          name=name['name'], type=acl['type'])
            response.append((resource_key,interface))

        for xml_egress in xml_interface.xpath(XPATH_I_EGRESS, namespaces=NAMESPACES):
        for xml_egress in xml_interface.xpath(xpath_acl_egress, namespaces=NAMESPACES):

            e_name = xml_egress.find('ocacl:set-name-egress', namespaces=NAMESPACES)
            e_name = find_element(xml_egress, 'acl_set_name_egress', device_type, NAMESPACES)
            add_value_from_tag(interface, 'egress-set-name' , e_name)

            e_type = xml_egress.find('ocacl:type-egress', namespaces=NAMESPACES)
            e_type = find_element(xml_egress, 'acl_type_egress', device_type, NAMESPACES)
            add_value_from_tag(interface, 'egress-type' , e_type)

            resource_key =  '/acl/interfaces/egress[{:s}][{:s}]'.format(
                name['name'], acl['type'])
            resource_key = get_resource_key('acl_interfaces_egress', device_type,
                                          name=name['name'], type=acl['type'])
            response.append((resource_key,interface))
    return response
+17 −14
Original line number Diff line number Diff line
@@ -17,18 +17,22 @@ from typing import Any, Dict, List, Tuple
from common.proto.kpi_sample_types_pb2 import KpiSampleType
from .Namespace import NAMESPACES
from .Tools import add_value_from_collection, add_value_from_tag
from inter_device_translation import get_dict_helper, DictHelper
from . import find_element, get_resource_key

LOGGER = logging.getLogger(__name__)

XPATH_PORTS = "//ocp:components/ocp:component"
XPATH_IFACE_COUNTER = "//oci:interfaces/oci:interface[oci:name='{:s}']/state/counters/{:s}"
def parse(xml_data : ET.Element, device_type : str = None) -> List[Tuple[str, Dict[str, Any]]]:
    # Get device-specific paths
    dict_helper = get_dict_helper(device_type)
    xpath_ports = "//" + dict_helper.get_path('ports')
    xpath_iface_counter = "//" + dict_helper.get_path('interface_counters')
    
def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
    response = []
    for xml_component in xml_data.xpath(XPATH_PORTS, namespaces=NAMESPACES):
    for xml_component in xml_data.xpath(xpath_ports, namespaces=NAMESPACES):
        #LOGGER.info('xml_component = {:s}'.format(str(ET.tostring(xml_component))))

        component_type = xml_component.find('ocp:state/ocp:type', namespaces=NAMESPACES)
        component_type = find_element(xml_component, 'ep_component_type', device_type, NAMESPACES)
        if component_type is None or component_type.text is None: continue
        component_type = component_type.text
        if component_type not in {'PORT', 'oc-platform-types:PORT', 'idx:PORT'}: continue
@@ -37,23 +41,22 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:

        endpoint = {}

        component_name = xml_component.find('ocp:name', namespaces=NAMESPACES)
        component_name = find_element(xml_component, 'ep_component_name', device_type, NAMESPACES)
        if component_name is None or component_name.text is None: continue
        add_value_from_tag(endpoint, 'uuid', component_name)

        component_type = xml_component.find(
            'ocpp:port/ocpp:breakout-mode/ocpp:state/ocpp:channel-speed', namespaces=NAMESPACES)
        component_type = find_element(xml_component, 'ep_port_channel_speed', device_type, NAMESPACES)
        add_value_from_tag(endpoint, 'type', component_type)
        if 'type' not in endpoint: endpoint['type'] = '-'

        sample_types = {
            KpiSampleType.KPISAMPLETYPE_BYTES_RECEIVED     : XPATH_IFACE_COUNTER.format(endpoint['uuid'], 'in-octets' ),
            KpiSampleType.KPISAMPLETYPE_BYTES_TRANSMITTED  : XPATH_IFACE_COUNTER.format(endpoint['uuid'], 'out-octets'),
            KpiSampleType.KPISAMPLETYPE_PACKETS_RECEIVED   : XPATH_IFACE_COUNTER.format(endpoint['uuid'], 'in-pkts'   ),
            KpiSampleType.KPISAMPLETYPE_PACKETS_TRANSMITTED: XPATH_IFACE_COUNTER.format(endpoint['uuid'], 'out-pkts'  ),
            KpiSampleType.KPISAMPLETYPE_BYTES_RECEIVED     : "//" + dict_helper.get_path('interface_counters', interface_name=endpoint['uuid'], counter_name='in-octets'),
            KpiSampleType.KPISAMPLETYPE_BYTES_TRANSMITTED  : "//" + dict_helper.get_path('interface_counters', interface_name=endpoint['uuid'], counter_name='out-octets'),
            KpiSampleType.KPISAMPLETYPE_PACKETS_RECEIVED   : "//" + dict_helper.get_path('interface_counters', interface_name=endpoint['uuid'], counter_name='in-pkts'),
            KpiSampleType.KPISAMPLETYPE_PACKETS_TRANSMITTED: "//" + dict_helper.get_path('interface_counters', interface_name=endpoint['uuid'], counter_name='out-pkts'),
        }
        add_value_from_collection(endpoint, 'sample_types', sample_types)

        if len(endpoint) == 0: continue
        response.append(('/endpoints/endpoint[{:s}]'.format(endpoint['uuid']), endpoint))
        response.append((get_resource_key('endpoints_endpoint', device_type, uuid=endpoint['uuid']), endpoint))
    return response
+43 −38

File changed.

Preview size limit exceeded, changes collapsed.

+28 −24
Original line number Diff line number Diff line
@@ -16,11 +16,11 @@ import logging, lxml.etree as ET
from typing import Any, Dict, List, Tuple
from .Namespace import NAMESPACES
from .Tools import add_value_from_tag
from inter_device_translation import get_dict_helper
from . import find_element, get_resource_key

LOGGER = logging.getLogger(__name__)

XPATH_PORTS = "//ocp:components/ocp:component"

"""
#Method Name: parse

@@ -52,10 +52,14 @@ XPATH_PORTS = "//ocp:components/ocp:component"
    with the information extracted from the XML document components is returned.
"""

def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
def parse(xml_data : ET.Element, device_type : str = None) -> List[Tuple[str, Dict[str, Any]]]:
    # Get device-specific paths
    dict_helper = get_dict_helper(device_type)
    xpath_ports = "//" + dict_helper.get_path('ports')
    
    response = []
    parent_types = {}
    for xml_component in xml_data.xpath(XPATH_PORTS, namespaces=NAMESPACES):
    for xml_component in xml_data.xpath(xpath_ports, namespaces=NAMESPACES):
        LOGGER.info('xml_component inventario = {:s}'.format(str(ET.tostring(xml_component))))
        inventory = {}
        inventory['parent-component-references'] = ''
@@ -64,82 +68,82 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
        inventory['attributes'] = {}
        component_reference = []

        component_name = xml_component.find('ocp:name', namespaces=NAMESPACES)
        component_name = find_element(xml_component, 'inv_component_name', device_type, NAMESPACES)
        if component_name is None or component_name.text is None: continue
        add_value_from_tag(inventory, 'name', component_name)        

        component_description = xml_component.find('ocp:state/ocp:description', namespaces=NAMESPACES)
        component_description = find_element(xml_component, 'inv_component_description', device_type, NAMESPACES)
        if not component_description is None:
            add_value_from_tag(inventory['attributes'], 'description', component_description)
        
        component_location = xml_component.find('ocp:state/ocp:location', namespaces=NAMESPACES)
        component_location = find_element(xml_component, 'inv_component_location', device_type, NAMESPACES)
        if not component_location is None:
            add_value_from_tag(inventory['attributes'], 'location', component_location)

        component_id = xml_component.find('ocp:state/ocp:id', namespaces=NAMESPACES)
        component_id = find_element(xml_component, 'inv_component_id', device_type, NAMESPACES)
        if not component_id is None:
            add_value_from_tag(inventory['attributes'], 'id', component_id)
        
        component_type = xml_component.find('ocp:state/ocp:type', namespaces=NAMESPACES)
        component_type = find_element(xml_component, 'inv_component_type', device_type, NAMESPACES)
        if component_type is not None:
            component_type.text = component_type.text.replace('oc-platform-types:','')
            add_value_from_tag(inventory, 'class', component_type)
        
        if inventory['class'] == 'CPU' or inventory['class'] == 'STORAGE': continue

        component_empty = xml_component.find('ocp:state/ocp:empty', namespaces=NAMESPACES)
        component_empty = find_element(xml_component, 'inv_component_empty', device_type, NAMESPACES)
        if not component_empty is None:
            add_value_from_tag(inventory['attributes'], 'empty', component_empty)

        component_parent = xml_component.find('ocp:state/ocp:parent', namespaces=NAMESPACES)
        component_parent = find_element(xml_component, 'inv_component_parent', device_type, NAMESPACES)
        if not component_parent is None: 
            add_value_from_tag(inventory, 'parent-component-references', component_parent)

        component_HW = xml_component.find('ocp:state/ocp:hardware-version', namespaces=NAMESPACES)
        component_HW = find_element(xml_component, 'inv_component_hardware_version', device_type, NAMESPACES)
        if not component_HW is None:
            add_value_from_tag(inventory['attributes'], 'hardware-rev', component_HW)

        component_firmware_version = xml_component.find('ocp:state/ocp:firmware-version', namespaces=NAMESPACES)
        component_firmware_version = find_element(xml_component, 'inv_component_firmware_version', device_type, NAMESPACES)
        if not component_firmware_version is None:
            add_value_from_tag(inventory['attributes'], 'firmware-rev', component_firmware_version)

        component_SW = xml_component.find('ocp:state/ocp:software-version', namespaces=NAMESPACES)
        component_SW = find_element(xml_component, 'inv_component_software_version', device_type, NAMESPACES)
        if not component_SW is None:
            add_value_from_tag(inventory['attributes'], 'software-rev', component_SW)

        component_serial = xml_component.find('ocp:state/ocp:serial-no', namespaces=NAMESPACES)
        component_serial = find_element(xml_component, 'inv_component_serial', device_type, NAMESPACES)
        if not component_serial is None:
            add_value_from_tag(inventory['attributes'], 'serial-num', component_serial)

        component_mfg_name = xml_component.find('ocp:state/ocp:mfg-name', namespaces=NAMESPACES)
        component_mfg_name = find_element(xml_component, 'inv_component_mfg_name', device_type, NAMESPACES)
        if not component_mfg_name is None:
            add_value_from_tag(inventory['attributes'], 'mfg-name', component_mfg_name)
        
        component_removable = xml_component.find('ocp:state/ocp:removable', namespaces=NAMESPACES)
        component_removable = find_element(xml_component, 'inv_component_removable', device_type, NAMESPACES)
        if not component_removable is None:
            add_value_from_tag(inventory['attributes'], 'removable', component_removable)

        component_mfg_date = xml_component.find('ocp:state/ocp:mfg-date', namespaces=NAMESPACES)
        component_mfg_date = find_element(xml_component, 'inv_component_mfg_date', device_type, NAMESPACES)
        if not component_mfg_date is None:
            add_value_from_tag(inventory['attributes'], 'mfg-date', component_mfg_date)

        #Transceiver Information
        component_serial_t = xml_component.find('ocptr:transceiver/ocptr:state/ocptr:serial-no', namespaces=NAMESPACES)
        component_serial_t = find_element(xml_component, 'inv_transceiver_serial', device_type, NAMESPACES)
        if not component_serial_t is None:
            add_value_from_tag(inventory['attributes'], 'serial-num', component_serial_t)
            
        component_present = xml_component.find('ocptr:transceiver/ocptr:state/ocptr:present', namespaces=NAMESPACES)
        component_present = find_element(xml_component, 'inv_transceiver_present', device_type, NAMESPACES)
        if component_present is not None and 'NOT_PRESENT' in component_present.text: continue
        
        component_vendor = xml_component.find('ocptr:transceiver/ocptr:state/ocptr:vendor', namespaces=NAMESPACES)
        component_vendor = find_element(xml_component, 'inv_transceiver_vendor', device_type, NAMESPACES)
        if not component_vendor is None:
            add_value_from_tag(inventory['attributes'], 'vendor', component_vendor)
        component_connector = xml_component.find('ocptr:transceiver/ocptr:state/ocptr:connector-type', namespaces=NAMESPACES)
        component_connector = find_element(xml_component, 'inv_transceiver_connector', device_type, NAMESPACES)
        if not component_connector is None:
            component_connector.text = component_connector.text.replace('oc-opt-types:','')
            add_value_from_tag(inventory['attributes'], 'connector-type', component_connector)
        
        component_form = xml_component.find('ocptr:transceiver/ocptr:state/ocptr:form-factor', namespaces=NAMESPACES)
        component_form = find_element(xml_component, 'inv_transceiver_form', device_type, NAMESPACES)
        if not component_form is None:
            component_form.text = component_form.text.replace('oc-opt-types:','')
            add_value_from_tag(inventory['attributes'], 'form-factor', component_form)
@@ -149,7 +153,7 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:

        component_reference.extend([parent_types[inventory['parent-component-references']]])
        
        response.append(('/inventory/{:s}'.format(inventory['name']), inventory))
        response.append((get_resource_key('inventory_component', device_type, name=inventory['name']), inventory))

        for tupla in response:
            if inventory['parent-component-references'] in tupla[0]:
Loading