diff --git a/src/compute/service/__main__.py b/src/compute/service/__main__.py index 345b2fdd6950ecda802e8bd1c86e1421b5c60d84..cfd65e1de87ec783546511cf6f5a0c4701e271ff 100644 --- a/src/compute/service/__main__.py +++ b/src/compute/service/__main__.py @@ -21,6 +21,7 @@ from common.Settings import ( from .ComputeService import ComputeService from .rest_server.RestServer import RestServer from .rest_server.nbi_plugins.ietf_l2vpn import register_ietf_l2vpn +from .rest_server.nbi_plugins.ietf_network_slice import register_ietf_nss terminate = threading.Event() LOGGER = None @@ -54,8 +55,10 @@ def main(): grpc_service = ComputeService() grpc_service.start() + # Starting Rest Server rest_server = RestServer() - register_ietf_l2vpn(rest_server) + register_ietf_l2vpn(rest_server) # Registering L2VPN entrypoint + register_ietf_nss(rest_server) # Registering NSS entrypoint rest_server.start() # Wait for Ctrl+C or termination signal diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py index c77d714a94fa8d2d4ee9cd2c3db06949665a489c..aad85240afa58186708e6da99c750be7e3ee61f6 100644 --- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py +++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py @@ -20,9 +20,9 @@ from common.Constants import DEFAULT_CONTEXT_UUID from common.proto.context_pb2 import ServiceId, ServiceStatusEnum, SliceStatusEnum from context.client.ContextClient import ContextClient from service.client.ServiceClient import ServiceClient -from .tools.Authentication import HTTP_AUTH -from .tools.ContextMethods import get_service, get_slice -from .tools.HttpStatusCodes import HTTP_GATEWAYTIMEOUT, HTTP_NOCONTENT, HTTP_OK, HTTP_SERVERERROR +from compute.service.rest_server.nbi_plugins.tools.Authentication import HTTP_AUTH +from compute.service.rest_server.nbi_plugins.tools.ContextMethods import get_service, get_slice +from compute.service.rest_server.nbi_plugins.tools.HttpStatusCodes import HTTP_GATEWAYTIMEOUT, HTTP_NOCONTENT, HTTP_OK, HTTP_SERVERERROR LOGGER = logging.getLogger(__name__) diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py index 7b959b2895d0f0acd27058fcb5e9a571cf6553d2..7dbdfd37a285d3323ab3fb20dd547838056032fd 100644 --- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py +++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py @@ -23,9 +23,9 @@ from common.proto.context_pb2 import Service, ServiceStatusEnum, ServiceTypeEnum from service.client.ServiceClient import ServiceClient from slice.client.SliceClient import SliceClient from .schemas.vpn_service import SCHEMA_VPN_SERVICE -from .tools.Authentication import HTTP_AUTH -from .tools.HttpStatusCodes import HTTP_CREATED, HTTP_SERVERERROR -from .tools.Validator import validate_message +from compute.service.rest_server.nbi_plugins.tools.HttpStatusCodes import HTTP_CREATED, HTTP_SERVERERROR +from compute.service.rest_server.nbi_plugins.tools.Validator import validate_message +from compute.service.rest_server.nbi_plugins.tools.Authentication import HTTP_AUTH LOGGER = logging.getLogger(__name__) diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py index 8be63895b813d7411b76ddeb33902babbf4c9743..609828b1aea9119664d9f1aa684db028ca5cc980 100644 --- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py +++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py @@ -26,10 +26,10 @@ from context.client.ContextClient import ContextClient from service.client.ServiceClient import ServiceClient from slice.client.SliceClient import SliceClient from .schemas.site_network_access import SCHEMA_SITE_NETWORK_ACCESS -from .tools.Authentication import HTTP_AUTH -from .tools.ContextMethods import get_service, get_slice -from .tools.HttpStatusCodes import HTTP_NOCONTENT, HTTP_SERVERERROR -from .tools.Validator import validate_message +from compute.service.rest_server.nbi_plugins.tools.Authentication import HTTP_AUTH +from compute.service.rest_server.nbi_plugins.tools.ContextMethods import get_service, get_slice +from compute.service.rest_server.nbi_plugins.tools.HttpStatusCodes import HTTP_NOCONTENT, HTTP_SERVERERROR +from compute.service.rest_server.nbi_plugins.tools.Validator import validate_message from .Constants import BEARER_MAPPINGS, DEFAULT_ADDRESS_FAMILIES, DEFAULT_BGP_AS, DEFAULT_BGP_ROUTE_TARGET, DEFAULT_MTU LOGGER = logging.getLogger(__name__) diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Service.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Service.py new file mode 100644 index 0000000000000000000000000000000000000000..9c7c116031caf4c3078517732b51bbc40da2c97e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Service.py @@ -0,0 +1,45 @@ +# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) +# +# 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 flask.json import jsonify +from flask_restful import Resource +from flask import request +from compute.service.rest_server.nbi_plugins.tools.Authentication import HTTP_AUTH +from compute.service.rest_server.nbi_plugins.tools.HttpStatusCodes import HTTP_OK + +LOGGER = logging.getLogger(__name__) + +class NSS_Service(Resource): + @HTTP_AUTH.login_required + def get(self, slice_id : str): + LOGGER.debug('GET Slice ID: {:s}'.format(str(slice_id))) + LOGGER.debug('GET Request: {:s}'.format(str(request))) + + # TODO Return information and status about requested slice + + response = jsonify({"message": "Requested info for slice {:s}".format(slice_id)}) + response.status_code = HTTP_OK + return response + + @HTTP_AUTH.login_required + def delete(self, slice_id : str): + LOGGER.debug('DELETE Slice ID: {:s}'.format(str(slice_id))) + LOGGER.debug('DELETE Request: {:s}'.format(str(request))) + + # TODO Delete the requested slice + + response = jsonify({"message": "Deletion request for slice {:s}".format(slice_id)}) + response.status_code = HTTP_OK + return response diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services.py new file mode 100644 index 0000000000000000000000000000000000000000..08f1dced4d82b84ecd25aa978d504641822dad75 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services.py @@ -0,0 +1,44 @@ +# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) +# +# 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 typing import Dict +from flask.json import jsonify +from flask_restful import Resource +from flask import request +from compute.service.rest_server.nbi_plugins.tools.Authentication import HTTP_AUTH +from compute.service.rest_server.nbi_plugins.tools.HttpStatusCodes import HTTP_BADREQUEST, HTTP_OK +from werkzeug.exceptions import UnsupportedMediaType + +LOGGER = logging.getLogger(__name__) + +class NSS_Services(Resource): + @HTTP_AUTH.login_required + def get(self): + response = jsonify({"message": "All went well!"}) + response.status_code + + # TODO Return list of current network-slice-services + return response + + @HTTP_AUTH.login_required + def post(self): + if not request.is_json: raise UnsupportedMediaType('JSON payload is required') + request_data : Dict = request.json + LOGGER.debug('POST Request: {:s}'.format(str(request_data))) + + # TODO Parse network-slice-service request and cascade to Slice and Policy componentes + response = jsonify({"message" : "POST message received correctly"}) + response.status_code = HTTP_OK + return response \ No newline at end of file diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..aa45206cd2e20546ad1a4af100c9ec1855b28b64 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/__init__.py @@ -0,0 +1,32 @@ +# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) +# +# 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. + +# IETF draft-ietf-teas-ietf-network-slice-nbi-yang-02 - IETF Network Slice Service YANG Model +# Ref: https://datatracker.ietf.org/doc/draft-ietf-teas-ietf-network-slice-nbi-yang/ + +from flask_restful import Resource +from compute.service.rest_server.RestServer import RestServer +from .NSS_Services import NSS_Services +from .NSS_Service import NSS_Service + +URL_PREFIX = '/ietf-network-slice-service:ietf-nss' + +def _add_resource(rest_server : RestServer, resource : Resource, *urls, **kwargs): + urls = [(URL_PREFIX + url) for url in urls] + rest_server.add_resource(resource, *urls, **kwargs) + +def register_ietf_nss(rest_server : RestServer): + _add_resource(rest_server, NSS_Services, '/network-slice-services') + _add_resource(rest_server, NSS_Service, '/network-slice-services/slice-service=<string:slice_id>') + \ No newline at end of file diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/ietf-network-slice-service.txt b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/ietf-network-slice-service.txt new file mode 100644 index 0000000000000000000000000000000000000000..b81498dd8aa94457e2658cc29586de66242ae391 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/ietf-network-slice-service.txt @@ -0,0 +1,261 @@ +# IETF draft-ietf-teas-ietf-network-slice-nbi-yang-02 - IETF Network Slice Service YANG Model +# Ref: https://datatracker.ietf.org/doc/draft-ietf-teas-ietf-network-slice-nbi-yang/ + +module: ietf-network-slice-service + +--rw network-slice-services + +--rw slo-sle-templates + | +--rw slo-sle-template* [id] + | +--rw id string + | +--rw template-description? string + +--rw slice-service* [service-id] + +--rw service-id string + +--rw service-description? string + +--rw service-tags + | +--rw tag-type* [tag-type] + | | +--rw tag-type identityref + | | +--rw value* string + | +--rw tag-opaque* [tag-name] + | +--rw tag-name string + | +--rw value* string + +--rw (slo-sle-policy)? + | +--:(standard) + | | +--rw slo-sle-template? leafref + | +--:(custom) + | +--rw service-slo-sle-policy + | +--rw policy-description? string + | +--rw metric-bounds + | | +--rw metric-bound* [metric-type] + | | +--rw metric-type identityref + | | +--rw metric-unit string + | | +--rw value-description? string + | | +--rw bound? uint64 + | +--rw security* identityref + | +--rw isolation? identityref + | +--rw max-occupancy-level? uint8 + | +--rw mtu? uint16 + | +--rw steering-constraints + | +--rw path-constraints + | +--rw service-function + +--rw status + | +--rw admin-status + | | +--rw status? identityref + | | +--rw last-updated? yang:date-and-time + | +--ro oper-status + | +--ro status? identityref + | +--ro last-updated? yang:date-and-time + +--rw sdps + | +--rw sdp* [sdp-id] + | +--rw sdp-id string + | +--rw sdp-description? string + | +--rw location + | | +--rw altitude? int64 + | | +--rw latitude? decimal64 + | | +--rw longitude? decimal64 + | +--rw node-id? string + | +--rw sdp-ip? inet:ip-address + | +--rw service-match-criteria + | | +--rw match-criterion* [index] + | | +--rw index uint32 + | | +--rw match-type + | | | identityref + | | +--rw value* string + | | +--rw target-connection-group-id leafref + | | +--rw connection-group-sdp-role? + | | | identityref + | | +--rw target-connectivity-construct-id? leafref + | +--rw sdp-peering + | | +--rw protocol* [protocol-type] + | | | +--rw protocol-type identityref + | | | +--rw attribute* [attribute-type] + | | | +--rw attribute-type identityref + | | | +--rw value* string + | | +--rw opaque* [attribute-name] + | | +--rw attribute-name string + | | +--rw value* string + | +--rw attachment-circuits + | | +--rw attachment-circuit* [ac-id] + | | +--rw ac-id string + | | +--rw ac-description? string + | | +--rw ac-node-id? string + | | +--rw ac-tp-id? string + | | +--rw ac-ip-address? inet:ip-address + | | +--rw ac-ip-prefix-length? uint8 + | | +--rw ac-qos-policy-name? string + | | +--rw mtu? uint16 + | | +--rw ac-tags + | | | +--rw ac-tags* [ac-tag-type] + | | | | +--rw ac-tag-type identityref + | | | | +--rw value* string + | | | +--rw ac-tag-opaque* [tag-name] + | | | +--rw tag-name string + | | | +--rw value* string + | | +--rw service-match-criteria + | | | +--rw match-criterion* [index] + | | | +--rw index + | | | | uint32 + | | | +--rw match-type + | | | | identityref + | | | +--rw value* + | | | | string + | | | +--rw target-connection-group-id leafref + | | | +--rw connection-group-sdp-role? + | | | | identityref + | | | +--rw target-connectivity-construct-id? leafref + | | +--rw sdp-peering + | | | +--rw protocol* [protocol-type] + | | | | +--rw protocol-type identityref + | | | | +--rw attribute* [attribute-type] + | | | | +--rw attribute-type identityref + | | | | +--rw value* string + | | | +--rw opaque* [attribute-name] + | | | +--rw attribute-name string + | | | +--rw value* string + | | +--rw incoming-rate-limits + | | | +--rw cir? uint64 + | | | +--rw cbs? uint64 + | | | +--rw eir? uint64 + | | | +--rw ebs? uint64 + | | | +--rw pir? uint64 + | | | +--rw pbs? uint64 + | | +--rw outgoing-rate-limits + | | +--rw cir? uint64 + | | +--rw cbs? uint64 + | | +--rw eir? uint64 + | | +--rw ebs? uint64 + | | +--rw pir? uint64 + | | +--rw pbs? uint64 + | +--rw incoming-rate-limits + | | +--rw cir? uint64 + | | +--rw cbs? uint64 + | | +--rw eir? uint64 + | | +--rw ebs? uint64 + | | +--rw pir? uint64 + | | +--rw pbs? uint64 + | +--rw outgoing-rate-limits + | | +--rw cir? uint64 + | | +--rw cbs? uint64 + | | +--rw eir? uint64 + | | +--rw ebs? uint64 + | | +--rw pir? uint64 + | | +--rw pbs? uint64 + | +--rw status + | | +--rw admin-status + | | | +--rw status? identityref + | | | +--rw last-updated? yang:date-and-time + | | +--ro oper-status + | | +--ro status? identityref + | | +--ro last-updated? yang:date-and-time + | +--ro sdp-monitoring + | +--ro incoming-utilized-bandwidth? + | | te-types:te-bandwidth + | +--ro incoming-bw-utilization decimal64 + | +--ro outgoing-utilized-bandwidth? + | | te-types:te-bandwidth + | +--ro outgoing-bw-utilization decimal64 + +--rw connection-groups + +--rw connection-group* [connection-group-id] + +--rw connection-group-id string + +--rw connectivity-type? identityref + +--rw (slo-sle-policy)? + | +--:(standard) + | | +--rw slo-sle-template? leafref + | +--:(custom) + | +--rw service-slo-sle-policy + | +--rw policy-description? string + | +--rw metric-bounds + | | +--rw metric-bound* [metric-type] + | | +--rw metric-type identityref + | | +--rw metric-unit string + | | +--rw value-description? string + | | +--rw bound? uint64 + | +--rw security* identityref + | +--rw isolation? identityref + | +--rw max-occupancy-level? uint8 + | +--rw mtu? uint16 + | +--rw steering-constraints + | +--rw path-constraints + | +--rw service-function + +--rw connectivity-construct* [cc-id] + | +--rw cc-id uint32 + | +--rw (connectivity-construct-type)? + | | +--:(p2p) + | | | +--rw p2p-sender-sdp? + | | | | -> ../../../../sdps/sdp/sdp-id + | | | +--rw p2p-receiver-sdp? + | | | -> ../../../../sdps/sdp/sdp-id + | | +--:(p2mp) + | | | +--rw p2mp-sender-sdp? + | | | | -> ../../../../sdps/sdp/sdp-id + | | | +--rw p2mp-receiver-sdp* + | | | -> ../../../../sdps/sdp/sdp-id + | | +--:(a2a) + | | +--rw a2a-sdp* [sdp-id] + | | +--rw sdp-id + | | | -> ../../../../../sdps/sdp/sdp-id + | | +--rw (slo-sle-policy)? + | | +--:(standard) + | | | +--rw slo-sle-template? leafref + | | +--:(custom) + | | +--rw service-slo-sle-policy + | | +--rw policy-description? + | | | string + | | +--rw metric-bounds + | | | +--rw metric-bound* + | | | [metric-type] + | | | +--rw metric-type + | | | | identityref + | | | +--rw metric-unit + | | | | string + | | | +--rw value-description? + | | | | string + | | | +--rw bound? + | | | uint64 + | | +--rw security* + | | | identityref + | | +--rw isolation? + | | | identityref + | | +--rw max-occupancy-level? + | | | uint8 + | | +--rw mtu? + | | | uint16 + | | +--rw steering-constraints + | | +--rw path-constraints + | | +--rw service-function + | +--rw (slo-sle-policy)? + | | +--:(standard) + | | | +--rw slo-sle-template? leafref + | | +--:(custom) + | | +--rw service-slo-sle-policy + | | +--rw policy-description? string + | | +--rw metric-bounds + | | | +--rw metric-bound* [metric-type] + | | | +--rw metric-type + | | | | identityref + | | | +--rw metric-unit string + | | | +--rw value-description? string + | | | +--rw bound? uint64 + | | +--rw security* identityref + | | +--rw isolation? identityref + | | +--rw max-occupancy-level? uint8 + | | +--rw mtu? uint16 + | | +--rw steering-constraints + | | +--rw path-constraints + | | +--rw service-function + | +--ro connectivity-construct-monitoring + | +--ro one-way-min-delay? uint32 + | +--ro one-way-max-delay? uint32 + | +--ro one-way-delay-variation? uint32 + | +--ro one-way-packet-loss? decimal64 + | +--ro two-way-min-delay? uint32 + | +--ro two-way-max-delay? uint32 + | +--ro two-way-delay-variation? uint32 + | +--ro two-way-packet-loss? decimal64 + +--ro connection-group-monitoring + +--ro one-way-min-delay? uint32 + +--ro one-way-max-delay? uint32 + +--ro one-way-delay-variation? uint32 + +--ro one-way-packet-loss? decimal64 + +--ro two-way-min-delay? uint32 + +--ro two-way-max-delay? uint32 + +--ro two-way-delay-variation? uint32 + +--ro two-way-packet-loss? decimal64 \ No newline at end of file diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/Authentication.py b/src/compute/service/rest_server/nbi_plugins/tools/Authentication.py similarity index 100% rename from src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/Authentication.py rename to src/compute/service/rest_server/nbi_plugins/tools/Authentication.py diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/ContextMethods.py b/src/compute/service/rest_server/nbi_plugins/tools/ContextMethods.py similarity index 100% rename from src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/ContextMethods.py rename to src/compute/service/rest_server/nbi_plugins/tools/ContextMethods.py diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/HttpStatusCodes.py b/src/compute/service/rest_server/nbi_plugins/tools/HttpStatusCodes.py similarity index 100% rename from src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/HttpStatusCodes.py rename to src/compute/service/rest_server/nbi_plugins/tools/HttpStatusCodes.py diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/Validator.py b/src/compute/service/rest_server/nbi_plugins/tools/Validator.py similarity index 100% rename from src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/Validator.py rename to src/compute/service/rest_server/nbi_plugins/tools/Validator.py diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/__init__.py b/src/compute/service/rest_server/nbi_plugins/tools/__init__.py similarity index 100% rename from src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/__init__.py rename to src/compute/service/rest_server/nbi_plugins/tools/__init__.py