Commit 4ab38947 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Tests - Tools - Mock NCE T Ctrl:

- Added support for Data-change callbacks
- Added redeploy script to test with SIMAP
- Added NCE-T client for testing
parent 1e344945
Loading
Loading
Loading
Loading
+134 −0
Original line number Diff line number Diff line
OSU_TUNNEL_NAME = 'osu_tunnel_1'
URL_OSU_TUNNEL_ITEM = '/ietf-te:te/tunnels/tunnel={:s}'.format(OSU_TUNNEL_NAME)
REQUEST_OSU_TUNNEL = {"ietf-te:te": {"tunnels": {"tunnel": [
    {
        "name": OSU_TUNNEL_NAME,
        "title": "OSU_TUNNEL_1",
        "admin-state": "ietf-te-types:tunnel-admin-state-up",
        "delay": 20,
        "te-bandwidth": {
            "layer": "odu",
            "odu-type": "osuflex",
            "number": 40
        },
        "bidirectional": True,
        "destination-endpoints": {
            "destination-endpoint": [
                {
                    "node-id": "10.0.30.1",
                    "tp-id": "200",
                    "ttp-channel-name": "och:1-odu2:1-oduflex:3-osuflex:1",
                    "protection-role": "work"
                }
            ]
        },
        "source-endpoints": {
            "source-endpoint": [
                {
                    "node-id": "10.0.10.1",
                    "tp-id": "200",
                    "ttp-channel-name": "och:1-odu2:1-oduflex:1-osuflex:2",
                    "protection-role": "work"
                }
            ]
        },
        "restoration": {
            "restoration-type": "ietf-te-types:lsp-restoration-not-applicable",
            "restoration-lock": False
        },
        "protection": {
            "protection-type": "ietf-te-types:lsp-protection-unprotected",
            "protection-reversion-disable": True
        }
    }
]}}}

ETHT_SERVICE_NAME = 'etht_service_1'
URL_ETHT_SERVICE_ITEM = '/ietf-eth-tran-service:etht-svc/etht-svc-instances={:s}'.format(ETHT_SERVICE_NAME)
REQUEST_ETHT_SERVICE = {"ietf-eth-tran-service:etht-svc": {"etht-svc-instances": [
    {
        "etht-svc-name": ETHT_SERVICE_NAME,
        "etht-svc-title": "ETHT_SERVICE_1",
        "etht-svc-type": "op-mp2mp-svc",
        "source-endpoints": {
            "source-endpoint": [
                {
                    "node-id": "10.0.10.1",
                    "tp-id": "200",
                    "protection-role": "work",
                    "layer-specific": {
                        "access-type": "port"
                    },
                    "is-extendable": False,
                    "is-terminal": True,
                    "static-route-list": [
                        {
                            "destination": "128.32.10.5",
                            "destination-mask": 24,
                            "next-hop": "128.32.33.5"
                        },
                        {
                            "destination": "128.32.20.5",
                            "destination-mask": 24,
                            "next-hop": "128.32.33.5"
                        }
                    ],
                    "outer-tag": {
                        "tag-type": "ietf-eth-tran-types:classify-c-vlan",
                        "vlan-value": 21
                    },
                    "service-classification-type": "ietf-eth-tran-type:vlan-classification",
                    "ingress-egress-bandwidth-profile" : {
                        "bandwidth-profile-type": "ietf-eth-tran-types:mef-10-bwp",
                        "CIR": 10000000,
                        "EIR": 10000000
                    }
                }
            ]
        },
        "destination-endpoints": {
            "destination-endpoint": [
                {
                    "node-id": "10.0.30.1",
                    "tp-id": "200",
                    "protection-role": "work",
                    "layer-specific": {
                        "access-type": "port"
                    },
                    "is-extendable": False,
                    "is-terminal": True,
                    "static-route-list": [
                        {
                            "destination": "172.1.101.22",
                            "destination-mask": 24,
                            "next-hop": "172.10.33.5"
                        }
                    ],
                    "outer-tag": {
                        "tag-type": "ietf-eth-tran-types:classify-c-vlan",
                        "vlan-value": 101
                    },
                    "service-classification-type": "ietf-eth-tran-type:vlan-classification",
                    "ingress-egress-bandwidth-profile" : {
                        "bandwidth-profile-type": "ietf-eth-tran-types:mef-10-bwp",
                        "CIR": 10000000,
                        "EIR": 10000000
                    }
                }
            ]
        },
        "svc-tunnel": [
            {
                "tunnel-name": "OSU_TUNNEL_NAME"
            }
        ],
        "optimizations": {
            "optimization-metric": [
                {
                    "metric-role": "work",
                    "metric-type": "ietf-te-types:path-metric-te"
                }
            ]
        }
    }
]}}
+14 −0
Original line number Diff line number Diff line
# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+41 −0
Original line number Diff line number Diff line
# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


