Loading src/tests/tools/mock_ietf_actn_sdn_ctrl/ssl_not_working/Dockerfile→src/tests/tools/mock_ietf_actn_sdn_ctrl/Dockerfile +5 −3 Original line number Diff line number Diff line Loading @@ -23,13 +23,15 @@ RUN python3 -m pip install --upgrade setuptools wheel RUN python3 -m pip install --upgrade pip-tools # Create component sub-folders, and copy content RUN mkdir -p /var/teraflow/mock_mw_sdn_ctrl WORKDIR /var/teraflow/mock_mw_sdn_ctrl RUN mkdir -p /var/teraflow/mock_ietf_actn_sdn_ctrl WORKDIR /var/teraflow/mock_ietf_actn_sdn_ctrl COPY . . # Get specific Python packages RUN pip-compile --quiet --output-file=requirements.txt requirements.in RUN python3 -m pip install -r requirements.txt RUN python3 -m pip list # Start the service ENTRYPOINT ["python", "MockMWSdnCtrl.py"] ENTRYPOINT ["python", "MockIetfActnSdnCtrl.py"] src/tests/tools/mock_ietf_actn_sdn_ctrl/MockIetfActnSdnCtrl.py +24 −94 Original line number Diff line number Diff line Loading @@ -12,79 +12,27 @@ # See the License for the specific language governing permissions and # limitations under the License. # Mock MicroWave SDN controller # Mock IETF ACTN SDN controller # ----------------------------- # REST server implementing minimal support for: # - IETF YANG data model for Network Topology # Ref: https://www.rfc-editor.org/rfc/rfc8345.html # - IETF YANG data model for Transport Network Client Signals # Ref: https://www.ietf.org/archive/id/draft-ietf-ccamp-client-signal-yang-07.html # - IETF YANG Data Model for Transport Network Client Signals # Ref: https://www.ietf.org/archive/id/draft-ietf-ccamp-client-signal-yang-10.html # - IETF YANG Data Model for Traffic Engineering Tunnels, Label Switched Paths and Interfaces # Ref: https://www.ietf.org/archive/id/draft-ietf-teas-yang-te-34.html # Ref: https://blog.miguelgrinberg.com/post/running-your-flask-application-over-https # Ref: https://blog.miguelgrinberg.com/post/designing-a-restful-api-using-flask-restful import functools, logging, sys, time from flask import Flask, abort, jsonify, make_response, request from flask import Flask, jsonify, make_response, request from flask_restful import Api, Resource from ResourceEthServices import EthService, EthServices from ResourceOsuTunnels import OsuTunnel, OsuTunnels BIND_ADDRESS = '0.0.0.0' BIND_PORT = 8443 BASE_URL = '/nmswebs/restconf/data' BASE_URL = '/restconf/data' STR_ENDPOINT = 'https://{:s}:{:s}{:s}'.format(str(BIND_ADDRESS), str(BIND_PORT), str(BASE_URL)) LOG_LEVEL = logging.DEBUG NETWORK_NODES = [ {'node-id': '192.168.27.139', 'ietf-network-topology:termination-point': [ {'tp-id': '1', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '2', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '3', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '4', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '5', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '6', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '10', 'ietf-te-topology:te': {'name': 'antena' }}, ]}, {'node-id': '192.168.27.140', 'ietf-network-topology:termination-point': [ {'tp-id': '1', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '2', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '3', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '4', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '5', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '6', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '10', 'ietf-te-topology:te': {'name': 'antena' }}, ]}, {'node-id': '192.168.27.141', 'ietf-network-topology:termination-point': [ {'tp-id': '1', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '2', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '3', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '4', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '5', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '6', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '10', 'ietf-te-topology:te': {'name': 'antena' }}, ]}, {'node-id': '192.168.27.142', 'ietf-network-topology:termination-point': [ {'tp-id': '1', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '2', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '3', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '4', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '5', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '6', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '10', 'ietf-te-topology:te': {'name': 'antena' }}, ]} ] NETWORK_LINKS = [ { 'link-id' : '192.168.27.139:10--192.168.27.140:10', 'source' : {'source-node': '192.168.27.139', 'source-tp': '10'}, 'destination': {'dest-node' : '192.168.27.140', 'dest-tp' : '10'}, }, { 'link-id' : '192.168.27.141:10--192.168.27.142:10', 'source' : {'source-node': '192.168.27.141', 'source-tp': '10'}, 'destination': {'dest-node' : '192.168.27.142', 'dest-tp' : '10'}, } ] NETWORK_SERVICES = {} logging.basicConfig(level=LOG_LEVEL, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s") LOGGER = logging.getLogger(__name__) Loading @@ -99,35 +47,6 @@ class Health(Resource): def get(self): return make_response(jsonify({}), 200) class Network(Resource): def get(self, network_uuid : str): if network_uuid != 'SIAE-ETH-TOPOLOGY': abort(400) network = {'node': NETWORK_NODES, 'ietf-network-topology:link': NETWORK_LINKS} return make_response(jsonify({'ietf-network:network': network}), 200) class Services(Resource): def get(self): services = [service for service in NETWORK_SERVICES.values()] return make_response(jsonify({'ietf-eth-tran-service:etht-svc': {'etht-svc-instances': services}}), 200) def post(self): json_request = request.get_json() if not json_request: abort(400) if not isinstance(json_request, dict): abort(400) if 'etht-svc-instances' not in json_request: abort(400) json_services = json_request['etht-svc-instances'] if not isinstance(json_services, list): abort(400) if len(json_services) != 1: abort(400) svc_data = json_services[0] etht_svc_name = svc_data['etht-svc-name'] NETWORK_SERVICES[etht_svc_name] = svc_data return make_response(jsonify({}), 201) class DelServices(Resource): def delete(self, service_uuid : str): NETWORK_SERVICES.pop(service_uuid, None) return make_response(jsonify({}), 204) def main(): LOGGER.info('Starting...') Loading @@ -135,10 +54,21 @@ def main(): app.after_request(functools.partial(log_request, LOGGER)) api = Api(app, prefix=BASE_URL) api.add_resource(Health, '/ietf-network:networks') api.add_resource(Network, '/ietf-network:networks/network=<string:network_uuid>') api.add_resource(Services, '/ietf-eth-tran-service:etht-svc') api.add_resource(DelServices, '/ietf-eth-tran-service:etht-svc/etht-svc-instances=<string:service_uuid>') api.add_resource( Health, '/' ) api.add_resource( OsuTunnels, '/ietf-te:tunnel' ) api.add_resource( OsuTunnel, '/ietf-te:tunnel[name=<string:name>]' ) api.add_resource( EthServices, '/ietf-eth-tran-service:etht-svc' ) api.add_resource( EthService, '/ietf-eth-tran-service:etht-svc/etht-svc-instances[etht-svc-name=<string:etht_svc_name>]' ) LOGGER.info('Listening on {:s}...'.format(str(STR_ENDPOINT))) app.run(debug=True, host=BIND_ADDRESS, port=BIND_PORT, ssl_context='adhoc') Loading src/tests/tools/mock_ietf_actn_sdn_ctrl/ResourceEthServices.py 0 → 100644 +53 −0 Original line number Diff line number Diff line # Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. # REST-API resource implementing minimal support for "IETF YANG Data Model for Transport Network Client Signals". # Ref: https://www.ietf.org/archive/id/draft-ietf-ccamp-client-signal-yang-10.html from flask import abort, jsonify, make_response, request from flask_restful import Resource ETH_SERVICES = {} class EthServices(Resource): def get(self): eth_services = [eth_service for eth_service in ETH_SERVICES.values()] data = {'ietf-eth-tran-service:etht-svc': {'etht-svc-instances': eth_services}} return make_response(jsonify(data), 200) def post(self): json_request = request.get_json() if not json_request: abort(400) if not isinstance(json_request, dict): abort(400) if 'ietf-eth-tran-service:etht-svc' not in json_request: abort(400) json_request = json_request['ietf-eth-tran-service:etht-svc'] if 'etht-svc-instances' not in json_request: abort(400) eth_services = json_request['etht-svc-instances'] if not isinstance(eth_services, list): abort(400) if len(eth_services) != 1: abort(400) eth_service = eth_services[0] etht_svc_name = eth_service['etht-svc-name'] ETH_SERVICES[etht_svc_name] = eth_service return make_response(jsonify({}), 201) class EthService(Resource): def get(self, service_uuid : str): eth_service = ETH_SERVICES.get(service_uuid, None) data,status = ({}, 404) if eth_service is None else (eth_service, 200) return make_response(jsonify(data), status) def delete(self, service_uuid : str): eth_service = ETH_SERVICES.pop(service_uuid, None) data,status = ({}, 404) if eth_service is None else (eth_service, 204) return make_response(jsonify(data), status) src/tests/tools/mock_ietf_actn_sdn_ctrl/ResourceOsuTunnels.py 0 → 100644 +51 −0 Original line number Diff line number Diff line # Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. # REST-API resource implementing minimal support for "IETF YANG Data Model for Traffic Engineering Tunnels, # Label Switched Paths and Interfaces". # Ref: https://www.ietf.org/archive/id/draft-ietf-teas-yang-te-34.html from flask import abort, jsonify, make_response, request from flask_restful import Resource OSU_TUNNELS = {} class OsuTunnels(Resource): def get(self): osu_tunnels = [osu_tunnel for osu_tunnel in OSU_TUNNELS.values()] data = {'ietf-te:tunnel': osu_tunnels} return make_response(jsonify(data), 200) def post(self): json_request = request.get_json() if not json_request: abort(400) if not isinstance(json_request, list): abort(400) osu_tunnels = json_request['ietf-te:tunnel'] if len(osu_tunnels) != 1: abort(400) osu_tunnel = osu_tunnels[0] name = osu_tunnel['name'] OSU_TUNNELS[name] = osu_tunnel return make_response(jsonify({}), 201) class OsuTunnel(Resource): def get(self, osu_tunnel_name : str): osu_tunnel = OSU_TUNNELS.get(osu_tunnel_name, None) data,status = ({}, 404) if osu_tunnel is None else (osu_tunnel, 200) return make_response(jsonify(data), status) def delete(self, osu_tunnel_name : str): osu_tunnel = OSU_TUNNELS.pop(osu_tunnel_name, None) data,status = ({}, 404) if osu_tunnel is None else (osu_tunnel, 204) return make_response(jsonify(data), status) src/tests/tools/mock_ietf_actn_sdn_ctrl/__init__.py 0 → 100644 +14 −0 Original line number Diff line number Diff line # Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. Loading
src/tests/tools/mock_ietf_actn_sdn_ctrl/ssl_not_working/Dockerfile→src/tests/tools/mock_ietf_actn_sdn_ctrl/Dockerfile +5 −3 Original line number Diff line number Diff line Loading @@ -23,13 +23,15 @@ RUN python3 -m pip install --upgrade setuptools wheel RUN python3 -m pip install --upgrade pip-tools # Create component sub-folders, and copy content RUN mkdir -p /var/teraflow/mock_mw_sdn_ctrl WORKDIR /var/teraflow/mock_mw_sdn_ctrl RUN mkdir -p /var/teraflow/mock_ietf_actn_sdn_ctrl WORKDIR /var/teraflow/mock_ietf_actn_sdn_ctrl COPY . . # Get specific Python packages RUN pip-compile --quiet --output-file=requirements.txt requirements.in RUN python3 -m pip install -r requirements.txt RUN python3 -m pip list # Start the service ENTRYPOINT ["python", "MockMWSdnCtrl.py"] ENTRYPOINT ["python", "MockIetfActnSdnCtrl.py"]
src/tests/tools/mock_ietf_actn_sdn_ctrl/MockIetfActnSdnCtrl.py +24 −94 Original line number Diff line number Diff line Loading @@ -12,79 +12,27 @@ # See the License for the specific language governing permissions and # limitations under the License. # Mock MicroWave SDN controller # Mock IETF ACTN SDN controller # ----------------------------- # REST server implementing minimal support for: # - IETF YANG data model for Network Topology # Ref: https://www.rfc-editor.org/rfc/rfc8345.html # - IETF YANG data model for Transport Network Client Signals # Ref: https://www.ietf.org/archive/id/draft-ietf-ccamp-client-signal-yang-07.html # - IETF YANG Data Model for Transport Network Client Signals # Ref: https://www.ietf.org/archive/id/draft-ietf-ccamp-client-signal-yang-10.html # - IETF YANG Data Model for Traffic Engineering Tunnels, Label Switched Paths and Interfaces # Ref: https://www.ietf.org/archive/id/draft-ietf-teas-yang-te-34.html # Ref: https://blog.miguelgrinberg.com/post/running-your-flask-application-over-https # Ref: https://blog.miguelgrinberg.com/post/designing-a-restful-api-using-flask-restful import functools, logging, sys, time from flask import Flask, abort, jsonify, make_response, request from flask import Flask, jsonify, make_response, request from flask_restful import Api, Resource from ResourceEthServices import EthService, EthServices from ResourceOsuTunnels import OsuTunnel, OsuTunnels BIND_ADDRESS = '0.0.0.0' BIND_PORT = 8443 BASE_URL = '/nmswebs/restconf/data' BASE_URL = '/restconf/data' STR_ENDPOINT = 'https://{:s}:{:s}{:s}'.format(str(BIND_ADDRESS), str(BIND_PORT), str(BASE_URL)) LOG_LEVEL = logging.DEBUG NETWORK_NODES = [ {'node-id': '192.168.27.139', 'ietf-network-topology:termination-point': [ {'tp-id': '1', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '2', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '3', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '4', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '5', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '6', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '10', 'ietf-te-topology:te': {'name': 'antena' }}, ]}, {'node-id': '192.168.27.140', 'ietf-network-topology:termination-point': [ {'tp-id': '1', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '2', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '3', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '4', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '5', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '6', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '10', 'ietf-te-topology:te': {'name': 'antena' }}, ]}, {'node-id': '192.168.27.141', 'ietf-network-topology:termination-point': [ {'tp-id': '1', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '2', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '3', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '4', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '5', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '6', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '10', 'ietf-te-topology:te': {'name': 'antena' }}, ]}, {'node-id': '192.168.27.142', 'ietf-network-topology:termination-point': [ {'tp-id': '1', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '2', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '3', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '4', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '5', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '6', 'ietf-te-topology:te': {'name': 'ethernet'}}, {'tp-id': '10', 'ietf-te-topology:te': {'name': 'antena' }}, ]} ] NETWORK_LINKS = [ { 'link-id' : '192.168.27.139:10--192.168.27.140:10', 'source' : {'source-node': '192.168.27.139', 'source-tp': '10'}, 'destination': {'dest-node' : '192.168.27.140', 'dest-tp' : '10'}, }, { 'link-id' : '192.168.27.141:10--192.168.27.142:10', 'source' : {'source-node': '192.168.27.141', 'source-tp': '10'}, 'destination': {'dest-node' : '192.168.27.142', 'dest-tp' : '10'}, } ] NETWORK_SERVICES = {} logging.basicConfig(level=LOG_LEVEL, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s") LOGGER = logging.getLogger(__name__) Loading @@ -99,35 +47,6 @@ class Health(Resource): def get(self): return make_response(jsonify({}), 200) class Network(Resource): def get(self, network_uuid : str): if network_uuid != 'SIAE-ETH-TOPOLOGY': abort(400) network = {'node': NETWORK_NODES, 'ietf-network-topology:link': NETWORK_LINKS} return make_response(jsonify({'ietf-network:network': network}), 200) class Services(Resource): def get(self): services = [service for service in NETWORK_SERVICES.values()] return make_response(jsonify({'ietf-eth-tran-service:etht-svc': {'etht-svc-instances': services}}), 200) def post(self): json_request = request.get_json() if not json_request: abort(400) if not isinstance(json_request, dict): abort(400) if 'etht-svc-instances' not in json_request: abort(400) json_services = json_request['etht-svc-instances'] if not isinstance(json_services, list): abort(400) if len(json_services) != 1: abort(400) svc_data = json_services[0] etht_svc_name = svc_data['etht-svc-name'] NETWORK_SERVICES[etht_svc_name] = svc_data return make_response(jsonify({}), 201) class DelServices(Resource): def delete(self, service_uuid : str): NETWORK_SERVICES.pop(service_uuid, None) return make_response(jsonify({}), 204) def main(): LOGGER.info('Starting...') Loading @@ -135,10 +54,21 @@ def main(): app.after_request(functools.partial(log_request, LOGGER)) api = Api(app, prefix=BASE_URL) api.add_resource(Health, '/ietf-network:networks') api.add_resource(Network, '/ietf-network:networks/network=<string:network_uuid>') api.add_resource(Services, '/ietf-eth-tran-service:etht-svc') api.add_resource(DelServices, '/ietf-eth-tran-service:etht-svc/etht-svc-instances=<string:service_uuid>') api.add_resource( Health, '/' ) api.add_resource( OsuTunnels, '/ietf-te:tunnel' ) api.add_resource( OsuTunnel, '/ietf-te:tunnel[name=<string:name>]' ) api.add_resource( EthServices, '/ietf-eth-tran-service:etht-svc' ) api.add_resource( EthService, '/ietf-eth-tran-service:etht-svc/etht-svc-instances[etht-svc-name=<string:etht_svc_name>]' ) LOGGER.info('Listening on {:s}...'.format(str(STR_ENDPOINT))) app.run(debug=True, host=BIND_ADDRESS, port=BIND_PORT, ssl_context='adhoc') Loading
src/tests/tools/mock_ietf_actn_sdn_ctrl/ResourceEthServices.py 0 → 100644 +53 −0 Original line number Diff line number Diff line # Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. # REST-API resource implementing minimal support for "IETF YANG Data Model for Transport Network Client Signals". # Ref: https://www.ietf.org/archive/id/draft-ietf-ccamp-client-signal-yang-10.html from flask import abort, jsonify, make_response, request from flask_restful import Resource ETH_SERVICES = {} class EthServices(Resource): def get(self): eth_services = [eth_service for eth_service in ETH_SERVICES.values()] data = {'ietf-eth-tran-service:etht-svc': {'etht-svc-instances': eth_services}} return make_response(jsonify(data), 200) def post(self): json_request = request.get_json() if not json_request: abort(400) if not isinstance(json_request, dict): abort(400) if 'ietf-eth-tran-service:etht-svc' not in json_request: abort(400) json_request = json_request['ietf-eth-tran-service:etht-svc'] if 'etht-svc-instances' not in json_request: abort(400) eth_services = json_request['etht-svc-instances'] if not isinstance(eth_services, list): abort(400) if len(eth_services) != 1: abort(400) eth_service = eth_services[0] etht_svc_name = eth_service['etht-svc-name'] ETH_SERVICES[etht_svc_name] = eth_service return make_response(jsonify({}), 201) class EthService(Resource): def get(self, service_uuid : str): eth_service = ETH_SERVICES.get(service_uuid, None) data,status = ({}, 404) if eth_service is None else (eth_service, 200) return make_response(jsonify(data), status) def delete(self, service_uuid : str): eth_service = ETH_SERVICES.pop(service_uuid, None) data,status = ({}, 404) if eth_service is None else (eth_service, 204) return make_response(jsonify(data), status)
src/tests/tools/mock_ietf_actn_sdn_ctrl/ResourceOsuTunnels.py 0 → 100644 +51 −0 Original line number Diff line number Diff line # Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. # REST-API resource implementing minimal support for "IETF YANG Data Model for Traffic Engineering Tunnels, # Label Switched Paths and Interfaces". # Ref: https://www.ietf.org/archive/id/draft-ietf-teas-yang-te-34.html from flask import abort, jsonify, make_response, request from flask_restful import Resource OSU_TUNNELS = {} class OsuTunnels(Resource): def get(self): osu_tunnels = [osu_tunnel for osu_tunnel in OSU_TUNNELS.values()] data = {'ietf-te:tunnel': osu_tunnels} return make_response(jsonify(data), 200) def post(self): json_request = request.get_json() if not json_request: abort(400) if not isinstance(json_request, list): abort(400) osu_tunnels = json_request['ietf-te:tunnel'] if len(osu_tunnels) != 1: abort(400) osu_tunnel = osu_tunnels[0] name = osu_tunnel['name'] OSU_TUNNELS[name] = osu_tunnel return make_response(jsonify({}), 201) class OsuTunnel(Resource): def get(self, osu_tunnel_name : str): osu_tunnel = OSU_TUNNELS.get(osu_tunnel_name, None) data,status = ({}, 404) if osu_tunnel is None else (osu_tunnel, 200) return make_response(jsonify(data), status) def delete(self, osu_tunnel_name : str): osu_tunnel = OSU_TUNNELS.pop(osu_tunnel_name, None) data,status = ({}, 404) if osu_tunnel is None else (osu_tunnel, 204) return make_response(jsonify(data), status)
src/tests/tools/mock_ietf_actn_sdn_ctrl/__init__.py 0 → 100644 +14 −0 Original line number Diff line number Diff line # Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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.