Commit 8ce6153b authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

NBI Component - IETF Network plugin:

- Added example flags in run_tests_locally script
- Added data model bindings
- Fixed Composer methods
- Updated ManualFixes.py
- Updated unitary test
- Renamed TODO.txt to test_commands.txt
parent 04f63033
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -20,5 +20,6 @@ cd $PROJECTDIR/src
RCFILE=$PROJECTDIR/coverage/.coveragerc

# Run unitary tests and analyze coverage of code at same time
# helpful pytest flags: --log-level=INFO -o log_cli=true --verbose --maxfail=1 --durations=0
coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
    nbi/tests/test_ietf_network.py
+52 −7
Original line number Diff line number Diff line
@@ -13,20 +13,46 @@
# limitations under the License.

import logging, re
from common.DeviceTypes import DeviceTypeEnum
from common.proto.context_pb2 import TopologyDetails
from nbi.service.rest_server.nbi_plugins.ietf_network.NetworkTypeEnum import NetworkTypeEnum, get_network_topology_type
from .bindings.networks.network import network
from .NameMapping import NameMappings
from .ComposeNode import compose_node
from .ComposeLink import compose_link
from .ComposeNode import compose_node
from .NameMapping import NameMappings
from .NetworkTypeEnum import NetworkTypeEnum, get_network_topology_type

LOGGER = logging.getLogger(__name__)

def compose_network(ietf_network_obj : network, topology_details : TopologyDetails) -> None:
    ietf_network_obj.te.name = 'Huawei-Network'
IGNORE_DEVICE_TYPES = {
    DeviceTypeEnum.CLIENT.value,
    DeviceTypeEnum.DATACENTER.value,
    DeviceTypeEnum.EMULATED_CLIENT.value,
    DeviceTypeEnum.EMULATED_DATACENTER.value,
    DeviceTypeEnum.EMULATED_MICROWAVE_RADIO_SYSTEM.value,
    DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value,
    DeviceTypeEnum.EMULATED_XR_CONSTELLATION.value,
    DeviceTypeEnum.MICROWAVE_RADIO_SYSTEM.value,
    DeviceTypeEnum.NETWORK.value,
    DeviceTypeEnum.OPEN_LINE_SYSTEM.value,
    DeviceTypeEnum.XR_CONSTELLATION.value,
}

IGNORE_DEVICE_NAMES = {
    NetworkTypeEnum.TE_OTN_TOPOLOGY: {
        '128.32.10.1', '128.32.33.5', '128.32.20.5', '128.32.20.1', '128.32.10.5', 'nce-t'
    },
    NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY: {

    },
}

    topology_name = topology_details.name
    match = re.match(r'providerId\-([^\-]*)-clientId-([^\-]*)-topologyId-([^\-]*)', topology_name)
TE_TOPOLOGY_NAME = 'Huawei-Network'

def compose_network(ietf_network_obj : network, te_topology_name : str, topology_details : TopologyDetails) -> None:
    ietf_network_obj.te.name = TE_TOPOLOGY_NAME

    #te_topology_name = topology_details.name
    match = re.match(r'providerId\-([^\-]*)-clientId-([^\-]*)-topologyId-([^\-]*)', te_topology_name)
    if match is not None:
        provider_id, client_id, topology_id = match.groups()
        ietf_network_obj.te_topology_identifier.provider_id = int(provider_id)
