diff --git a/manifests/serviceservice.yaml b/manifests/serviceservice.yaml index aa94e4269daae85872573d2dc32a5d56da89673b..72c3015b31844f7bd38e47f7be2ed2691db59adb 100644 --- a/manifests/serviceservice.yaml +++ b/manifests/serviceservice.yaml @@ -36,7 +36,7 @@ spec: - containerPort: 9192 env: - name: LOG_LEVEL - value: "INFO" + value: "DEBUG" readinessProbe: exec: command: ["/bin/grpc_health_probe", "-addr=:3030"] diff --git a/src/common/DeviceTypes.py b/src/common/DeviceTypes.py index ccc83c9a6cf446ac60bd64cf5fd0bd632e21ad7b..b357c32be362e94634be38fe642c6b93c6a8c61f 100644 --- a/src/common/DeviceTypes.py +++ b/src/common/DeviceTypes.py @@ -1,4 +1,4 @@ -# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) +# Copyright 2022-2024 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. @@ -48,6 +48,7 @@ class DeviceTypeEnum(Enum): PACKET_SWITCH = 'packet-switch' XR_CONSTELLATION = 'xr-constellation' QKD_NODE = 'qkd-node' + OPEN_ROADM = 'openroadm' OPENFLOW_RYU_CONTROLLER = 'openflow-ryu-controller' # ETSI TeraFlowSDN controller diff --git a/src/device/service/drivers/OpenFlow/OpenFlowDriver.py b/src/device/service/drivers/OpenFlow/OpenFlowDriver.py index 7e70d11fb50351e23f91abb8d92ba149b3f24dc2..a425943e4b5b50fe3af95433ca2ccf96295416a2 100644 --- a/src/device/service/drivers/OpenFlow/OpenFlowDriver.py +++ b/src/device/service/drivers/OpenFlow/OpenFlowDriver.py @@ -41,7 +41,6 @@ class OpenFlowDriver(_Driver): scheme = self.settings.get('scheme', 'http') self.__base_url = '{:s}://{:s}:{:d}'.format(scheme, self.address, int(self.port)) self.__timeout = int(self.settings.get('timeout', 120)) - config = {'mapping_not_needed': False, 'service_endpoint_mapping': []} self.tac = TfsApiClient(self.address, int(self.port), scheme=scheme, username=username, password=password) def Connect(self) -> bool: diff --git a/src/device/service/drivers/OpenFlow/TfsApiClient.py b/src/device/service/drivers/OpenFlow/TfsApiClient.py index aab5f06457ce08ff8cb9ddb612fc130d5c060bc3..bc95fe9ff7758ca295f79f25590ce89d7af4099f 100644 --- a/src/device/service/drivers/OpenFlow/TfsApiClient.py +++ b/src/device/service/drivers/OpenFlow/TfsApiClient.py @@ -94,7 +94,7 @@ class TfsApiClient: 'uuid': device_uuid, 'name': device_uuid, 'type': 'packet-switch', - 'status': 2, # Uncomment if device_status is included + 'status': 2, 'drivers': 'DEVICEDRIVER_RYU', } result.append((device_url, device_data)) diff --git a/src/device/service/drivers/OpenFlow/Tools.py b/src/device/service/drivers/OpenFlow/Tools.py index d683470876ea8c00fc26be9d6378dd46549b1c75..e68a47f3a72820b58c9c70efcfc66788e9bdc424 100644 --- a/src/device/service/drivers/OpenFlow/Tools.py +++ b/src/device/service/drivers/OpenFlow/Tools.py @@ -1,11 +1,8 @@ -# Copyright 2022-2024 ETSI OSG/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. diff --git a/src/device/service/drivers/__init__.py b/src/device/service/drivers/__init__.py index 837d83d53c75b02f8122990d59b6804a5ba72903..62942cd88ba54f1753837e0dd675ab9615f2e48b 100644 --- a/src/device/service/drivers/__init__.py +++ b/src/device/service/drivers/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) +# Copyright 2022-2024 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. diff --git a/src/service/service/service_handler_api/FilterFields.py b/src/service/service/service_handler_api/FilterFields.py index 78f084605bcd759825975cb7f11abc659506755b..6cd9f3bc40955f9300b1b48dc292b0c7ec1de953 100644 --- a/src/service/service/service_handler_api/FilterFields.py +++ b/src/service/service/service_handler_api/FilterFields.py @@ -44,6 +44,7 @@ DEVICE_DRIVER_VALUES = { DeviceDriverEnum.DEVICEDRIVER_IETF_ACTN, DeviceDriverEnum.DEVICEDRIVER_OC, DeviceDriverEnum.DEVICEDRIVER_QKD, + DeviceDriverEnum.DEVICEDRIVER_RYU, } # Map allowed filter fields to allowed values per Filter field. If no restriction (free text) None is specified diff --git a/src/service/service/service_handler_api/ServiceHandlerFactory.py b/src/service/service/service_handler_api/ServiceHandlerFactory.py index e692a9e773c9c54c843b2fe1ed7ed3d7b1158802..5ced40233949c3eca5352730a00183d1e42bd15c 100644 --- a/src/service/service/service_handler_api/ServiceHandlerFactory.py +++ b/src/service/service/service_handler_api/ServiceHandlerFactory.py @@ -11,7 +11,6 @@ # 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, operator from enum import Enum from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Set, Tuple @@ -26,7 +25,6 @@ if TYPE_CHECKING: from service.service.service_handler_api._ServiceHandler import _ServiceHandler LOGGER = logging.getLogger(__name__) - class ServiceHandlerFactory: def __init__(self, service_handlers : List[Tuple[type, List[Dict[FilterFieldEnum, Any]]]]) -> None: # Dict{field_name => Dict{field_value => Set{ServiceHandler}}} @@ -41,7 +39,6 @@ class ServiceHandlerFactory: from service.service.service_handler_api._ServiceHandler import _ServiceHandler if not issubclass(service_handler_class, _ServiceHandler): raise UnsupportedServiceHandlerClassException(str(service_handler_class)) - service_handler_name = service_handler_class.__name__ supported_filter_fields = set(FILTER_FIELD_ALLOWED_VALUES.keys()) unsupported_filter_fields = set(filter_fields.keys()).difference(supported_filter_fields) @@ -80,6 +77,9 @@ class ServiceHandlerFactory: field_enum_values = FILTER_FIELD_ALLOWED_VALUES.get(field_name) field_candidate_service_handler_classes = set() + #LOGGER.debug(f"Filter fields: {filter_fields}") + #LOGGER.debug(f"Field indices: {self.__indices}") + #LOGGER.debug(f"Candidate handlers after each field: {candidate_service_handler_classes}") for field_value in field_values: if field_enum_values is not None and field_value not in field_enum_values: raise UnsupportedFilterFieldValueException(field_name, field_value, field_enum_values) diff --git a/src/service/service/service_handlers/__init__.py b/src/service/service/service_handlers/__init__.py index f93cf011fe02139ae350b91eab52eb71ded0574d..0be5fb6d7f3a5880b8925c4a5c32093065cbd368 100644 --- a/src/service/service/service_handlers/__init__.py +++ b/src/service/service/service_handlers/__init__.py @@ -28,6 +28,7 @@ from .tapi_xr.TapiXrServiceHandler import TapiXrServiceHandler from .e2e_orch.E2EOrchestratorServiceHandler import E2EOrchestratorServiceHandler from .oc.OCServiceHandler import OCServiceHandler from .qkd.qkd_service_handler import QKDServiceHandler +from .l3nm_ryu.L3NMryuServiceHandler import RYUServiceHandler SERVICE_HANDLERS = [ (L2NMEmulatedServiceHandler, [ @@ -113,5 +114,12 @@ SERVICE_HANDLERS = [ FilterFieldEnum.SERVICE_TYPE : ServiceTypeEnum.SERVICETYPE_QKD, FilterFieldEnum.DEVICE_DRIVER : [DeviceDriverEnum.DEVICEDRIVER_QKD], } + ]), + + (RYUServiceHandler, [ + { + FilterFieldEnum.SERVICE_TYPE : ServiceTypeEnum.SERVICETYPE_L3NM, + FilterFieldEnum.DEVICE_DRIVER : [DeviceDriverEnum.DEVICEDRIVER_RYU], + } ]) ] diff --git a/src/service/service/service_handlers/l3nm_ryu/L3NMryuServiceHandler.py b/src/service/service/service_handlers/l3nm_ryu/L3NMryuServiceHandler.py new file mode 100644 index 0000000000000000000000000000000000000000..536f3997d008b9121f4817b90b1951c795cc9318 --- /dev/null +++ b/src/service/service/service_handlers/l3nm_ryu/L3NMryuServiceHandler.py @@ -0,0 +1,91 @@ +# Copyright 2022-2024 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 json, logging, netaddr +from re import L +from typing import Any, Dict, List, Optional, Tuple, Union +from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method +from common.proto.context_pb2 import ConfigRule, Device, DeviceId, EndPoint, Service +from common.tools.grpc.Tools import grpc_message_to_json_string +from common.tools.object_factory.ConfigRule import json_config_rule_delete, json_config_rule_set +from common.tools.object_factory.Device import json_device_id +from common.type_checkers.Checkers import chk_type +from service.service.service_handler_api.Tools import get_device_endpoint_uuids, get_endpoint_matching +from service.service.service_handler_api._ServiceHandler import _ServiceHandler +from service.service.service_handler_api.SettingsHandler import SettingsHandler +from service.service.task_scheduler.TaskExecutor import TaskExecutor +import requests + +logging.basicConfig(level=logging.DEBUG) +LOGGER = logging.getLogger(__name__) + +METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'l3nm_ryu'}) + +class RYUServiceHandler(_ServiceHandler): + def __init__( # pylint: disable=super-init-not-called + self, service : Service, task_executor : TaskExecutor, **settings + ) -> None: + self.__service = service + self.__task_executor = task_executor + self.__settings_handler = SettingsHandler(service.service_config, **settings) + + + #def _get_endpoint_details( + # self, endpoint : Tuple[str, str, Optional[str]] + #) -> Tuple[Device, EndPoint, Dict]: + # device_uuid, endpoint_uuid = get_device_endpoint_uuids(endpoint) + # LOGGER.debug('device_uuid = {:s}'.format(str(device_uuid))) + # LOGGER.debug('endpoint_uuid = {:s}'.format(str(endpoint_uuid))) + # device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) + # LOGGER.debug('device_obj = {:s}'.format(str(grpc_message_to_json_string(device_obj)))) + # endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid) + # LOGGER.debug('endpoint_obj = {:s}'.format(str(grpc_message_to_json_string(endpoint_obj)))) + # endpoint_settings = self.__settings_handler.get_endpoint_settings(device_obj, endpoint_obj) + # device_name = device_obj.name + # endpoint_name = endpoint_obj.name + # if endpoint_settings is None: + # MSG = 'Settings not found for Endpoint(device=[uuid={:s}, name={:s}], endpoint=[uuid={:s}, name={:s}])' + # raise Exception(MSG.format(device_uuid, device_name, endpoint_uuid, endpoint_name)) + # endpoint_settings_dict : Dict = endpoint_settings.value + # LOGGER.debug('endpoint_settings_dict = {:s}'.format(str(endpoint_settings_dict))) + # return device_obj, endpoint_obj, endpoint_settings_dict + + + @metered_subclass_method(METRICS_POOL) + def SetEndpoint( + self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None + ) -> List[Union[bool, Exception]]: + LOGGER.debug('endpoints = {:s}'.format(str(endpoints))) + chk_type('endpoints', endpoints, list) + if len(endpoints) < 2: + LOGGER.warning('nothing done: not enough endpoints') + return [] + service_uuid = self.__service.service_id.service_uuid.uuid + LOGGER.debug('service_uuid = {:s}'.format(str(service_uuid))) + LOGGER.debug('self.__settings_handler = {:s}'.format(str(self.__settings_handler.dump_config_rules()))) + results = [] + try: + # Get endpoint details + src_device, src_endpoint, src_settings = self._get_endpoint_details(endpoints[0]) + dst_device, dst_endpoint, dst_settings = self._get_endpoint_details(endpoints[-1]) + LOGGER.debug(f"Source settings: {src_settings}") + LOGGER.debug(f"Destination settings: {dst_settings}") + + return results + + except Exception as e: + LOGGER.error(f"Error in SetEndpoint: {e}") + return [e] + + diff --git a/tmp-code/OpenFlow/__init__.py b/src/service/service/service_handlers/l3nm_ryu/__init__.py similarity index 70% rename from tmp-code/OpenFlow/__init__.py rename to src/service/service/service_handlers/l3nm_ryu/__init__.py index 4f3d1a042c69720452803e994c38f7c2e966c684..53d5157f750bfb085125cbd33faff1cec5924e14 100644 --- a/tmp-code/OpenFlow/__init__.py +++ b/src/service/service/service_handlers/l3nm_ryu/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) +# Copyright 2022-2024 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. @@ -12,9 +12,3 @@ # See the License for the specific language governing permissions and # limitations under the License. -from device.service.driver_api._Driver import RESOURCE_ENDPOINTS, RESOURCE_SERVICES - -ALL_RESOURCE_KEYS = [ - RESOURCE_ENDPOINTS, - RESOURCE_SERVICES, -] diff --git a/tmp-code/DeviceTypes.py b/tmp-code/DeviceTypes.py deleted file mode 100644 index f88ec8bb4814b6e5b85f9e28000d99a47a3ad329..0000000000000000000000000000000000000000 --- a/tmp-code/DeviceTypes.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright 2022-2024 ETSI OSG/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. - -from enum import Enum - -class DeviceTypeEnum(Enum): - - # Abstractions - NETWORK = 'network' - - # Emulated device types - EMULATED_CLIENT = 'emu-client' - EMULATED_DATACENTER = 'emu-datacenter' - EMULATED_IP_SDN_CONTROLLER = 'emu-ip-sdn-controller' - EMULATED_MICROWAVE_RADIO_SYSTEM = 'emu-microwave-radio-system' - EMULATED_OPEN_LINE_SYSTEM = 'emu-open-line-system' - EMULATED_OPTICAL_ROADM = 'emu-optical-roadm' - EMULATED_OPTICAL_TRANSPONDER = 'emu-optical-transponder' - EMULATED_OPTICAL_SPLITTER = 'emu-optical-splitter' # passive component required for XR Constellation - EMULATED_P4_SWITCH = 'emu-p4-switch' - EMULATED_PACKET_RADIO_ROUTER = 'emu-packet-radio-router' - EMULATED_PACKET_ROUTER = 'emu-packet-router' - EMULATED_PACKET_SWITCH = 'emu-packet-switch' - EMULATED_XR_CONSTELLATION = 'emu-xr-constellation' - EMULATED_OPEN_FLOW_CONTROLLER = 'open-flow-controller' - - # Real device types - CLIENT = 'client' - DATACENTER = 'datacenter' - IP_SDN_CONTROLLER = 'ip-sdn-controller' - MICROWAVE_RADIO_SYSTEM = 'microwave-radio-system' - OPEN_LINE_SYSTEM = 'open-line-system' - OPTICAL_ROADM = 'optical-roadm' - OPTICAL_TRANSPONDER = 'optical-transponder' - P4_SWITCH = 'p4-switch' - PACKET_RADIO_ROUTER = 'packet-radio-router' - PACKET_ROUTER = 'packet-router' - PACKET_SWITCH = 'packet-switch' - XR_CONSTELLATION = 'xr-constellation' - QKD_NODE = 'qkd-node' - OPENFLOW_RYU_CONTROLLER = 'openflow-ryu-controller' - - # ETSI TeraFlowSDN controller - TERAFLOWSDN_CONTROLLER = 'teraflowsdn' diff --git a/tmp-code/OpenFlow/OpenFlowDriver.py b/tmp-code/OpenFlow/OpenFlowDriver.py deleted file mode 100644 index 2aee0cd298c836bbed98b14fbcec9d2b14d93541..0000000000000000000000000000000000000000 --- a/tmp-code/OpenFlow/OpenFlowDriver.py +++ /dev/null @@ -1,173 +0,0 @@ -# Copyright 2022-2024 ETSI OSG/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 json -import logging, requests, threading -from requests.auth import HTTPBasicAuth -from typing import Any, Iterator, List, Optional, Tuple, Union -from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method -from common.type_checkers.Checkers import chk_string, chk_type -from device.service.driver_api._Driver import _Driver -from . import ALL_RESOURCE_KEYS -from device.service.drivers.OpenFlow.Tools import find_key, get_switches, get_flows , add_flow , delete_flow , get_desc,get_port_desc, get_links_information,get_switches_information,del_flow_entry -LOGGER = logging.getLogger(__name__) - -DRIVER_NAME = 'openflow_api' -METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME}) - -class OpenFlowDriver(_Driver): - def __init__(self, address: str, port: int, **settings) -> None: - super().__init__(DRIVER_NAME, address, port, **settings) - self.__lock = threading.Lock() - self.__started = threading.Event() - self.__terminate = threading.Event() - username = self.settings.get('username') - password = self.settings.get('password') - self.__auth = HTTPBasicAuth(username, password) if username is not None and password is not None else None - scheme = self.settings.get('scheme', 'http') - self.__base_url = '{:s}://{:s}:{:d}'.format(scheme, self.address, int(self.port)) - self.__timeout = int(self.settings.get('timeout', 120)) - - def Connect(self) -> bool: - url = f"{self.__base_url}/stats/desc/1" - with self.__lock: - if self.__started.is_set(): - return True - try: - response = requests.get(url, timeout=self.__timeout, verify=False, auth=self.__auth) - response.raise_for_status() - except requests.exceptions.Timeout: - LOGGER.exception(f"Timeout connecting to {self.__base_url}") - return False - except requests.exceptions.RequestException as e: - LOGGER.exception(f"Exception connecting to {self.__base_url}: {e}") - return False - else: - self.__started.set() - return True - - def Disconnect(self) -> bool: - with self.__lock: - self.__terminate.set() - return True - - #@metered_subclass_method(METRICS_POOL) - #def GetInitialConfig(self) -> List[Tuple[str, Any]]: - # with self.__lock: - # switches = get_switches(self.__base_url, auth=self.__auth, timeout=self.__timeout) - # return [("switches", switches)] - - @metered_subclass_method(METRICS_POOL) - def GetConfig(self, resource_keys: List[str] = []) -> List[Tuple[str, Union[Any, None, Exception]]]: - chk_type('resources', resource_keys, list) - results = [] - with self.__lock: - for key in resource_keys: - try: - if key.startswith('flows:'): - dpid = key.split(':', 1)[1] - flows = get_flows(self.__base_url, dpid, auth=self.__auth, timeout=self.__timeout) - results.append((key, flows)) - elif key.startswith('description:'): - dpid = key.split(':', 1)[1] - desc = get_desc(self.__base_url, dpid, auth=self.__auth, timeout=self.__timeout) - results.append((key, desc)) - elif key.startswith('switches'): - switches = get_switches(self.__base_url, auth=self.__auth, timeout=self.__timeout) - results.append((key, switches)) - elif key.startswith('port_description:'): - dpid = key.split(':', 1)[1] - desc = get_port_desc(self.__base_url,dpid, auth=self.__auth, timeout=self.__timeout) - results.append((key, desc)) - elif key.startswith('switch_info'): - sin = get_switches_information(self.__base_url, auth=self.__auth, timeout=self.__timeout) - results.append((key, sin)) - elif key.startswith('links_info'): - lin = get_links_information(self.__base_url, auth=self.__auth, timeout=self.__timeout) - results.append((key, lin)) - else: - results.append((key, None)) # If key not handled, append None - except Exception as e: - results.append((key, e)) - return results - - @metered_subclass_method(METRICS_POOL) - def DeleteConfig(self, resource_keys: List[str] = []) -> List[Tuple[str, Union[Any, None, Exception]]]: - chk_type('resources', resource_keys, list) - results = [] - with self.__lock: - for item in resource_keys: - try: - if isinstance(item, tuple): - key, data = item - else: - key, data = item, None - if key.startswith('flowentry_delete:'): - dpid = key.split(':', 1)[1] - flows = del_flow_entry(self.__base_url, dpid, auth=self.__auth, timeout=self.__timeout) - results.append((key, flows)) - elif key=='flow_data' and data: - flow_del = delete_flow (self.__base_url,data,auth=self.__auth, timeout=self.__timeout) - results.append((key, flow_del)) - else: - results.append((key, None)) - except Exception as e: - results.append((key, e)) - return results - - @metered_subclass_method(METRICS_POOL) - def SetConfig(self, resources: List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: - results = [] - if not resources: - return results - with self.__lock: - for item in resources: - LOGGER.info('resources contains: %s', item) - try: - if isinstance(item, tuple) and len(item) == 2: - key, flow_data = item - else: - LOGGER.warning("Resource format invalid. Each item should be a tuple with (key, data).") - results.append(False) - continue - if key == "flow_data" and isinstance(flow_data, dict): - LOGGER.info(f"Found valid flow_data entry: {flow_data}") - success = add_flow(self.__base_url, flow_data, auth=self.__auth, timeout=self.__timeout) - results.append(success) - else: - LOGGER.warning(f"Skipping item with key: {key} due to invalid format or missing data.") - results.append(False) - - except Exception as e: - LOGGER.error(f"Exception while setting configuration for item {item}: {str(e)}") - results.append(e) - - return results - - - - @metered_subclass_method(METRICS_POOL) - def SubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]: - # TODO: TAPI does not support monitoring by now - return [False for _ in subscriptions] - - @metered_subclass_method(METRICS_POOL) - def UnsubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]: - # TODO: TAPI does not support monitoring by now - return [False for _ in subscriptions] - - def GetState( - self, blocking=False, terminate : Optional[threading.Event] = None - ) -> Iterator[Tuple[float, str, Any]]: - # TODO: TAPI does not support monitoring by now - return [] diff --git a/tmp-code/OpenFlow/Tools.py b/tmp-code/OpenFlow/Tools.py deleted file mode 100644 index d683470876ea8c00fc26be9d6378dd46549b1c75..0000000000000000000000000000000000000000 --- a/tmp-code/OpenFlow/Tools.py +++ /dev/null @@ -1,174 +0,0 @@ -# Copyright 2022-2024 ETSI OSG/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 json, logging, operator, requests -from requests.auth import HTTPBasicAuth -from typing import Optional -from device.service.driver_api._Driver import RESOURCE_ENDPOINTS, RESOURCE_SERVICES -from typing import List, Dict, Optional, Tuple, Union - -LOGGER = logging.getLogger(__name__) - -RESOURCE_ENDPOINTS = { - #get configurations - "switches": "/stats/switches", - "description": "/stats/desc", - "flows": "/stats/flow", - "port_description":"/stats/portdesc", - "switch_info":"/v1.0/topology/switches", - "links_info":"/v1.0/topology/links", - #add flow - "flow_add": "/stats/flowentry/add", - #Delete all matching flow entries of the switch. - "flow_delete": "/stats/flowentry/delete", - "flowentry_delete":"/stats/flowentry/clear", #according to dpid - -} - -HTTP_OK_CODES = { - 200, # OK - 201, # Created - 202, # Accepted - 204, # No Content -} - -# Utility function to find and extract a specific key from a resource. -def find_key(resource: Tuple[str, str], key: str) -> Union[dict, str, None]: - try: - return json.loads(resource[1])[key] - except KeyError: - LOGGER.warning(f"Key '{key}' not found in resource.") - return None - -def get_switches(root_url: str, auth: Optional[HTTPBasicAuth] = None, timeout: Optional[int] = None) -> List[Dict]: - url = f"{root_url}{RESOURCE_ENDPOINTS['switches']}" - result = [] - try: - response = requests.get(url, timeout=timeout, verify=False, auth=auth) - response.raise_for_status() - switches = response.json() - LOGGER.info(f"Successfully retrieved switches: {switches}") - result = switches - except requests.exceptions.Timeout: - LOGGER.exception(f"Timeout connecting to {url}") - except requests.exceptions.RequestException as e: - LOGGER.exception(f"Error retrieving switches: {str(e)}") - return result - -def get_switches_information(root_url: str, auth: Optional[HTTPBasicAuth] = None, timeout: Optional[int] = None) -> List[Dict]: - url = f"{root_url}{RESOURCE_ENDPOINTS['switch_info']}" - result = [] - try: - response = requests.get(url, timeout=timeout, verify=False, auth=auth) - response.raise_for_status() - switches_info = response.json() - LOGGER.info(f"Successfully retrieved switches: {switches_info}") - result = switches_info - except requests.exceptions.Timeout: - LOGGER.exception(f"Timeout connecting to {url}") - except requests.exceptions.RequestException as e: - LOGGER.exception(f"Error retrieving switches: {str(e)}") - return result - -def get_links_information(root_url: str, auth: Optional[HTTPBasicAuth] = None, timeout: Optional[int] = None) -> List[Dict]: - url = f"{root_url}{RESOURCE_ENDPOINTS['links_info']}" - result = [] - try: - response = requests.get(url, timeout=timeout, verify=False, auth=auth) - response.raise_for_status() - links_info = response.json() - LOGGER.info(f"Successfully retrieved switches: {links_info}") - result = links_info - except requests.exceptions.Timeout: - LOGGER.exception(f"Timeout connecting to {url}") - except requests.exceptions.RequestException as e: - LOGGER.exception(f"Error retrieving switches: {str(e)}") - return result - -def get_flows(root_url: str, dpid: str, auth: Optional[HTTPBasicAuth] = None, timeout: Optional[int] = None) -> List[Dict]: - url = f"{root_url}{RESOURCE_ENDPOINTS['flows']}/{dpid}" - try: - response = requests.get(url, timeout=timeout, verify=False, auth=auth) - response.raise_for_status() - flows = response.json() - LOGGER.info(f"Successfully retrieved flow rules for DPID {dpid}") - return flows - except requests.exceptions.RequestException as e: - LOGGER.error(f"Failed to retrieve flow rules for DPID {dpid}: {str(e)}") - return [] - -#get description -def get_desc(root_url: str, dpid: str, auth: Optional[HTTPBasicAuth] = None, timeout: Optional[int] = None) -> Dict: - url = f"{root_url}{RESOURCE_ENDPOINTS['description']}/{dpid}" - try: - response = requests.get(url, timeout=timeout, verify=False, auth=auth) - response.raise_for_status() - desc = response.json() - LOGGER.info(f"Successfully retrieved description for DPID {dpid}: {desc}") - return desc - except requests.exceptions.RequestException as e: - LOGGER.error(f"Failed to retrieve description for DPID {dpid}: {str(e)}") - return {} - -def get_port_desc(root_url: str, dpid: str, auth: Optional[HTTPBasicAuth] = None, timeout: Optional[int] = None) -> Dict: - url = f"{root_url}{RESOURCE_ENDPOINTS['port_description']}/{dpid}" - try: - response = requests.get(url, timeout=timeout, verify=False, auth=auth) - response.raise_for_status() - port_desc = response.json() - LOGGER.info(f"Successfully retrieved description for DPID {dpid}: {port_desc}") - return port_desc - except requests.exceptions.RequestException as e: - LOGGER.error(f"Failed to retrieve description for DPID {dpid}: {str(e)}") - return {} - -##according to dpid -def del_flow_entry(root_url: str, dpid: str, auth: Optional[HTTPBasicAuth] = None, timeout: Optional[int] = None) -> Dict: - url = f"{root_url}{RESOURCE_ENDPOINTS['flowentry_delete']}/{dpid}" - try: - response = requests.delete(url, timeout=timeout, verify=False, auth=auth) - response.raise_for_status() - flow_desc = response.json() - LOGGER.info(f"Successfully retrieved description for DPID {dpid}: {flow_desc}") - return flow_desc - except requests.exceptions.RequestException as e: - LOGGER.error(f"Failed to retrieve description for DPID {dpid}: {str(e)}") - return {} - -# to delete a flow based on match criteria. -def delete_flow(root_url: str, flow_data: dict, auth: Optional[HTTPBasicAuth] = None, timeout: Optional[int] = None) -> bool: - url = f"{root_url}{RESOURCE_ENDPOINTS['flow_delete']}" - try: - response = requests.post(url, json=flow_data, timeout=timeout, verify=False, auth=auth) - response.raise_for_status() - LOGGER.info(f"Flow configuration deleted successfully for DPID {flow_data.get('dpid')}.") - return True - except requests.exceptions.RequestException as e: - LOGGER.error(f"Failed to delete flow configuration for DPID {flow_data.get('dpid')}: {str(e)}") - return False - -def add_flow(root_url: str, flow_data: dict, auth: Optional[HTTPBasicAuth] = None, timeout: Optional[int] = None) -> bool: - url = f"{root_url}{RESOURCE_ENDPOINTS['flow_add']}" - LOGGER.info(f"Posting flow data: {flow_data} (type: {type(flow_data)}) to URL: {url}") - try: - response = requests.post(url, json=flow_data, timeout=timeout, verify=False, auth=auth) - response.raise_for_status() - LOGGER.info("Flow configuration added successfully.") - return True - except requests.exceptions.RequestException as e: - LOGGER.error(f"Failed to add flow configuration: {str(e)}") - return False - - - diff --git a/tmp-code/__init__.py b/tmp-code/__init__.py deleted file mode 100644 index 487cf7d40aac66251f3657867207f4c4ac66514d..0000000000000000000000000000000000000000 --- a/tmp-code/__init__.py +++ /dev/null @@ -1,202 +0,0 @@ -# Copyright 2022-2024 ETSI OSG/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 os -from common.DeviceTypes import DeviceTypeEnum -from common.proto.context_pb2 import DeviceDriverEnum -from device.Config import LOAD_ALL_DEVICE_DRIVERS -from ..driver_api.FilterFields import FilterFieldEnum - -DRIVERS = [] - -from .emulated.EmulatedDriver import EmulatedDriver # pylint: disable=wrong-import-position -DRIVERS.append( - (EmulatedDriver, [ - # TODO: multi-filter is not working - { - FilterFieldEnum.DEVICE_TYPE: [ - DeviceTypeEnum.EMULATED_DATACENTER, - DeviceTypeEnum.EMULATED_MICROWAVE_RADIO_SYSTEM, - DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM, - DeviceTypeEnum.EMULATED_OPTICAL_ROADM, - DeviceTypeEnum.EMULATED_OPTICAL_TRANSPONDER, - DeviceTypeEnum.EMULATED_P4_SWITCH, - DeviceTypeEnum.EMULATED_PACKET_ROUTER, - DeviceTypeEnum.EMULATED_PACKET_SWITCH, - - #DeviceTypeEnum.DATACENTER, - #DeviceTypeEnum.MICROWAVE_RADIO_SYSTEM, - #DeviceTypeEnum.OPEN_LINE_SYSTEM, - #DeviceTypeEnum.OPTICAL_ROADM, - #DeviceTypeEnum.OPTICAL_TRANSPONDER, - #DeviceTypeEnum.P4_SWITCH, - #DeviceTypeEnum.PACKET_ROUTER, - #DeviceTypeEnum.PACKET_SWITCH, - ], - FilterFieldEnum.DRIVER: [ - DeviceDriverEnum.DEVICEDRIVER_UNDEFINED, - ], - }, - #{ - # # Emulated devices, all drivers => use Emulated - # FilterFieldEnum.DEVICE_TYPE: [ - # DeviceTypeEnum.EMULATED_DATACENTER, - # DeviceTypeEnum.EMULATED_MICROWAVE_RADIO_SYSTEM, - # DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM, - # DeviceTypeEnum.EMULATED_OPTICAL_ROADM, - # DeviceTypeEnum.EMULATED_OPTICAL_TRANSPONDER, - # DeviceTypeEnum.EMULATED_P4_SWITCH, - # DeviceTypeEnum.EMULATED_PACKET_ROUTER, - # DeviceTypeEnum.EMULATED_PACKET_SWITCH, - # ], - # FilterFieldEnum.DRIVER: [ - # DeviceDriverEnum.DEVICEDRIVER_UNDEFINED, - # DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG, - # DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API, - # DeviceDriverEnum.DEVICEDRIVER_P4, - # DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY, - # DeviceDriverEnum.DEVICEDRIVER_ONF_TR_532, - # DeviceDriverEnum.DEVICEDRIVER_GNMI_OPENCONFIG, - # ], - #} - ])) - -from .ietf_l2vpn.IetfL2VpnDriver import IetfL2VpnDriver # pylint: disable=wrong-import-position -DRIVERS.append( - (IetfL2VpnDriver, [ - { - FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.TERAFLOWSDN_CONTROLLER, - FilterFieldEnum.DRIVER: DeviceDriverEnum.DEVICEDRIVER_IETF_L2VPN, - } - ])) - -from .ietf_actn.IetfActnDriver import IetfActnDriver # pylint: disable=wrong-import-position -DRIVERS.append( - (IetfActnDriver, [ - { - FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.OPEN_LINE_SYSTEM, - FilterFieldEnum.DRIVER: DeviceDriverEnum.DEVICEDRIVER_IETF_ACTN, - } - ])) - -if LOAD_ALL_DEVICE_DRIVERS: - from .openconfig.OpenConfigDriver import OpenConfigDriver # pylint: disable=wrong-import-position - DRIVERS.append( - (OpenConfigDriver, [ - { - # Real Packet Router, specifying OpenConfig Driver => use OpenConfigDriver - FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.PACKET_ROUTER, - FilterFieldEnum.DRIVER : DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG, - } - ])) - -if LOAD_ALL_DEVICE_DRIVERS: - from .gnmi_openconfig.GnmiOpenConfigDriver import GnmiOpenConfigDriver # pylint: disable=wrong-import-position - DRIVERS.append( - (GnmiOpenConfigDriver, [ - { - # Real Packet Router, specifying gNMI OpenConfig Driver => use GnmiOpenConfigDriver - FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.PACKET_ROUTER, - FilterFieldEnum.DRIVER : DeviceDriverEnum.DEVICEDRIVER_GNMI_OPENCONFIG, - } - ])) - -if LOAD_ALL_DEVICE_DRIVERS: - from .transport_api.TransportApiDriver import TransportApiDriver # pylint: disable=wrong-import-position - DRIVERS.append( - (TransportApiDriver, [ - { - # Real OLS, specifying TAPI Driver => use TransportApiDriver - FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.OPEN_LINE_SYSTEM, - FilterFieldEnum.DRIVER : DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API, - } - ])) - -if LOAD_ALL_DEVICE_DRIVERS: - from .p4.p4_driver import P4Driver # pylint: disable=wrong-import-position - DRIVERS.append( - (P4Driver, [ - { - # Real P4 Switch, specifying P4 Driver => use P4Driver - FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.P4_SWITCH, - FilterFieldEnum.DRIVER : DeviceDriverEnum.DEVICEDRIVER_P4, - } - ])) - -if LOAD_ALL_DEVICE_DRIVERS: - from .microwave.IETFApiDriver import IETFApiDriver # pylint: disable=wrong-import-position - DRIVERS.append( - (IETFApiDriver, [ - { - FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.MICROWAVE_RADIO_SYSTEM, - FilterFieldEnum.DRIVER : DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY, - } - ])) -if LOAD_ALL_DEVICE_DRIVERS: - from.OpenFlow.OpenFlowDriver import OpenFlowDriver - DRIVERS.append( - (OpenFlowDriver, [ - { - # Specify the device type and driver that should use OpenFlowDriver - FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.OPENFLOW_RYU_CONTROLLER , - FilterFieldEnum.DRIVER: DeviceDriverEnum.DEVICEDRIVER_OPENFLOW, - } - ]) - ) - -if LOAD_ALL_DEVICE_DRIVERS: - from .xr.XrDriver import XrDriver # pylint: disable=wrong-import-position - DRIVERS.append( - (XrDriver, [ - { - # Close enough, it does optical switching - FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.XR_CONSTELLATION, - FilterFieldEnum.DRIVER : DeviceDriverEnum.DEVICEDRIVER_XR, - } - ])) - -if LOAD_ALL_DEVICE_DRIVERS: - from .optical_tfs.OpticalTfsDriver import OpticalTfsDriver # pylint: disable=wrong-import-position - DRIVERS.append( - (OpticalTfsDriver, [ - { - FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.OPEN_LINE_SYSTEM, - FilterFieldEnum.DRIVER: DeviceDriverEnum.DEVICEDRIVER_OPTICAL_TFS, - } - ])) - -if LOAD_ALL_DEVICE_DRIVERS: - from .oc_driver.OCDriver import OCDriver # pylint: disable=wrong-import-position - DRIVERS.append( - (OCDriver, [ - { - # Real Packet Router, specifying OpenConfig Driver => use OpenConfigDriver - FilterFieldEnum.DEVICE_TYPE: [ - DeviceTypeEnum.OPTICAL_ROADM, - DeviceTypeEnum.OPTICAL_TRANSPONDER - ], - FilterFieldEnum.DRIVER : DeviceDriverEnum.DEVICEDRIVER_OC, - } - ])) - -if LOAD_ALL_DEVICE_DRIVERS: - from .qkd.QKDDriver2 import QKDDriver # pylint: disable=wrong-import-position - DRIVERS.append( - (QKDDriver, [ - { - # Close enough, it does optical switching - FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.QKD_NODE, - FilterFieldEnum.DRIVER : DeviceDriverEnum.DEVICEDRIVER_QKD, - } - ])) diff --git a/tmp-code/context.proto b/tmp-code/context.proto deleted file mode 100644 index 2ab6f0aea615efcb2ab24bbbf6938f5c84a95a45..0000000000000000000000000000000000000000 --- a/tmp-code/context.proto +++ /dev/null @@ -1,698 +0,0 @@ -// Copyright 2022-2024 ETSI OSG/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. - -syntax = "proto3"; -package context; - -import "acl.proto"; -import "kpi_sample_types.proto"; - -service ContextService { - rpc ListContextIds (Empty ) returns ( ContextIdList ) {} - rpc ListContexts (Empty ) returns ( ContextList ) {} - rpc GetContext (ContextId ) returns ( Context ) {} - rpc SetContext (Context ) returns ( ContextId ) {} - rpc RemoveContext (ContextId ) returns ( Empty ) {} - rpc GetContextEvents (Empty ) returns (stream ContextEvent ) {} - - rpc ListTopologyIds (ContextId ) returns ( TopologyIdList ) {} - rpc ListTopologies (ContextId ) returns ( TopologyList ) {} - rpc GetTopology (TopologyId ) returns ( Topology ) {} - rpc GetTopologyDetails (TopologyId ) returns ( TopologyDetails ) {} - rpc SetTopology (Topology ) returns ( TopologyId ) {} - rpc RemoveTopology (TopologyId ) returns ( Empty ) {} - rpc GetTopologyEvents (Empty ) returns (stream TopologyEvent ) {} - - rpc ListDeviceIds (Empty ) returns ( DeviceIdList ) {} - rpc ListDevices (Empty ) returns ( DeviceList ) {} - rpc GetDevice (DeviceId ) returns ( Device ) {} - rpc SetDevice (Device ) returns ( DeviceId ) {} - rpc RemoveDevice (DeviceId ) returns ( Empty ) {} - rpc GetDeviceEvents (Empty ) returns (stream DeviceEvent ) {} - rpc SelectDevice (DeviceFilter ) returns ( DeviceList ) {} - rpc ListEndPointNames (EndPointIdList) returns ( EndPointNameList) {} - - rpc ListLinkIds (Empty ) returns ( LinkIdList ) {} - rpc ListLinks (Empty ) returns ( LinkList ) {} - rpc GetLink (LinkId ) returns ( Link ) {} - rpc SetLink (Link ) returns ( LinkId ) {} - rpc RemoveLink (LinkId ) returns ( Empty ) {} - rpc GetLinkEvents (Empty ) returns (stream LinkEvent ) {} - - rpc ListServiceIds (ContextId ) returns ( ServiceIdList ) {} - rpc ListServices (ContextId ) returns ( ServiceList ) {} - rpc GetService (ServiceId ) returns ( Service ) {} - rpc SetService (Service ) returns ( ServiceId ) {} - rpc UnsetService (Service ) returns ( ServiceId ) {} - rpc RemoveService (ServiceId ) returns ( Empty ) {} - rpc GetServiceEvents (Empty ) returns (stream ServiceEvent ) {} - rpc SelectService (ServiceFilter ) returns ( ServiceList ) {} - - rpc ListSliceIds (ContextId ) returns ( SliceIdList ) {} - rpc ListSlices (ContextId ) returns ( SliceList ) {} - rpc GetSlice (SliceId ) returns ( Slice ) {} - rpc SetSlice (Slice ) returns ( SliceId ) {} - rpc UnsetSlice (Slice ) returns ( SliceId ) {} - rpc RemoveSlice (SliceId ) returns ( Empty ) {} - rpc GetSliceEvents (Empty ) returns (stream SliceEvent ) {} - rpc SelectSlice (SliceFilter ) returns ( SliceList ) {} - - rpc ListConnectionIds (ServiceId ) returns ( ConnectionIdList) {} - rpc ListConnections (ServiceId ) returns ( ConnectionList ) {} - rpc GetConnection (ConnectionId ) returns ( Connection ) {} - rpc SetConnection (Connection ) returns ( ConnectionId ) {} - rpc RemoveConnection (ConnectionId ) returns ( Empty ) {} - rpc GetConnectionEvents(Empty ) returns (stream ConnectionEvent ) {} - - - // ------------------------------ Experimental ----------------------------- - rpc GetOpticalConfig (Empty ) returns (OpticalConfigList ) {} - rpc SetOpticalConfig (OpticalConfig ) returns (OpticalConfigId ) {} - rpc SelectOpticalConfig(OpticalConfigId) returns (OpticalConfig ) {} - - rpc SetOpticalLink (OpticalLink ) returns (Empty ) {} - rpc GetOpticalLink (OpticalLinkId ) returns (OpticalLink ) {} - rpc GetFiber (FiberId ) returns (Fiber ) {} -} - -// ----- Generic ------------------------------------------------------------------------------------------------------- -message Empty {} - -message Uuid { - string uuid = 1; -} - -enum EventTypeEnum { - EVENTTYPE_UNDEFINED = 0; - EVENTTYPE_CREATE = 1; - EVENTTYPE_UPDATE = 2; - EVENTTYPE_REMOVE = 3; -} - -message Timestamp { - double timestamp = 1; -} - -message Event { - Timestamp timestamp = 1; - EventTypeEnum event_type = 2; -} - -// ----- Context ------------------------------------------------------------------------------------------------------- -message ContextId { - Uuid context_uuid = 1; -} - -message Context { - ContextId context_id = 1; - string name = 2; - repeated TopologyId topology_ids = 3; - repeated ServiceId service_ids = 4; - repeated SliceId slice_ids = 5; - TeraFlowController controller = 6; -} - -message ContextIdList { - repeated ContextId context_ids = 1; -} - -message ContextList { - repeated Context contexts = 1; -} - -message ContextEvent { - Event event = 1; - ContextId context_id = 2; -} - - -// ----- Topology ------------------------------------------------------------------------------------------------------ -message TopologyId { - ContextId context_id = 1; - Uuid topology_uuid = 2; -} - -message Topology { - TopologyId topology_id = 1; - string name = 2; - repeated DeviceId device_ids = 3; - repeated LinkId link_ids = 4; -} - -message TopologyDetails { - TopologyId topology_id = 1; - string name = 2; - repeated Device devices = 3; - repeated Link links = 4; -} - -message TopologyIdList { - repeated TopologyId topology_ids = 1; -} - -message TopologyList { - repeated Topology topologies = 1; -} - -message TopologyEvent { - Event event = 1; - TopologyId topology_id = 2; -} - - -// ----- Device -------------------------------------------------------------------------------------------------------- -message DeviceId { - Uuid device_uuid = 1; -} - -message Device { - DeviceId device_id = 1; - string name = 2; - string device_type = 3; - DeviceConfig device_config = 4; - DeviceOperationalStatusEnum device_operational_status = 5; - repeated DeviceDriverEnum device_drivers = 6; - repeated EndPoint device_endpoints = 7; - repeated Component components = 8; // Used for inventory - DeviceId controller_id = 9; // Identifier of node controlling the actual device -} - -message Component { //Defined previously to this section - Tested OK - Uuid component_uuid = 1; - string name = 2; - string type = 3; - - map<string, string> attributes = 4; // dict[attr.name => json.dumps(attr.value)] - string parent = 5; -} - -message DeviceConfig { - repeated ConfigRule config_rules = 1; -} - -enum DeviceDriverEnum { - DEVICEDRIVER_UNDEFINED = 0; // also used for emulated - DEVICEDRIVER_OPENCONFIG = 1; - DEVICEDRIVER_TRANSPORT_API = 2; - DEVICEDRIVER_P4 = 3; - DEVICEDRIVER_IETF_NETWORK_TOPOLOGY = 4; - DEVICEDRIVER_ONF_TR_532 = 5; - DEVICEDRIVER_XR = 6; - DEVICEDRIVER_IETF_L2VPN = 7; - DEVICEDRIVER_GNMI_OPENCONFIG = 8; - DEVICEDRIVER_OPTICAL_TFS = 9; - DEVICEDRIVER_IETF_ACTN = 10; - DEVICEDRIVER_OC = 11; - DEVICEDRIVER_QKD = 12; - DEVICEDRIVER_RYU = 13; -} - -enum DeviceOperationalStatusEnum { - DEVICEOPERATIONALSTATUS_UNDEFINED = 0; - DEVICEOPERATIONALSTATUS_DISABLED = 1; - DEVICEOPERATIONALSTATUS_ENABLED = 2; -} - -message DeviceIdList { - repeated DeviceId device_ids = 1; -} - -message DeviceList { - repeated Device devices = 1; -} - -message DeviceFilter { - DeviceIdList device_ids = 1; - bool include_endpoints = 2; - bool include_config_rules = 3; - bool include_components = 4; -} - -message DeviceEvent { - Event event = 1; - DeviceId device_id = 2; - DeviceConfig device_config = 3; -} - - -// ----- Link ---------------------------------------------------------------------------------------------------------- -message LinkId { - Uuid link_uuid = 1; -} - -message LinkAttributes { - float total_capacity_gbps = 1; - float used_capacity_gbps = 2; -} - -message Link { - LinkId link_id = 1; - string name = 2; - repeated EndPointId link_endpoint_ids = 3; - LinkAttributes attributes = 4; - LinkTypeEnum link_type = 5; -} - -message LinkIdList { - repeated LinkId link_ids = 1; -} - -message LinkList { - repeated Link links = 1; -} - -message LinkEvent { - Event event = 1; - LinkId link_id = 2; -} - -enum LinkTypeEnum { - LINKTYPE_UNKNOWN = 0; - LINKTYPE_COPPER = 1; - LINKTYPE_VIRTUAL_COPPER = 2; - LINKTYPE_OPTICAL = 3; - LINKTYPE_VIRTUAL_OPTICAL = 4; -} - -// ----- Service ------------------------------------------------------------------------------------------------------- -message ServiceId { - ContextId context_id = 1; - Uuid service_uuid = 2; -} - -message Service { - ServiceId service_id = 1; - string name = 2; - ServiceTypeEnum service_type = 3; - repeated EndPointId service_endpoint_ids = 4; - repeated Constraint service_constraints = 5; - ServiceStatus service_status = 6; - ServiceConfig service_config = 7; - Timestamp timestamp = 8; -} - -enum ServiceTypeEnum { - SERVICETYPE_UNKNOWN = 0; - SERVICETYPE_L3NM = 1; - SERVICETYPE_L2NM = 2; - SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3; - SERVICETYPE_TE = 4; - SERVICETYPE_E2E = 5; - SERVICETYPE_OPTICAL_CONNECTIVITY = 6; - SERVICETYPE_QKD = 7; -} - -enum ServiceStatusEnum { - SERVICESTATUS_UNDEFINED = 0; - SERVICESTATUS_PLANNED = 1; - SERVICESTATUS_ACTIVE = 2; - SERVICESTATUS_UPDATING = 3; - SERVICESTATUS_PENDING_REMOVAL = 4; - SERVICESTATUS_SLA_VIOLATED = 5; -} - -message ServiceStatus { - ServiceStatusEnum service_status = 1; -} - -message ServiceConfig { - repeated ConfigRule config_rules = 1; -} - -message ServiceIdList { - repeated ServiceId service_ids = 1; -} - -message ServiceList { - repeated Service services = 1; -} - -message ServiceFilter { - ServiceIdList service_ids = 1; - bool include_endpoint_ids = 2; - bool include_constraints = 3; - bool include_config_rules = 4; -} - -message ServiceEvent { - Event event = 1; - ServiceId service_id = 2; -} - -// ----- Slice --------------------------------------------------------------------------------------------------------- -message SliceId { - ContextId context_id = 1; - Uuid slice_uuid = 2; -} - -message Slice { - SliceId slice_id = 1; - string name = 2; - repeated EndPointId slice_endpoint_ids = 3; - repeated Constraint slice_constraints = 4; - repeated ServiceId slice_service_ids = 5; - repeated SliceId slice_subslice_ids = 6; - SliceStatus slice_status = 7; - SliceConfig slice_config = 8; - SliceOwner slice_owner = 9; - Timestamp timestamp = 10; -} - -message SliceOwner { - Uuid owner_uuid = 1; - string owner_string = 2; -} - -enum SliceStatusEnum { - SLICESTATUS_UNDEFINED = 0; - SLICESTATUS_PLANNED = 1; - SLICESTATUS_INIT = 2; - SLICESTATUS_ACTIVE = 3; - SLICESTATUS_DEINIT = 4; - SLICESTATUS_SLA_VIOLATED = 5; -} - -message SliceStatus { - SliceStatusEnum slice_status = 1; -} - -message SliceConfig { - repeated ConfigRule config_rules = 1; -} - -message SliceIdList { - repeated SliceId slice_ids = 1; -} - -message SliceList { - repeated Slice slices = 1; -} - -message SliceFilter { - SliceIdList slice_ids = 1; - bool include_endpoint_ids = 2; - bool include_constraints = 3; - bool include_service_ids = 4; - bool include_subslice_ids = 5; - bool include_config_rules = 6; -} - -message SliceEvent { - Event event = 1; - SliceId slice_id = 2; -} - -// ----- Connection ---------------------------------------------------------------------------------------------------- -message ConnectionId { - Uuid connection_uuid = 1; -} - -message ConnectionSettings_L0 { - string lsp_symbolic_name = 1; -} - -message ConnectionSettings_L2 { - string src_mac_address = 1; - string dst_mac_address = 2; - uint32 ether_type = 3; - uint32 vlan_id = 4; - uint32 mpls_label = 5; - uint32 mpls_traffic_class = 6; -} - -message ConnectionSettings_L3 { - string src_ip_address = 1; - string dst_ip_address = 2; - uint32 dscp = 3; - uint32 protocol = 4; - uint32 ttl = 5; -} - -message ConnectionSettings_L4 { - uint32 src_port = 1; - uint32 dst_port = 2; - uint32 tcp_flags = 3; - uint32 ttl = 4; -} - -message ConnectionSettings { - ConnectionSettings_L0 l0 = 1; - ConnectionSettings_L2 l2 = 2; - ConnectionSettings_L3 l3 = 3; - ConnectionSettings_L4 l4 = 4; -} - -message Connection { - ConnectionId connection_id = 1; - ServiceId service_id = 2; - repeated EndPointId path_hops_endpoint_ids = 3; - repeated ServiceId sub_service_ids = 4; - ConnectionSettings settings = 5; -} - -message ConnectionIdList { - repeated ConnectionId connection_ids = 1; -} - -message ConnectionList { - repeated Connection connections = 1; -} - -message ConnectionEvent { - Event event = 1; - ConnectionId connection_id = 2; -} - - -// ----- Endpoint ------------------------------------------------------------------------------------------------------ -message EndPointId { - TopologyId topology_id = 1; - DeviceId device_id = 2; - Uuid endpoint_uuid = 3; -} - -message EndPoint { - EndPointId endpoint_id = 1; - string name = 2; - string endpoint_type = 3; - repeated kpi_sample_types.KpiSampleType kpi_sample_types = 4; - Location endpoint_location = 5; -} - -message EndPointName { - EndPointId endpoint_id = 1; - string device_name = 2; - string endpoint_name = 3; - string endpoint_type = 4; -} - -message EndPointIdList { - repeated EndPointId endpoint_ids = 1; -} - -message EndPointNameList { - repeated EndPointName endpoint_names = 1; -} - - -// ----- Configuration ------------------------------------------------------------------------------------------------- -enum ConfigActionEnum { - CONFIGACTION_UNDEFINED = 0; - CONFIGACTION_SET = 1; - CONFIGACTION_DELETE = 2; -} - -message ConfigRule_Custom { - string resource_key = 1; - string resource_value = 2; -} - -message ConfigRule_ACL { - EndPointId endpoint_id = 1; - acl.AclRuleSet rule_set = 2; -} - -message ConfigRule { - ConfigActionEnum action = 1; - oneof config_rule { - ConfigRule_Custom custom = 2; - ConfigRule_ACL acl = 3; - } -} - - -// ----- Constraint ---------------------------------------------------------------------------------------------------- -enum ConstraintActionEnum { - CONSTRAINTACTION_UNDEFINED = 0; - CONSTRAINTACTION_SET = 1; - CONSTRAINTACTION_DELETE = 2; -} - -message Constraint_Custom { - string constraint_type = 1; - string constraint_value = 2; -} - -message Constraint_Schedule { - double start_timestamp = 1; - float duration_days = 2; -} - -message GPS_Position { - float latitude = 1; - float longitude = 2; -} - -message Location { - oneof location { - string region = 1; - GPS_Position gps_position = 2; - } -} - -message Constraint_EndPointLocation { - EndPointId endpoint_id = 1; - Location location = 2; -} - -message Constraint_EndPointPriority { - EndPointId endpoint_id = 1; - uint32 priority = 2; -} - -message Constraint_SLA_Latency { - float e2e_latency_ms = 1; -} - -message Constraint_SLA_Capacity { - float capacity_gbps = 1; -} - -message Constraint_SLA_Availability { - uint32 num_disjoint_paths = 1; - bool all_active = 2; - float availability = 3; // 0.0 .. 100.0 percentage of availability -} - -enum IsolationLevelEnum { - NO_ISOLATION = 0; - PHYSICAL_ISOLATION = 1; - LOGICAL_ISOLATION = 2; - PROCESS_ISOLATION = 3; - PHYSICAL_MEMORY_ISOLATION = 4; - PHYSICAL_NETWORK_ISOLATION = 5; - VIRTUAL_RESOURCE_ISOLATION = 6; - NETWORK_FUNCTIONS_ISOLATION = 7; - SERVICE_ISOLATION = 8; -} - -message Constraint_SLA_Isolation_level { - repeated IsolationLevelEnum isolation_level = 1; -} - -message Constraint_Exclusions { - bool is_permanent = 1; - repeated DeviceId device_ids = 2; - repeated EndPointId endpoint_ids = 3; - repeated LinkId link_ids = 4; -} - - -message QoSProfileId { - context.Uuid qos_profile_id = 1; -} - -message Constraint_QoSProfile { - QoSProfileId qos_profile_id = 1; - string qos_profile_name = 2; -} - -message Constraint { - ConstraintActionEnum action = 1; - oneof constraint { - Constraint_Custom custom = 2; - Constraint_Schedule schedule = 3; - Constraint_EndPointLocation endpoint_location = 4; - Constraint_EndPointPriority endpoint_priority = 5; - Constraint_SLA_Capacity sla_capacity = 6; - Constraint_SLA_Latency sla_latency = 7; - Constraint_SLA_Availability sla_availability = 8; - Constraint_SLA_Isolation_level sla_isolation = 9; - Constraint_Exclusions exclusions = 10; - Constraint_QoSProfile qos_profile = 11; - } -} - - -// ----- Miscellaneous ------------------------------------------------------------------------------------------------- -message TeraFlowController { - ContextId context_id = 1; - string ip_address = 2; - uint32 port = 3; -} - -message AuthenticationResult { - ContextId context_id = 1; - bool authenticated = 2; -} - -// ---------------- Experimental ------------------------ -message OpticalConfigId { - string opticalconfig_uuid = 1; -} -message OpticalConfig { - OpticalConfigId opticalconfig_id = 1; - string config = 2; -} - -message OpticalConfigList { - repeated OpticalConfig opticalconfigs = 1; -} - -// ---- Optical Link ---- - -message OpticalLinkId { - Uuid optical_link_uuid = 1; -} - -message FiberId { - Uuid fiber_uuid = 1; -} - -message Fiber { - string ID = 10; - string src_port = 1; - string dst_port = 2; - string local_peer_port = 3; - string remote_peer_port = 4; - repeated int32 c_slots = 5; - repeated int32 l_slots = 6; - repeated int32 s_slots = 7; - float length = 8; - bool used = 9; - FiberId fiber_uuid = 11; - -} -message OpticalLinkDetails { - float length = 1; - string source = 2; - string target = 3; - repeated Fiber fibers = 4; -} - -message OpticalLink { - string name = 1; - OpticalLinkDetails details = 2; - OpticalLinkId optical_link_uuid = 3; -} diff --git a/tmp-code/run_openflow.sh b/tmp-code/run_openflow.sh deleted file mode 100755 index 2c525ca70242374ebe7c09993833cee867455167..0000000000000000000000000000000000000000 --- a/tmp-code/run_openflow.sh +++ /dev/null @@ -1,8 +0,0 @@ -PROJECTDIR=`pwd` - -cd $PROJECTDIR/src -RCFILE=$PROJECTDIR/coverage/.coveragerc - -# Run unitary tests and analyze coverage of code at same time -coverage run --rcfile=$RCFILE --append -m pytest --log-level=DEBUG --verbose \ - device/tests/test_OpenFlow.py \ No newline at end of file diff --git a/tmp-code/test_OpenFlow.py b/tmp-code/test_OpenFlow.py deleted file mode 100644 index 60ee4542c768a50747be95e490254cb027eba6e2..0000000000000000000000000000000000000000 --- a/tmp-code/test_OpenFlow.py +++ /dev/null @@ -1,77 +0,0 @@ -import json -from re import A -import resource -import logging, os, sys, time -#from typing import Dict, Self, Tuple -os.environ['DEVICE_EMULATED_ONLY'] = 'YES' -from device.service.drivers.OpenFlow.OpenFlowDriver import OpenFlowDriver -logging.basicConfig(level=logging.DEBUG) -LOGGER = logging.getLogger(__name__) -LOGGER.setLevel(logging.DEBUG) - - -def test_main(): - driver_settings = { - 'protocol': 'http', - 'username': None, - 'password': None, - 'use_tls': False, - } - driver = OpenFlowDriver('127.0.0.1', 8080 , **driver_settings) - driver.Connect() - - - # Test: GetConfig - #resource_keys = [ 'flows:1','description:1','switches','port_description:1','switch_info','links_info'] - # config = driver.GetConfig(resource_keys ) - # LOGGER.info('Specific configuration: %s', config) - - #resource_delete=["flowentry_delete:1"] - #config = driver.DeleteConfig(resource_delete) - #LOGGER.info('Specific configuration: %s', config) - #a=driver.GetConfig(["flows:1"]) - #LOGGER.info('flow 1 = {:s}'.format(str(a))) -# delete_data = { -# "dpid": 2, -# "cookie": 1, -# "cookie_mask": 1, -# "table_id": 0, -# "idle_timeout": 30, -# "hard_timeout": 30, -# "priority": 11111, -# "flags": 1, -# "match":{ -# "in_port":2 -# }, -# "actions":[ -# { -# "type":"ddf", -# "port": 1 -# } -# ] -# } -# delete_result = driver.DeleteConfig([("flow_data", delete_data)]) -# LOGGER.info('resources_to_delete = {:s}'.format(str(delete_result))) -# a=driver.GetConfig(["flows:1"]) -# LOGGER.info('flow 2 = {:s}'.format(str(a))) - flow_data = { - "dpid": 2, - "priority": 22224, - "match": { - "in_port": 1 - }, - "actions": [ - { - "type": "GOTO_TABLE", - "table_id": 1 - } - ] - } - set_result = driver.SetConfig([('flow_data',flow_data)]) - LOGGER.info(set_result) - driver.Disconnect() - - raise Exception () - -if __name__ == '__main__': - sys.exit(test_main())