import logging
from common.tools.rest_conf.client.RestConfClient import RestConfClient
from .Requests import (
    URL_OSU_TUNNEL_ITEM, REQUEST_OSU_TUNNEL,
    URL_ETHT_SERVICE_ITEM, REQUEST_ETHT_SERVICE,
)

logging.basicConfig(level=logging.INFO)
logging.getLogger('RestConfClient').setLevel(logging.DEBUG)
LOGGER = logging.getLogger(__name__)

def main() -> None:
    restconf_client = RestConfClient(
        '172.17.0.1', port=8081,
        logger=logging.getLogger('RestConfClient')
    )

    LOGGER.info('Creating OSU Tunnel: {:s}'.format(str(REQUEST_OSU_TUNNEL)))
    restconf_client.post(URL_OSU_TUNNEL_ITEM, body=REQUEST_OSU_TUNNEL)

    LOGGER.info('Creating ETH-T Service: {:s}'.format(str(REQUEST_ETHT_SERVICE)))
    restconf_client.post(URL_ETHT_SERVICE_ITEM, body=REQUEST_ETHT_SERVICE)


if __name__ == '__main__':
    main()
+53 −0
Original line number Diff line number Diff line
# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


import logging, re
from typing import Dict, Optional
from common.tools.rest_conf.server.restconf_server.Callbacks import _Callback


LOGGER = logging.getLogger(__name__)


class CallbackOsuTunnel(_Callback):
    def __init__(self) -> None:
        pattern = r'/restconf/data'
        pattern += r'/ietf-te:te/tunnels'
        pattern += r'/tunnel=(?P<osu_tunnel_name>[^/]+)'
        super().__init__(pattern)

    def execute(
        self, match : re.Match, path : str, old_data : Optional[Dict],
        new_data : Optional[Dict]
    ) -> bool:
        MSG = '[on_osu_tunnel] match={:s} path={:s} old_data={:s} new_data={:s}'
        LOGGER.warning(MSG.format(str(match.groupdict()), str(path), str(old_data), str(new_data)))
        return False


class CallbackEthTService(_Callback):
    def __init__(self) -> None:
        pattern = r'/restconf/data'
        pattern += r'/ietf-eth-tran-service:etht-svc'
        pattern += r'/etht-svc-instances=(?P<etht_service_name>[^/]+)'
        super().__init__(pattern)

    def execute(
        self, match : re.Match, path : str, old_data : Optional[Dict],
        new_data : Optional[Dict]
    ) -> bool:
        MSG = '[on_etht_service] match={:s} path={:s} old_data={:s} new_data={:s}'
        LOGGER.warning(MSG.format(str(match.groupdict()), str(path), str(old_data), str(new_data)))
        return False
+6 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

import logging
from common.tools.rest_conf.server.restconf_server.RestConfServerApplication import RestConfServerApplication
from .Callbacks import CallbackEthTService, CallbackOsuTunnel
from .SimapUpdater import SimapUpdater


@@ -31,6 +32,7 @@ logging.getLogger('RestConfClient').setLevel(logging.WARN)

LOGGER.info('Starting...')
rcs_app = RestConfServerApplication()

rcs_app.register_host_meta()
rcs_app.register_restconf()
LOGGER.info('All connectors registered')
@@ -43,6 +45,10 @@ if len(networks) == 1 and networks[0]['network-id'] == 'admin':
    simap_updater = SimapUpdater()
    simap_updater.upload_topology(networks[0])

    rcs_app.callback_dispatcher.register(CallbackOsuTunnel())
    rcs_app.callback_dispatcher.register(CallbackEthTService())
    LOGGER.info('All callbacks registered')

rcs_app.dump_configuration()
app = rcs_app.get_flask_app()

Loading