@@ -57,12 +83,31 @@ def compose_network(ietf_network_obj : network, topology_details : TopologyDetai

    name_mappings = NameMappings()

    ignore_device_uuids = set()

    for device in topology_details.devices:
        device_uuid = device.device_id.device_uuid.uuid

        device_type = device.device_type
        if device_type in IGNORE_DEVICE_TYPES:
            ignore_device_uuids.add(device_uuid)
            continue

        device_name = device.name
        if device_name in IGNORE_DEVICE_NAMES.get(network_type, set()):
            ignore_device_uuids.add(device_uuid)
            continue

        ietf_node_obj = ietf_network_obj.node.add(device_name)
        compose_node(ietf_node_obj, device, name_mappings, network_type)

    for link in topology_details.links:
        link_device_uuids = {
            endpoint_id.device_id.device_uuid.uuid
            for endpoint_id in link.link_endpoint_ids
        }
        if len(ignore_device_uuids.intersection(link_device_uuids)) > 0:
            continue
        link_name = link.name
        ietf_link_obj = ietf_network_obj.link.add(link_name)
        compose_link(ietf_link_obj, link, name_mappings, network_type)
+22 −8
Original line number Diff line number Diff line
@@ -21,18 +21,23 @@ from .NetworkTypeEnum import NetworkTypeEnum

LOGGER = logging.getLogger(__name__)

NODE_NAME_MAPPINGS = {
MAPPINGS_TE_NODE_NAME = {
    '10.0.10.1'  : 'OA',
    '10.0.20.1'  : 'P',
    '10.0.30.1'  : 'OE',
    '10.0.40.1'  : 'P',

    '128.32.10.1': 'ONT1',
    '128.32.20.1': 'ONT2',
    '128.32.33.5': 'OLT',
}

IGNORE_ENDPOINT_NAMES = {'mgmt', 'eth1'}

def compose_node(
    ietf_node_obj : node, device : Device, name_mappings : NameMappings, network_type : NetworkTypeEnum
) -> None:
    device_name = device.name
    LOGGER.warning('network_type={:s} device_name={:s}'.format(str(network_type.value), str(device_name)))

    name_mappings.store_device_name(device)

@@ -40,11 +45,11 @@ def compose_node(

    ietf_node_obj.te._set_oper_status('up')
    ietf_node_obj.te.te_node_attributes.admin_status = 'up'
    ietf_node_obj.te.te_node_attributes.name = NODE_NAME_MAPPINGS.get(device_name, device_name)
    ietf_node_obj.te.te_node_attributes.name = MAPPINGS_TE_NODE_NAME.get(device_name, device_name)

    for endpoint in device.device_endpoints:
        endpoint_name = endpoint.name
        if endpoint_name == 'mgmt': continue
        if endpoint_name in IGNORE_ENDPOINT_NAMES: continue
        if network_type == NetworkTypeEnum.TE_OTN_TOPOLOGY and endpoint.endpoint_type != 'optical': continue

        ietf_tp_obj = ietf_node_obj.termination_point.add(endpoint_name)
@@ -91,3 +96,12 @@ def compose_node(
            ntaw._set_oper_status('up')
            ntaw.protection_type = 'ietf-te-types:lsp-protection-unprotected'
            ntaw.switching_capability = 'ietf-te-types:switching-otn'
    elif network_type == NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY:
        if device_name in {'128.32.33.5'}:
            connectivity_matrices = ietf_node_obj.te.te_node_attributes.connectivity_matrices
            lr0 = connectivity_matrices.label_restrictions.label_restriction.add(0)
            lr0.label_start.te_label.vlanid = 21
            lr0.label_end.te_label.vlanid = 21
            lr1 = connectivity_matrices.label_restrictions.label_restriction.add(1)
            lr1.label_start.te_label.vlanid = 31
            lr1.label_end.te_label.vlanid = 31
+26 −10
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import logging
from common.proto.context_pb2 import Device, EndPoint
from .bindings.networks.network.node.termination_point import termination_point
from .NameMapping import NameMappings
@@ -36,15 +37,28 @@ MAPPINGS_TE_NAME = {
    (NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY, '10.0.10.1', '500'): 'endpoint:111',
    (NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY, '10.0.10.1', '501'): 'endpoint:111',

    (NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY, '10.0.30.1', '200'): '172.10.33.254',
    (NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY, '10.0.20.1', '500'): 'endpoint:111',
    (NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY, '10.0.20.1', '501'): 'endpoint:111',

    (NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY, '10.0.30.1', '200'): 'endpoint:111',
    (NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY, '10.0.30.1', '500'): 'endpoint:111',
    (NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY, '10.0.30.1', '501'): 'endpoint:111',

    (NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY, '10.0.40.1', '500'): 'endpoint:111',
    (NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY, '10.0.40.1', '501'): 'endpoint:111',

    (NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY, '128.32.33.5', '500') : 'endpoint:111',
}

MAPPINGS_TE_TP_ID = {
    (NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY, '10.0.10.1', '200'): '128.32.33.254',
    (NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY, '10.0.30.1', '200'): '172.10.33.254',

    (NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY, '128.32.33.5', '500') : '128.32.33.2',
}

LOGGER = logging.getLogger(__name__)

def compose_term_point(
    ietf_tp_obj : termination_point, device : Device, endpoint : EndPoint, name_mappings : NameMappings,
    network_type : NetworkTypeEnum
@@ -56,11 +70,13 @@ def compose_term_point(

    ietf_tp_obj.te_tp_id = MAPPINGS_TE_TP_ID.get((network_type, device_name, endpoint_name), endpoint_name)

    if (network_type, device_name, endpoint_name) in MAPPINGS_TE_NAME:
        ietf_tp_obj.te._set_oper_status('up')
        ietf_tp_obj.te.admin_status = 'up'
        ietf_tp_obj.te.name = MAPPINGS_TE_NAME.get((network_type, device_name, endpoint_name), endpoint_name)

    if network_type == NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY:
        if (network_type, device_name, endpoint_name) in MAPPINGS_TE_NAME:
            ietf_if_sw_cap = ietf_tp_obj.te.interface_switching_capability.add(
                'ietf-te-types:switching-l2sc ietf-te-types:lsp-encoding-ethernet'
            )
+23 −8
Original line number Diff line number Diff line
@@ -32,22 +32,19 @@ def manual_fixes(json_response : Dict) -> None:
        else:
            network_type = None

        # Fix value type of 
        for json_node in json_network.get('node', []):
            for json_tp in json_node.get('ietf-network-topology:termination-point', []):

                if json_node['node-id'] in {'10.0.10.1', '10.0.30.1'}:
                    if network_type == NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY:
                        if 'ietf-eth-te-topology:eth-svc' in json_tp:
                            client_facing = json_tp['tp-id'] == '200'
                            json_tp['ietf-eth-te-topology:eth-svc']['client-facing'] = client_facing

                json_tp_te = json_tp.get('ietf-te-topology:te', {})

                if network_type == NetworkTypeEnum.TE_OTN_TOPOLOGY:
                    json_tp_te_cs = json_tp_te.setdefault('ietf-otn-topology:client-svc', {})
                    json_tp_te_cs['client-facing'] = False
                elif network_type == NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY:
                    if 'ietf-eth-te-topology:eth-svc' in json_tp:
                        client_facing = json_tp['tp-id'] in {'200', '201'}
                        json_tp['ietf-eth-te-topology:eth-svc']['client-facing'] = client_facing

                # Fix value type of bandwidth
                for json_if_sw_cap in json_tp_te.get('interface-switching-capability', []):
                    for json_max_lsp_bandwidth in json_if_sw_cap.get('max-lsp-bandwidth', []):
                        json_te_bw = json_max_lsp_bandwidth.get('te-bandwidth', {})
@@ -56,3 +53,21 @@ def manual_fixes(json_response : Dict) -> None:
                                eth_bw = json_te_bw['ietf-eth-te-topology:eth-bandwidth']
                                if isinstance(eth_bw, str):
                                    json_te_bw['ietf-eth-te-topology:eth-bandwidth'] = int(eth_bw)

        for json_link in json_network.get('ietf-network-topology:link', []):
            json_link_te_attributes = json_link.get('ietf-te-topology:te', {}).get('te-link-attributes', {})

            # Fix value type of bandwidth
            json_te_bw = json_link_te_attributes.get('max-link-bandwidth', {}).get('te-bandwidth', {})
            if network_type == NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY:
                if 'ietf-eth-te-topology:eth-bandwidth' in json_te_bw:
                    eth_bw = json_te_bw['ietf-eth-te-topology:eth-bandwidth']
                    if isinstance(eth_bw, str):
                        json_te_bw['ietf-eth-te-topology:eth-bandwidth'] = int(eth_bw)

                for json_unresv_bandwidth in json_link_te_attributes.get('unreserved-bandwidth', []):
                    json_te_bw = json_unresv_bandwidth.get('te-bandwidth', {})
                    if 'ietf-eth-te-topology:eth-bandwidth' in json_te_bw:
                        eth_bw = json_te_bw['ietf-eth-te-topology:eth-bandwidth']
                        if isinstance(eth_bw, str):
                            json_te_bw['ietf-eth-te-topology:eth-bandwidth'] = int(eth_bw)
Loading