From e8b49b4b87c4eef4399c3db3615119cb7768f028 Mon Sep 17 00:00:00 2001 From: sgambelluri Date: Mon, 4 Mar 2024 16:56:38 +0000 Subject: [PATCH 01/13] leftover contribution --- manifests/opticalcontrollerservice.yaml | 57 + my_deploy.sh | 7 +- proto/context.proto | 62 +- proto/openconfig_device.proto | 26 + scripts/show_logs_opticalcontroller.sh | 27 + src/common/Constants.py | 1 + src/common/DeviceTypes.py | 1 + src/common/Settings.py | 2 + src/common/tools/descriptor/Loader.py | 1 + src/common/tools/descriptor/Tools.py | 11 +- src/context/client/ContextClient.py | 24 +- .../service/ContextServiceServicerImpl.py | 22 +- src/context/service/database/ConfigModel.py | 125 ++ src/context/service/database/Device.py | 13 +- .../service/database/MyConfigOperator.py | 129 ++ src/context/service/database/Service.py | 4 +- .../service/database/models/MyConfigModel.py | 51 + .../database/models/enums/DeviceDriver.py | 1 + .../database/models/enums/ServiceType.py | 1 + src/device/client/DeviceClient.py | 3 +- src/device/service/DeviceService.py | 1 + .../service/DeviceServiceServicerImpl.py | 9 +- src/device/service/OpenConfigServicer.py | 53 +- src/device/service/Tools.py | 117 +- src/device/service/drivers/__init__.py | 8 +- .../service/drivers/oc_driver/OCDriver.py | 54 +- .../templates/Interfaces/interfaces.py | 2 +- .../drivers/oc_driver/templates/Tools.py | 7 +- .../oc_driver/templates/VPN/physical.py | 17 +- src/opticalcontroller/OpticalController.py | 22 +- src/opticalcontroller/RSA.py | 37 + src/opticalcontroller/dijsktra.py | 20 +- .../json_files/tfs copy.json | 1286 +++++++++++++++++ src/opticalcontroller/json_files/tfs.json | 836 ++--------- src/opticalcontroller/tools.py | 14 - src/opticalcontroller/variables.py | 14 - src/service/Dockerfile | 7 +- .../service/ServiceServiceServicerImpl.py | 134 +- src/service/service/__main__.py | 14 +- .../service_handler_api/FilterFields.py | 2 + .../service_handlers/oc/OCServiceHandler.py | 144 +- .../service/service_handlers/oc/OCTools.py | 12 +- .../service/task_scheduler/TaskExecutor.py | 84 +- src/service/service/tools/OpticalTools.py | 51 +- startExtraNetConfigAgent.sh | 25 + start_topo.sh | 23 + 46 files changed, 2477 insertions(+), 1084 deletions(-) create mode 100644 manifests/opticalcontrollerservice.yaml create mode 100644 proto/openconfig_device.proto create mode 100755 scripts/show_logs_opticalcontroller.sh create mode 100644 src/context/service/database/ConfigModel.py create mode 100644 src/context/service/database/MyConfigOperator.py create mode 100644 src/context/service/database/models/MyConfigModel.py create mode 100644 src/opticalcontroller/json_files/tfs copy.json create mode 100755 startExtraNetConfigAgent.sh create mode 100755 start_topo.sh diff --git a/manifests/opticalcontrollerservice.yaml b/manifests/opticalcontrollerservice.yaml new file mode 100644 index 000000000..ba1edcc56 --- /dev/null +++ b/manifests/opticalcontrollerservice.yaml @@ -0,0 +1,57 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: opticalcontrollerservice +spec: + selector: + matchLabels: + app: opticalcontrollerservice + replicas: 1 + template: + metadata: + annotations: + # Required for IETF L2VPN SBI when both parent and child run in same K8s cluster with Linkerd + config.linkerd.io/skip-outbound-ports: "8022" + labels: + app: opticalcontrollerservice + spec: + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: localhost:32000/tfs/opticalcontroller:dev + imagePullPolicy: Never + ports: + - containerPort: 5022 + - containerPort: 9192 + + env: + - name: LOG_LEVEL + value: "INFO" + + resources: + requests: + cpu: 500m + memory: 128Mi + limits: + cpu: 1000m + memory: 1024Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: opticalcontrollerservice + labels: + app: opticalcontrollerservice +spec: + type: ClusterIP + selector: + app: opticalcontrollerservice + ports: + - name: grpc + protocol: TCP + port: 5022 + targetPort: 5022 + - name: metrics + protocol: TCP + port: 9192 + targetPort: 9192 diff --git a/my_deploy.sh b/my_deploy.sh index 0c5ba03c5..524abc6cc 100755 --- a/my_deploy.sh +++ b/my_deploy.sh @@ -20,13 +20,10 @@ export TFS_REGISTRY_IMAGES="http://localhost:32000/tfs/" # Set the list of components, separated by spaces, you want to build images for, and deploy. -export TFS_COMPONENTS="context device pathcomp service slice nbi webui load_generator" +export TFS_COMPONENTS="context device pathcomp opticalcontroller service slice webui " # Uncomment to activate Monitoring -#export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" - -# Uncomment to activate bgpls_speaker -#export TFS_COMPONENTS="${TFS_COMPONENTS} bgpls_speaker" +#export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring"../ # Uncomment to activate ZTP #export TFS_COMPONENTS="${TFS_COMPONENTS} ztp" diff --git a/proto/context.proto b/proto/context.proto index d5022ac29..e96181693 100644 --- a/proto/context.proto +++ b/proto/context.proto @@ -74,6 +74,16 @@ service ContextService { rpc SetConnection (Connection ) returns ( ConnectionId ) {} rpc RemoveConnection (ConnectionId ) returns ( Empty ) {} rpc GetConnectionEvents(Empty ) returns (stream ConnectionEvent ) {} + + +// ------------------------------ Experimental------------------------------ + rpc GetMyConfig (Empty ) returns ( MyConfigList ) {} + rpc SetMyConfig (MyConfig) returns (MyConfigId) {} + rpc SelectMyConfig (MyConfigId) returns (MyConfig) {} + + rpc SetOpticalLink (OpticalLink) returns (Empty) {} + rpc GetOpticalLink (OpticalLinkId) returns (OpticalLink) {} + rpc GetFiber (FiberId) returns (Fiber) {} } // ----- Generic ------------------------------------------------------------------------------------------------------- @@ -201,8 +211,9 @@ enum DeviceDriverEnum { DEVICEDRIVER_XR = 6; DEVICEDRIVER_IETF_L2VPN = 7; DEVICEDRIVER_GNMI_OPENCONFIG = 8; - DEVICEDRIVER_FLEXSCALE = 9; - DEVICEDRIVER_IETF_ACTN = 10; + DEVICEDRIVER_OC = 11; + DEVICEDRIVER_FLEXSCALE=10; + DEVICEDRIVER_IETF_ACTN=9; } enum DeviceOperationalStatusEnum { @@ -288,6 +299,7 @@ enum ServiceTypeEnum { SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3; SERVICETYPE_TE = 4; SERVICETYPE_E2E = 5; +SERVICETYPE_OPTICAL_CONNECTIVITY = 6; } enum ServiceStatusEnum { @@ -612,3 +624,49 @@ message AuthenticationResult { ContextId context_id = 1; bool authenticated = 2; } + +// ---------------- Experimental ------------------------ +message MyConfigId { + string myconfig_uuid= 1; +} +message MyConfig { + MyConfigId myconfig_id=1; + string config =2 ; +} +message MyConfigList { + repeated MyConfig MyConfigs =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 { + OpticalLinkId optical_link_uuid=3; + string name=1; + OpticalLinkDetails details=2; +} diff --git a/proto/openconfig_device.proto b/proto/openconfig_device.proto new file mode 100644 index 000000000..d00e46645 --- /dev/null +++ b/proto/openconfig_device.proto @@ -0,0 +1,26 @@ +// 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. + +syntax = "proto3"; +package openconfig_device; + +import "context.proto"; +import "monitoring.proto"; + +service OpenConfigService { + rpc AddOpenConfigDevice (context.MyConfig ) returns (context.MyConfigId ) {} + + rpc ConfigureOpticalDevice (context.MyConfig) returns (context.Empty) {} + +} diff --git a/scripts/show_logs_opticalcontroller.sh b/scripts/show_logs_opticalcontroller.sh new file mode 100755 index 000000000..e32ea7ef9 --- /dev/null +++ b/scripts/show_logs_opticalcontroller.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# 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. + +######################################################################################################################## +# Define your deployment settings here +######################################################################################################################## + +# If not already set, set the name of the Kubernetes namespace to deploy to. +export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} + +######################################################################################################################## +# Automated steps start here +######################################################################################################################## + +kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/opticalcontrollerservice -c server > logs/opticalcontroller.log && vi logs/opticalcontroller.log diff --git a/src/common/Constants.py b/src/common/Constants.py index c7ba01f69..0a36c6ac5 100644 --- a/src/common/Constants.py +++ b/src/common/Constants.py @@ -59,6 +59,7 @@ class ServiceNameEnum(Enum): TE = 'te' FORECASTER = 'forecaster' E2EORCHESTRATOR = 'e2eorchestrator' + OPTICALCONTROLLER = 'opticalcontroller' BGPLS = 'bgpls-speaker' # Used for test and debugging only diff --git a/src/common/DeviceTypes.py b/src/common/DeviceTypes.py index 72b3e21fd..f4ade564b 100644 --- a/src/common/DeviceTypes.py +++ b/src/common/DeviceTypes.py @@ -47,6 +47,7 @@ class DeviceTypeEnum(Enum): PACKET_ROUTER = 'packet-router' PACKET_SWITCH = 'packet-switch' XR_CONSTELLATION = 'xr-constellation' + # ETSI TeraFlowSDN controller TERAFLOWSDN_CONTROLLER = 'teraflowsdn' diff --git a/src/common/Settings.py b/src/common/Settings.py index 5d6fba2fd..fc503ea2d 100644 --- a/src/common/Settings.py +++ b/src/common/Settings.py @@ -37,6 +37,8 @@ ENVVAR_SUFIX_SERVICE_HOST = 'SERVICE_HOST' ENVVAR_SUFIX_SERVICE_PORT_GRPC = 'SERVICE_PORT_GRPC' ENVVAR_SUFIX_SERVICE_PORT_HTTP = 'SERVICE_PORT_HTTP' + + def find_environment_variables( environment_variable_names : List[str] = [] ) -> Dict[str, str]: diff --git a/src/common/tools/descriptor/Loader.py b/src/common/tools/descriptor/Loader.py index 4ab33beae..eef41bbd8 100644 --- a/src/common/tools/descriptor/Loader.py +++ b/src/common/tools/descriptor/Loader.py @@ -262,6 +262,7 @@ class DescriptorLoader: # Device, Service and Slice require to first create the entity and the configure it self.__devices_add, self.__devices_config = split_devices_by_rules(self.__devices) + self.__services_add = get_descriptors_add_services(self.__services) self.__slices_add = get_descriptors_add_slices(self.__slices) diff --git a/src/common/tools/descriptor/Tools.py b/src/common/tools/descriptor/Tools.py index b4a76ff4f..a4792436a 100644 --- a/src/common/tools/descriptor/Tools.py +++ b/src/common/tools/descriptor/Tools.py @@ -12,9 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -import copy, json +import copy, json,logging from typing import Dict, List, Optional, Tuple, Union from common.DeviceTypes import DeviceTypeEnum +from common.proto.context_pb2 import DeviceDriverEnum def get_descriptors_add_contexts(contexts : List[Dict]) -> List[Dict]: contexts_add = copy.deepcopy(contexts) @@ -66,6 +67,8 @@ def format_device_custom_config_rules(device : Dict) -> Dict: config_rules = device.get('device_config', {}).get('config_rules', []) config_rules = format_custom_config_rules(config_rules) device['device_config']['config_rules'] = config_rules + + return device def format_service_custom_config_rules(service : Dict) -> Dict: @@ -83,7 +86,9 @@ def format_slice_custom_config_rules(slice_ : Dict) -> Dict: def split_devices_by_rules(devices : List[Dict]) -> Tuple[List[Dict], List[Dict]]: devices_add = [] devices_config = [] + for device in devices: + connect_rules = [] config_rules = [] for config_rule in device.get('device_config', {}).get('config_rules', []): @@ -95,13 +100,15 @@ def split_devices_by_rules(devices : List[Dict]) -> Tuple[List[Dict], List[Dict] if len(connect_rules) > 0: device_add = copy.deepcopy(device) - device_add['device_endpoints'] = [] + if (device['device_drivers'][0] != DeviceDriverEnum.DEVICEDRIVER_OC): + device_add['device_endpoints'] = [] device_add['device_config'] = {'config_rules': connect_rules} devices_add.append(device_add) if len(config_rules) > 0: device['device_config'] = {'config_rules': config_rules} devices_config.append(device) + return devices_add, devices_config diff --git a/src/context/client/ContextClient.py b/src/context/client/ContextClient.py index 13d9dc003..a1a6bcb08 100644 --- a/src/context/client/ContextClient.py +++ b/src/context/client/ContextClient.py @@ -26,7 +26,8 @@ from common.proto.context_pb2 import ( Link, LinkEvent, LinkId, LinkIdList, LinkList, Service, ServiceEvent, ServiceFilter, ServiceId, ServiceIdList, ServiceList, Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList, - Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList) + Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList, + MyConfig,MyConfigId,MyConfigList) from common.proto.context_pb2_grpc import ContextServiceStub from common.proto.context_policy_pb2_grpc import ContextPolicyServiceStub from common.proto.policy_pb2 import PolicyRuleIdList, PolicyRuleId, PolicyRuleList, PolicyRule @@ -436,3 +437,24 @@ class ContextClient: response = self.policy_stub.RemovePolicyRule(request) LOGGER.debug('RemovePolicyRule result: {:s}'.format(grpc_message_to_json_string(response))) return response + #//////////////// Experimental ////////////////// + @RETRY_DECORATOR + def SetMyConfig (self,request:MyConfig) ->MyConfigId: + LOGGER.debug('SettingMyConfig request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.SetMyConfig(request) + LOGGER.debug('SettingMyconfig result: {:s}'.format(grpc_message_to_json_string(response))) + return response + + @RETRY_DECORATOR + def GetMyConfig (self,request:Empty) ->MyConfigList: + LOGGER.debug('GettingMyConfig request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.GetMyConfig(request) + LOGGER.debug('GetMyConfig result: {:s}'.format(grpc_message_to_json_string(response))) + return response + + @RETRY_DECORATOR + def SelectMyConfig (self,request:MyConfigId) ->MyConfigList: + LOGGER.debug('Selecting request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.SelectMyConfig(request) + LOGGER.debug('GetMyConfig result: {:s}'.format(grpc_message_to_json_string(response))) + return response diff --git a/src/context/service/ContextServiceServicerImpl.py b/src/context/service/ContextServiceServicerImpl.py index 5aad7f9c9..f4d2cc307 100644 --- a/src/context/service/ContextServiceServicerImpl.py +++ b/src/context/service/ContextServiceServicerImpl.py @@ -23,7 +23,8 @@ from common.proto.context_pb2 import ( Link, LinkEvent, LinkId, LinkIdList, LinkList, Service, ServiceEvent, ServiceFilter, ServiceId, ServiceIdList, ServiceList, Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList, - Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList) + Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList, + MyConfigList,MyConfigId,MyConfig) from common.proto.policy_pb2 import PolicyRuleIdList, PolicyRuleId, PolicyRuleList, PolicyRule from common.proto.context_pb2_grpc import ContextServiceServicer from common.proto.context_policy_pb2_grpc import ContextPolicyServiceServicer @@ -43,6 +44,7 @@ from .database.Slice import ( slice_delete, slice_get, slice_list_ids, slice_list_objs, slice_select, slice_set, slice_unset) from .database.Topology import ( topology_delete, topology_get, topology_get_details, topology_list_ids, topology_list_objs, topology_set) +from .database.MyConfigOperator import (set_myconfig,select_MyConfig,get_myconfig) LOGGER = logging.getLogger(__name__) @@ -296,3 +298,21 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RemovePolicyRule(self, request : PolicyRuleId, context: grpc.ServicerContext) -> Empty: return policyrule_delete(self.db_engine, self.messagebroker, request) + # ---------------------------- Experimental ------------------- + @safe_and_metered_rpc_method(METRICS_POOL,LOGGER) + def GetMyConfig(self,request:Empty,context:grpc.ServicerContext) -> MyConfigList: + + result =get_myconfig(db_engine=self.db_engine) + + return MyConfigList(MyConfigs=result) + def SetMyConfig(self,request:MyConfig,context:grpc.ServicerContext)-> MyConfigId: + + myconfig_id= set_myconfig(db_engine=self.db_engine,request=request) + + return MyConfigId(**myconfig_id) + def SelectMyConfig (self,request:MyConfigId,context:grpc.ServicerContext) -> MyConfig: + result =select_MyConfig(db_engine=self.db_engine,request=request) + logging.info(f"FromSelectMyConfig {result}") + myid =MyConfigId() + myid.CopyFrom(result.myconfig_id) + return MyConfig(config=result.config,myconfig_id=myid) diff --git a/src/context/service/database/ConfigModel.py b/src/context/service/database/ConfigModel.py new file mode 100644 index 000000000..234e155f0 --- /dev/null +++ b/src/context/service/database/ConfigModel.py @@ -0,0 +1,125 @@ +# 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 functools, logging, operator +from enum import Enum +from typing import Dict, List, Optional, Tuple, Union +from common.orm.Database import Database +from common.orm.HighLevel import get_object, get_or_create_object, update_or_create_object +from common.orm.backend.Tools import key_to_str +from common.orm.fields.EnumeratedField import EnumeratedField +from common.orm.fields.ForeignKeyField import ForeignKeyField +from common.orm.fields.IntegerField import IntegerField +from common.orm.fields.PrimaryKeyField import PrimaryKeyField +from common.orm.fields.StringField import StringField +from common.orm.model.Model import Model +from context.proto.context_pb2 import ConfigActionEnum +from .Tools import fast_hasher, grpc_to_enum, remove_dict_key + +LOGGER = logging.getLogger(__name__) + +class ORM_ConfigActionEnum(Enum): + UNDEFINED = ConfigActionEnum.CONFIGACTION_UNDEFINED + SET = ConfigActionEnum.CONFIGACTION_SET + DELETE = ConfigActionEnum.CONFIGACTION_DELETE + +grpc_to_enum__config_action = functools.partial( + grpc_to_enum, ConfigActionEnum, ORM_ConfigActionEnum) + +class ConfigModel(Model): # pylint: disable=abstract-method + pk = PrimaryKeyField() + + def dump(self) -> List[Dict]: + db_config_rule_pks = self.references(ConfigRuleModel) + config_rules = [ConfigRuleModel(self.database, pk).dump(include_position=True) for pk,_ in db_config_rule_pks] + config_rules = sorted(config_rules, key=operator.itemgetter('position')) + return [remove_dict_key(config_rule, 'position') for config_rule in config_rules] + +class ConfigRuleModel(Model): # pylint: disable=abstract-method + pk = PrimaryKeyField() + config_fk = ForeignKeyField(ConfigModel) + position = IntegerField(min_value=0, required=True) + action = EnumeratedField(ORM_ConfigActionEnum, required=True) + key = StringField(required=True, allow_empty=False) + value = StringField(required=True, allow_empty=False) + + def dump(self, include_position=True) -> Dict: # pylint: disable=arguments-differ + result = { + 'action': self.action.value, + 'resource_key': self.key, + 'resource_value': self.value, + } + if include_position: result['position'] = self.position + return result + +def set_config_rule( + database : Database, db_config : ConfigModel, position : int, resource_key : str, resource_value : str + ) -> Tuple[ConfigRuleModel, bool]: + + str_rule_key_hash = fast_hasher(resource_key) + str_config_rule_key = key_to_str([db_config.pk, str_rule_key_hash], separator=':') + result : Tuple[ConfigRuleModel, bool] = update_or_create_object(database, ConfigRuleModel, str_config_rule_key, { + 'config_fk': db_config, 'position': position, 'action': ORM_ConfigActionEnum.SET, + 'key': resource_key, 'value': resource_value}) + db_config_rule, updated = result + return db_config_rule, updated + +def delete_config_rule( + database : Database, db_config : ConfigModel, resource_key : str + ) -> None: + + str_rule_key_hash = fast_hasher(resource_key) + str_config_rule_key = key_to_str([db_config.pk, str_rule_key_hash], separator=':') + db_config_rule : Optional[ConfigRuleModel] = get_object( + database, ConfigRuleModel, str_config_rule_key, raise_if_not_found=False) + if db_config_rule is None: return + db_config_rule.delete() + +def delete_all_config_rules( + database : Database, db_config : ConfigModel + ) -> None: + + db_config_rule_pks = db_config.references(ConfigRuleModel) + for pk,_ in db_config_rule_pks: ConfigRuleModel(database, pk).delete() + +def grpc_config_rules_to_raw(grpc_config_rules) -> List[Tuple[ORM_ConfigActionEnum, str, str]]: + def translate(grpc_config_rule): + action = grpc_to_enum__config_action(grpc_config_rule.action) + return action, grpc_config_rule.resource_key, grpc_config_rule.resource_value + return [translate(grpc_config_rule) for grpc_config_rule in grpc_config_rules] + +def update_config( + database : Database, db_parent_pk : str, config_name : str, + raw_config_rules : List[Tuple[ORM_ConfigActionEnum, str, str]] + ) -> List[Tuple[Union[ConfigModel, ConfigRuleModel], bool]]: + + str_config_key = key_to_str([db_parent_pk, config_name], separator=':') + result : Tuple[ConfigModel, bool] = get_or_create_object(database, ConfigModel, str_config_key) + db_config, created = result + + db_objects : List[Tuple[Union[ConfigModel, ConfigRuleModel], bool]] = [(db_config, created)] + + for position,(action, resource_key, resource_value) in enumerate(raw_config_rules): + if action == ORM_ConfigActionEnum.SET: + result : Tuple[ConfigRuleModel, bool] = set_config_rule( + database, db_config, position, resource_key, resource_value) + db_config_rule, updated = result + db_objects.append((db_config_rule, updated)) + elif action == ORM_ConfigActionEnum.DELETE: + delete_config_rule(database, db_config, resource_key) + else: + msg = 'Unsupported action({:s}) for resource_key({:s})/resource_value({:s})' + raise AttributeError(msg.format(str(ConfigActionEnum.Name(action)), str(resource_key), str(resource_value))) + + return db_objects diff --git a/src/context/service/database/Device.py b/src/context/service/database/Device.py index 3aff20ade..76eac944e 100644 --- a/src/context/service/database/Device.py +++ b/src/context/service/database/Device.py @@ -21,7 +21,8 @@ from typing import Dict, List, Optional, Set, Tuple from common.method_wrappers.ServiceExceptions import InvalidArgumentException, NotFoundException from common.message_broker.MessageBroker import MessageBroker from common.proto.context_pb2 import ( - Device, DeviceFilter, DeviceId, DeviceIdList, DeviceList, Empty, EventTypeEnum, TopologyId) + Device, DeviceFilter, DeviceId, DeviceIdList + , DeviceList, Empty, EventTypeEnum, TopologyId,DeviceDriverEnum) from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.object_factory.Device import json_device_id from context.service.database.uuids.Topology import topology_get_uuid @@ -76,6 +77,7 @@ def device_get(db_engine : Engine, request : DeviceId) -> Device: return Device(**obj) def device_set(db_engine : Engine, messagebroker : MessageBroker, request : Device) -> DeviceId: + raw_device_uuid = request.device_id.device_uuid.uuid raw_device_name = request.name device_name = raw_device_uuid if len(raw_device_name) == 0 else raw_device_name @@ -87,6 +89,7 @@ def device_set(db_engine : Engine, messagebroker : MessageBroker, request : Devi controller_uuid = None device_type = request.device_type + oper_status = grpc_to_enum__device_operational_status(request.device_operational_status) device_drivers = [grpc_to_enum__device_driver(d) for d in request.device_drivers] @@ -94,7 +97,7 @@ def device_set(db_engine : Engine, messagebroker : MessageBroker, request : Devi topology_uuids : Set[str] = set() related_topologies : List[Dict] = list() - + # By default, always add device to default Context/Topology _,topology_uuid = topology_get_uuid(TopologyId(), allow_random=False, allow_default=True) related_topologies.append({ @@ -103,10 +106,14 @@ def device_set(db_engine : Engine, messagebroker : MessageBroker, request : Devi }) topology_uuids.add(topology_uuid) + + is_oc_driver= [d for d in request.device_drivers][0]==DeviceDriverEnum.DEVICEDRIVER_OC + + endpoints_data : List[Dict] = list() for i, endpoint in enumerate(request.device_endpoints): endpoint_device_uuid = endpoint.endpoint_id.device_id.device_uuid.uuid - if len(endpoint_device_uuid) == 0: endpoint_device_uuid = device_uuid + if len(endpoint_device_uuid) == 0 or is_oc_driver : endpoint_device_uuid = device_uuid if endpoint_device_uuid not in {raw_device_uuid, device_uuid}: raise InvalidArgumentException( 'request.device_endpoints[{:d}].device_id.device_uuid.uuid'.format(i), endpoint_device_uuid, diff --git a/src/context/service/database/MyConfigOperator.py b/src/context/service/database/MyConfigOperator.py new file mode 100644 index 000000000..0ca58f6ca --- /dev/null +++ b/src/context/service/database/MyConfigOperator.py @@ -0,0 +1,129 @@ +# 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. +import uuid,json + +import datetime, logging +from sqlalchemy.dialects.postgresql import insert +from sqlalchemy.engine import Engine +from sqlalchemy.orm import Session, selectinload, sessionmaker +from sqlalchemy_cockroachdb import run_transaction +from typing import Dict, List, Optional, Set, Tuple +from common.method_wrappers.ServiceExceptions import InvalidArgumentException, NotFoundException +from common.proto.context_pb2 import Device, DeviceFilter, DeviceId, TopologyId,MyConfig,MyConfigId,MyConfigList +from common.tools.grpc.Tools import grpc_message_to_json_string +from common.tools.object_factory.Device import json_device_id +from context.service.database.uuids.Topology import topology_get_uuid +from .models.DeviceModel import DeviceModel +from .models.EndPointModel import EndPointModel +from .models.TopologyModel import TopologyDeviceModel +from .models.enums.DeviceDriver import grpc_to_enum__device_driver +from .models.enums.DeviceOperationalStatus import grpc_to_enum__device_operational_status +from .models.enums.KpiSampleType import grpc_to_enum__kpi_sample_type +from .uuids.Device import device_get_uuid +from .uuids.EndPoint import endpoint_get_uuid +from .ConfigRule import compose_config_rules_data, upsert_config_rules +from .models.MyConfigModel import MyConfigModel +LOGGER = logging.getLogger(__name__) + +def get_myconfig (db_engine:Engine): + + def callback(session:Session): + + lst = list() + results = session.query(MyConfigModel).all() + + for obj in results: + myconfig=MyConfig() + myconfig.config=json.dump(obj.config) + myid=MyConfigId() + myid.myconfig_uuid=obj.myconfig_uuid + myconfig.myconfig_id.CopyFrom(myid) + + lst.append(myconfig) + return lst + obj=run_transaction(sessionmaker(bind=db_engine),callback) + return obj + + + + +def set_myconfig (db_engine:Engine,request:MyConfig): + + myconfig_id=MyConfigId() + myconfig_id.myconfig_uuid=request.myconfig_id.myconfig_uuid + my_config_data=[] + if (request.config): + channels=[] + transceivers=[] + config = json.loads(request.config) + + if ( "channels" in config and len(config["channels"])>0): + channels=[channel['name']['index'] for channel in config["channels"]] + if ("transceivers" in config and len(config["transceivers"]["transceiver"])>0): + transceivers=[transceiver for transceiver in config["transceivers"]["transceiver"]] + + + my_config_data=[ + { + "myconfig_uuid":request.myconfig_id.myconfig_uuid, + "channels":channels, + "transcievers":transceivers, + "interfaces":json.dumps(config["interfaces"]["interface"]), + "channel_namespace":config["channel_namespace"], + "endpoints":[json.dumps(endpoint) for endpoint in config["endpoints"]], + "frequency":config["frequency"] if "frequency" in config else 0, + "operational_mode":config["operational_mode"] if "operational_mode" in config else 0, + "output_power":config["output_power"] if "output_power" in config else '', + } + ] + + def callback(session:Session)->bool: + + stmt = insert(MyConfigModel).values(my_config_data) + stmt = stmt.on_conflict_do_update( + index_elements=[MyConfigModel.myconfig_uuid], + set_=dict( + + channel_namespace=stmt.excluded.channel_namespace + ) + ) + + stmt = stmt.returning(MyConfigModel.myconfig_uuid) + + id = session.execute(stmt).fetchone() + + myconfig_id =run_transaction(sessionmaker(bind=db_engine),callback) + + return {'myconfig_uuid': myconfig_id} + + + +def select_MyConfig(db_engine:Engine,request:MyConfigId): + + def callback(session : Session) -> MyConfig: + result=MyConfig() + obj = session.query(MyConfigModel).filter_by(myconfig_uuid=request.myconfig_uuid).first() + + if (obj is not None): + + + myid=MyConfigId() + myid.myconfig_uuid=obj.myconfig_uuid + result.config=json.dumps(obj.dump()) + result.myconfig_id.CopyFrom(myid) + + + return result + + return run_transaction(sessionmaker(bind=db_engine,expire_on_commit=False), callback) \ No newline at end of file diff --git a/src/context/service/database/Service.py b/src/context/service/database/Service.py index fc196ddde..38e5d5ec1 100644 --- a/src/context/service/database/Service.py +++ b/src/context/service/database/Service.py @@ -82,8 +82,10 @@ def service_set(db_engine : Engine, messagebroker : MessageBroker, request : Ser raw_service_name = request.name service_name = raw_service_uuid if len(raw_service_name) == 0 else raw_service_name context_uuid,service_uuid = service_get_uuid(request.service_id, service_name=service_name, allow_random=True) - + service_type = grpc_to_enum__service_type(request.service_type) + service_type="OPTICAL_CONNECTIVITY" if service_type is None and request.service_type==6 else service_type + service_status = grpc_to_enum__service_status(request.service_status.service_status) now = datetime.datetime.utcnow() diff --git a/src/context/service/database/models/MyConfigModel.py b/src/context/service/database/models/MyConfigModel.py new file mode 100644 index 000000000..960f7368b --- /dev/null +++ b/src/context/service/database/models/MyConfigModel.py @@ -0,0 +1,51 @@ +# 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. + +import json,logging +from sqlalchemy import Column, String ,Integer +from sqlalchemy.dialects.postgresql import ARRAY + + +from ._Base import _Base + + + + +class MyConfigModel (_Base): + __tablename__="MyConfig" + myconfig_uuid = Column(String, primary_key=True) + channels=Column(ARRAY(String),nullable=True) + transcievers= Column(ARRAY(String),nullable=True) + interfaces =Column(String,nullable=True) + channel_namespace=Column(String,nullable=True) + endpoints=Column(ARRAY(String),nullable=True) + frequency=Column(Integer,nullable=True) + operational_mode=Column(Integer,nullable=True) + output_power=Column(String,nullable=True) + + + + def dump (self): + + return { + "channels":[{'name':{'index':channel}} for channel in self.channels], + "transceivers":{"transceiver":[transciever for transciever in self.transcievers]}, + "interfaces":{"interface":json.loads(self.interfaces)}, + "channel_namespace":self.channel_namespace, + "endpoints":[json.loads(endpoint) for endpoint in self.endpoints], + "frequency":self.frequency, + "output_power":self.output_power, + "operational_mode":self.operational_mode + } + diff --git a/src/context/service/database/models/enums/DeviceDriver.py b/src/context/service/database/models/enums/DeviceDriver.py index 8e15bf058..2ccdda272 100644 --- a/src/context/service/database/models/enums/DeviceDriver.py +++ b/src/context/service/database/models/enums/DeviceDriver.py @@ -33,6 +33,7 @@ class ORM_DeviceDriverEnum(enum.Enum): GNMI_OPENCONFIG = DeviceDriverEnum.DEVICEDRIVER_GNMI_OPENCONFIG FLEXSCALE = DeviceDriverEnum.DEVICEDRIVER_FLEXSCALE IETF_ACTN = DeviceDriverEnum.DEVICEDRIVER_IETF_ACTN + OC = DeviceDriverEnum.DEVICEDRIVER_OC grpc_to_enum__device_driver = functools.partial( grpc_to_enum, DeviceDriverEnum, ORM_DeviceDriverEnum) diff --git a/src/context/service/database/models/enums/ServiceType.py b/src/context/service/database/models/enums/ServiceType.py index ce198f8c1..01ed68c17 100644 --- a/src/context/service/database/models/enums/ServiceType.py +++ b/src/context/service/database/models/enums/ServiceType.py @@ -28,6 +28,7 @@ class ORM_ServiceTypeEnum(enum.Enum): TAPI_CONNECTIVITY_SERVICE = ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE TE = ServiceTypeEnum.SERVICETYPE_TE E2E = ServiceTypeEnum.SERVICETYPE_E2E + OPTICAL_CONNECTIVITY = ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY grpc_to_enum__service_type = functools.partial( grpc_to_enum, ServiceTypeEnum, ORM_ServiceTypeEnum) diff --git a/src/device/client/DeviceClient.py b/src/device/client/DeviceClient.py index 32fa685b9..9b4880c04 100644 --- a/src/device/client/DeviceClient.py +++ b/src/device/client/DeviceClient.py @@ -15,7 +15,7 @@ import grpc, logging from common.Constants import ServiceNameEnum from common.Settings import get_service_host, get_service_port_grpc -from common.proto.context_pb2 import Device, DeviceConfig, DeviceId, Empty, MyConfig, MyConfigId +from common.proto.context_pb2 import Device, DeviceConfig, DeviceId, Empty,MyConfig,MyConfigId from common.proto.device_pb2 import MonitoringSettings from common.proto.device_pb2_grpc import DeviceServiceStub from common.tools.client.RetryDecorator import retry, delay_exponential @@ -82,7 +82,6 @@ class DeviceClient: response = self.stub.MonitorDeviceKpi(request) LOGGER.debug('MonitorDeviceKpi result: {:s}'.format(grpc_message_to_json_string(response))) return response - def ConfigureOpticalDevice(self, request : MyConfig) -> MyConfigId: LOGGER.debug('ConfigureOpticalDevice request: {:s}'.format(grpc_message_to_json_string(request))) response = self.openconfig_stub.ConfigureOpticalDevice(request) diff --git a/src/device/service/DeviceService.py b/src/device/service/DeviceService.py index c7868e445..544f250f6 100644 --- a/src/device/service/DeviceService.py +++ b/src/device/service/DeviceService.py @@ -39,6 +39,7 @@ class DeviceService(GenericGrpcService): self.monitoring_loops.start() add_DeviceServiceServicer_to_server(self.device_servicer, self.server) add_OpenConfigServiceServicer_to_server(self.openconfig_device_servicer,self.server) + def stop(self): super().stop() diff --git a/src/device/service/DeviceServiceServicerImpl.py b/src/device/service/DeviceServiceServicerImpl.py index 7592e5b58..da5d1134e 100644 --- a/src/device/service/DeviceServiceServicerImpl.py +++ b/src/device/service/DeviceServiceServicerImpl.py @@ -20,8 +20,7 @@ from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, get_env_var_name from common.method_wrappers.Decorator import MetricTypeEnum, MetricsPool, safe_and_metered_rpc_method from common.method_wrappers.ServiceExceptions import NotFoundException, OperationFailedException from common.proto.context_pb2 import ( - Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty, Link, MyConfig, MyConfigId -) + Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty, Link,MyConfig,MyConfigId) from common.proto.device_pb2 import MonitoringSettings from common.proto.device_pb2_grpc import DeviceServiceServicer from common.tools.context_queries.Device import get_device @@ -55,12 +54,13 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def AddDevice(self, request : Device, context : grpc.ServicerContext) -> DeviceId: + t0 = time.time() device_uuid = request.device_id.device_uuid.uuid connection_config_rules = check_connect_rules(request.device_config) - if (request.device_drivers[0]!= 9) : + if (request.device_drivers[0]!= DeviceDriverEnum.DEVICEDRIVER_OC) : check_no_endpoints(request.device_endpoints) t1 = time.time() @@ -143,12 +143,13 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): device.device_operational_status = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED # temporary line - if (request.device_drivers[0]== 9 and len(request.device_endpoints)>0): + if (request.device_drivers[0]== DeviceDriverEnum.DEVICEDRIVER_OC and len(request.device_endpoints)>0): for endpoint in request.device_endpoints: #endpoint.endpoint_id.device_id.CopyFrom(device.device_id) pass device.device_endpoints.extend(request.device_endpoints) + device_id = context_client.SetDevice(device) t10 = time.time() diff --git a/src/device/service/OpenConfigServicer.py b/src/device/service/OpenConfigServicer.py index 5be11cb31..329bceef2 100644 --- a/src/device/service/OpenConfigServicer.py +++ b/src/device/service/OpenConfigServicer.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import grpc, logging, os, time +import grpc, logging, os, time,json from typing import Dict from prometheus_client import Histogram from common.Constants import ServiceNameEnum @@ -20,9 +20,7 @@ from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, get_env_var_name from common.method_wrappers.Decorator import MetricTypeEnum, MetricsPool, safe_and_metered_rpc_method from common.method_wrappers.ServiceExceptions import NotFoundException, OperationFailedException from common.proto.context_pb2 import ( - Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty, Link, MyConfig, MyConfigId, - MyConfig, MyConfigList -) + Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty, Link,MyConfig,MyConfigId ,MyConfig,MyConfigList) from common.proto.device_pb2 import MonitoringSettings from common.proto.device_pb2_grpc import DeviceServiceServicer from common.tools.context_queries.Device import get_device @@ -59,9 +57,7 @@ class OpenConfigServicer(DeviceServiceServicer): def AddOpenConfigDevice(self, request : MyConfig, context : grpc.ServicerContext) -> DeviceId: device_uuid = request.device_id.device_uuid.uuid - device_type=request.device_type - ocdriver=OCDriver() - connection_config_rules = check_connect_rules(request.device_config) + check_no_endpoints(request.device_endpoints) context_client = ContextClient() @@ -74,39 +70,43 @@ class OpenConfigServicer(DeviceServiceServicer): device.device_type = request.device_type device.device_operational_status = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_UNDEFINED device.device_drivers.extend(request.device_drivers) # pylint: disable=no-member - device.device_config.CopyFrom(request.device_config) # pylint: disable=no-member + device.device_config.CopyFrom(request.device_config) + device.device_endpoints.extend(request.device_endpoints) + # pylint: disable=no-member device_id = context_client.SetDevice(device) device = get_device(context_client, device_id.device_uuid.uuid, rw_copy=True) # update device_uuid to honor UUID provided by Context device_uuid = device.device_id.device_uuid.uuid - LOGGER.debug('device type %s',device) - t2 = time.time() + + self.mutex_queues.wait_my_turn(device_uuid) - t3 = time.time() - #temp fix to solve the error - #todo check what to pass here - resources_to_get = [] + try: - #driver : _Driver = get_driver(self.driver_instance_cache, device) - results_getconfig=ocdriver.GetConfig(resource_keys=resources_to_get,device_uuid=device_uuid) - #results_getconfig = driver.GetConfig(resources_to_get,device_uuid) + + device_id = context_client.SetDevice(device) except Exception as error : LOGGER.debug("error %s",error) + + + + #modified Andrea @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def ConfigureOpticalDevice (self, request : MyConfig, context:grpc.ServicerContext) -> Empty: - LOGGER.info('Setting from ConfigureOpticalDevice with Flows %s',request) - #device_id = request.myconfig_id - #device_uuid = device_id.myconfig_uuid + device_uuid = request.myconfig_id.myconfig_uuid - LOGGER.info("device uuid {}".format(device_uuid)) + resources=[] result=None - config = eval(request.config) - filter_fields= ["frequency", "target-output-power", "interface", "operational-mode"] + + config =json.loads(request.config) + + + try: + context_client = ContextClient() device = get_device( @@ -114,12 +114,11 @@ class OpenConfigServicer(DeviceServiceServicer): include_config_rules=False) if device is None: - LOGGER.info("device is none") + raise NotFoundException('Device', device_uuid, extra_details='loading in ConfigureDevice') resources,conditions=extract_resources(config=config,device=device) driver : _Driver = get_driver(self.driver_instance_cache, device) - LOGGER.info("resource %s conditions %s",resources,conditions) - + result = driver.SetConfig(resources=resources,conditions=conditions) #todo #add a control with the NETCONF get @@ -129,6 +128,6 @@ class OpenConfigServicer(DeviceServiceServicer): LOGGER.info("error in configuring %s",e) - LOGGER.info("result %s",result) + return Empty() \ No newline at end of file diff --git a/src/device/service/Tools.py b/src/device/service/Tools.py index 8ccb77afa..c4b41020a 100644 --- a/src/device/service/Tools.py +++ b/src/device/service/Tools.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. - from uuid import UUID, uuid4, uuid5 import json, logging from typing import Any, Dict, List, Optional, Tuple, Union @@ -455,7 +454,6 @@ def update_endpoints(src_device : Device, dst_device : Device) -> None: dst_topology_id = dst_endpoint_id.topology_id if len(src_topology_uuid) > 0: dst_topology_id.topology_uuid.uuid = src_topology_uuid if len(src_context_uuid) > 0: dst_topology_id.context_id.context_uuid.uuid = src_context_uuid - def oc_default_endpoints( device : Device, driver : _Driver, monitoring_loops : MonitoringLoops, new_sub_devices : Dict[str, Device], new_sub_links : Dict[str, Link] @@ -471,61 +469,62 @@ def get_edit_target (device:Device,is_opticalband:bool)-> str: if device.device_type =='optical-roadm': return 'media-channel' else : return 'optical-channel' -def extract_resources (config : dict, device : Device)-> list: - conditions={} - resources=[] - resources.append({"resource_key":"channel_namespace","value":config["channel_namespace"] if "channel_namespace" in config else None}) - resources.append({"resource_key":'add_transceiver',"value":config['add_transceiver'] if 'add_transceiver' in config else None}) - resources.append({"resource_key":"interface","value":config["update_interface"] if 'update_interface' in config else None}) - is_opticalband=config['is_opticalband'] if 'is_opticalband' in config else False - conditions["is_opticalband"]=is_opticalband - conditions["edit_type"]=get_edit_target(device=device,is_opticalband=is_opticalband) - if ('flow' in config): - #for tuple_value in config['flow'][device.name]: - source_vals = [] - dest_vals = [] - for tuple_value in config['flow']: - source_port=None - destination_port=None - #resources.append({"resource_key":"source_port","value":source_port}) - #resources.append({"resource_key":"destination_port","value":destination_port}) - source_port_uuid,destination_port_uuid=tuple_value - if (source_port_uuid !='0'): - src_endpoint_obj = get_endpoint_matching(device, source_port_uuid) - source_port = src_endpoint_obj.name - source_vals.append(source_port) - if (destination_port_uuid !='0'): - dst_endpoint_obj = get_endpoint_matching(device, destination_port_uuid) - destination_port = dst_endpoint_obj.name - dest_vals.append(destination_port) - resources.append({"resource_key":"source_port","value":source_vals}) - resources.append({"resource_key":"destination_port","value":dest_vals}) - if ('new_config' in config): - lower_frequency=None - upper_frequency=None - resources.append({"resource_key":"target-output-power","value":config["new_config"]["target-output-power"] if "target-output-power" in config["new_config"] else None }) - #resources.append({"resource_key":"frequency","value":config["new_config"]["frequency"] if "frequency" in config else config["new_config"]["freqency"]}) - resources.append({"resource_key":"frequency","value":config["new_config"]["frequency"] if "frequency" in config["new_config"] else None}) - resources.append({"resource_key":"operational-mode","value":config["new_config"]["operational-mode"] if "operational-mode" in config["new_config"] else None}) - resources.append({"resource_key":"line-port","value":config["new_config"]["line-port"] if "line-port" in config["new_config"] else None}) - - resources.append({"resource_key":"name","value":config['new_config']['band_type'] if 'band_type' in config['new_config'] else None}) - resources.append({"resource_key":"optical-band-parent","value":config["new_config"]["ob_id"] if "ob_id" in config["new_config"] else None }) - resources.append({"resource_key":"channel_name","value":config["new_config"]["name"] if "name" in config["new_config"] else None}) - - if not is_opticalband : - if 'frequency' in config['new_config'] and 'band' in config['new_config'] and conditions["edit_type"] == 'media-channel': - lower_frequency= int(int(config['new_config']['frequency']) - (int(config['new_config']['band'])/2)) - upper_frequency= int(int(config['new_config']['frequency']) + (int(config['new_config']['band'])/2)) - - #lower_frequency= (config['new_config']['frequency']- config['new_config']['band'])/2 - #upper_frequency=(config['new_config']['frequency']+ config['new_config']['band'])/2 - resources.append({"resource_key":"index","value":config["new_config"]["flow_id"] if "flow_id" in config["new_config"] else None}) - else : - lower_frequency=config['new_config']['low-freq'] if "low-freq" in config['new_config'] else None - upper_frequency=config['new_config']['up-freq'] if 'up-freq' in config['new_config'] else None - resources.append({"resource_key":"index","value":config["new_config"]["ob_id"] if "ob_id" in config["new_config"] else None}) +def extract_resources (config:dict,device:Device)-> list : + conditions={} + resources=[] + resources.append({"resource_key":"channel_namespace","value":config["channel_namespace"] if "channel_namespace" in config else None}) + resources.append({"resource_key":'add_transceiver',"value":config['add_transceiver'] if 'add_transceiver' in config else None}) + resources.append({"resource_key":"interface","value":config["update_interface"] if 'update_interface' in config else None}) + is_opticalband=config['is_opticalband'] if 'is_opticalband' in config else False + conditions["is_opticalband"]=is_opticalband + conditions["edit_type"]=get_edit_target(device=device,is_opticalband=is_opticalband) + if ('flow' in config): + #for tuple_value in config['flow'][device.name]: + source_vals = [] + dest_vals = [] + for tuple_value in config['flow']: + source_port=None + destination_port=None + #resources.append({"resource_key":"source_port","value":source_port}) + #resources.append({"resource_key":"destination_port","value":destination_port}) + source_port_uuid,destination_port_uuid=tuple_value + if (source_port_uuid !='0'): + src_endpoint_obj = get_endpoint_matching(device, source_port_uuid) + source_port = src_endpoint_obj.name + source_vals.append(source_port) + if (destination_port_uuid !='0'): + dst_endpoint_obj = get_endpoint_matching(device, destination_port_uuid) + destination_port = dst_endpoint_obj.name + dest_vals.append(destination_port) + resources.append({"resource_key":"source_port","value":source_vals}) + resources.append({"resource_key":"destination_port","value":dest_vals}) + if ('new_config' in config): + lower_frequency=None + upper_frequency=None + resources.append({"resource_key":"target-output-power","value":config["new_config"]["target-output-power"] if "target-output-power" in config["new_config"] else None }) + #resources.append({"resource_key":"frequency","value":config["new_config"]["frequency"] if "frequency" in config else config["new_config"]["freqency"]}) + resources.append({"resource_key":"frequency","value":config["new_config"]["frequency"] if "frequency" in config["new_config"] else None}) + resources.append({"resource_key":"operational-mode","value":config["new_config"]["operational-mode"] if "operational-mode" in config["new_config"] else None}) + resources.append({"resource_key":"line-port","value":config["new_config"]["line-port"] if "line-port" in config["new_config"] else None}) + + resources.append({"resource_key":"name","value":config['new_config']['band_type'] if 'band_type' in config['new_config'] else None}) + resources.append({"resource_key":"optical-band-parent","value":config["new_config"]["ob_id"] if "ob_id" in config["new_config"] else None }) + resources.append({"resource_key":"channel_name","value":config["new_config"]["name"] if "name" in config["new_config"] else None}) + + if not is_opticalband : + if 'frequency' in config['new_config'] and 'band' in config['new_config'] and conditions["edit_type"] == 'media-channel': + lower_frequency= int(int(config['new_config']['frequency']) - (int(config['new_config']['band'])/2)) + upper_frequency= int(int(config['new_config']['frequency']) + (int(config['new_config']['band'])/2)) + + #lower_frequency= (config['new_config']['frequency']- config['new_config']['band'])/2 + #upper_frequency=(config['new_config']['frequency']+ config['new_config']['band'])/2 + resources.append({"resource_key":"index","value":config["new_config"]["flow_id"] if "flow_id" in config["new_config"] else None}) + else : + lower_frequency=config['new_config']['low-freq'] if "low-freq" in config['new_config'] else None + upper_frequency=config['new_config']['up-freq'] if 'up-freq' in config['new_config'] else None + resources.append({"resource_key":"index","value":config["new_config"]["ob_id"] if "ob_id" in config["new_config"] else None}) + + resources.append({"resource_key":"lower-frequency","value":lower_frequency}) + resources.append({"resource_key":"upper-frequency","value":upper_frequency}) + return [resources,conditions] - resources.append({"resource_key":"lower-frequency","value":lower_frequency}) - resources.append({"resource_key":"upper-frequency","value":upper_frequency}) - return [resources,conditions] diff --git a/src/device/service/drivers/__init__.py b/src/device/service/drivers/__init__.py index 09c4d33b7..4c0a89ebd 100644 --- a/src/device/service/drivers/__init__.py +++ b/src/device/service/drivers/__init__.py @@ -167,7 +167,6 @@ if LOAD_ALL_DEVICE_DRIVERS: FilterFieldEnum.DRIVER: DeviceDriverEnum.DEVICEDRIVER_FLEXSCALE, } ])) - if LOAD_ALL_DEVICE_DRIVERS: from .oc_driver.OCDriver import OCDriver # pylint: disable=wrong-import-position DRIVERS.append( @@ -175,11 +174,12 @@ if LOAD_ALL_DEVICE_DRIVERS: { # Real Packet Router, specifying OpenConfig Driver => use OpenConfigDriver - FilterFieldEnum.DEVICE_TYPE: [ - DeviceTypeEnum.NETCONFIG_AGENT, + FilterFieldEnum.DEVICE_TYPE:[ + DeviceTypeEnum.OPTICAL_ROADM, DeviceTypeEnum.OPTICAL_TRANSPONDER - ], + + ], FilterFieldEnum.DRIVER : DeviceDriverEnum.DEVICEDRIVER_OC, } ])) diff --git a/src/device/service/drivers/oc_driver/OCDriver.py b/src/device/service/drivers/oc_driver/OCDriver.py index 512ec49ba..8467a8ceb 100644 --- a/src/device/service/drivers/oc_driver/OCDriver.py +++ b/src/device/service/drivers/oc_driver/OCDriver.py @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# 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. @@ -135,8 +135,7 @@ class NetconfSessionHandler: response= self.__manager.edit_config( config, target=target, default_operation=default_operation, test_option=test_option, error_option=error_option, format=format) - logging.info("response message %s",response) - + @RETRY_DECORATOR def locked(self, target): @@ -154,17 +153,12 @@ def edit_config( commit_per_rule=False, target='running', default_operation='merge', test_option=None, error_option=None, format='xml' ): - str_method = 'DeleteConfig' if delete else 'SetConfig' + #str_method = 'DeleteConfig' if delete else 'SetConfig' results = [] str_config_messages=[] - #try: - # if add_proccess: - # str_config_messages = add_transceiver(resources[0]['value']) - # elif update_interface: - # str_config_messages = interface_template(resources[0]["value"]) - # else: + if (conditions['edit_type']=='optical-channel'): #transponder str_config_messages = create_optical_channel(resources) @@ -174,14 +168,8 @@ def edit_config( else : #roadm media-channel str_config_messages=create_media_channel(resources) - logging.info("config message %s",str_config_messages) - # if (add_proccess or update_interface): - - # netconf_handler.edit_config( # configure the device - # config=str_config_messages, target=target, default_operation=default_operation, - # test_option=test_option, error_option=error_option, format=format) - # if commit_per_rule: - # netconf_handler.commit() + + for str_config_message in str_config_messages: # configuration of the received templates @@ -195,23 +183,7 @@ def edit_config( #results[i] = True results.append(True) - # except Exception as e: # pylint: disable=broad-except - # str_operation = 'preparing' if target == 'candidate' else ('deleting' if delete else 'setting') - # msg = '[{:s}] Exception {:s} {:s}: {:s}' - # logger.info("error %s",e) - # logger.exception(msg.format(e)) - # #results[i] = e # if validation fails, store the exception - # results.append(e) - - # if not commit_per_rule: - # try: - # netconf_handler.commit() - # except Exception as e: # pylint: disable=broad-except - # msg = '[{:s}] Exception committing: {:s}' - # str_operation = 'preparing' if target == 'candidate' else ('deleting' if delete else 'setting') - # logger.exception(msg.format(str_method, str_operation, str(resources))) - # results = [e for _ in resources] # if commit fails, set exception in each resource - # return results + class OCDriver(_Driver): def __init__(self, address : str, port : int,device_uuid=None, **settings) -> None: @@ -232,7 +204,7 @@ class OCDriver(_Driver): self._temp_address=f"{address}{port}" self.__out_samples = queue.Queue() self.__netconf_handler = NetconfSessionHandler(self.address, self.port, **(self.settings)) - self.__logger.info("settings are %s",settings) + self.__device_uuid=device_uuid self.Connect() @@ -267,7 +239,7 @@ class OCDriver(_Driver): @metered_subclass_method(METRICS_POOL) def GetConfig(self, resource_keys : List[str] = []) -> List[Tuple[str, Union[Any, None, Exception]]]: - self.__logger.info("device_uuid %s",self.__device_uuid) + chk_type('resources', resource_keys, list) results = [] myConfig= MyConfig() @@ -275,7 +247,7 @@ class OCDriver(_Driver): with self.__lock: - self.__logger.info(" resources_key %s",resource_keys) + context_client.connect() config={} channels_lst=[] @@ -301,10 +273,8 @@ class OCDriver(_Driver): value_dic["interfaces"]=interfaces value_dic["channel_namespace"]=channel_namespace value_dic["endpoints"]=endpoints - self.__logger.info("config from get config %s",str(value_dic)) - myConfig.config=str(value_dic) - - myconfig_id=MyConfigId() + + myConfig.config=json.dumps(value_dic) myConfig.myconfig_id.myconfig_uuid=self.__device_uuid if self.__device_uuid is not None else "" config_id=context_client.SetMyConfig(myConfig) diff --git a/src/device/service/drivers/oc_driver/templates/Interfaces/interfaces.py b/src/device/service/drivers/oc_driver/templates/Interfaces/interfaces.py index b4df7c2bf..8d3049cfe 100644 --- a/src/device/service/drivers/oc_driver/templates/Interfaces/interfaces.py +++ b/src/device/service/drivers/oc_driver/templates/Interfaces/interfaces.py @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# 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. diff --git a/src/device/service/drivers/oc_driver/templates/Tools.py b/src/device/service/drivers/oc_driver/templates/Tools.py index 4370495c9..1af7b9b7f 100644 --- a/src/device/service/drivers/oc_driver/templates/Tools.py +++ b/src/device/service/drivers/oc_driver/templates/Tools.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 re,logging import json import lxml.etree as ET @@ -92,7 +91,6 @@ def extract_channels_based_on_channelnamespace (xml_data:str,channel_namespace:s xml_bytes = xml_data.encode("utf-8") root = ET.fromstring(xml_bytes) channels=[] - logging.info("channel namespace %s opticalband %s",channel_namespace ,is_opticalband) # Find the component names whose children include the "optical-channel" element if (not is_opticalband): @@ -122,7 +120,6 @@ def extract_channels_based_on_channelnamespace (xml_data:str,channel_namespace:s # Retrieve port-name for dest - logging.info("extract channels %s",channels) return channels def extract_channels_based_on_type (xml_data:str): xml_bytes = xml_data.encode("utf-8") @@ -230,10 +227,10 @@ def has_opticalbands(xml_data:str): return has_opticalbands def extractor(data_xml:str,resource_keys:list,dic:dict): - logging.info('data xml %s',data_xml) + endpoints=[] is_opticalband=has_opticalbands(xml_data=data_xml) - logging.info("from extractor opticalband %s",is_opticalband) + channel_namespace=extract_channel_xmlns(data_xml=data_xml,is_opticalband=is_opticalband) # channel_names=extract_channels_based_on_type(xml_data=data_xml) # if len(channel_names)==0 : diff --git a/src/device/service/drivers/oc_driver/templates/VPN/physical.py b/src/device/service/drivers/oc_driver/templates/VPN/physical.py index ba0de7ea6..def67a9a8 100644 --- a/src/device/service/drivers/oc_driver/templates/VPN/physical.py +++ b/src/device/service/drivers/oc_driver/templates/VPN/physical.py @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# 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. @@ -21,7 +21,7 @@ def seperate_port_config(resources:list,unwanted_keys:list[str])->list[list,dict ports={} index=None for item in resources : - logging.info("Andrea223344 item={}".format(item['resource_key'])) + if (item['value'] is not None and (item['resource_key'] not in unwanted_keys)): config.append({'resource_key':item['resource_key'], 'value':item['value']} ) #if (item['resource_key'] == 'destination_port' or item['resource_key'] == 'source_port') and item['value'] is not None: @@ -30,25 +30,24 @@ def seperate_port_config(resources:list,unwanted_keys:list[str])->list[list,dict ports[item['resource_key']]=item['value'] if (item['resource_key']=='index' and item['value'] is not None) : index=item['value'] - logging.info("from create_templates config %s ports %s index %s",config,ports,index) + return [config,ports,index] def create_optical_channel(resources): - logging.debug("TRANSPONDERconfiguration, resources={}".format(resources)) + unwanted_keys=['destination_port','source_port','channel_namespace','optical-band-parent','index', 'name'] results =[] data={"name":i["value"] for i in resources if i["resource_key"]=="channel_name"} data["channel_namespace"]=next((i["value"] for i in resources if i["resource_key"] == "channel_namespace"), None) config,ports,index=seperate_port_config(resources,unwanted_keys=unwanted_keys) - logging.info("from physical %s",resources) - + port_val = "" if 'destination_port' in ports and ports['destination_port'][0] is not None: port_val = ports['destination_port'][0] else: port_val = ports['source_port'][0] - logging.info("transponder port={}".format(port_val)) + doc, tag, text = Doc().tagtext() #with tag('config'): @@ -69,7 +68,7 @@ def create_optical_channel(resources): ) results.append(result) - logging.info("xml %s",results) + return results def add_transceiver (transceiver_name:str): @@ -184,7 +183,7 @@ def create_media_channel (resources): with tag('config'): #with tag('index'):text(index) for resource in config: - logging.info("Andrea223344 resources_key= {}".format(resource['resource_key'])) + if resource['resource_key'] == "index": with tag('index'):text(str(int(index)+i)) else: diff --git a/src/opticalcontroller/OpticalController.py b/src/opticalcontroller/OpticalController.py index e8e0e2164..ceaa97ecf 100644 --- a/src/opticalcontroller/OpticalController.py +++ b/src/opticalcontroller/OpticalController.py @@ -1,17 +1,3 @@ -# 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. - from flask import Flask from flask import render_template from flask_restplus import Resource, Api @@ -198,7 +184,7 @@ class GetBands(Resource): return "Error", 404 -@optical.route('/GetOpticalBand/') +@optical.route('/GetOpticalBand/') @optical.response(200, 'Success') @optical.response(404, 'Error, not found') class GetBand(Resource): @@ -238,9 +224,9 @@ if __name__ == '__main__': nodes_dict, links_dict = readTopologyData(nodes_json, topology_json) - topologies,links= getTopology() - print ("topologies{} and devices {}".format(topologies,links)) + #topologies,links= getTopology() + #print ("topologies{} and devices {}".format(topologies,links)) rsa = RSA(nodes_dict, links_dict) - LOGGER.info(rsa.init_link_slots(testing)) + app.run(host='0.0.0.0', port=5022,debug=True) diff --git a/src/opticalcontroller/RSA.py b/src/opticalcontroller/RSA.py index acf080d7f..919e5dfcf 100644 --- a/src/opticalcontroller/RSA.py +++ b/src/opticalcontroller/RSA.py @@ -1,3 +1,5 @@ +<<<<<<< HEAD +======= # Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -12,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +>>>>>>> e19583176d771a8f8c1216d8a79488d0e50097c1 import dijsktra from tools import * from variables import * @@ -322,11 +325,21 @@ class RSA(): return fiber_list def get_link_by_name (self, key): +<<<<<<< HEAD + result = None +======= +>>>>>>> e19583176d771a8f8c1216d8a79488d0e50097c1 for link in self.links_dict["links"]: if link["optical_link"]["name"] == key: if debug: print(link) +<<<<<<< HEAD + result = link + break + return result +======= return link +>>>>>>> e19583176d771a8f8c1216d8a79488d0e50097c1 def get_fiber_details(self, link_key, fiber_id): for link in self.links_dict["links"]: @@ -787,6 +800,16 @@ class RSA(): return self.flow_id, [] optical_band_id, temp_links = self.create_optical_band(links, path, bidir, num_slots_ob) return None, optical_band_id +<<<<<<< HEAD + self.flow_id += 1 + self.db_flows[self.flow_id] = {} + self.db_flows[self.flow_id]["flow_id"] = self.flow_id + self.db_flows[self.flow_id]["src"] = src + self.db_flows[self.flow_id]["dst"] = dst + self.db_flows[self.flow_id]["bitrate"] = rate + self.db_flows[self.flow_id]["bidir"] = bidir +======= +>>>>>>> e19583176d771a8f8c1216d8a79488d0e50097c1 print("INFO: TP to TP connection") if band is None: temp_links2 = [] @@ -806,6 +829,9 @@ class RSA(): temp_path.append(roadm_dst) temp_path.append(t_dst) existing_ob = self.get_optical_bands(roadm_src, roadm_dst) +<<<<<<< HEAD + +======= self.flow_id += 1 self.db_flows[self.flow_id] = {} self.db_flows[self.flow_id]["flow_id"] = self.flow_id @@ -813,6 +839,7 @@ class RSA(): self.db_flows[self.flow_id]["dst"] = dst self.db_flows[self.flow_id]["bitrate"] = rate self.db_flows[self.flow_id]["bidir"] = bidir +>>>>>>> e19583176d771a8f8c1216d8a79488d0e50097c1 if len(existing_ob) > 0: print("INFO: Evaluating existing OB {}".format(existing_ob)) @@ -875,6 +902,15 @@ class RSA(): links, path = self.compute_path(src, dst) optical_band_id, temp_links = self.create_optical_band(links, path, bidir, num_slots_ob) op, num_slots = map_rate_to_slot(rate) +<<<<<<< HEAD + # self.flow_id += 1 + # self.db_flows[self.flow_id] = {} + # self.db_flows[self.flow_id]["flow_id"] = self.flow_id + # self.db_flows[self.flow_id]["src"] = src + # self.db_flows[self.flow_id]["dst"] = dst + # self.db_flows[self.flow_id]["bitrate"] = rate + # self.db_flows[self.flow_id]["bidir"] = bidir +======= self.flow_id += 1 self.db_flows[self.flow_id] = {} self.db_flows[self.flow_id]["flow_id"] = self.flow_id @@ -882,6 +918,7 @@ class RSA(): self.db_flows[self.flow_id]["dst"] = dst self.db_flows[self.flow_id]["bitrate"] = rate self.db_flows[self.flow_id]["bidir"] = bidir +>>>>>>> e19583176d771a8f8c1216d8a79488d0e50097c1 if debug: print(temp_links) diff --git a/src/opticalcontroller/dijsktra.py b/src/opticalcontroller/dijsktra.py index a86d1d93d..5be78c624 100644 --- a/src/opticalcontroller/dijsktra.py +++ b/src/opticalcontroller/dijsktra.py @@ -1,21 +1,3 @@ -# 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. - -# TODO: migrate to NetworkX: -# https://networkx.org/documentation/stable/index.html -# https://networkx.org/documentation/stable/reference/algorithms/shortest_paths.html - import sys class Vertex: @@ -237,4 +219,4 @@ if __name__ == '__main__': print ('The shortest path : %s' %(path[::-1]))""" p = shortest_path(g, g.get_vertex('a'), g.get_vertex('e')) - print(p) + print(p) \ No newline at end of file diff --git a/src/opticalcontroller/json_files/tfs copy.json b/src/opticalcontroller/json_files/tfs copy.json new file mode 100644 index 000000000..a108ed13e --- /dev/null +++ b/src/opticalcontroller/json_files/tfs copy.json @@ -0,0 +1,1286 @@ +{ + "links": [ + { + "link_id": { + "link_uuid": { + "uuid": "T1->R1" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "T1" + } + }, + "endpoint_uuid": { + "uuid": "1" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "endpoint_uuid": { + "uuid": "12" + } + } + ], + "optical_link": { + "name": "T1-R1", + "details": { + "length": 0, + "source": "muxT", + "target": "srgR", + "fibers": [ + { + "ID": "M1", + "length": 0, + "src_port": "1", + "dst_port": "2001", + "local_peer_port": "1", + "remote_peer_port": "1001", + "used": false, + "c_slots": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20 + ], + "l_slots": [ + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120 + ], + "s_slots": [ + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520 + ] + }, + { + "ID": "M2", + "length": 0, + "src_port": "2", + "dst_port": "2002", + "local_peer_port": "2", + "remote_peer_port": "1002", + "used": false, + "c_slots": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20 + ], + "l_slots": [ + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120 + ], + "s_slots": [ + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520 + ] + }, + { + "ID": "M3", + "length": 0, + "src_port": "3", + "dst_port": "2003", + "local_peer_port": "3", + "remote_peer_port": "1003", + "used": false, + "c_slots": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20 + ], + "l_slots": [ + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120 + ], + "s_slots": [ + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520 + ] + } + ] + } + } + }, + { + "link_id": { + "link_uuid": { + "uuid": "R1->T1" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "endpoint_uuid": { + "uuid": "2" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "T1" + } + }, + "endpoint_uuid": { + "uuid": "1" + } + } + ], + "optical_link": { + "name": "R1-T1", + "details": { + "length": 0, + "source": "srgT", + "target": "muxT", + "fibers": [ + { + "ID": "M1", + "length": 0, + "src_port": "1001", + "dst_port": "1", + "local_peer_port": "2001", + "remote_peer_port": "1", + "used": false, + "c_slots": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20 + ], + "l_slots": [ + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120 + ], + "s_slots": [ + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520 + ] + }, + { + "ID": "M2", + "length": 0, + "src_port": "1002", + "dst_port": "2", + "local_peer_port": "2002", + "remote_peer_port": "2", + "used": false, + "c_slots": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20 + ], + "l_slots": [ + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120 + ], + "s_slots": [ + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520 + ] + }, + { + "ID": "M3", + "length": 0, + "src_port": "1003", + "dst_port": "3", + "local_peer_port": "2003", + "remote_peer_port": "3", + "used": false, + "c_slots": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20 + ], + "l_slots": [ + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120 + ], + "s_slots": [ + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520 + ] + } + ] + } + } + }, + { + "link_id": { + "link_uuid": { + "uuid": "R1->R2" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "endpoint_uuid": { + "uuid": "13" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "endpoint_uuid": { + "uuid": "24" + } + } + ], + "optical_link": { + "name": "R1-R2", + "details": { + "length": 0, + "source": "D1", + "target": "D1", + "fibers": [ + { + "ID": "D11", + "length": 0, + "src_port": "13", + "dst_port": "24", + "local_peer_port": "23", + "remote_peer_port": "14", + "c_slots": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20 + ], + "l_slots": [ + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120 + ], + "s_slots": [ + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520 + ] + } + ] + } + } + }, + { + "link_id": { + "link_uuid": { + "uuid": "R2->R1" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "endpoint_uuid": { + "uuid": "14" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "endpoint_uuid": { + "uuid": "23" + } + } + ], + "optical_link": { + "name": "R2-R1", + "details": { + "length": 0, + "source": "D1", + "target": "D1", + "fibers": [ + { + "ID": "D11", + "length": 0, + "src_port": "14", + "dst_port": "23", + "local_peer_port": "24", + "remote_peer_port": "13", + "c_slots": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20 + ], + "l_slots": [ + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120 + ], + "s_slots": [ + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520 + ] + } + ] + } + } + }, + { + "link_id": { + "link_uuid": { + "uuid": "T2->R2" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "T2" + } + }, + "endpoint_uuid": { + "uuid": "1" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "endpoint_uuid": { + "uuid": "1001" + } + } + ], + "optical_link": { + "name": "T2-R2", + "details": { + "length": 0, + "source": "srgT", + "target": "muxT", + "fibers": [ + { + "ID": "M1", + "length": 0, + "src_port": "1", + "dst_port": "1001", + "local_peer_port": "1", + "remote_peer_port": "2001", + "used": false, + "c_slots": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20 + ], + "l_slots": [ + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120 + ], + "s_slots": [ + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520 + ] + }, + { + "ID": "M2", + "length": 0, + "src_port": "2", + "dst_port": "1002", + "local_peer_port": "2", + "remote_peer_port": "2002", + "used": false, + "c_slots": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20 + ], + "l_slots": [ + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120 + ], + "s_slots": [ + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520 + ] + }, + { + "ID": "M3", + "length": 0, + "src_port": "3", + "dst_port": "1003", + "local_peer_port": "3", + "remote_peer_port": "2003", + "used": false, + "c_slots": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20 + ], + "l_slots": [ + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120 + ], + "s_slots": [ + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520 + ] + } + ] + } + } + }, + { + "link_id": { + "link_uuid": { + "uuid": "R2->T2" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "endpoint_uuid": { + "uuid": "5" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "T2" + } + }, + "endpoint_uuid": { + "uuid": "6" + } + } + ], + "optical_link": { + "name": "R2-T2", + "details": { + "length": 0, + "source": "srgT", + "target": "muxT", + "fibers": [ + { + "ID": "M1", + "length": 0, + "src_port": "1001", + "dst_port": "1", + "local_peer_port": "2001", + "remote_peer_port": "1", + "used": false, + "c_slots": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20 + ], + "l_slots": [ + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120 + ], + "s_slots": [ + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520 + ] + }, + { + "ID": "M2", + "length": 0, + "src_port": "1002", + "dst_port": "2", + "local_peer_port": "2002", + "remote_peer_port": "2", + "used": false, + "c_slots": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20 + ], + "l_slots": [ + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120 + ], + "s_slots": [ + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520 + ] + }, + { + "ID": "M3", + "length": 0, + "src_port": "1003", + "dst_port": "3", + "local_peer_port": "2003", + "remote_peer_port": "3", + "used": false, + "c_slots": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20 + ], + "l_slots": [ + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120 + ], + "s_slots": [ + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520 + ] + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/src/opticalcontroller/json_files/tfs.json b/src/opticalcontroller/json_files/tfs.json index a108ed13e..31803b893 100644 --- a/src/opticalcontroller/json_files/tfs.json +++ b/src/opticalcontroller/json_files/tfs.json @@ -39,159 +39,9 @@ "ID": "M1", "length": 0, "src_port": "1", - "dst_port": "2001", + "dst_port": "12", "local_peer_port": "1", - "remote_peer_port": "1001", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - }, - { - "ID": "M2", - "length": 0, - "src_port": "2", - "dst_port": "2002", - "local_peer_port": "2", - "remote_peer_port": "1002", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - }, - { - "ID": "M3", - "length": 0, - "src_port": "3", - "dst_port": "2003", - "local_peer_port": "3", - "remote_peer_port": "1003", + "remote_peer_port": "2", "used": false, "c_slots": [ 1, @@ -302,9 +152,9 @@ { "ID": "M1", "length": 0, - "src_port": "1001", + "src_port": "2", "dst_port": "1", - "local_peer_port": "2001", + "local_peer_port": "12", "remote_peer_port": "1", "used": false, "c_slots": [ @@ -373,15 +223,53 @@ 519, 520 ] - }, + } + ] + } + } + }, + { + "link_id": { + "link_uuid": { + "uuid": "R1->R2" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "endpoint_uuid": { + "uuid": "3" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "endpoint_uuid": { + "uuid": "14" + } + } + ], + "optical_link": { + "name": "R1-R2", + "details": { + "length": 0, + "source": "D1", + "target": "D1", + "fibers": [ { - "ID": "M2", + "ID": "D11", "length": 0, - "src_port": "1002", - "dst_port": "2", - "local_peer_port": "2002", - "remote_peer_port": "2", - "used": false, + "src_port": "3", + "dst_port": "14", + "local_peer_port": "13", + "remote_peer_port": "4", "c_slots": [ 1, 2, @@ -448,15 +336,53 @@ 519, 520 ] - }, + } + ] + } + } + }, + { + "link_id": { + "link_uuid": { + "uuid": "R2->R1" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "endpoint_uuid": { + "uuid": "4" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "endpoint_uuid": { + "uuid": "13" + } + } + ], + "optical_link": { + "name": "R2-R1", + "details": { + "length": 0, + "source": "D1", + "target": "D1", + "fibers": [ { - "ID": "M3", + "ID": "D11", "length": 0, - "src_port": "1003", - "dst_port": "3", - "local_peer_port": "2003", + "src_port": "4", + "dst_port": "13", + "local_peer_port": "14", "remote_peer_port": "3", - "used": false, "c_slots": [ 1, 2, @@ -531,18 +457,18 @@ { "link_id": { "link_uuid": { - "uuid": "R1->R2" + "uuid": "T2->R2" } }, "link_endpoint_ids": [ { "device_id": { "device_uuid": { - "uuid": "R1" + "uuid": "T2" } }, "endpoint_uuid": { - "uuid": "13" + "uuid": "6" } }, { @@ -552,24 +478,25 @@ } }, "endpoint_uuid": { - "uuid": "24" + "uuid": "15" } } ], "optical_link": { - "name": "R1-R2", + "name": "T2-R2", "details": { "length": 0, - "source": "D1", - "target": "D1", + "source": "srgT", + "target": "muxT", "fibers": [ { - "ID": "D11", + "ID": "M1", "length": 0, - "src_port": "13", - "dst_port": "24", - "local_peer_port": "23", - "remote_peer_port": "14", + "src_port": "6", + "dst_port": "15", + "local_peer_port": "6", + "remote_peer_port": "5", + "used": false, "c_slots": [ 1, 2, @@ -644,7 +571,7 @@ { "link_id": { "link_uuid": { - "uuid": "R2->R1" + "uuid": "R2->T2" } }, "link_endpoint_ids": [ @@ -655,561 +582,34 @@ } }, "endpoint_uuid": { - "uuid": "14" + "uuid": "5" } }, { "device_id": { "device_uuid": { - "uuid": "R1" + "uuid": "T2" } }, "endpoint_uuid": { - "uuid": "23" + "uuid": "6" } } ], "optical_link": { - "name": "R2-R1", + "name": "R2-T2", "details": { "length": 0, - "source": "D1", - "target": "D1", + "source": "srgT", + "target": "muxT", "fibers": [ { - "ID": "D11", + "ID": "M1", "length": 0, - "src_port": "14", - "dst_port": "23", - "local_peer_port": "24", - "remote_peer_port": "13", - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - } - ] - } - } - }, - { - "link_id": { - "link_uuid": { - "uuid": "T2->R2" - } - }, - "link_endpoint_ids": [ - { - "device_id": { - "device_uuid": { - "uuid": "T2" - } - }, - "endpoint_uuid": { - "uuid": "1" - } - }, - { - "device_id": { - "device_uuid": { - "uuid": "R2" - } - }, - "endpoint_uuid": { - "uuid": "1001" - } - } - ], - "optical_link": { - "name": "T2-R2", - "details": { - "length": 0, - "source": "srgT", - "target": "muxT", - "fibers": [ - { - "ID": "M1", - "length": 0, - "src_port": "1", - "dst_port": "1001", - "local_peer_port": "1", - "remote_peer_port": "2001", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - }, - { - "ID": "M2", - "length": 0, - "src_port": "2", - "dst_port": "1002", - "local_peer_port": "2", - "remote_peer_port": "2002", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - }, - { - "ID": "M3", - "length": 0, - "src_port": "3", - "dst_port": "1003", - "local_peer_port": "3", - "remote_peer_port": "2003", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - } - ] - } - } - }, - { - "link_id": { - "link_uuid": { - "uuid": "R2->T2" - } - }, - "link_endpoint_ids": [ - { - "device_id": { - "device_uuid": { - "uuid": "R2" - } - }, - "endpoint_uuid": { - "uuid": "5" - } - }, - { - "device_id": { - "device_uuid": { - "uuid": "T2" - } - }, - "endpoint_uuid": { - "uuid": "6" - } - } - ], - "optical_link": { - "name": "R2-T2", - "details": { - "length": 0, - "source": "srgT", - "target": "muxT", - "fibers": [ - { - "ID": "M1", - "length": 0, - "src_port": "1001", - "dst_port": "1", - "local_peer_port": "2001", - "remote_peer_port": "1", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - }, - { - "ID": "M2", - "length": 0, - "src_port": "1002", - "dst_port": "2", - "local_peer_port": "2002", - "remote_peer_port": "2", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - }, - { - "ID": "M3", - "length": 0, - "src_port": "1003", - "dst_port": "3", - "local_peer_port": "2003", - "remote_peer_port": "3", + "src_port": "5", + "dst_port": "6", + "local_peer_port": "15", + "remote_peer_port": "6", "used": false, "c_slots": [ 1, diff --git a/src/opticalcontroller/tools.py b/src/opticalcontroller/tools.py index 3b3223d81..d91240d45 100644 --- a/src/opticalcontroller/tools.py +++ b/src/opticalcontroller/tools.py @@ -1,17 +1,3 @@ -# 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. - import numpy as np from variables import * import json diff --git a/src/opticalcontroller/variables.py b/src/opticalcontroller/variables.py index cbb65200f..32fe4bd8d 100644 --- a/src/opticalcontroller/variables.py +++ b/src/opticalcontroller/variables.py @@ -1,17 +1,3 @@ -# 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. - debug = 1 Fl = 184800 diff --git a/src/service/Dockerfile b/src/service/Dockerfile index aed4ce64c..c48f1ab0a 100644 --- a/src/service/Dockerfile +++ b/src/service/Dockerfile @@ -62,15 +62,16 @@ RUN python3 -m pip install -r requirements.txt # Add component files into working directory WORKDIR /var/teraflow -COPY src/context/__init__.py context/__init__.py -COPY src/context/client/. context/client/ +COPY src/service/. service/ +#COPY src/context/__init__.py context/__init__.py +#COPY src/context/client/. context/client/ +COPY src/context/. context/. COPY src/device/__init__.py device/__init__.py COPY src/device/client/. device/client/ COPY src/pathcomp/frontend/__init__.py pathcomp/frontend/__init__.py COPY src/pathcomp/frontend/client/. pathcomp/frontend/client/ COPY src/e2e_orchestrator/__init__.py e2e_orchestrator/__init__.py COPY src/e2e_orchestrator/client/. e2e_orchestrator/client/ -COPY src/service/. service/ # Start the service ENTRYPOINT ["python", "-m", "service.service"] diff --git a/src/service/service/ServiceServiceServicerImpl.py b/src/service/service/ServiceServiceServicerImpl.py index b06295dee..d9789be5d 100644 --- a/src/service/service/ServiceServiceServicerImpl.py +++ b/src/service/service/ServiceServiceServicerImpl.py @@ -248,81 +248,80 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): if len(service_with_uuids.service_endpoint_ids) >= num_expected_endpoints: pathcomp_request = PathCompRequest() pathcomp_request.services.append(service_with_uuids) # pylint: disable=no-member - if service.service_type == ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY: - context_id_x = json_context_id(DEFAULT_CONTEXT_NAME) - topology_id_x = json_topology_id( - DEFAULT_TOPOLOGY_NAME, context_id_x) - topology_details = context_client.GetTopologyDetails( - TopologyId(**topology_id_x)) - devices = topology_details.devices - context_uuid_x = topology_details.topology_id.context_id.context_uuid.uuid - topology_uuid_x = topology_details.topology_id.topology_uuid.uuid - devs = [] - ports = [] - for endpoint_id in service.service_endpoint_ids: - devs.append(endpoint_id.device_id.device_uuid.uuid) - ports.append(endpoint_id.endpoint_uuid.uuid) - src = devs[0] - dst = devs[1] - bidir = None - ob_band = None - bitrate = 100 - for constraint in service.service_constraints: - if "bandwidth" in constraint.custom.constraint_type: - bitrate = int(float(constraint.custom.constraint_value)) - elif "bidirectionality" in constraint.custom.constraint_type: - bidir = int(constraint.custom.constraint_value) - elif "optical-band-width" in constraint.custom.constraint_type: - ob_band = int(constraint.custom.constraint_value) - - # to get the reply form the optical module - reply_txt = add_lightpath(src, dst, bitrate, bidir, ob_band) - - # reply with 2 transponders and 2 roadms - reply_json = json.loads(reply_txt) - optical_band_txt = "" - if "new_optical_band" in reply_json.keys(): - if reply_json["new_optical_band"] == 1: - if reply_json["parent_opt_band"]: - if "parent_opt_band" in reply_json.keys(): - parent_ob = reply_json["parent_opt_band"] - LOGGER.debug('Parent optical-band={}'.format(parent_ob)) - optical_band_txt = get_optical_band(parent_ob) - LOGGER.debug('optical-band details={}'.format(optical_band_txt)) + context_id_x = json_context_id(DEFAULT_CONTEXT_NAME) + topology_id_x = json_topology_id( + DEFAULT_TOPOLOGY_NAME, context_id_x) + topology_details = context_client.GetTopologyDetails( + TopologyId(**topology_id_x)) + # devices = get_devices_in_topology(context_client, TopologyId(**topology_id_x), ContextId(**context_id_x)) + devices = topology_details.devices + context_uuid_x = topology_details.topology_id.context_id.context_uuid.uuid + topology_uuid_x = topology_details.topology_id.topology_uuid.uuid + devs = [] + ports = [] + for endpoint_id in service.service_endpoint_ids: + devs.append(endpoint_id.device_id.device_uuid.uuid) + ports.append(endpoint_id.endpoint_uuid.uuid) + src = devs[0] + dst = devs[1] + bidir = None + ob_band = None + bitrate = 100 + for constraint in service.service_constraints: + if "bandwidth" in constraint.custom.constraint_type: + bitrate = int(float(constraint.custom.constraint_value)) + elif "bidirectionality" in constraint.custom.constraint_type: + bidir = int(constraint.custom.constraint_value) + elif "optical-band-width" in constraint.custom.constraint_type: + ob_band = int(constraint.custom.constraint_value) + + + # to get the reply form the optical module + reply_txt = add_lightpath(src, dst, bitrate, bidir, ob_band) + + # reply with 2 transponders and 2 roadms + reply_json = json.loads(reply_txt) + optical_band_txt = "" + if "new_optical_band" in reply_json.keys(): + if reply_json["new_optical_band"] == 1: + if reply_json["parent_opt_band"]: + if "parent_opt_band" in reply_json.keys(): + parent_ob = reply_json["parent_opt_band"] + LOGGER.debug('Parent optical-band={}'.format(parent_ob)) + optical_band_txt = get_optical_band(parent_ob) + LOGGER.info('optical-band details={}'.format(optical_band_txt)) + else: + LOGGER.debug('expected optical band not found') else: LOGGER.debug('expected optical band not found') else: - LOGGER.debug('expected optical band not found') + LOGGER.debug('Using existing optical band') else: LOGGER.debug('Using existing optical band') - else: - LOGGER.debug('Using existing optical band') - if reply_txt is not None: - optical_reply = adapt_reply( - devices, _service, reply_json, context_uuid_x, topology_uuid_x, optical_band_txt - ) - LOGGER.debug('optical_reply={:s}'.format( - grpc_message_to_json_string(optical_reply))) - - tasks_scheduler.compose_from_pathcompreply( - optical_reply, is_delete=False) - - if num_disjoint_paths is None or num_disjoint_paths in {0, 1}: - pathcomp_request.shortest_path.Clear() # pylint: disable=no-member - else: - pathcomp_request.k_disjoint_path.num_disjoint = num_disjoint_paths # pylint: disable=no-member + if reply_txt is not None: + optical_reply = adapt_reply(devices, _service, reply_json, context_uuid_x, topology_uuid_x, optical_band_txt) + LOGGER.info('optical_reply={:s}'.format( + grpc_message_to_json_string(optical_reply))) + + tasks_scheduler.compose_from_pathcompreply( + optical_reply, is_delete=False) + else: + if num_disjoint_paths is None or num_disjoint_paths in {0, 1} : + pathcomp_request.shortest_path.Clear() # pylint: disable=no-member + else: + pathcomp_request.k_disjoint_path.num_disjoint = num_disjoint_paths # pylint: disable=no-member - LOGGER.debug('pathcomp_request={:s}'.format(grpc_message_to_json_string(pathcomp_request))) - pathcomp = PathCompClient() - pathcomp_reply = pathcomp.Compute(pathcomp_request) - pathcomp.close() - LOGGER.debug('pathcomp_reply={:s}'.format(grpc_message_to_json_string(pathcomp_reply))) + + pathcomp = PathCompClient() + pathcomp_reply = pathcomp.Compute(pathcomp_request) + pathcomp.close() + # Feed TaskScheduler with this path computation reply. TaskScheduler identifies inter-dependencies among # the services and connections retrieved and produces a schedule of tasks (an ordered list of tasks to be # executed) to implement the requested create/update operation. - tasks_scheduler.compose_from_pathcompreply(pathcomp_reply, is_delete=False) + tasks_scheduler.compose_from_pathcompreply(pathcomp_reply, is_delete=False) tasks_scheduler.execute_all() return service_with_uuids.service_id @@ -365,9 +364,10 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): if len(service.service_config.config_rules) > 0: c_rules_dict = json.loads( service.service_config.config_rules[0].custom.resource_value) - flow_id = c_rules_dict["flow_id"] - - reply = delete_lightpath(flow_id, src, dst, bitrate) + if ("flow_id" in c_rules_dict): + flow_id = c_rules_dict["flow_id"] + + reply = delete_lightpath(flow_id, src, dst, bitrate) # Normal service diff --git a/src/service/service/__main__.py b/src/service/service/__main__.py index f2b6e38d6..52210c8ab 100644 --- a/src/service/service/__main__.py +++ b/src/service/service/__main__.py @@ -12,12 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging, signal, sys, threading +import logging, signal, sys, threading,os from prometheus_client import start_http_server from common.Constants import ServiceNameEnum from common.Settings import ( ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_log_level, get_metrics_port, - wait_for_environment_variables) + wait_for_environment_variables,find_environment_variables) from .ServiceService import ServiceService from .service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory from .service_handlers import SERVICE_HANDLERS @@ -43,8 +43,16 @@ def main(): get_env_var_name(ServiceNameEnum.DEVICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC), get_env_var_name(ServiceNameEnum.PATHCOMP, ENVVAR_SUFIX_SERVICE_HOST ), get_env_var_name(ServiceNameEnum.PATHCOMP, ENVVAR_SUFIX_SERVICE_PORT_GRPC), + get_env_var_name(ServiceNameEnum.PATHCOMP, ENVVAR_SUFIX_SERVICE_HOST), + get_env_var_name(ServiceNameEnum.PATHCOMP, ENVVAR_SUFIX_SERVICE_PORT_GRPC) + + ]) - + variables= find_environment_variables([ + get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER,ENVVAR_SUFIX_SERVICE_HOST), + get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER,ENVVAR_SUFIX_SERVICE_PORT_GRPC), + ]) + signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) diff --git a/src/service/service/service_handler_api/FilterFields.py b/src/service/service/service_handler_api/FilterFields.py index e771e24f1..633f41b63 100644 --- a/src/service/service/service_handler_api/FilterFields.py +++ b/src/service/service/service_handler_api/FilterFields.py @@ -26,6 +26,7 @@ SERVICE_TYPE_VALUES = { ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE, ServiceTypeEnum.SERVICETYPE_TE, ServiceTypeEnum.SERVICETYPE_E2E, + ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY } DEVICE_DRIVER_VALUES = { @@ -40,6 +41,7 @@ DEVICE_DRIVER_VALUES = { DeviceDriverEnum.DEVICEDRIVER_GNMI_OPENCONFIG, DeviceDriverEnum.DEVICEDRIVER_FLEXSCALE, DeviceDriverEnum.DEVICEDRIVER_IETF_ACTN, + DeviceDriverEnum.DEVICEDRIVER_OC } # 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_handlers/oc/OCServiceHandler.py b/src/service/service/service_handlers/oc/OCServiceHandler.py index 8ae426393..b2b0a86ee 100644 --- a/src/service/service/service_handlers/oc/OCServiceHandler.py +++ b/src/service/service/service_handlers/oc/OCServiceHandler.py @@ -15,19 +15,20 @@ import json, logging from typing import Any, List, Optional, Tuple, Union from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method -from common.proto.context_pb2 import ConfigRule, DeviceId, EndPointId, Service +from common.proto.context_pb2 import ConfigRule, DeviceId, Service 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 -#from .ConfigRules import setup_config_rules, teardown_config_rules -from .OCTools import convert_endpoints_to_flows, handle_flows_names +from .ConfigRules import setup_config_rules, teardown_config_rules +from common.proto.context_pb2 import EndPointId +from .OCTools import convert_endpoints_to_flows, handle_flows_names LOGGER = logging.getLogger(__name__) -METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'oc'}) +METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'l3nm_emulated'}) class OCServiceHandler(_ServiceHandler): def __init__( # pylint: disable=super-init-not-called @@ -37,6 +38,73 @@ class OCServiceHandler(_ServiceHandler): self.__task_executor = task_executor self.__settings_handler = SettingsHandler(service.service_config, **settings) + + + + ''' + @metered_subclass_method(METRICS_POOL) + def SetEndpoint( + self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None + ) -> List[Union[bool, Exception]]: + + chk_type('endpoints', endpoints, list) + if len(endpoints) == 0: return [] + + service_uuid = self.__service.service_id.service_uuid.uuid + if self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid)): + settings = self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid)) + else: + settings = self.__settings_handler.get('/settings') + LOGGER.info("AAAAAAAAAAAAAAAAAAAA settings={}".format(settings)) + + settings = self.__settings_handler.get('/settings') + #new structure + #in, dev, out, topo(opt) + entries = List[Tuple[str, str, str Optional[str]]] + entry_tuple = device_uuid, endpoint_uuid, topology_uuid + entries.append(endpoint_id_tuple) + for i in range (1, len(endpoints)): + endpoint_x = endpoints[i] + dev_x = endpoint_x[0] + if_x = endpoint_x[1] + + + + + + results = [] + for endpoint in endpoints: + try: + device_uuid, endpoint_uuid = get_device_endpoint_uuids(endpoint) + + device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) + endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid) + endpoint_settings = self.__settings_handler.get_endpoint_settings(device_obj, endpoint_obj) + endpoint_name = endpoint_obj.name + + json_config_rules = setup_config_rules( + service_uuid, connection_uuid, device_uuid, endpoint_uuid, endpoint_name, + settings, endpoint_settings) + LOGGER.info("Start configuring device %s",settings) + if (settings): + self.__task_executor.configure_optical_device(device_obj,settings) + if len(json_config_rules) > 0: + LOGGER.info("Start configuring device") + del device_obj.device_config.config_rules[:] + for json_config_rule in json_config_rules: + device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule)) + self.__task_executor.configure_optical_device(device_obj) + #self.__task_executor.configure_device(device_obj) + + results.append(True) + except Exception as e: # pylint: disable=broad-except + LOGGER.exception('Unable to SetEndpoint({:s})'.format(str(endpoint))) + results.append(e) + + return results + ''' + + @metered_subclass_method(METRICS_POOL) def SetEndpoint( self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None @@ -53,29 +121,68 @@ class OCServiceHandler(_ServiceHandler): else: settings = self.__settings_handler.get('/settings') - LOGGER.debug("settings={}".format(settings)) + # settings = self.__settings_handler.get('/settings') #flow is the new variable that stores input-output relationship flows = convert_endpoints_to_flows(endpoints) #handled_flows=handle_flows_names(flows=flows,task_executor=self.__task_executor) - LOGGER.debug("dict of flows= {}".format(flows)) + #LOGGER.info("Handled Flows %s",handled_flows) results = [] #new cycle for setting optical devices - for device_uuid, dev_flows in flows.items(): + for device_uuid in flows.keys(): try: + dev_flows = flows[device_uuid] device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) - LOGGER.debug("device_obj={}".format(device_obj)) + + ''' + #to be imported in the device handler + endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid) + endpoint_settings = self.__settings_handler.get_endpoint_settings(device_obj, endpoint_obj) + endpoint_name = endpoint_obj.name + ''' if (settings): - LOGGER.debug("settings={}".format(settings)) + self.__task_executor.configure_optical_device(device_obj, settings, dev_flows, is_opticalband) results.append(True) except Exception as e: # pylint: disable=broad-except LOGGER.exception('Unable to configure Device({:s})'.format(str(device_uuid))) results.append(e) + + ''' + for endpoint in endpoints: + try: + device_uuid, endpoint_uuid = get_device_endpoint_uuids(endpoint) + + device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) + endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid) + endpoint_settings = self.__settings_handler.get_endpoint_settings(device_obj, endpoint_obj) + endpoint_name = endpoint_obj.name + + # json_config_rules = setup_config_rules( + # service_uuid, connection_uuid, device_uuid, endpoint_uuid, endpoint_name, + # settings, endpoint_settings) + + if (settings): + LOGGER.debug("Andrea234 settings={}".format(settings)) + self.__task_executor.configure_optical_device(device_obj,settings,handled_flows,is_opticalband) + #we don't use config_rules + # if len(json_config_rules) > 0: + # LOGGER.debug("VBNMHGStart configuring device") + # del device_obj.device_config.config_rules[:] + # for json_config_rule in json_config_rules: + # device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule)) + # self.__task_executor.configure_optical_device(device_obj) + #self.__task_executor.configure_device(device_obj) + + results.append(True) + except Exception as e: # pylint: disable=broad-except + LOGGER.exception('Unable to SetEndpoint({:s})'.format(str(endpoint))) + results.append(e) + ''' return results @@ -86,14 +193,29 @@ class OCServiceHandler(_ServiceHandler): chk_type('endpoints', endpoints, list) if len(endpoints) == 0: return [] - # TODO: to be checked and elaborated + service_uuid = self.__service.service_id.service_uuid.uuid + settings = self.__settings_handler.get('/settings') results = [] for endpoint in endpoints: try: device_uuid, endpoint_uuid = get_device_endpoint_uuids(endpoint) + device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) - self.__task_executor.configure_device(device_obj) + endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid) + endpoint_settings = self.__settings_handler.get_endpoint_settings(device_obj, endpoint_obj) + endpoint_name = endpoint_obj.name + + json_config_rules = teardown_config_rules( + service_uuid, connection_uuid, device_uuid, endpoint_uuid, endpoint_name, + settings, endpoint_settings) + + if len(json_config_rules) > 0: + del device_obj.device_config.config_rules[:] + for json_config_rule in json_config_rules: + device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule)) + self.__task_executor.configure_device(device_obj) + results.append(True) except Exception as e: # pylint: disable=broad-except LOGGER.exception('Unable to DeleteEndpoint({:s})'.format(str(endpoint))) diff --git a/src/service/service/service_handlers/oc/OCTools.py b/src/service/service/service_handlers/oc/OCTools.py index f40cb65be..529a1bc7f 100644 --- a/src/service/service/service_handlers/oc/OCTools.py +++ b/src/service/service/service_handlers/oc/OCTools.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. - from service.service.service_handler_api.Tools import get_device_endpoint_uuids, get_endpoint_matching from typing import Dict, Any, List, Optional, Tuple import logging @@ -26,7 +25,8 @@ def convert_endpoints_to_flows(endpoints : List[Tuple[str, str, Optional[str]]]) #entries = Dict[str: List[Tuple[str, str]]] entries = {} #tuple is in, out - end = len(endpoints) + #end = len(endpoints) if isinstance(endpoints,list) else 0 + end=len(endpoints) i = 0 bidir = 0 log.debug("end={}".format(end)) @@ -115,10 +115,14 @@ def convert_endpoints_to_flows(endpoints : List[Tuple[str, str, Optional[str]]]) def get_device_endpint_name (endpoint_uuid:str,device_uuid:str,task_executor)->Tuple: + + + device_obj = task_executor.get_device(DeviceId(**json_device_id(device_uuid))) endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid) endpoint_name = endpoint_obj.name - return (device_obj.name, endpoint_name) + + return (device_obj.name,endpoint_name) def handle_flows_names (task_executor,flows:dict)->Dict : new_flows={} @@ -137,4 +141,4 @@ def handle_flows_names (task_executor,flows:dict)->Dict : if (device_name not in new_flows): new_flows[device_name]=[] new_flows[device_name].append((source_port,destination_port)) - return new_flows + return new_flows \ No newline at end of file diff --git a/src/service/service/task_scheduler/TaskExecutor.py b/src/service/service/task_scheduler/TaskExecutor.py index 6d24da4c0..48449e4d9 100644 --- a/src/service/service/task_scheduler/TaskExecutor.py +++ b/src/service/service/task_scheduler/TaskExecutor.py @@ -12,13 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging #, json +import logging , json from enum import Enum from typing import TYPE_CHECKING, Any, Dict, Optional, Union from common.method_wrappers.ServiceExceptions import NotFoundException -from common.proto.context_pb2 import ( - Connection, ConnectionId, Device, DeviceDriverEnum, DeviceId, Service, ServiceId, MyConfig, MyConfigId -) +from common.proto.context_pb2 import Connection, ConnectionId, Device, DeviceDriverEnum, DeviceId, Service, ServiceId,MyConfig,MyConfigId from common.tools.context_queries.Connection import get_connection_by_id from common.tools.context_queries.Device import get_device from common.tools.context_queries.Service import get_service_by_id @@ -115,32 +113,70 @@ class TaskExecutor: self._device_client.ConfigureDevice(device) self._store_grpc_object(CacheableObjectType.DEVICE, device_key, device) - # New function Andrea for Optical Devices - def configure_optical_device(self, device : Device, settings : str, flows : list, is_opticalband : bool): + # New function Andrea for Optical Devices + def configure_optical_device(self,device:Device,settings:str,flows:list,is_opticalband:bool): + + device_key = get_device_key(device.device_id) - myid = MyConfigId() - myid.myconfig_uuid = device.device_id.device_uuid.uuid - myConfig = MyConfig() + myid=MyConfigId() + myid.myconfig_uuid=device.device_id.device_uuid.uuid + myConfig=MyConfig() - setting = settings.value if settings else "" + setting =settings.value if settings else "" - new_config = {} + new_config={} try: - result = self._context_client.SelectMyConfig(myid) - new_config = eval(result.config) - LOGGER.info("result %s",result) - if result is not None : - new_config["new_config"]=setting - new_config["is_opticalband"]=is_opticalband - new_config["flow"]=flows - result.config = str(new_config) - myConfig.CopyFrom(result) - self._device_client.ConfigureOpticalDevice(myConfig) - - self._store_grpc_object(CacheableObjectType.DEVICE, device_key, device) + result=self._context_client.SelectMyConfig(myid) + + new_config=json.loads(result.config) + + if result is not None : + + new_config["new_config"]=setting + new_config["is_opticalband"]=is_opticalband + new_config["flow"]=flows + result.config = str(new_config) + myConfig.CopyFrom(result) + + self._device_client.ConfigureOpticalDevice(myConfig) + + self._store_grpc_object(CacheableObjectType.DEVICE, device_key, device) + except Exception as e: + LOGGER.info("error in config my config %s",e) + + ''' + # For Optical Devices + def configure_optical_device (self,device:Device,settings:str,flows:dict,is_opticalband:bool) : + + + device_key = get_device_key(device.device_id) + myid=MyConfigId() + myid.myconfig_uuid=device.device_id.device_uuid.uuid + myConfig=MyConfig() + + setting =settings.value if settings else "" + + new_config={} + try: + result=self._context_client.SelectMyConfig(myid) + new_config=eval(result.config) + + if result is not None : + + new_config["new_config"]=setting + new_config["is_opticalband"]=is_opticalband + new_config["flow"]=flows + result.config = str(new_config) + myConfig.CopyFrom(result) + + self._device_client.ConfigureOpticalDevice(myConfig) + + self._store_grpc_object(CacheableObjectType.DEVICE, device_key, device) except Exception as e: LOGGER.debug("error in config my config %s",e) - + ''' + + def get_device_controller(self, device : Device) -> Optional[Device]: #json_controller = None #for config_rule in device.device_config.config_rules: diff --git a/src/service/service/tools/OpticalTools.py b/src/service/service/tools/OpticalTools.py index 227be2765..a5529adc8 100644 --- a/src/service/service/tools/OpticalTools.py +++ b/src/service/service/tools/OpticalTools.py @@ -15,14 +15,16 @@ import json import requests -import uuid +import uuid ,os from common.Constants import * from typing import Dict, List from common.proto.context_pb2 import( Device, DeviceId, Service, Connection, EndPointId, TopologyId, ContextId, Uuid, ConfigRule, ConfigActionEnum, ConfigRule_Custom) from common.proto.pathcomp_pb2 import PathCompReply from typing import Dict, List, Optional, Tuple - +from common.Constants import ServiceNameEnum +from common.Settings import ( + ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, find_environment_variables ,get_env_var_name) from context.service.database.uuids.EndPoint import endpoint_get_uuid @@ -30,9 +32,15 @@ from service.service.tools.replies import reply_uni_txt, optical_band_uni_txt, r log = logging.getLogger(__name__) -testing = True +testing = False - +opticalcontrollers_url= find_environment_variables([ + get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER,ENVVAR_SUFIX_SERVICE_HOST), + get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER,ENVVAR_SUFIX_SERVICE_PORT_GRPC), + ]) +OPTICAL_IP=opticalcontrollers_url[get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER,ENVVAR_SUFIX_SERVICE_HOST)] +OPTICAL_PORT=opticalcontrollers_url[get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER,ENVVAR_SUFIX_SERVICE_PORT_GRPC)] +log.info(OPTICAL_IP,OPTICAL_PORT) def get_uuids_from_names(devices: List[Device], device_name: str, port_name: str): device_uuid = "" @@ -134,6 +142,7 @@ def adapt_reply(devices, service, reply_json, context_id, topology_id, optical_b #add optical band connection first rules_ob= [] ob_id = 0 + connection_ob=None if optical_band_txt != "": ob_json = json.loads(optical_band_txt) ob = ob_json @@ -176,7 +185,7 @@ def adapt_reply(devices, service, reply_json, context_id, topology_id, optical_b end_point_b = EndPointId(topology_id=topo, device_id=DeviceId(device_uuid=Uuid(uuid=d_ob)), endpoint_uuid=Uuid(uuid=p_ob)) connection_ob.path_hops_endpoint_ids.add().CopyFrom(end_point_b) else: - log.INFO("no map device port for device {} port {}".format(devxb, in_end_point_f)) + log.info("no map device port for device {} port {}".format(devxb, in_end_point_f)) if out_end_point_f != "0": d_ob, p_ob = get_uuids_from_names(devices, devxb, out_end_point_f) @@ -184,21 +193,21 @@ def adapt_reply(devices, service, reply_json, context_id, topology_id, optical_b end_point_b = EndPointId(topology_id=topo, device_id=DeviceId(device_uuid=Uuid(uuid=d_ob)), endpoint_uuid=Uuid(uuid=p_ob)) connection_ob.path_hops_endpoint_ids.add().CopyFrom(end_point_b) else: - log.INFO("no map device port for device {} port {}".format(devxb, out_end_point_f)) + log.info("no map device port for device {} port {}".format(devxb, out_end_point_f)) if in_end_point_b != "0": d_ob, p_ob = get_uuids_from_names(devices, devxb, in_end_point_b) if d_ob != "" and p_ob != "": end_point_b = EndPointId(topology_id=topo, device_id=DeviceId(device_uuid=Uuid(uuid=d_ob)), endpoint_uuid=Uuid(uuid=p_ob)) connection_ob.path_hops_endpoint_ids.add().CopyFrom(end_point_b) else: - log.INFO("no map device port for device {} port {}".format(devxb, in_end_point_b)) + log.info("no map device port for device {} port {}".format(devxb, in_end_point_b)) if out_end_point_b != "0": d_ob, p_ob = get_uuids_from_names(devices, devxb, out_end_point_b) if d_ob != "" and p_ob != "": end_point_b = EndPointId(topology_id=topo, device_id=DeviceId(device_uuid=Uuid(uuid=d_ob)), endpoint_uuid=Uuid(uuid=p_ob)) connection_ob.path_hops_endpoint_ids.add().CopyFrom(end_point_b) else: - log.INFO("no map device port for device {} port {}".format(devxb, out_end_point_b)) + log.info("no map device port for device {} port {}".format(devxb, out_end_point_b)) log.debug("optical-band connection {}".format(connection_ob)) r = reply_json bidir_f = r["bidir"] @@ -223,39 +232,39 @@ def adapt_reply(devices, service, reply_json, context_id, topology_id, optical_b end_point = EndPointId(topology_id=topo, device_id=DeviceId(device_uuid=Uuid(uuid=d)), endpoint_uuid=Uuid(uuid=p)) connection_f.path_hops_endpoint_ids.add().CopyFrom(end_point) else: - log.INFO("no map device port for device {} port {}".format(devx, in_end_point_f)) + log.info("no map device port for device {} port {}".format(devx, in_end_point_f)) if out_end_point_f != "0": d, p = get_uuids_from_names(devices, devx, out_end_point_f) if d != "" and p != "": end_point = EndPointId(topology_id=topo, device_id=DeviceId(device_uuid=Uuid(uuid=d)), endpoint_uuid=Uuid(uuid=p)) connection_f.path_hops_endpoint_ids.add().CopyFrom(end_point) else: - log.INFO("no map device port for device {} port {}".format(devx, out_end_point_f)) + log.info("no map device port for device {} port {}".format(devx, out_end_point_f)) if in_end_point_b != "0": d, p = get_uuids_from_names(devices, devx, in_end_point_b) if d != "" and p != "": end_point = EndPointId(topology_id=topo, device_id=DeviceId(device_uuid=Uuid(uuid=d)), endpoint_uuid=Uuid(uuid=p)) connection_f.path_hops_endpoint_ids.add().CopyFrom(end_point) else: - log.INFO("no map device port for device {} port {}".format(devx, in_end_point_b)) + log.info("no map device port for device {} port {}".format(devx, in_end_point_b)) if out_end_point_b != "0": d, p = get_uuids_from_names(devices, devx, out_end_point_b) if d != "" and p != "": end_point = EndPointId(topology_id=topo, device_id=DeviceId(device_uuid=Uuid(uuid=d)), endpoint_uuid=Uuid(uuid=p)) connection_f.path_hops_endpoint_ids.add().CopyFrom(end_point) else: - log.INFO("no map device port for device {} port {}".format(devx, out_end_point_b)) + log.info("no map device port for device {} port {}".format(devx, out_end_point_b)) #check that list of endpoints is not empty - if len(connection_ob.path_hops_endpoint_ids) == 0: + if connection_ob is not None and len(connection_ob.path_hops_endpoint_ids) == 0: log.debug("deleting empty optical-band connection") opt_reply.connections.remove(connection_ob) #inizialize custom optical parameters - band = r["band"] - op_mode = r["op-mode"] - frequency = r["freq"] - flow_id = r["flow_id"] - r_type = r["band_type"] + band = r["band"] if "band" in r else None + op_mode = r["op-mode"] if "op-mode" in r else None + frequency = r["freq"] if "freq" in r else None + flow_id = r["flow_id"] if "flow_id" in r else None + r_type = r["band_type"] if "band_type" in r else None if r_type == "l_slots": band_type = "L_BAND" elif r_type == "s_slots": @@ -263,14 +272,14 @@ def adapt_reply(devices, service, reply_json, context_id, topology_id, optical_b else: band_type = "C_BAND" - if ob_id is not 0: + if ob_id != 0: val = {"frequency": frequency, "operational-mode": op_mode, "band": band, "flow_id": flow_id, "ob_id": ob_id, "band_type": band_type,} else: val = {"frequency": frequency, "operational-mode": op_mode, "band": band, "flow_id": flow_id, "band_type": band_type,} custom_rule = ConfigRule_Custom(resource_key="/settings", resource_value=json.dumps(val)) rule = ConfigRule(action=ConfigActionEnum.CONFIGACTION_SET, custom=custom_rule) service.service_config.config_rules.add().CopyFrom(rule) - log.debug("optical-band rules {}".format(rules_ob)) + if len(rules_ob) > 0: for rulex in rules_ob: rule_ob = ConfigRule(action=ConfigActionEnum.CONFIGACTION_SET, custom=rulex) @@ -287,4 +296,4 @@ def add_service_to_reply(reply : PathCompReply, service : Service)-> Service: def add_connection_to_reply(reply : PathCompReply)-> Connection: conn = reply.connections.add() - return conn + return conn \ No newline at end of file diff --git a/startExtraNetConfigAgent.sh b/startExtraNetConfigAgent.sh new file mode 100755 index 000000000..79efe3773 --- /dev/null +++ b/startExtraNetConfigAgent.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +Docker_Container=$1 +Docker_Port=$2 +if [ -n "$Docker_Container" ] && [ -n "$Docker_Port" ];then + sudo docker stop "$Docker_Container" -t 1 + + sudo docker rm "$Docker_Container" + + + echo "Creating TPs" + screen -dmS t1 -T xterm sh -c "docker run -p 10.0.2.15:"$Docker_Port":2022 -v ~/tfs-ctrl/tempOC/files:/files --name $Docker_Container -it asgamb1/oc23bgp.img:latest" + sleep 2 + if [ "$( docker container inspect -f '{{.State.Running}}' "$Docker_Container")" = "true" ]; then + + docker exec "$Docker_Container" cp /files/demoECOC21_4.xml demoECOC21.xml + + docker exec "$Docker_Container" /confd/examples.confd/OC23/startNetconfAgent.sh + else + echo "your container is not running yet" + fi +else + echo "Please define the docker container name and port" +fi + diff --git a/start_topo.sh b/start_topo.sh new file mode 100755 index 000000000..574d0c1d5 --- /dev/null +++ b/start_topo.sh @@ -0,0 +1,23 @@ +#!/bin/bash +asgamb1/flexscale-node.imgasgamb1/flexscale-node.imgasgamb1/flexscale-node.imgasgamb1/flexscale-node.img#!/bin/bash + +sudo docker stop na1 -t 1 +sudo docker stop na2 -t 1 +sudo docker stop na3 -t 1 +sudo docker stop na4 -t 1 + +sudo docker rm na2 +sudo docker rm na1 +sudo docker rm na3 +sudo docker rm na4 + +echo "Creating NewAgent" +echo " It may take a while , Hang on ..." +source "./startExtraNetConfigAgent.sh" "na1" "2023" +sleep 3 + +source "./startExtraNetConfigAgent.sh" "na2" "2024" +sleep 3 + +screen -dmS t3 -T xterm sh -c 'docker run -p 10.0.2.15:2025:2022 -v ~/tfs-ctrl/tempOC/files:/files --name na3 -it asgamb1/flexscale-node.img:latest ./startNetconfAgent.sh' +screen -dmS t4 -T xterm sh -c 'docker run -p 10.0.2.15:2026:2022 -v ~/tfs-ctrl/tempOC/files:/files --name na4 -it asgamb1/flexscale-node.img:latest ./startNetconfAgent.sh' \ No newline at end of file -- GitLab From 9bf7940266c0d22bf486fcb5bc8f021c32f5c191 Mon Sep 17 00:00:00 2001 From: sgambelluri Date: Tue, 5 Mar 2024 14:20:19 +0000 Subject: [PATCH 02/13] First Round Cleaning For Merge --- manifests/opticalcontrollerservice.yaml | 4 +- .../startExtraNetConfigAgent.sh | 0 start_topo.sh => ofc24/start_topo.sh | 0 proto/context.proto | 24 +- proto/openconfig_device.proto | 4 +- scripts/show_logs_opticalcontroller.sh | 2 +- src/context/client/ContextClient.py | 24 +- .../service/ContextServiceServicerImpl.py | 28 +- src/context/service/database/ConfigModel.py | 2 +- .../{MyConfigOperator.py => OpticalConfig.py} | 52 +- ...MyConfigModel.py => OpticalConfigModel.py} | 6 +- src/device/client/DeviceClient.py | 4 +- .../service/DeviceServiceServicerImpl.py | 2 +- src/device/service/OpenConfigServicer.py | 8 +- src/device/service/Tools.py | 46 +- .../service/drivers/oc_driver/OCDriver.py | 14 +- .../templates/Interfaces/interfaces.py | 2 +- .../oc_driver/templates/VPN/physical.py | 2 +- src/opticalcontroller/OpticalController.py | 14 + src/opticalcontroller/RSA.py | 47 - .../json_files/tfs copy.json | 1286 ----------------- src/opticalcontroller/tools.py | 16 + src/opticalcontroller/variables.py | 16 + src/service/service/__main__.py | 10 +- .../service_handlers/oc/OCServiceHandler.py | 105 +- .../service/task_scheduler/TaskExecutor.py | 46 +- 26 files changed, 180 insertions(+), 1584 deletions(-) rename startExtraNetConfigAgent.sh => ofc24/startExtraNetConfigAgent.sh (100%) rename start_topo.sh => ofc24/start_topo.sh (100%) rename src/context/service/database/{MyConfigOperator.py => OpticalConfig.py} (70%) rename src/context/service/database/models/{MyConfigModel.py => OpticalConfigModel.py} (93%) delete mode 100644 src/opticalcontroller/json_files/tfs copy.json diff --git a/manifests/opticalcontrollerservice.yaml b/manifests/opticalcontrollerservice.yaml index ba1edcc56..db760c23e 100644 --- a/manifests/opticalcontrollerservice.yaml +++ b/manifests/opticalcontrollerservice.yaml @@ -9,9 +9,7 @@ spec: replicas: 1 template: metadata: - annotations: - # Required for IETF L2VPN SBI when both parent and child run in same K8s cluster with Linkerd - config.linkerd.io/skip-outbound-ports: "8022" + labels: app: opticalcontrollerservice spec: diff --git a/startExtraNetConfigAgent.sh b/ofc24/startExtraNetConfigAgent.sh similarity index 100% rename from startExtraNetConfigAgent.sh rename to ofc24/startExtraNetConfigAgent.sh diff --git a/start_topo.sh b/ofc24/start_topo.sh similarity index 100% rename from start_topo.sh rename to ofc24/start_topo.sh diff --git a/proto/context.proto b/proto/context.proto index e96181693..73c478865 100644 --- a/proto/context.proto +++ b/proto/context.proto @@ -77,9 +77,9 @@ service ContextService { // ------------------------------ Experimental------------------------------ - rpc GetMyConfig (Empty ) returns ( MyConfigList ) {} - rpc SetMyConfig (MyConfig) returns (MyConfigId) {} - rpc SelectMyConfig (MyConfigId) returns (MyConfig) {} + 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) {} @@ -211,9 +211,11 @@ enum DeviceDriverEnum { DEVICEDRIVER_XR = 6; DEVICEDRIVER_IETF_L2VPN = 7; DEVICEDRIVER_GNMI_OPENCONFIG = 8; - DEVICEDRIVER_OC = 11; - DEVICEDRIVER_FLEXSCALE=10; DEVICEDRIVER_IETF_ACTN=9; + DEVICEDRIVER_FLEXSCALE=10; + DEVICEDRIVER_OC = 11; + + } enum DeviceOperationalStatusEnum { @@ -626,15 +628,15 @@ message AuthenticationResult { } // ---------------- Experimental ------------------------ -message MyConfigId { - string myconfig_uuid= 1; +message OpticalConfigId { + string opticalconfig_uuid= 1; } -message MyConfig { - MyConfigId myconfig_id=1; +message OpticalConfig { + OpticalConfigId opticalconfig_id=1; string config =2 ; } -message MyConfigList { - repeated MyConfig MyConfigs =1 ; +message OpticalConfigList { + repeated OpticalConfig opticalconfigs =1 ; } //----Optical Link ---- message OpticalLinkId { diff --git a/proto/openconfig_device.proto b/proto/openconfig_device.proto index d00e46645..8a0a97df2 100644 --- a/proto/openconfig_device.proto +++ b/proto/openconfig_device.proto @@ -19,8 +19,8 @@ import "context.proto"; import "monitoring.proto"; service OpenConfigService { - rpc AddOpenConfigDevice (context.MyConfig ) returns (context.MyConfigId ) {} + rpc AddOpenConfigDevice (context.OpticalConfig ) returns (context.OpticalConfigId ) {} - rpc ConfigureOpticalDevice (context.MyConfig) returns (context.Empty) {} + rpc ConfigureOpticalDevice (context.OpticalConfig) returns (context.Empty) {} } diff --git a/scripts/show_logs_opticalcontroller.sh b/scripts/show_logs_opticalcontroller.sh index e32ea7ef9..a4778c308 100755 --- a/scripts/show_logs_opticalcontroller.sh +++ b/scripts/show_logs_opticalcontroller.sh @@ -24,4 +24,4 @@ export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} # Automated steps start here ######################################################################################################################## -kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/opticalcontrollerservice -c server > logs/opticalcontroller.log && vi logs/opticalcontroller.log +kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/opticalcontrollerservice -c server > logs/opticalcontroller.log diff --git a/src/context/client/ContextClient.py b/src/context/client/ContextClient.py index a1a6bcb08..96a2f3f8d 100644 --- a/src/context/client/ContextClient.py +++ b/src/context/client/ContextClient.py @@ -27,7 +27,7 @@ from common.proto.context_pb2 import ( Service, ServiceEvent, ServiceFilter, ServiceId, ServiceIdList, ServiceList, Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList, Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList, - MyConfig,MyConfigId,MyConfigList) + OpticalConfig,OpticalConfigId,OpticalConfigList) from common.proto.context_pb2_grpc import ContextServiceStub from common.proto.context_policy_pb2_grpc import ContextPolicyServiceStub from common.proto.policy_pb2 import PolicyRuleIdList, PolicyRuleId, PolicyRuleList, PolicyRule @@ -439,22 +439,22 @@ class ContextClient: return response #//////////////// Experimental ////////////////// @RETRY_DECORATOR - def SetMyConfig (self,request:MyConfig) ->MyConfigId: - LOGGER.debug('SettingMyConfig request: {:s}'.format(grpc_message_to_json_string(request))) - response = self.stub.SetMyConfig(request) - LOGGER.debug('SettingMyconfig result: {:s}'.format(grpc_message_to_json_string(response))) + def SetOpticalConfig (self,request:OpticalConfig) ->OpticalConfigId: + LOGGER.debug('SettingOpticalConfig request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.SetOpticalConfig(request) + LOGGER.debug('SettingOpticalConfig result: {:s}'.format(grpc_message_to_json_string(response))) return response @RETRY_DECORATOR - def GetMyConfig (self,request:Empty) ->MyConfigList: - LOGGER.debug('GettingMyConfig request: {:s}'.format(grpc_message_to_json_string(request))) - response = self.stub.GetMyConfig(request) - LOGGER.debug('GetMyConfig result: {:s}'.format(grpc_message_to_json_string(response))) + def GetOpticalConfig (self,request:Empty) ->OpticalConfigList: + LOGGER.debug('GettingOpticalConfig request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.GetOpticalConfig(request) + LOGGER.debug('GetOpticalConfig result: {:s}'.format(grpc_message_to_json_string(response))) return response @RETRY_DECORATOR - def SelectMyConfig (self,request:MyConfigId) ->MyConfigList: + def SelectOpticalConfig (self,request:OpticalConfigId) ->OpticalConfigList: LOGGER.debug('Selecting request: {:s}'.format(grpc_message_to_json_string(request))) - response = self.stub.SelectMyConfig(request) - LOGGER.debug('GetMyConfig result: {:s}'.format(grpc_message_to_json_string(response))) + response = self.stub.SelectOpticalConfig(request) + LOGGER.debug('GetOpticalConfig result: {:s}'.format(grpc_message_to_json_string(response))) return response diff --git a/src/context/service/ContextServiceServicerImpl.py b/src/context/service/ContextServiceServicerImpl.py index f4d2cc307..8b5a3f7bc 100644 --- a/src/context/service/ContextServiceServicerImpl.py +++ b/src/context/service/ContextServiceServicerImpl.py @@ -24,7 +24,7 @@ from common.proto.context_pb2 import ( Service, ServiceEvent, ServiceFilter, ServiceId, ServiceIdList, ServiceList, Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList, Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList, - MyConfigList,MyConfigId,MyConfig) + OpticalConfigList,OpticalConfigId,OpticalConfig) from common.proto.policy_pb2 import PolicyRuleIdList, PolicyRuleId, PolicyRuleList, PolicyRule from common.proto.context_pb2_grpc import ContextServiceServicer from common.proto.context_policy_pb2_grpc import ContextPolicyServiceServicer @@ -44,7 +44,7 @@ from .database.Slice import ( slice_delete, slice_get, slice_list_ids, slice_list_objs, slice_select, slice_set, slice_unset) from .database.Topology import ( topology_delete, topology_get, topology_get_details, topology_list_ids, topology_list_objs, topology_set) -from .database.MyConfigOperator import (set_myconfig,select_MyConfig,get_myconfig) +from .database.OpticalConfigOperator import (set_OpticalConfig,select_OpticalConfig,get_OpticalConfig) LOGGER = logging.getLogger(__name__) @@ -300,19 +300,19 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer return policyrule_delete(self.db_engine, self.messagebroker, request) # ---------------------------- Experimental ------------------- @safe_and_metered_rpc_method(METRICS_POOL,LOGGER) - def GetMyConfig(self,request:Empty,context:grpc.ServicerContext) -> MyConfigList: + def GetOpticalConfig(self,request:Empty,context:grpc.ServicerContext) -> OpticalConfigList: - result =get_myconfig(db_engine=self.db_engine) + result =get_OpticalConfig(db_engine=self.db_engine) - return MyConfigList(MyConfigs=result) - def SetMyConfig(self,request:MyConfig,context:grpc.ServicerContext)-> MyConfigId: + return OpticalConfigList(OpticalConfigs=result) + def SetOpticalConfig(self,request:OpticalConfig,context:grpc.ServicerContext)-> OpticalConfigId: - myconfig_id= set_myconfig(db_engine=self.db_engine,request=request) + OpticalConfig_id= set_OpticalConfig(db_engine=self.db_engine,request=request) - return MyConfigId(**myconfig_id) - def SelectMyConfig (self,request:MyConfigId,context:grpc.ServicerContext) -> MyConfig: - result =select_MyConfig(db_engine=self.db_engine,request=request) - logging.info(f"FromSelectMyConfig {result}") - myid =MyConfigId() - myid.CopyFrom(result.myconfig_id) - return MyConfig(config=result.config,myconfig_id=myid) + return OpticalConfigId(**OpticalConfig_id) + def SelectOpticalConfig (self,request:OpticalConfigId,context:grpc.ServicerContext) -> OpticalConfig: + result =select_OpticalConfig(db_engine=self.db_engine,request=request) + logging.info(f"FromSelectOpticalConfig {result}") + myid =OpticalConfigId() + myid.CopyFrom(result.OpticalConfig_id) + return OpticalConfig(config=result.config,OpticalConfig_id=myid) diff --git a/src/context/service/database/ConfigModel.py b/src/context/service/database/ConfigModel.py index 234e155f0..94519dcec 100644 --- a/src/context/service/database/ConfigModel.py +++ b/src/context/service/database/ConfigModel.py @@ -11,7 +11,7 @@ # 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. - +# Todo check if the file is in use by the TFS import functools, logging, operator from enum import Enum from typing import Dict, List, Optional, Tuple, Union diff --git a/src/context/service/database/MyConfigOperator.py b/src/context/service/database/OpticalConfig.py similarity index 70% rename from src/context/service/database/MyConfigOperator.py rename to src/context/service/database/OpticalConfig.py index 0ca58f6ca..33227a016 100644 --- a/src/context/service/database/MyConfigOperator.py +++ b/src/context/service/database/OpticalConfig.py @@ -20,7 +20,7 @@ from sqlalchemy.orm import Session, selectinload, sessionmaker from sqlalchemy_cockroachdb import run_transaction from typing import Dict, List, Optional, Set, Tuple from common.method_wrappers.ServiceExceptions import InvalidArgumentException, NotFoundException -from common.proto.context_pb2 import Device, DeviceFilter, DeviceId, TopologyId,MyConfig,MyConfigId,MyConfigList +from common.proto.context_pb2 import Device, DeviceFilter, DeviceId, TopologyId,OpticalConfig,OpticalConfigId,OpticalConfigList from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.object_factory.Device import json_device_id from context.service.database.uuids.Topology import topology_get_uuid @@ -33,24 +33,24 @@ from .models.enums.KpiSampleType import grpc_to_enum__kpi_sample_type from .uuids.Device import device_get_uuid from .uuids.EndPoint import endpoint_get_uuid from .ConfigRule import compose_config_rules_data, upsert_config_rules -from .models.MyConfigModel import MyConfigModel +from .models.OpticalConfigModel import OpticalConfigModel LOGGER = logging.getLogger(__name__) -def get_myconfig (db_engine:Engine): +def get_opticalconfig (db_engine:Engine): def callback(session:Session): lst = list() - results = session.query(MyConfigModel).all() + results = session.query(OpticalConfigModel).all() for obj in results: - myconfig=MyConfig() - myconfig.config=json.dump(obj.config) - myid=MyConfigId() - myid.myconfig_uuid=obj.myconfig_uuid - myconfig.myconfig_id.CopyFrom(myid) + OpticalConfig=OpticalConfig() + OpticalConfig.config=json.dump(obj.config) + myid=OpticalConfigId() + myid.opticalconfig_uuid=obj.opticalconfig_uuid + OpticalConfig.opticalconfig_id.CopyFrom(myid) - lst.append(myconfig) + lst.append(OpticalConfig) return lst obj=run_transaction(sessionmaker(bind=db_engine),callback) return obj @@ -58,10 +58,10 @@ def get_myconfig (db_engine:Engine): -def set_myconfig (db_engine:Engine,request:MyConfig): +def set_opticalconfig (db_engine:Engine,request:OpticalConfig): - myconfig_id=MyConfigId() - myconfig_id.myconfig_uuid=request.myconfig_id.myconfig_uuid + opticalconfig_id=OpticalConfigId() + opticalconfig_id.opticalconfig_uuid=request.opticalconfig_id.opticalconfig_uuid my_config_data=[] if (request.config): channels=[] @@ -76,7 +76,7 @@ def set_myconfig (db_engine:Engine,request:MyConfig): my_config_data=[ { - "myconfig_uuid":request.myconfig_id.myconfig_uuid, + "opticalconfig_uuid":request.opticalconfig_id.opticalconfig_uuid, "channels":channels, "transcievers":transceivers, "interfaces":json.dumps(config["interfaces"]["interface"]), @@ -90,38 +90,38 @@ def set_myconfig (db_engine:Engine,request:MyConfig): def callback(session:Session)->bool: - stmt = insert(MyConfigModel).values(my_config_data) + stmt = insert(OpticalConfigModel).values(my_config_data) stmt = stmt.on_conflict_do_update( - index_elements=[MyConfigModel.myconfig_uuid], + index_elements=[OpticalConfigModel.opticalconfig_uuid], set_=dict( channel_namespace=stmt.excluded.channel_namespace ) ) - stmt = stmt.returning(MyConfigModel.myconfig_uuid) + stmt = stmt.returning(OpticalConfigModel.opticalconfig_uuid) id = session.execute(stmt).fetchone() - myconfig_id =run_transaction(sessionmaker(bind=db_engine),callback) + opticalconfig_id =run_transaction(sessionmaker(bind=db_engine),callback) - return {'myconfig_uuid': myconfig_id} + return {'opticalconfig_uuid': opticalconfig_id} -def select_MyConfig(db_engine:Engine,request:MyConfigId): +def select_opticalconfig(db_engine:Engine,request:OpticalConfigId): - def callback(session : Session) -> MyConfig: - result=MyConfig() - obj = session.query(MyConfigModel).filter_by(myconfig_uuid=request.myconfig_uuid).first() + def callback(session : Session) -> OpticalConfig: + result=OpticalConfig() + obj = session.query(OpticalConfigModel).filter_by(opticalconfig_uuid=request.opticalconfig_uuid).first() if (obj is not None): - myid=MyConfigId() - myid.myconfig_uuid=obj.myconfig_uuid + myid=OpticalConfigId() + myid.opticalconfig_uuid=obj.opticalconfig_uuid result.config=json.dumps(obj.dump()) - result.myconfig_id.CopyFrom(myid) + result.opticalconfig_id.CopyFrom(myid) return result diff --git a/src/context/service/database/models/MyConfigModel.py b/src/context/service/database/models/OpticalConfigModel.py similarity index 93% rename from src/context/service/database/models/MyConfigModel.py rename to src/context/service/database/models/OpticalConfigModel.py index 960f7368b..34a8c41f0 100644 --- a/src/context/service/database/models/MyConfigModel.py +++ b/src/context/service/database/models/OpticalConfigModel.py @@ -22,9 +22,9 @@ from ._Base import _Base -class MyConfigModel (_Base): - __tablename__="MyConfig" - myconfig_uuid = Column(String, primary_key=True) +class OpticalConfigModel (_Base): + __tablename__="OpticalConfig" + opticalconfig_uuid = Column(String, primary_key=True) channels=Column(ARRAY(String),nullable=True) transcievers= Column(ARRAY(String),nullable=True) interfaces =Column(String,nullable=True) diff --git a/src/device/client/DeviceClient.py b/src/device/client/DeviceClient.py index 9b4880c04..3fde3df77 100644 --- a/src/device/client/DeviceClient.py +++ b/src/device/client/DeviceClient.py @@ -15,7 +15,7 @@ import grpc, logging from common.Constants import ServiceNameEnum from common.Settings import get_service_host, get_service_port_grpc -from common.proto.context_pb2 import Device, DeviceConfig, DeviceId, Empty,MyConfig,MyConfigId +from common.proto.context_pb2 import Device, DeviceConfig, DeviceId, Empty,OpticalConfig,OpticalConfigId from common.proto.device_pb2 import MonitoringSettings from common.proto.device_pb2_grpc import DeviceServiceStub from common.tools.client.RetryDecorator import retry, delay_exponential @@ -82,7 +82,7 @@ class DeviceClient: response = self.stub.MonitorDeviceKpi(request) LOGGER.debug('MonitorDeviceKpi result: {:s}'.format(grpc_message_to_json_string(response))) return response - def ConfigureOpticalDevice(self, request : MyConfig) -> MyConfigId: + def ConfigureOpticalDevice(self, request : OpticalConfig) -> OpticalConfigId: LOGGER.debug('ConfigureOpticalDevice request: {:s}'.format(grpc_message_to_json_string(request))) response = self.openconfig_stub.ConfigureOpticalDevice(request) LOGGER.debug('ConfigureOpticalDevice result: {:s}'.format(grpc_message_to_json_string(response))) diff --git a/src/device/service/DeviceServiceServicerImpl.py b/src/device/service/DeviceServiceServicerImpl.py index da5d1134e..6abb06dd0 100644 --- a/src/device/service/DeviceServiceServicerImpl.py +++ b/src/device/service/DeviceServiceServicerImpl.py @@ -20,7 +20,7 @@ from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, get_env_var_name from common.method_wrappers.Decorator import MetricTypeEnum, MetricsPool, safe_and_metered_rpc_method from common.method_wrappers.ServiceExceptions import NotFoundException, OperationFailedException from common.proto.context_pb2 import ( - Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty, Link,MyConfig,MyConfigId) + Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty, Link,OpticalConfig,OpticalConfigId) from common.proto.device_pb2 import MonitoringSettings from common.proto.device_pb2_grpc import DeviceServiceServicer from common.tools.context_queries.Device import get_device diff --git a/src/device/service/OpenConfigServicer.py b/src/device/service/OpenConfigServicer.py index 329bceef2..fc4e75e67 100644 --- a/src/device/service/OpenConfigServicer.py +++ b/src/device/service/OpenConfigServicer.py @@ -20,7 +20,7 @@ from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, get_env_var_name from common.method_wrappers.Decorator import MetricTypeEnum, MetricsPool, safe_and_metered_rpc_method from common.method_wrappers.ServiceExceptions import NotFoundException, OperationFailedException from common.proto.context_pb2 import ( - Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty, Link,MyConfig,MyConfigId ,MyConfig,MyConfigList) + Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty, Link,OpticalConfig,OpticalConfigId ,OpticalConfig,OpticalConfigList) from common.proto.device_pb2 import MonitoringSettings from common.proto.device_pb2_grpc import DeviceServiceServicer from common.tools.context_queries.Device import get_device @@ -54,7 +54,7 @@ class OpenConfigServicer(DeviceServiceServicer): LOGGER.debug('Servicer Created') @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) - def AddOpenConfigDevice(self, request : MyConfig, context : grpc.ServicerContext) -> DeviceId: + def AddOpenConfigDevice(self, request : OpticalConfig, context : grpc.ServicerContext) -> DeviceId: device_uuid = request.device_id.device_uuid.uuid @@ -94,9 +94,9 @@ class OpenConfigServicer(DeviceServiceServicer): #modified Andrea @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) - def ConfigureOpticalDevice (self, request : MyConfig, context:grpc.ServicerContext) -> Empty: + def ConfigureOpticalDevice (self, request : OpticalConfig, context:grpc.ServicerContext) -> Empty: - device_uuid = request.myconfig_id.myconfig_uuid + device_uuid = request.opticalconfig_id.opticalconfig_uuid resources=[] result=None diff --git a/src/device/service/Tools.py b/src/device/service/Tools.py index c4b41020a..04fb54be5 100644 --- a/src/device/service/Tools.py +++ b/src/device/service/Tools.py @@ -468,14 +468,26 @@ def get_edit_target (device:Device,is_opticalband:bool)-> str: else : if device.device_type =='optical-roadm': return 'media-channel' else : return 'optical-channel' - + +def is_key_existed( key:str ,keys_dic=dict,key_name_to_use= None | str ) -> dict: + dic={} + dic["resource_key"]=key + if key_name_to_use is not None: + dic["resource_key"]=key_name_to_use + if key in keys_dic : + dic["value"]=keys_dic[key] + else : + dic["value"]=None + return dic + def extract_resources (config:dict,device:Device)-> list : conditions={} resources=[] - resources.append({"resource_key":"channel_namespace","value":config["channel_namespace"] if "channel_namespace" in config else None}) - resources.append({"resource_key":'add_transceiver',"value":config['add_transceiver'] if 'add_transceiver' in config else None}) - resources.append({"resource_key":"interface","value":config["update_interface"] if 'update_interface' in config else None}) - is_opticalband=config['is_opticalband'] if 'is_opticalband' in config else False + resources.append(is_key_existed("channel_namespace",config)) + resources.append(is_key_existed("add_transceiver",config)) + is_opticalband=False + if ( 'is_opticalband' in config): + is_opticalband=config['is_opticalband'] conditions["is_opticalband"]=is_opticalband conditions["edit_type"]=get_edit_target(device=device,is_opticalband=is_opticalband) if ('flow' in config): @@ -501,16 +513,13 @@ def extract_resources (config:dict,device:Device)-> list : if ('new_config' in config): lower_frequency=None upper_frequency=None - resources.append({"resource_key":"target-output-power","value":config["new_config"]["target-output-power"] if "target-output-power" in config["new_config"] else None }) - #resources.append({"resource_key":"frequency","value":config["new_config"]["frequency"] if "frequency" in config else config["new_config"]["freqency"]}) - resources.append({"resource_key":"frequency","value":config["new_config"]["frequency"] if "frequency" in config["new_config"] else None}) - resources.append({"resource_key":"operational-mode","value":config["new_config"]["operational-mode"] if "operational-mode" in config["new_config"] else None}) - resources.append({"resource_key":"line-port","value":config["new_config"]["line-port"] if "line-port" in config["new_config"] else None}) - - resources.append({"resource_key":"name","value":config['new_config']['band_type'] if 'band_type' in config['new_config'] else None}) - resources.append({"resource_key":"optical-band-parent","value":config["new_config"]["ob_id"] if "ob_id" in config["new_config"] else None }) - resources.append({"resource_key":"channel_name","value":config["new_config"]["name"] if "name" in config["new_config"] else None}) - + resources.append(is_key_existed(key="target-output-power",keys_dic=config["new_config"])) + resources.append(is_key_existed(key="frequency",keys_dic=config["new_config"])) + resources.append(is_key_existed(key="operational-mode",keys_dic=config["new_config"])) + resources.append(is_key_existed(key="line-port",keys_dic=config["new_config"])) + resources.append(is_key_existed(key="band_type",keys_dic=config["new_config"],key_name_to_use='name')) + resources.append(is_key_existed("ob_id",config["new_config"],key_name_to_use='optical-band-parent')) + resources.append(is_key_existed(key="name",keys_dic=config["new_config"],key_name_to_use="channel_name")) if not is_opticalband : if 'frequency' in config['new_config'] and 'band' in config['new_config'] and conditions["edit_type"] == 'media-channel': lower_frequency= int(int(config['new_config']['frequency']) - (int(config['new_config']['band'])/2)) @@ -518,11 +527,14 @@ def extract_resources (config:dict,device:Device)-> list : #lower_frequency= (config['new_config']['frequency']- config['new_config']['band'])/2 #upper_frequency=(config['new_config']['frequency']+ config['new_config']['band'])/2 - resources.append({"resource_key":"index","value":config["new_config"]["flow_id"] if "flow_id" in config["new_config"] else None}) + + resources.append(is_key_existed(key="flow_id",keys_dic=config["new_config"],key_name_to_use="index")) + #resources.append({"resource_key":"index","value":config["new_config"]["flow_id"] if "flow_id" in config["new_config"] else None}) else : lower_frequency=config['new_config']['low-freq'] if "low-freq" in config['new_config'] else None upper_frequency=config['new_config']['up-freq'] if 'up-freq' in config['new_config'] else None - resources.append({"resource_key":"index","value":config["new_config"]["ob_id"] if "ob_id" in config["new_config"] else None}) + resources.append(is_key_existed(key="ob_id",keys_dic=config["new_config"],key_name_to_use="index")) + #resources.append({"resource_key":"index","value":config["new_config"]["ob_id"] if "ob_id" in config["new_config"] else None}) resources.append({"resource_key":"lower-frequency","value":lower_frequency}) resources.append({"resource_key":"upper-frequency","value":upper_frequency}) diff --git a/src/device/service/drivers/oc_driver/OCDriver.py b/src/device/service/drivers/oc_driver/OCDriver.py index 8467a8ceb..16f00cfb4 100644 --- a/src/device/service/drivers/oc_driver/OCDriver.py +++ b/src/device/service/drivers/oc_driver/OCDriver.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) +# 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. @@ -35,9 +35,9 @@ from .templates.VPN.physical import create_optical_channel,add_transceiver,crea from .RetryDecorator import retry from context.client.ContextClient import ContextClient from common.proto.context_pb2 import ( - MyConfig, + OpticalConfig, ConfigActionEnum, Device, DeviceDriverEnum, DeviceId, DeviceList, DeviceOperationalStatusEnum, Empty - ,MyConfigId,Uuid) + ,OpticalConfigId,Uuid) from .templates.Tools import extractor from .Tools import generate_uuid_from_numbers DEBUG_MODE = False @@ -242,7 +242,7 @@ class OCDriver(_Driver): chk_type('resources', resource_keys, list) results = [] - myConfig= MyConfig() + opticalConfig= OpticalConfig() j=0 with self.__lock: @@ -274,9 +274,9 @@ class OCDriver(_Driver): value_dic["channel_namespace"]=channel_namespace value_dic["endpoints"]=endpoints - myConfig.config=json.dumps(value_dic) - myConfig.myconfig_id.myconfig_uuid=self.__device_uuid if self.__device_uuid is not None else "" - config_id=context_client.SetMyConfig(myConfig) + opticalConfig.config=json.dumps(value_dic) + opticalConfig.opticalconfig_id.opticalconfig_uuid=self.__device_uuid if self.__device_uuid is not None else "" + config_id=context_client.SetOpticalConfig(opticalConfig) context_client.close() diff --git a/src/device/service/drivers/oc_driver/templates/Interfaces/interfaces.py b/src/device/service/drivers/oc_driver/templates/Interfaces/interfaces.py index 8d3049cfe..b4df7c2bf 100644 --- a/src/device/service/drivers/oc_driver/templates/Interfaces/interfaces.py +++ b/src/device/service/drivers/oc_driver/templates/Interfaces/interfaces.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) +# 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. diff --git a/src/device/service/drivers/oc_driver/templates/VPN/physical.py b/src/device/service/drivers/oc_driver/templates/VPN/physical.py index def67a9a8..355858d2d 100644 --- a/src/device/service/drivers/oc_driver/templates/VPN/physical.py +++ b/src/device/service/drivers/oc_driver/templates/VPN/physical.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) +# 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. diff --git a/src/opticalcontroller/OpticalController.py b/src/opticalcontroller/OpticalController.py index ceaa97ecf..e1b8c7aeb 100644 --- a/src/opticalcontroller/OpticalController.py +++ b/src/opticalcontroller/OpticalController.py @@ -1,3 +1,17 @@ +# 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. + from flask import Flask from flask import render_template from flask_restplus import Resource, Api diff --git a/src/opticalcontroller/RSA.py b/src/opticalcontroller/RSA.py index 919e5dfcf..138b5399c 100644 --- a/src/opticalcontroller/RSA.py +++ b/src/opticalcontroller/RSA.py @@ -1,20 +1,3 @@ -<<<<<<< HEAD -======= -# 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. - ->>>>>>> e19583176d771a8f8c1216d8a79488d0e50097c1 import dijsktra from tools import * from variables import * @@ -325,21 +308,14 @@ class RSA(): return fiber_list def get_link_by_name (self, key): -<<<<<<< HEAD result = None -======= ->>>>>>> e19583176d771a8f8c1216d8a79488d0e50097c1 for link in self.links_dict["links"]: if link["optical_link"]["name"] == key: if debug: print(link) -<<<<<<< HEAD result = link break return result -======= - return link ->>>>>>> e19583176d771a8f8c1216d8a79488d0e50097c1 def get_fiber_details(self, link_key, fiber_id): for link in self.links_dict["links"]: @@ -800,7 +776,6 @@ class RSA(): return self.flow_id, [] optical_band_id, temp_links = self.create_optical_band(links, path, bidir, num_slots_ob) return None, optical_band_id -<<<<<<< HEAD self.flow_id += 1 self.db_flows[self.flow_id] = {} self.db_flows[self.flow_id]["flow_id"] = self.flow_id @@ -808,8 +783,6 @@ class RSA(): self.db_flows[self.flow_id]["dst"] = dst self.db_flows[self.flow_id]["bitrate"] = rate self.db_flows[self.flow_id]["bidir"] = bidir -======= ->>>>>>> e19583176d771a8f8c1216d8a79488d0e50097c1 print("INFO: TP to TP connection") if band is None: temp_links2 = [] @@ -829,17 +802,7 @@ class RSA(): temp_path.append(roadm_dst) temp_path.append(t_dst) existing_ob = self.get_optical_bands(roadm_src, roadm_dst) -<<<<<<< HEAD -======= - self.flow_id += 1 - self.db_flows[self.flow_id] = {} - self.db_flows[self.flow_id]["flow_id"] = self.flow_id - self.db_flows[self.flow_id]["src"] = src - self.db_flows[self.flow_id]["dst"] = dst - self.db_flows[self.flow_id]["bitrate"] = rate - self.db_flows[self.flow_id]["bidir"] = bidir ->>>>>>> e19583176d771a8f8c1216d8a79488d0e50097c1 if len(existing_ob) > 0: print("INFO: Evaluating existing OB {}".format(existing_ob)) @@ -902,7 +865,6 @@ class RSA(): links, path = self.compute_path(src, dst) optical_band_id, temp_links = self.create_optical_band(links, path, bidir, num_slots_ob) op, num_slots = map_rate_to_slot(rate) -<<<<<<< HEAD # self.flow_id += 1 # self.db_flows[self.flow_id] = {} # self.db_flows[self.flow_id]["flow_id"] = self.flow_id @@ -910,15 +872,6 @@ class RSA(): # self.db_flows[self.flow_id]["dst"] = dst # self.db_flows[self.flow_id]["bitrate"] = rate # self.db_flows[self.flow_id]["bidir"] = bidir -======= - self.flow_id += 1 - self.db_flows[self.flow_id] = {} - self.db_flows[self.flow_id]["flow_id"] = self.flow_id - self.db_flows[self.flow_id]["src"] = src - self.db_flows[self.flow_id]["dst"] = dst - self.db_flows[self.flow_id]["bitrate"] = rate - self.db_flows[self.flow_id]["bidir"] = bidir ->>>>>>> e19583176d771a8f8c1216d8a79488d0e50097c1 if debug: print(temp_links) diff --git a/src/opticalcontroller/json_files/tfs copy.json b/src/opticalcontroller/json_files/tfs copy.json deleted file mode 100644 index a108ed13e..000000000 --- a/src/opticalcontroller/json_files/tfs copy.json +++ /dev/null @@ -1,1286 +0,0 @@ -{ - "links": [ - { - "link_id": { - "link_uuid": { - "uuid": "T1->R1" - } - }, - "link_endpoint_ids": [ - { - "device_id": { - "device_uuid": { - "uuid": "T1" - } - }, - "endpoint_uuid": { - "uuid": "1" - } - }, - { - "device_id": { - "device_uuid": { - "uuid": "R1" - } - }, - "endpoint_uuid": { - "uuid": "12" - } - } - ], - "optical_link": { - "name": "T1-R1", - "details": { - "length": 0, - "source": "muxT", - "target": "srgR", - "fibers": [ - { - "ID": "M1", - "length": 0, - "src_port": "1", - "dst_port": "2001", - "local_peer_port": "1", - "remote_peer_port": "1001", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - }, - { - "ID": "M2", - "length": 0, - "src_port": "2", - "dst_port": "2002", - "local_peer_port": "2", - "remote_peer_port": "1002", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - }, - { - "ID": "M3", - "length": 0, - "src_port": "3", - "dst_port": "2003", - "local_peer_port": "3", - "remote_peer_port": "1003", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - } - ] - } - } - }, - { - "link_id": { - "link_uuid": { - "uuid": "R1->T1" - } - }, - "link_endpoint_ids": [ - { - "device_id": { - "device_uuid": { - "uuid": "R1" - } - }, - "endpoint_uuid": { - "uuid": "2" - } - }, - { - "device_id": { - "device_uuid": { - "uuid": "T1" - } - }, - "endpoint_uuid": { - "uuid": "1" - } - } - ], - "optical_link": { - "name": "R1-T1", - "details": { - "length": 0, - "source": "srgT", - "target": "muxT", - "fibers": [ - { - "ID": "M1", - "length": 0, - "src_port": "1001", - "dst_port": "1", - "local_peer_port": "2001", - "remote_peer_port": "1", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - }, - { - "ID": "M2", - "length": 0, - "src_port": "1002", - "dst_port": "2", - "local_peer_port": "2002", - "remote_peer_port": "2", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - }, - { - "ID": "M3", - "length": 0, - "src_port": "1003", - "dst_port": "3", - "local_peer_port": "2003", - "remote_peer_port": "3", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - } - ] - } - } - }, - { - "link_id": { - "link_uuid": { - "uuid": "R1->R2" - } - }, - "link_endpoint_ids": [ - { - "device_id": { - "device_uuid": { - "uuid": "R1" - } - }, - "endpoint_uuid": { - "uuid": "13" - } - }, - { - "device_id": { - "device_uuid": { - "uuid": "R2" - } - }, - "endpoint_uuid": { - "uuid": "24" - } - } - ], - "optical_link": { - "name": "R1-R2", - "details": { - "length": 0, - "source": "D1", - "target": "D1", - "fibers": [ - { - "ID": "D11", - "length": 0, - "src_port": "13", - "dst_port": "24", - "local_peer_port": "23", - "remote_peer_port": "14", - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - } - ] - } - } - }, - { - "link_id": { - "link_uuid": { - "uuid": "R2->R1" - } - }, - "link_endpoint_ids": [ - { - "device_id": { - "device_uuid": { - "uuid": "R2" - } - }, - "endpoint_uuid": { - "uuid": "14" - } - }, - { - "device_id": { - "device_uuid": { - "uuid": "R1" - } - }, - "endpoint_uuid": { - "uuid": "23" - } - } - ], - "optical_link": { - "name": "R2-R1", - "details": { - "length": 0, - "source": "D1", - "target": "D1", - "fibers": [ - { - "ID": "D11", - "length": 0, - "src_port": "14", - "dst_port": "23", - "local_peer_port": "24", - "remote_peer_port": "13", - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - } - ] - } - } - }, - { - "link_id": { - "link_uuid": { - "uuid": "T2->R2" - } - }, - "link_endpoint_ids": [ - { - "device_id": { - "device_uuid": { - "uuid": "T2" - } - }, - "endpoint_uuid": { - "uuid": "1" - } - }, - { - "device_id": { - "device_uuid": { - "uuid": "R2" - } - }, - "endpoint_uuid": { - "uuid": "1001" - } - } - ], - "optical_link": { - "name": "T2-R2", - "details": { - "length": 0, - "source": "srgT", - "target": "muxT", - "fibers": [ - { - "ID": "M1", - "length": 0, - "src_port": "1", - "dst_port": "1001", - "local_peer_port": "1", - "remote_peer_port": "2001", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - }, - { - "ID": "M2", - "length": 0, - "src_port": "2", - "dst_port": "1002", - "local_peer_port": "2", - "remote_peer_port": "2002", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - }, - { - "ID": "M3", - "length": 0, - "src_port": "3", - "dst_port": "1003", - "local_peer_port": "3", - "remote_peer_port": "2003", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - } - ] - } - } - }, - { - "link_id": { - "link_uuid": { - "uuid": "R2->T2" - } - }, - "link_endpoint_ids": [ - { - "device_id": { - "device_uuid": { - "uuid": "R2" - } - }, - "endpoint_uuid": { - "uuid": "5" - } - }, - { - "device_id": { - "device_uuid": { - "uuid": "T2" - } - }, - "endpoint_uuid": { - "uuid": "6" - } - } - ], - "optical_link": { - "name": "R2-T2", - "details": { - "length": 0, - "source": "srgT", - "target": "muxT", - "fibers": [ - { - "ID": "M1", - "length": 0, - "src_port": "1001", - "dst_port": "1", - "local_peer_port": "2001", - "remote_peer_port": "1", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - }, - { - "ID": "M2", - "length": 0, - "src_port": "1002", - "dst_port": "2", - "local_peer_port": "2002", - "remote_peer_port": "2", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - }, - { - "ID": "M3", - "length": 0, - "src_port": "1003", - "dst_port": "3", - "local_peer_port": "2003", - "remote_peer_port": "3", - "used": false, - "c_slots": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "l_slots": [ - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120 - ], - "s_slots": [ - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520 - ] - } - ] - } - } - } - ] -} \ No newline at end of file diff --git a/src/opticalcontroller/tools.py b/src/opticalcontroller/tools.py index d91240d45..fc349b499 100644 --- a/src/opticalcontroller/tools.py +++ b/src/opticalcontroller/tools.py @@ -1,3 +1,19 @@ + +# 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. + + import numpy as np from variables import * import json diff --git a/src/opticalcontroller/variables.py b/src/opticalcontroller/variables.py index 32fe4bd8d..88e8ce513 100644 --- a/src/opticalcontroller/variables.py +++ b/src/opticalcontroller/variables.py @@ -1,3 +1,19 @@ + +# 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. + + debug = 1 Fl = 184800 diff --git a/src/service/service/__main__.py b/src/service/service/__main__.py index 52210c8ab..31dbbdbe6 100644 --- a/src/service/service/__main__.py +++ b/src/service/service/__main__.py @@ -48,10 +48,12 @@ def main(): ]) - variables= find_environment_variables([ - get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER,ENVVAR_SUFIX_SERVICE_HOST), - get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER,ENVVAR_SUFIX_SERVICE_PORT_GRPC), - ]) + + #Commented for merging with develop branch + # variables= find_environment_variables([ + # get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER,ENVVAR_SUFIX_SERVICE_HOST), + # get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER,ENVVAR_SUFIX_SERVICE_PORT_GRPC), + # ]) signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) diff --git a/src/service/service/service_handlers/oc/OCServiceHandler.py b/src/service/service/service_handlers/oc/OCServiceHandler.py index b2b0a86ee..87a9a0075 100644 --- a/src/service/service/service_handlers/oc/OCServiceHandler.py +++ b/src/service/service/service_handlers/oc/OCServiceHandler.py @@ -41,70 +41,6 @@ class OCServiceHandler(_ServiceHandler): - ''' - @metered_subclass_method(METRICS_POOL) - def SetEndpoint( - self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None - ) -> List[Union[bool, Exception]]: - - chk_type('endpoints', endpoints, list) - if len(endpoints) == 0: return [] - - service_uuid = self.__service.service_id.service_uuid.uuid - if self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid)): - settings = self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid)) - else: - settings = self.__settings_handler.get('/settings') - LOGGER.info("AAAAAAAAAAAAAAAAAAAA settings={}".format(settings)) - - settings = self.__settings_handler.get('/settings') - #new structure - #in, dev, out, topo(opt) - entries = List[Tuple[str, str, str Optional[str]]] - entry_tuple = device_uuid, endpoint_uuid, topology_uuid - entries.append(endpoint_id_tuple) - for i in range (1, len(endpoints)): - endpoint_x = endpoints[i] - dev_x = endpoint_x[0] - if_x = endpoint_x[1] - - - - - - results = [] - for endpoint in endpoints: - try: - device_uuid, endpoint_uuid = get_device_endpoint_uuids(endpoint) - - device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) - endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid) - endpoint_settings = self.__settings_handler.get_endpoint_settings(device_obj, endpoint_obj) - endpoint_name = endpoint_obj.name - - json_config_rules = setup_config_rules( - service_uuid, connection_uuid, device_uuid, endpoint_uuid, endpoint_name, - settings, endpoint_settings) - LOGGER.info("Start configuring device %s",settings) - if (settings): - self.__task_executor.configure_optical_device(device_obj,settings) - if len(json_config_rules) > 0: - LOGGER.info("Start configuring device") - del device_obj.device_config.config_rules[:] - for json_config_rule in json_config_rules: - device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule)) - self.__task_executor.configure_optical_device(device_obj) - #self.__task_executor.configure_device(device_obj) - - results.append(True) - except Exception as e: # pylint: disable=broad-except - LOGGER.exception('Unable to SetEndpoint({:s})'.format(str(endpoint))) - results.append(e) - - return results - ''' - - @metered_subclass_method(METRICS_POOL) def SetEndpoint( self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None @@ -138,12 +74,7 @@ class OCServiceHandler(_ServiceHandler): dev_flows = flows[device_uuid] device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) - ''' - #to be imported in the device handler - endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid) - endpoint_settings = self.__settings_handler.get_endpoint_settings(device_obj, endpoint_obj) - endpoint_name = endpoint_obj.name - ''' + if (settings): self.__task_executor.configure_optical_device(device_obj, settings, dev_flows, is_opticalband) @@ -151,39 +82,7 @@ class OCServiceHandler(_ServiceHandler): except Exception as e: # pylint: disable=broad-except LOGGER.exception('Unable to configure Device({:s})'.format(str(device_uuid))) results.append(e) - - ''' - for endpoint in endpoints: - try: - device_uuid, endpoint_uuid = get_device_endpoint_uuids(endpoint) - - device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) - endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid) - endpoint_settings = self.__settings_handler.get_endpoint_settings(device_obj, endpoint_obj) - endpoint_name = endpoint_obj.name - - # json_config_rules = setup_config_rules( - # service_uuid, connection_uuid, device_uuid, endpoint_uuid, endpoint_name, - # settings, endpoint_settings) - - if (settings): - LOGGER.debug("Andrea234 settings={}".format(settings)) - self.__task_executor.configure_optical_device(device_obj,settings,handled_flows,is_opticalband) - #we don't use config_rules - # if len(json_config_rules) > 0: - # LOGGER.debug("VBNMHGStart configuring device") - # del device_obj.device_config.config_rules[:] - # for json_config_rule in json_config_rules: - # device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule)) - # self.__task_executor.configure_optical_device(device_obj) - #self.__task_executor.configure_device(device_obj) - - results.append(True) - except Exception as e: # pylint: disable=broad-except - LOGGER.exception('Unable to SetEndpoint({:s})'.format(str(endpoint))) - results.append(e) - ''' - + return results @metered_subclass_method(METRICS_POOL) diff --git a/src/service/service/task_scheduler/TaskExecutor.py b/src/service/service/task_scheduler/TaskExecutor.py index 48449e4d9..487c61efe 100644 --- a/src/service/service/task_scheduler/TaskExecutor.py +++ b/src/service/service/task_scheduler/TaskExecutor.py @@ -16,7 +16,7 @@ import logging , json from enum import Enum from typing import TYPE_CHECKING, Any, Dict, Optional, Union from common.method_wrappers.ServiceExceptions import NotFoundException -from common.proto.context_pb2 import Connection, ConnectionId, Device, DeviceDriverEnum, DeviceId, Service, ServiceId,MyConfig,MyConfigId +from common.proto.context_pb2 import Connection, ConnectionId, Device, DeviceDriverEnum, DeviceId, Service, ServiceId,OpticalConfig,OpticalConfigId from common.tools.context_queries.Connection import get_connection_by_id from common.tools.context_queries.Device import get_device from common.tools.context_queries.Service import get_service_by_id @@ -108,7 +108,7 @@ class TaskExecutor: return device def configure_device(self, device : Device) -> None: - self._context_client.SelectMyConfig() + self._context_client.SelectOpticalConfig() device_key = get_device_key(device.device_id) self._device_client.ConfigureDevice(device) self._store_grpc_object(CacheableObjectType.DEVICE, device_key, device) @@ -118,15 +118,15 @@ class TaskExecutor: device_key = get_device_key(device.device_id) - myid=MyConfigId() - myid.myconfig_uuid=device.device_id.device_uuid.uuid - myConfig=MyConfig() + myid=OpticalConfigId() + myid.opticalconfig_uuid=device.device_id.device_uuid.uuid + opticalconfig=OpticalConfig() setting =settings.value if settings else "" new_config={} try: - result=self._context_client.SelectMyConfig(myid) + result=self._context_client.SelectOpticalConfig(myid) new_config=json.loads(result.config) @@ -136,45 +136,15 @@ class TaskExecutor: new_config["is_opticalband"]=is_opticalband new_config["flow"]=flows result.config = str(new_config) - myConfig.CopyFrom(result) + opticalconfig.CopyFrom(result) - self._device_client.ConfigureOpticalDevice(myConfig) + self._device_client.ConfigureOpticalDevice(opticalconfig) self._store_grpc_object(CacheableObjectType.DEVICE, device_key, device) except Exception as e: LOGGER.info("error in config my config %s",e) - ''' - # For Optical Devices - def configure_optical_device (self,device:Device,settings:str,flows:dict,is_opticalband:bool) : - - - device_key = get_device_key(device.device_id) - myid=MyConfigId() - myid.myconfig_uuid=device.device_id.device_uuid.uuid - myConfig=MyConfig() - setting =settings.value if settings else "" - - new_config={} - try: - result=self._context_client.SelectMyConfig(myid) - new_config=eval(result.config) - - if result is not None : - - new_config["new_config"]=setting - new_config["is_opticalband"]=is_opticalband - new_config["flow"]=flows - result.config = str(new_config) - myConfig.CopyFrom(result) - - self._device_client.ConfigureOpticalDevice(myConfig) - - self._store_grpc_object(CacheableObjectType.DEVICE, device_key, device) - except Exception as e: - LOGGER.debug("error in config my config %s",e) - ''' def get_device_controller(self, device : Device) -> Optional[Device]: -- GitLab From 849e3a0842941c8298192f7e9b8a7662d1a3f945 Mon Sep 17 00:00:00 2001 From: sgambelluri Date: Wed, 6 Mar 2024 15:38:17 +0000 Subject: [PATCH 03/13] bugs fixing --- deploy/tfs.sh | 2 +- src/context/service/ContextServiceServicerImpl.py | 8 ++++---- src/device/service/Tools.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/deploy/tfs.sh b/deploy/tfs.sh index 3a01606ce..19c0d75a0 100755 --- a/deploy/tfs.sh +++ b/deploy/tfs.sh @@ -364,7 +364,7 @@ for COMPONENT in $TFS_COMPONENTS; do echo "Waiting for '$COMPONENT' component..." COMPONENT_OBJNAME=$(echo "${COMPONENT}" | sed "s/\_/-/") kubectl wait --namespace $TFS_K8S_NAMESPACE \ - --for='condition=available' --timeout=300s deployment/${COMPONENT_OBJNAME}service + --for='condition=available' --timeout=90s deployment/${COMPONENT_OBJNAME}service printf "\n" done diff --git a/src/context/service/ContextServiceServicerImpl.py b/src/context/service/ContextServiceServicerImpl.py index 8b5a3f7bc..2cfe39b0c 100644 --- a/src/context/service/ContextServiceServicerImpl.py +++ b/src/context/service/ContextServiceServicerImpl.py @@ -44,7 +44,7 @@ from .database.Slice import ( slice_delete, slice_get, slice_list_ids, slice_list_objs, slice_select, slice_set, slice_unset) from .database.Topology import ( topology_delete, topology_get, topology_get_details, topology_list_ids, topology_list_objs, topology_set) -from .database.OpticalConfigOperator import (set_OpticalConfig,select_OpticalConfig,get_OpticalConfig) +from .database.OpticalConfig import (set_opticalconfig,select_opticalconfig,get_opticalconfig) LOGGER = logging.getLogger(__name__) @@ -302,16 +302,16 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer @safe_and_metered_rpc_method(METRICS_POOL,LOGGER) def GetOpticalConfig(self,request:Empty,context:grpc.ServicerContext) -> OpticalConfigList: - result =get_OpticalConfig(db_engine=self.db_engine) + result =get_opticalconfig(db_engine=self.db_engine) return OpticalConfigList(OpticalConfigs=result) def SetOpticalConfig(self,request:OpticalConfig,context:grpc.ServicerContext)-> OpticalConfigId: - OpticalConfig_id= set_OpticalConfig(db_engine=self.db_engine,request=request) + OpticalConfig_id= set_opticalconfig(db_engine=self.db_engine,request=request) return OpticalConfigId(**OpticalConfig_id) def SelectOpticalConfig (self,request:OpticalConfigId,context:grpc.ServicerContext) -> OpticalConfig: - result =select_OpticalConfig(db_engine=self.db_engine,request=request) + result =select_opticalconfig(db_engine=self.db_engine,request=request) logging.info(f"FromSelectOpticalConfig {result}") myid =OpticalConfigId() myid.CopyFrom(result.OpticalConfig_id) diff --git a/src/device/service/Tools.py b/src/device/service/Tools.py index 04fb54be5..35c542854 100644 --- a/src/device/service/Tools.py +++ b/src/device/service/Tools.py @@ -469,7 +469,7 @@ def get_edit_target (device:Device,is_opticalband:bool)-> str: if device.device_type =='optical-roadm': return 'media-channel' else : return 'optical-channel' -def is_key_existed( key:str ,keys_dic=dict,key_name_to_use= None | str ) -> dict: +def is_key_existed( key:str ,keys_dic=dict,key_name_to_use= None ) -> dict: dic={} dic["resource_key"]=key if key_name_to_use is not None: -- GitLab From 34f9f95ab56bc0c4fe750eff764a48a4097364c7 Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Wed, 6 Mar 2024 16:30:35 +0000 Subject: [PATCH 04/13] Optical component: - Pre-merge cleanup --- deploy/tfs.sh | 2 +- manifests/opticalcontrollerservice.yaml | 61 +++++++++++++-------- ofc24/startExtraNetConfigAgent.sh | 25 --------- src/common/Constants.py | 3 +- src/opticalcontroller/OpticalController.py | 3 +- src/tests/ofc24/startExtraNetConfigAgent.sh | 34 ++++++++++++ {ofc24 => src/tests/ofc24}/start_topo.sh | 16 +++++- 7 files changed, 91 insertions(+), 53 deletions(-) delete mode 100755 ofc24/startExtraNetConfigAgent.sh create mode 100755 src/tests/ofc24/startExtraNetConfigAgent.sh rename {ofc24 => src/tests/ofc24}/start_topo.sh (50%) diff --git a/deploy/tfs.sh b/deploy/tfs.sh index 19c0d75a0..3a01606ce 100755 --- a/deploy/tfs.sh +++ b/deploy/tfs.sh @@ -364,7 +364,7 @@ for COMPONENT in $TFS_COMPONENTS; do echo "Waiting for '$COMPONENT' component..." COMPONENT_OBJNAME=$(echo "${COMPONENT}" | sed "s/\_/-/") kubectl wait --namespace $TFS_K8S_NAMESPACE \ - --for='condition=available' --timeout=90s deployment/${COMPONENT_OBJNAME}service + --for='condition=available' --timeout=300s deployment/${COMPONENT_OBJNAME}service printf "\n" done diff --git a/manifests/opticalcontrollerservice.yaml b/manifests/opticalcontrollerservice.yaml index db760c23e..fcf1be742 100644 --- a/manifests/opticalcontrollerservice.yaml +++ b/manifests/opticalcontrollerservice.yaml @@ -1,3 +1,17 @@ +# 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. + apiVersion: apps/v1 kind: Deployment metadata: @@ -9,36 +23,39 @@ spec: replicas: 1 template: metadata: - labels: app: opticalcontrollerservice spec: terminationGracePeriodSeconds: 5 containers: - - name: server - image: localhost:32000/tfs/opticalcontroller:dev - imagePullPolicy: Never - ports: - - containerPort: 5022 - - containerPort: 9192 - - env: - - name: LOG_LEVEL - value: "INFO" - - resources: - requests: - cpu: 500m - memory: 128Mi - limits: - cpu: 1000m - memory: 1024Mi + - name: server + image: localhost:32000/tfs/opticalcontroller:dev + imagePullPolicy: Never + ports: + - containerPort: 10060 + - containerPort: 9192 + env: + - name: LOG_LEVEL + value: "INFO" + readinessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:10060"] + livenessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:10060"] + resources: + requests: + cpu: 500m + memory: 128Mi + limits: + cpu: 1000m + memory: 1024Mi --- apiVersion: v1 kind: Service metadata: name: opticalcontrollerservice - labels: + labels: app: opticalcontrollerservice spec: type: ClusterIP @@ -47,8 +64,8 @@ spec: ports: - name: grpc protocol: TCP - port: 5022 - targetPort: 5022 + port: 10060 + targetPort: 10060 - name: metrics protocol: TCP port: 9192 diff --git a/ofc24/startExtraNetConfigAgent.sh b/ofc24/startExtraNetConfigAgent.sh deleted file mode 100755 index 79efe3773..000000000 --- a/ofc24/startExtraNetConfigAgent.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -Docker_Container=$1 -Docker_Port=$2 -if [ -n "$Docker_Container" ] && [ -n "$Docker_Port" ];then - sudo docker stop "$Docker_Container" -t 1 - - sudo docker rm "$Docker_Container" - - - echo "Creating TPs" - screen -dmS t1 -T xterm sh -c "docker run -p 10.0.2.15:"$Docker_Port":2022 -v ~/tfs-ctrl/tempOC/files:/files --name $Docker_Container -it asgamb1/oc23bgp.img:latest" - sleep 2 - if [ "$( docker container inspect -f '{{.State.Running}}' "$Docker_Container")" = "true" ]; then - - docker exec "$Docker_Container" cp /files/demoECOC21_4.xml demoECOC21.xml - - docker exec "$Docker_Container" /confd/examples.confd/OC23/startNetconfAgent.sh - else - echo "your container is not running yet" - fi -else - echo "Please define the docker container name and port" -fi - diff --git a/src/common/Constants.py b/src/common/Constants.py index 0a36c6ac5..a1913a951 100644 --- a/src/common/Constants.py +++ b/src/common/Constants.py @@ -59,7 +59,7 @@ class ServiceNameEnum(Enum): TE = 'te' FORECASTER = 'forecaster' E2EORCHESTRATOR = 'e2eorchestrator' - OPTICALCONTROLLER = 'opticalcontroller' + OPTICALCONTROLLER = 'opticalcontroller' BGPLS = 'bgpls-speaker' # Used for test and debugging only @@ -88,6 +88,7 @@ DEFAULT_SERVICE_GRPC_PORTS = { ServiceNameEnum.TE .value : 10030, ServiceNameEnum.FORECASTER .value : 10040, ServiceNameEnum.E2EORCHESTRATOR .value : 10050, + ServiceNameEnum.OPTICALCONTROLLER .value : 10060, ServiceNameEnum.BGPLS .value : 20030, # Used for test and debugging only diff --git a/src/opticalcontroller/OpticalController.py b/src/opticalcontroller/OpticalController.py index e1b8c7aeb..0d571a9bd 100644 --- a/src/opticalcontroller/OpticalController.py +++ b/src/opticalcontroller/OpticalController.py @@ -241,6 +241,5 @@ if __name__ == '__main__': #topologies,links= getTopology() #print ("topologies{} and devices {}".format(topologies,links)) rsa = RSA(nodes_dict, links_dict) - - app.run(host='0.0.0.0', port=5022,debug=True) + app.run(host='0.0.0.0', port=10060,debug=True) diff --git a/src/tests/ofc24/startExtraNetConfigAgent.sh b/src/tests/ofc24/startExtraNetConfigAgent.sh new file mode 100755 index 000000000..d9428585e --- /dev/null +++ b/src/tests/ofc24/startExtraNetConfigAgent.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# 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. + +DOCKER_CONTAINER=$1 +DOCKER_PORT=$2 + +if [ -n "$DOCKER_CONTAINER" ] && [ -n "$DOCKER_PORT" ];then + sudo docker stop "$DOCKER_CONTAINER" -t 1 + sudo docker rm "$DOCKER_CONTAINER" + + echo "Creating TPs" + screen -dmS t1 -T xterm sh -c "docker run -p 10.0.2.15:"$DOCKER_PORT":2022 -v ~/tfs-ctrl/tempOC/files:/files --name $DOCKER_CONTAINER -it asgamb1/oc23bgp.img:latest" + sleep 2 + if [ "$( docker container inspect -f '{{.State.Running}}' "$DOCKER_CONTAINER")" = "true" ]; then + docker exec "$DOCKER_CONTAINER" cp /files/demoECOC21_4.xml demoECOC21.xml + docker exec "$DOCKER_CONTAINER" /confd/examples.confd/OC23/startNetconfAgent.sh + else + echo "your container is not running yet" + fi +else + echo "Please define the docker container name and port" +fi diff --git a/ofc24/start_topo.sh b/src/tests/ofc24/start_topo.sh similarity index 50% rename from ofc24/start_topo.sh rename to src/tests/ofc24/start_topo.sh index 574d0c1d5..4259842c9 100755 --- a/ofc24/start_topo.sh +++ b/src/tests/ofc24/start_topo.sh @@ -1,5 +1,17 @@ #!/bin/bash -asgamb1/flexscale-node.imgasgamb1/flexscale-node.imgasgamb1/flexscale-node.imgasgamb1/flexscale-node.img#!/bin/bash +# 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. sudo docker stop na1 -t 1 sudo docker stop na2 -t 1 @@ -20,4 +32,4 @@ source "./startExtraNetConfigAgent.sh" "na2" "2024" sleep 3 screen -dmS t3 -T xterm sh -c 'docker run -p 10.0.2.15:2025:2022 -v ~/tfs-ctrl/tempOC/files:/files --name na3 -it asgamb1/flexscale-node.img:latest ./startNetconfAgent.sh' -screen -dmS t4 -T xterm sh -c 'docker run -p 10.0.2.15:2026:2022 -v ~/tfs-ctrl/tempOC/files:/files --name na4 -it asgamb1/flexscale-node.img:latest ./startNetconfAgent.sh' \ No newline at end of file +screen -dmS t4 -T xterm sh -c 'docker run -p 10.0.2.15:2026:2022 -v ~/tfs-ctrl/tempOC/files:/files --name na4 -it asgamb1/flexscale-node.img:latest ./startNetconfAgent.sh' -- GitLab From d80836192e24928ebdf0f1d0ccf8689c9ca62fc4 Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Wed, 6 Mar 2024 16:39:54 +0000 Subject: [PATCH 05/13] Optical component: - Pre-merge cleanup --- ofc24 | 1 + proto/context.proto | 72 +++++++++++++------------- proto/openconfig_device.proto | 6 +-- scripts/show_logs_opticalcontroller.sh | 2 +- src/common/DeviceTypes.py | 1 - src/common/Settings.py | 2 - src/common/tools/descriptor/Loader.py | 1 - src/common/tools/descriptor/Tools.py | 7 +-- 8 files changed, 42 insertions(+), 50 deletions(-) create mode 120000 ofc24 diff --git a/ofc24 b/ofc24 new file mode 120000 index 000000000..baae92c8e --- /dev/null +++ b/ofc24 @@ -0,0 +1 @@ +src/tests/ofc24/ \ No newline at end of file diff --git a/proto/context.proto b/proto/context.proto index 73c478865..a734b3a96 100644 --- a/proto/context.proto +++ b/proto/context.proto @@ -76,14 +76,14 @@ service ContextService { rpc GetConnectionEvents(Empty ) returns (stream ConnectionEvent ) {} -// ------------------------------ Experimental------------------------------ - rpc GetOpticalConfig (Empty ) returns ( OpticalConfigList ) {} - rpc SetOpticalConfig (OpticalConfig) returns (OpticalConfigId) {} - rpc SelectOpticalConfig (OpticalConfigId) returns (OpticalConfig) {} + // ------------------------------ 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) {} + rpc SetOpticalLink (OpticalLink ) returns (Empty ) {} + rpc GetOpticalLink (OpticalLinkId ) returns (OpticalLink ) {} + rpc GetFiber (FiberId ) returns (Fiber ) {} } // ----- Generic ------------------------------------------------------------------------------------------------------- @@ -211,11 +211,9 @@ enum DeviceDriverEnum { DEVICEDRIVER_XR = 6; DEVICEDRIVER_IETF_L2VPN = 7; DEVICEDRIVER_GNMI_OPENCONFIG = 8; - DEVICEDRIVER_IETF_ACTN=9; - DEVICEDRIVER_FLEXSCALE=10; + DEVICEDRIVER_IETF_ACTN = 9; + DEVICEDRIVER_FLEXSCALE = 10; DEVICEDRIVER_OC = 11; - - } enum DeviceOperationalStatusEnum { @@ -301,7 +299,7 @@ enum ServiceTypeEnum { SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3; SERVICETYPE_TE = 4; SERVICETYPE_E2E = 5; -SERVICETYPE_OPTICAL_CONNECTIVITY = 6; + SERVICETYPE_OPTICAL_CONNECTIVITY = 6; } enum ServiceStatusEnum { @@ -629,16 +627,19 @@ message AuthenticationResult { // ---------------- Experimental ------------------------ message OpticalConfigId { - string opticalconfig_uuid= 1; + string opticalconfig_uuid = 1; } message OpticalConfig { - OpticalConfigId opticalconfig_id=1; - string config =2 ; + OpticalConfigId opticalconfig_id = 1; + string config = 2; } + message OpticalConfigList { - repeated OpticalConfig opticalconfigs =1 ; + repeated OpticalConfig opticalconfigs = 1; } -//----Optical Link ---- + +// ---- Optical Link ---- + message OpticalLinkId { Uuid optical_link_uuid = 1; } @@ -646,29 +647,30 @@ message OpticalLinkId { 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; + 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; + float length = 1; + string source = 2; + string target = 3; + repeated Fiber fibers = 4; } message OpticalLink { - OpticalLinkId optical_link_uuid=3; - string name=1; - OpticalLinkDetails details=2; + string name = 1; + OpticalLinkDetails details = 2; + OpticalLinkId optical_link_uuid = 3; } diff --git a/proto/openconfig_device.proto b/proto/openconfig_device.proto index 8a0a97df2..c622c77e4 100644 --- a/proto/openconfig_device.proto +++ b/proto/openconfig_device.proto @@ -19,8 +19,6 @@ import "context.proto"; import "monitoring.proto"; service OpenConfigService { - rpc AddOpenConfigDevice (context.OpticalConfig ) returns (context.OpticalConfigId ) {} - - rpc ConfigureOpticalDevice (context.OpticalConfig) returns (context.Empty) {} - + rpc AddOpenConfigDevice (context.OpticalConfig) returns (context.OpticalConfigId) {} + rpc ConfigureOpticalDevice(context.OpticalConfig) returns (context.Empty ) {} } diff --git a/scripts/show_logs_opticalcontroller.sh b/scripts/show_logs_opticalcontroller.sh index a4778c308..17af5483c 100755 --- a/scripts/show_logs_opticalcontroller.sh +++ b/scripts/show_logs_opticalcontroller.sh @@ -24,4 +24,4 @@ export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} # Automated steps start here ######################################################################################################################## -kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/opticalcontrollerservice -c server > logs/opticalcontroller.log +kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/opticalcontrollerservice -c server diff --git a/src/common/DeviceTypes.py b/src/common/DeviceTypes.py index f4ade564b..72b3e21fd 100644 --- a/src/common/DeviceTypes.py +++ b/src/common/DeviceTypes.py @@ -47,7 +47,6 @@ class DeviceTypeEnum(Enum): PACKET_ROUTER = 'packet-router' PACKET_SWITCH = 'packet-switch' XR_CONSTELLATION = 'xr-constellation' - # ETSI TeraFlowSDN controller TERAFLOWSDN_CONTROLLER = 'teraflowsdn' diff --git a/src/common/Settings.py b/src/common/Settings.py index fc503ea2d..5d6fba2fd 100644 --- a/src/common/Settings.py +++ b/src/common/Settings.py @@ -37,8 +37,6 @@ ENVVAR_SUFIX_SERVICE_HOST = 'SERVICE_HOST' ENVVAR_SUFIX_SERVICE_PORT_GRPC = 'SERVICE_PORT_GRPC' ENVVAR_SUFIX_SERVICE_PORT_HTTP = 'SERVICE_PORT_HTTP' - - def find_environment_variables( environment_variable_names : List[str] = [] ) -> Dict[str, str]: diff --git a/src/common/tools/descriptor/Loader.py b/src/common/tools/descriptor/Loader.py index eef41bbd8..4ab33beae 100644 --- a/src/common/tools/descriptor/Loader.py +++ b/src/common/tools/descriptor/Loader.py @@ -262,7 +262,6 @@ class DescriptorLoader: # Device, Service and Slice require to first create the entity and the configure it self.__devices_add, self.__devices_config = split_devices_by_rules(self.__devices) - self.__services_add = get_descriptors_add_services(self.__services) self.__slices_add = get_descriptors_add_slices(self.__slices) diff --git a/src/common/tools/descriptor/Tools.py b/src/common/tools/descriptor/Tools.py index a4792436a..e95fc7560 100644 --- a/src/common/tools/descriptor/Tools.py +++ b/src/common/tools/descriptor/Tools.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import copy, json,logging +import copy, json from typing import Dict, List, Optional, Tuple, Union from common.DeviceTypes import DeviceTypeEnum from common.proto.context_pb2 import DeviceDriverEnum @@ -67,8 +67,6 @@ def format_device_custom_config_rules(device : Dict) -> Dict: config_rules = device.get('device_config', {}).get('config_rules', []) config_rules = format_custom_config_rules(config_rules) device['device_config']['config_rules'] = config_rules - - return device def format_service_custom_config_rules(service : Dict) -> Dict: @@ -86,9 +84,7 @@ def format_slice_custom_config_rules(slice_ : Dict) -> Dict: def split_devices_by_rules(devices : List[Dict]) -> Tuple[List[Dict], List[Dict]]: devices_add = [] devices_config = [] - for device in devices: - connect_rules = [] config_rules = [] for config_rule in device.get('device_config', {}).get('config_rules', []): @@ -108,7 +104,6 @@ def split_devices_by_rules(devices : List[Dict]) -> Tuple[List[Dict], List[Dict] if len(config_rules) > 0: device['device_config'] = {'config_rules': config_rules} devices_config.append(device) - return devices_add, devices_config -- GitLab From 4ec7cd1ce34f19e3d2a62380e9f704fe078d61fe Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Wed, 6 Mar 2024 17:07:35 +0000 Subject: [PATCH 06/13] Optical component: - Pre-merge cleanup --- src/context/client/ContextClient.py | 27 ++-- .../service/ContextServiceServicerImpl.py | 38 ++--- src/context/service/database/ConfigModel.py | 125 ----------------- src/context/service/database/Device.py | 13 +- src/context/service/database/OpticalConfig.py | 131 ++++++------------ src/context/service/database/Service.py | 11 +- .../database/models/OpticalConfigModel.py | 53 +++---- 7 files changed, 114 insertions(+), 284 deletions(-) delete mode 100644 src/context/service/database/ConfigModel.py diff --git a/src/context/client/ContextClient.py b/src/context/client/ContextClient.py index 96a2f3f8d..48a635ccc 100644 --- a/src/context/client/ContextClient.py +++ b/src/context/client/ContextClient.py @@ -27,7 +27,8 @@ from common.proto.context_pb2 import ( Service, ServiceEvent, ServiceFilter, ServiceId, ServiceIdList, ServiceList, Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList, Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList, - OpticalConfig,OpticalConfigId,OpticalConfigList) + OpticalConfig, OpticalConfigId, OpticalConfigList +) from common.proto.context_pb2_grpc import ContextServiceStub from common.proto.context_policy_pb2_grpc import ContextPolicyServiceStub from common.proto.policy_pb2 import PolicyRuleIdList, PolicyRuleId, PolicyRuleList, PolicyRule @@ -437,24 +438,26 @@ class ContextClient: response = self.policy_stub.RemovePolicyRule(request) LOGGER.debug('RemovePolicyRule result: {:s}'.format(grpc_message_to_json_string(response))) return response - #//////////////// Experimental ////////////////// + + #//////////////// Experimental ////////////////// + @RETRY_DECORATOR - def SetOpticalConfig (self,request:OpticalConfig) ->OpticalConfigId: - LOGGER.debug('SettingOpticalConfig request: {:s}'.format(grpc_message_to_json_string(request))) + def SetOpticalConfig(self, request : OpticalConfig) -> OpticalConfigId: + LOGGER.debug('SetOpticalConfig request: {:s}'.format(grpc_message_to_json_string(request))) response = self.stub.SetOpticalConfig(request) - LOGGER.debug('SettingOpticalConfig result: {:s}'.format(grpc_message_to_json_string(response))) + LOGGER.debug('SetOpticalConfig result: {:s}'.format(grpc_message_to_json_string(response))) return response - + @RETRY_DECORATOR - def GetOpticalConfig (self,request:Empty) ->OpticalConfigList: - LOGGER.debug('GettingOpticalConfig request: {:s}'.format(grpc_message_to_json_string(request))) + def GetOpticalConfig(self, request : Empty) -> OpticalConfigList: + LOGGER.debug('GetOpticalConfig request: {:s}'.format(grpc_message_to_json_string(request))) response = self.stub.GetOpticalConfig(request) LOGGER.debug('GetOpticalConfig result: {:s}'.format(grpc_message_to_json_string(response))) return response - + @RETRY_DECORATOR - def SelectOpticalConfig (self,request:OpticalConfigId) ->OpticalConfigList: - LOGGER.debug('Selecting request: {:s}'.format(grpc_message_to_json_string(request))) + def SelectOpticalConfig(self,request : OpticalConfigId) -> OpticalConfigList: + LOGGER.debug('SelectOpticalConfig request: {:s}'.format(grpc_message_to_json_string(request))) response = self.stub.SelectOpticalConfig(request) - LOGGER.debug('GetOpticalConfig result: {:s}'.format(grpc_message_to_json_string(response))) + LOGGER.debug('SelectOpticalConfig result: {:s}'.format(grpc_message_to_json_string(response))) return response diff --git a/src/context/service/ContextServiceServicerImpl.py b/src/context/service/ContextServiceServicerImpl.py index 2cfe39b0c..de6b02a56 100644 --- a/src/context/service/ContextServiceServicerImpl.py +++ b/src/context/service/ContextServiceServicerImpl.py @@ -24,7 +24,8 @@ from common.proto.context_pb2 import ( Service, ServiceEvent, ServiceFilter, ServiceId, ServiceIdList, ServiceList, Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList, Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList, - OpticalConfigList,OpticalConfigId,OpticalConfig) + OpticalConfigList, OpticalConfigId, OpticalConfig +) from common.proto.policy_pb2 import PolicyRuleIdList, PolicyRuleId, PolicyRuleList, PolicyRule from common.proto.context_pb2_grpc import ContextServiceServicer from common.proto.context_policy_pb2_grpc import ContextPolicyServiceServicer @@ -298,21 +299,22 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RemovePolicyRule(self, request : PolicyRuleId, context: grpc.ServicerContext) -> Empty: return policyrule_delete(self.db_engine, self.messagebroker, request) - # ---------------------------- Experimental ------------------- - @safe_and_metered_rpc_method(METRICS_POOL,LOGGER) - def GetOpticalConfig(self,request:Empty,context:grpc.ServicerContext) -> OpticalConfigList: - - result =get_opticalconfig(db_engine=self.db_engine) - + + # ---------------------------- Experimental ------------------- + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def GetOpticalConfig(self, request : Empty, context : grpc.ServicerContext) -> OpticalConfigList: + result = get_opticalconfig(self.db_engine) return OpticalConfigList(OpticalConfigs=result) - def SetOpticalConfig(self,request:OpticalConfig,context:grpc.ServicerContext)-> OpticalConfigId: - - OpticalConfig_id= set_opticalconfig(db_engine=self.db_engine,request=request) - - return OpticalConfigId(**OpticalConfig_id) - def SelectOpticalConfig (self,request:OpticalConfigId,context:grpc.ServicerContext) -> OpticalConfig: - result =select_opticalconfig(db_engine=self.db_engine,request=request) - logging.info(f"FromSelectOpticalConfig {result}") - myid =OpticalConfigId() - myid.CopyFrom(result.OpticalConfig_id) - return OpticalConfig(config=result.config,OpticalConfig_id=myid) + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def SetOpticalConfig(self, request : OpticalConfig, context : grpc.ServicerContext) -> OpticalConfigId: + result = set_opticalconfig(self.db_engine, request) + return OpticalConfigId(**result) + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def SelectOpticalConfig(self, request : OpticalConfigId, context : grpc.ServicerContext) -> OpticalConfig: + result = select_opticalconfig(self.db_engine, request) + optical_config_id = OpticalConfigId() + optical_config_id.CopyFrom(result.OpticalConfig_id) + return OpticalConfig(config=result.config, OpticalConfig_id=optical_config_id) diff --git a/src/context/service/database/ConfigModel.py b/src/context/service/database/ConfigModel.py deleted file mode 100644 index 94519dcec..000000000 --- a/src/context/service/database/ConfigModel.py +++ /dev/null @@ -1,125 +0,0 @@ -# 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. -# Todo check if the file is in use by the TFS -import functools, logging, operator -from enum import Enum -from typing import Dict, List, Optional, Tuple, Union -from common.orm.Database import Database -from common.orm.HighLevel import get_object, get_or_create_object, update_or_create_object -from common.orm.backend.Tools import key_to_str -from common.orm.fields.EnumeratedField import EnumeratedField -from common.orm.fields.ForeignKeyField import ForeignKeyField -from common.orm.fields.IntegerField import IntegerField -from common.orm.fields.PrimaryKeyField import PrimaryKeyField -from common.orm.fields.StringField import StringField -from common.orm.model.Model import Model -from context.proto.context_pb2 import ConfigActionEnum -from .Tools import fast_hasher, grpc_to_enum, remove_dict_key - -LOGGER = logging.getLogger(__name__) - -class ORM_ConfigActionEnum(Enum): - UNDEFINED = ConfigActionEnum.CONFIGACTION_UNDEFINED - SET = ConfigActionEnum.CONFIGACTION_SET - DELETE = ConfigActionEnum.CONFIGACTION_DELETE - -grpc_to_enum__config_action = functools.partial( - grpc_to_enum, ConfigActionEnum, ORM_ConfigActionEnum) - -class ConfigModel(Model): # pylint: disable=abstract-method - pk = PrimaryKeyField() - - def dump(self) -> List[Dict]: - db_config_rule_pks = self.references(ConfigRuleModel) - config_rules = [ConfigRuleModel(self.database, pk).dump(include_position=True) for pk,_ in db_config_rule_pks] - config_rules = sorted(config_rules, key=operator.itemgetter('position')) - return [remove_dict_key(config_rule, 'position') for config_rule in config_rules] - -class ConfigRuleModel(Model): # pylint: disable=abstract-method - pk = PrimaryKeyField() - config_fk = ForeignKeyField(ConfigModel) - position = IntegerField(min_value=0, required=True) - action = EnumeratedField(ORM_ConfigActionEnum, required=True) - key = StringField(required=True, allow_empty=False) - value = StringField(required=True, allow_empty=False) - - def dump(self, include_position=True) -> Dict: # pylint: disable=arguments-differ - result = { - 'action': self.action.value, - 'resource_key': self.key, - 'resource_value': self.value, - } - if include_position: result['position'] = self.position - return result - -def set_config_rule( - database : Database, db_config : ConfigModel, position : int, resource_key : str, resource_value : str - ) -> Tuple[ConfigRuleModel, bool]: - - str_rule_key_hash = fast_hasher(resource_key) - str_config_rule_key = key_to_str([db_config.pk, str_rule_key_hash], separator=':') - result : Tuple[ConfigRuleModel, bool] = update_or_create_object(database, ConfigRuleModel, str_config_rule_key, { - 'config_fk': db_config, 'position': position, 'action': ORM_ConfigActionEnum.SET, - 'key': resource_key, 'value': resource_value}) - db_config_rule, updated = result - return db_config_rule, updated - -def delete_config_rule( - database : Database, db_config : ConfigModel, resource_key : str - ) -> None: - - str_rule_key_hash = fast_hasher(resource_key) - str_config_rule_key = key_to_str([db_config.pk, str_rule_key_hash], separator=':') - db_config_rule : Optional[ConfigRuleModel] = get_object( - database, ConfigRuleModel, str_config_rule_key, raise_if_not_found=False) - if db_config_rule is None: return - db_config_rule.delete() - -def delete_all_config_rules( - database : Database, db_config : ConfigModel - ) -> None: - - db_config_rule_pks = db_config.references(ConfigRuleModel) - for pk,_ in db_config_rule_pks: ConfigRuleModel(database, pk).delete() - -def grpc_config_rules_to_raw(grpc_config_rules) -> List[Tuple[ORM_ConfigActionEnum, str, str]]: - def translate(grpc_config_rule): - action = grpc_to_enum__config_action(grpc_config_rule.action) - return action, grpc_config_rule.resource_key, grpc_config_rule.resource_value - return [translate(grpc_config_rule) for grpc_config_rule in grpc_config_rules] - -def update_config( - database : Database, db_parent_pk : str, config_name : str, - raw_config_rules : List[Tuple[ORM_ConfigActionEnum, str, str]] - ) -> List[Tuple[Union[ConfigModel, ConfigRuleModel], bool]]: - - str_config_key = key_to_str([db_parent_pk, config_name], separator=':') - result : Tuple[ConfigModel, bool] = get_or_create_object(database, ConfigModel, str_config_key) - db_config, created = result - - db_objects : List[Tuple[Union[ConfigModel, ConfigRuleModel], bool]] = [(db_config, created)] - - for position,(action, resource_key, resource_value) in enumerate(raw_config_rules): - if action == ORM_ConfigActionEnum.SET: - result : Tuple[ConfigRuleModel, bool] = set_config_rule( - database, db_config, position, resource_key, resource_value) - db_config_rule, updated = result - db_objects.append((db_config_rule, updated)) - elif action == ORM_ConfigActionEnum.DELETE: - delete_config_rule(database, db_config, resource_key) - else: - msg = 'Unsupported action({:s}) for resource_key({:s})/resource_value({:s})' - raise AttributeError(msg.format(str(ConfigActionEnum.Name(action)), str(resource_key), str(resource_value))) - - return db_objects diff --git a/src/context/service/database/Device.py b/src/context/service/database/Device.py index 76eac944e..737ad7add 100644 --- a/src/context/service/database/Device.py +++ b/src/context/service/database/Device.py @@ -21,8 +21,9 @@ from typing import Dict, List, Optional, Set, Tuple from common.method_wrappers.ServiceExceptions import InvalidArgumentException, NotFoundException from common.message_broker.MessageBroker import MessageBroker from common.proto.context_pb2 import ( - Device, DeviceFilter, DeviceId, DeviceIdList - , DeviceList, Empty, EventTypeEnum, TopologyId,DeviceDriverEnum) + Device, DeviceDriverEnum, DeviceFilter, DeviceId, DeviceIdList, DeviceList, + Empty, EventTypeEnum, TopologyId +) from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.object_factory.Device import json_device_id from context.service.database.uuids.Topology import topology_get_uuid @@ -77,7 +78,6 @@ def device_get(db_engine : Engine, request : DeviceId) -> Device: return Device(**obj) def device_set(db_engine : Engine, messagebroker : MessageBroker, request : Device) -> DeviceId: - raw_device_uuid = request.device_id.device_uuid.uuid raw_device_name = request.name device_name = raw_device_uuid if len(raw_device_name) == 0 else raw_device_name @@ -89,7 +89,6 @@ def device_set(db_engine : Engine, messagebroker : MessageBroker, request : Devi controller_uuid = None device_type = request.device_type - oper_status = grpc_to_enum__device_operational_status(request.device_operational_status) device_drivers = [grpc_to_enum__device_driver(d) for d in request.device_drivers] @@ -97,7 +96,7 @@ def device_set(db_engine : Engine, messagebroker : MessageBroker, request : Devi topology_uuids : Set[str] = set() related_topologies : List[Dict] = list() - + # By default, always add device to default Context/Topology _,topology_uuid = topology_get_uuid(TopologyId(), allow_random=False, allow_default=True) related_topologies.append({ @@ -106,10 +105,8 @@ def device_set(db_engine : Engine, messagebroker : MessageBroker, request : Devi }) topology_uuids.add(topology_uuid) + is_oc_driver = DeviceDriverEnum.DEVICEDRIVER_OC in set(request.device_drivers) - is_oc_driver= [d for d in request.device_drivers][0]==DeviceDriverEnum.DEVICEDRIVER_OC - - endpoints_data : List[Dict] = list() for i, endpoint in enumerate(request.device_endpoints): endpoint_device_uuid = endpoint.endpoint_id.device_id.device_uuid.uuid diff --git a/src/context/service/database/OpticalConfig.py b/src/context/service/database/OpticalConfig.py index 33227a016..9e7552bc1 100644 --- a/src/context/service/database/OpticalConfig.py +++ b/src/context/service/database/OpticalConfig.py @@ -11,119 +11,78 @@ # 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 uuid,json -import datetime, logging +import json, logging from sqlalchemy.dialects.postgresql import insert from sqlalchemy.engine import Engine -from sqlalchemy.orm import Session, selectinload, sessionmaker +from sqlalchemy.orm import Session, sessionmaker from sqlalchemy_cockroachdb import run_transaction -from typing import Dict, List, Optional, Set, Tuple -from common.method_wrappers.ServiceExceptions import InvalidArgumentException, NotFoundException -from common.proto.context_pb2 import Device, DeviceFilter, DeviceId, TopologyId,OpticalConfig,OpticalConfigId,OpticalConfigList -from common.tools.grpc.Tools import grpc_message_to_json_string -from common.tools.object_factory.Device import json_device_id -from context.service.database.uuids.Topology import topology_get_uuid -from .models.DeviceModel import DeviceModel -from .models.EndPointModel import EndPointModel -from .models.TopologyModel import TopologyDeviceModel -from .models.enums.DeviceDriver import grpc_to_enum__device_driver -from .models.enums.DeviceOperationalStatus import grpc_to_enum__device_operational_status -from .models.enums.KpiSampleType import grpc_to_enum__kpi_sample_type -from .uuids.Device import device_get_uuid -from .uuids.EndPoint import endpoint_get_uuid -from .ConfigRule import compose_config_rules_data, upsert_config_rules +from common.proto.context_pb2 import OpticalConfig, OpticalConfigId from .models.OpticalConfigModel import OpticalConfigModel + LOGGER = logging.getLogger(__name__) -def get_opticalconfig (db_engine:Engine): - +def get_opticalconfig(db_engine : Engine): def callback(session:Session): - - lst = list() + optical_configs = list() results = session.query(OpticalConfigModel).all() - for obj in results: - OpticalConfig=OpticalConfig() - OpticalConfig.config=json.dump(obj.config) - myid=OpticalConfigId() - myid.opticalconfig_uuid=obj.opticalconfig_uuid - OpticalConfig.opticalconfig_id.CopyFrom(myid) - - lst.append(OpticalConfig) - return lst - obj=run_transaction(sessionmaker(bind=db_engine),callback) + optical_config = OpticalConfig() + optical_config.config = json.dump(obj.config) + optical_config.opticalconfig_id.opticalconfig_uuid = obj.opticalconfig_uuid + optical_configs.append(optical_config) + return optical_configs + obj = run_transaction(sessionmaker(bind=db_engine), callback) return obj - - - -def set_opticalconfig (db_engine:Engine,request:OpticalConfig): - - opticalconfig_id=OpticalConfigId() - opticalconfig_id.opticalconfig_uuid=request.opticalconfig_id.opticalconfig_uuid - my_config_data=[] - if (request.config): - channels=[] - transceivers=[] +def set_opticalconfig(db_engine : Engine, request : OpticalConfig): + opticalconfig_id = OpticalConfigId() + opticalconfig_id.opticalconfig_uuid = request.opticalconfig_id.opticalconfig_uuid + my_config_data = [] + if request.config: + channels = [] + transceivers = [] config = json.loads(request.config) - - if ( "channels" in config and len(config["channels"])>0): - channels=[channel['name']['index'] for channel in config["channels"]] - if ("transceivers" in config and len(config["transceivers"]["transceiver"])>0): - transceivers=[transceiver for transceiver in config["transceivers"]["transceiver"]] - - - my_config_data=[ + if 'channels' in config and len(config['channels']) > 0: + channels = [channel['name']['index'] for channel in config['channels']] + if 'transceivers' in config and len(config['transceivers']['transceiver']) > 0: + transceivers = [transceiver for transceiver in config['transceivers']['transceiver']] + + my_config_data = [ { - "opticalconfig_uuid":request.opticalconfig_id.opticalconfig_uuid, - "channels":channels, - "transcievers":transceivers, - "interfaces":json.dumps(config["interfaces"]["interface"]), - "channel_namespace":config["channel_namespace"], - "endpoints":[json.dumps(endpoint) for endpoint in config["endpoints"]], - "frequency":config["frequency"] if "frequency" in config else 0, - "operational_mode":config["operational_mode"] if "operational_mode" in config else 0, - "output_power":config["output_power"] if "output_power" in config else '', + "opticalconfig_uuid": request.opticalconfig_id.opticalconfig_uuid, + "channels" : channels, + "transcievers" : transceivers, + "interfaces" : json.dumps(config["interfaces"]["interface"]), + "channel_namespace" : config["channel_namespace"], + "endpoints" : [json.dumps(endpoint) for endpoint in config["endpoints"]], + "frequency" : config["frequency"] if "frequency" in config else 0, + "operational_mode" : config["operational_mode"] if "operational_mode" in config else 0, + "output_power" : config["output_power"] if "output_power" in config else '', } ] def callback(session:Session)->bool: - stmt = insert(OpticalConfigModel).values(my_config_data) stmt = stmt.on_conflict_do_update( index_elements=[OpticalConfigModel.opticalconfig_uuid], set_=dict( - channel_namespace=stmt.excluded.channel_namespace ) ) - stmt = stmt.returning(OpticalConfigModel.opticalconfig_uuid) - id = session.execute(stmt).fetchone() - - opticalconfig_id =run_transaction(sessionmaker(bind=db_engine),callback) - - return {'opticalconfig_uuid': opticalconfig_id} - - - + opticalconfig_id = run_transaction(sessionmaker(bind=db_engine), callback) + return {'opticalconfig_uuid': opticalconfig_id} + def select_opticalconfig(db_engine:Engine,request:OpticalConfigId): - def callback(session : Session) -> OpticalConfig: - result=OpticalConfig() - obj = session.query(OpticalConfigModel).filter_by(opticalconfig_uuid=request.opticalconfig_uuid).first() - - if (obj is not None): - - - myid=OpticalConfigId() - myid.opticalconfig_uuid=obj.opticalconfig_uuid - result.config=json.dumps(obj.dump()) - result.opticalconfig_id.CopyFrom(myid) - - + result = OpticalConfig() + stmt = session.query(OpticalConfigModel) + stmt = stmt.filter_by(opticalconfig_uuid=request.opticalconfig_uuid) + obj = stmt.first() + if obj is not None: + result.config = json.dumps(obj.dump()) + result.opticalconfig_id.opticalconfig_uuid = obj.opticalconfig_uuid return result - - return run_transaction(sessionmaker(bind=db_engine,expire_on_commit=False), callback) \ No newline at end of file + return run_transaction(sessionmaker(bind=db_engine, expire_on_commit=False), callback) diff --git a/src/context/service/database/Service.py b/src/context/service/database/Service.py index 38e5d5ec1..337bf592f 100644 --- a/src/context/service/database/Service.py +++ b/src/context/service/database/Service.py @@ -20,7 +20,9 @@ from sqlalchemy.orm import Session, selectinload, sessionmaker from sqlalchemy_cockroachdb import run_transaction from typing import Dict, List, Optional, Set from common.proto.context_pb2 import ( - ContextId, Empty, EventTypeEnum, Service, ServiceFilter, ServiceId, ServiceIdList, ServiceList) + ContextId, Empty, EventTypeEnum, Service, ServiceFilter, ServiceId, ServiceIdList, + ServiceList, ServiceTypeEnum +) from common.message_broker.MessageBroker import MessageBroker from common.method_wrappers.ServiceExceptions import InvalidArgumentException, NotFoundException from common.tools.object_factory.Context import json_context_id @@ -82,10 +84,11 @@ def service_set(db_engine : Engine, messagebroker : MessageBroker, request : Ser raw_service_name = request.name service_name = raw_service_uuid if len(raw_service_name) == 0 else raw_service_name context_uuid,service_uuid = service_get_uuid(request.service_id, service_name=service_name, allow_random=True) - + service_type = grpc_to_enum__service_type(request.service_type) - service_type="OPTICAL_CONNECTIVITY" if service_type is None and request.service_type==6 else service_type - + if service_type is None and request.service_type == ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY: + service_type = "OPTICAL_CONNECTIVITY" + service_status = grpc_to_enum__service_status(request.service_status.service_status) now = datetime.datetime.utcnow() diff --git a/src/context/service/database/models/OpticalConfigModel.py b/src/context/service/database/models/OpticalConfigModel.py index 34a8c41f0..10cf197f9 100644 --- a/src/context/service/database/models/OpticalConfigModel.py +++ b/src/context/service/database/models/OpticalConfigModel.py @@ -12,40 +12,31 @@ # See the License for the specific language governing permissions and # limitations under the License. -import json,logging -from sqlalchemy import Column, String ,Integer +import json +from sqlalchemy import Column, String, Integer from sqlalchemy.dialects.postgresql import ARRAY - - from ._Base import _Base - - - -class OpticalConfigModel (_Base): - __tablename__="OpticalConfig" +class OpticalConfigModel(_Base): + __tablename__ = 'optical_config' opticalconfig_uuid = Column(String, primary_key=True) - channels=Column(ARRAY(String),nullable=True) - transcievers= Column(ARRAY(String),nullable=True) - interfaces =Column(String,nullable=True) - channel_namespace=Column(String,nullable=True) - endpoints=Column(ARRAY(String),nullable=True) - frequency=Column(Integer,nullable=True) - operational_mode=Column(Integer,nullable=True) - output_power=Column(String,nullable=True) - - - - def dump (self): - + channels = Column(ARRAY(String), nullable=True) + transcievers = Column(ARRAY(String), nullable=True) + interfaces = Column(String, nullable=True) + channel_namespace = Column(String, nullable=True) + endpoints = Column(ARRAY(String), nullable=True) + frequency = Column(Integer, nullable=True) + operational_mode = Column(Integer, nullable=True) + output_power = Column(String, nullable=True) + + def dump(self): return { - "channels":[{'name':{'index':channel}} for channel in self.channels], - "transceivers":{"transceiver":[transciever for transciever in self.transcievers]}, - "interfaces":{"interface":json.loads(self.interfaces)}, - "channel_namespace":self.channel_namespace, - "endpoints":[json.loads(endpoint) for endpoint in self.endpoints], - "frequency":self.frequency, - "output_power":self.output_power, - "operational_mode":self.operational_mode + "channels" : [{'name': {'index': channel}} for channel in self.channels], + "transceivers" : {"transceiver": [transciever for transciever in self.transcievers]}, + "interfaces" : {"interface": json.loads(self.interfaces)}, + "channel_namespace" : self.channel_namespace, + "endpoints" : [json.loads(endpoint) for endpoint in self.endpoints], + "frequency" : self.frequency, + "output_power" : self.output_power, + "operational_mode" : self.operational_mode, } - -- GitLab From c0edbf1ee7ceb3939e2197042279c4775c98b42c Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Wed, 6 Mar 2024 19:00:49 +0000 Subject: [PATCH 07/13] Optical component: - Pre-merge cleanup --- proto/context.proto | 4 +- proto/openconfig_device.proto | 1 - .../service/ContextServiceServicerImpl.py | 2 +- src/device/service/DeviceService.py | 1 - .../service/DeviceServiceServicerImpl.py | 20 +++---- src/device/service/OpenConfigServicer.py | 56 +++---------------- src/device/service/drivers/__init__.py | 8 +-- .../drivers/oc_driver/templates/Tools.py | 1 + 8 files changed, 26 insertions(+), 67 deletions(-) diff --git a/proto/context.proto b/proto/context.proto index a734b3a96..8a6b019dc 100644 --- a/proto/context.proto +++ b/proto/context.proto @@ -211,8 +211,8 @@ enum DeviceDriverEnum { DEVICEDRIVER_XR = 6; DEVICEDRIVER_IETF_L2VPN = 7; DEVICEDRIVER_GNMI_OPENCONFIG = 8; - DEVICEDRIVER_IETF_ACTN = 9; - DEVICEDRIVER_FLEXSCALE = 10; + DEVICEDRIVER_FLEXSCALE = 9; + DEVICEDRIVER_IETF_ACTN = 10; DEVICEDRIVER_OC = 11; } diff --git a/proto/openconfig_device.proto b/proto/openconfig_device.proto index c622c77e4..913ac247e 100644 --- a/proto/openconfig_device.proto +++ b/proto/openconfig_device.proto @@ -16,7 +16,6 @@ syntax = "proto3"; package openconfig_device; import "context.proto"; -import "monitoring.proto"; service OpenConfigService { rpc AddOpenConfigDevice (context.OpticalConfig) returns (context.OpticalConfigId) {} diff --git a/src/context/service/ContextServiceServicerImpl.py b/src/context/service/ContextServiceServicerImpl.py index de6b02a56..a102fa176 100644 --- a/src/context/service/ContextServiceServicerImpl.py +++ b/src/context/service/ContextServiceServicerImpl.py @@ -45,7 +45,7 @@ from .database.Slice import ( slice_delete, slice_get, slice_list_ids, slice_list_objs, slice_select, slice_set, slice_unset) from .database.Topology import ( topology_delete, topology_get, topology_get_details, topology_list_ids, topology_list_objs, topology_set) -from .database.OpticalConfig import (set_opticalconfig,select_opticalconfig,get_opticalconfig) +from .database.OpticalConfig import set_opticalconfig, select_opticalconfig, get_opticalconfig LOGGER = logging.getLogger(__name__) diff --git a/src/device/service/DeviceService.py b/src/device/service/DeviceService.py index 544f250f6..c7868e445 100644 --- a/src/device/service/DeviceService.py +++ b/src/device/service/DeviceService.py @@ -39,7 +39,6 @@ class DeviceService(GenericGrpcService): self.monitoring_loops.start() add_DeviceServiceServicer_to_server(self.device_servicer, self.server) add_OpenConfigServiceServicer_to_server(self.openconfig_device_servicer,self.server) - def stop(self): super().stop() diff --git a/src/device/service/DeviceServiceServicerImpl.py b/src/device/service/DeviceServiceServicerImpl.py index 6abb06dd0..76fb65454 100644 --- a/src/device/service/DeviceServiceServicerImpl.py +++ b/src/device/service/DeviceServiceServicerImpl.py @@ -20,7 +20,9 @@ from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, get_env_var_name from common.method_wrappers.Decorator import MetricTypeEnum, MetricsPool, safe_and_metered_rpc_method from common.method_wrappers.ServiceExceptions import NotFoundException, OperationFailedException from common.proto.context_pb2 import ( - Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty, Link,OpticalConfig,OpticalConfigId) + Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty, Link, + OpticalConfig, OpticalConfigId +) from common.proto.device_pb2 import MonitoringSettings from common.proto.device_pb2_grpc import DeviceServiceServicer from common.tools.context_queries.Device import get_device @@ -54,15 +56,14 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def AddDevice(self, request : Device, context : grpc.ServicerContext) -> DeviceId: - t0 = time.time() device_uuid = request.device_id.device_uuid.uuid connection_config_rules = check_connect_rules(request.device_config) - if (request.device_drivers[0]!= DeviceDriverEnum.DEVICEDRIVER_OC) : + if request.device_drivers[0] != DeviceDriverEnum.DEVICEDRIVER_OC: check_no_endpoints(request.device_endpoints) - + t1 = time.time() context_client = ContextClient() @@ -143,13 +144,12 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): device.device_operational_status = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED # temporary line - if (request.device_drivers[0]== DeviceDriverEnum.DEVICEDRIVER_OC and len(request.device_endpoints)>0): - - for endpoint in request.device_endpoints: - #endpoint.endpoint_id.device_id.CopyFrom(device.device_id) - pass + if request.device_drivers[0] == DeviceDriverEnum.DEVICEDRIVER_OC and len(request.device_endpoints) > 0: + #for endpoint in request.device_endpoints: + # #endpoint.endpoint_id.device_id.CopyFrom(device.device_id) + # pass device.device_endpoints.extend(request.device_endpoints) - + device_id = context_client.SetDevice(device) t10 = time.time() diff --git a/src/device/service/OpenConfigServicer.py b/src/device/service/OpenConfigServicer.py index fc4e75e67..1060449f1 100644 --- a/src/device/service/OpenConfigServicer.py +++ b/src/device/service/OpenConfigServicer.py @@ -12,16 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -import grpc, logging, os, time,json -from typing import Dict -from prometheus_client import Histogram -from common.Constants import ServiceNameEnum -from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, get_env_var_name -from common.method_wrappers.Decorator import MetricTypeEnum, MetricsPool, safe_and_metered_rpc_method -from common.method_wrappers.ServiceExceptions import NotFoundException, OperationFailedException +import grpc, logging, json +from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method +from common.method_wrappers.ServiceExceptions import NotFoundException from common.proto.context_pb2 import ( - Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty, Link,OpticalConfig,OpticalConfigId ,OpticalConfig,OpticalConfigList) -from common.proto.device_pb2 import MonitoringSettings + Device, DeviceId, DeviceOperationalStatusEnum, Empty, OpticalConfig, OpticalConfig +) from common.proto.device_pb2_grpc import DeviceServiceServicer from common.tools.context_queries.Device import get_device from common.tools.mutex_queues.MutexQueues import MutexQueues @@ -29,13 +25,8 @@ from context.client.ContextClient import ContextClient from .driver_api._Driver import _Driver from .driver_api.DriverInstanceCache import DriverInstanceCache, get_driver from .monitoring.MonitoringLoops import MonitoringLoops -from .drivers.oc_driver.OCDriver import OCDriver -from .ErrorMessages import ERROR_MISSING_DRIVER, ERROR_MISSING_KPI from .Tools import extract_resources -from .Tools import ( - check_connect_rules, check_no_endpoints, compute_rules_to_add_delete, configure_rules, deconfigure_rules, - get_device_controller_uuid, populate_config_rules, populate_endpoint_monitoring_resources, populate_endpoints, - populate_initial_config_rules, subscribe_kpi, unsubscribe_kpi, update_endpoints) +from .Tools import check_no_endpoints LOGGER = logging.getLogger(__name__) @@ -52,12 +43,10 @@ class OpenConfigServicer(DeviceServiceServicer): self.monitoring_loops = monitoring_loops self.mutex_queues = MutexQueues() LOGGER.debug('Servicer Created') - + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def AddOpenConfigDevice(self, request : OpticalConfig, context : grpc.ServicerContext) -> DeviceId: - device_uuid = request.device_id.device_uuid.uuid - check_no_endpoints(request.device_endpoints) context_client = ContextClient() @@ -78,56 +67,29 @@ class OpenConfigServicer(DeviceServiceServicer): # update device_uuid to honor UUID provided by Context device_uuid = device.device_id.device_uuid.uuid - - - self.mutex_queues.wait_my_turn(device_uuid) - try: - device_id = context_client.SetDevice(device) except Exception as error : LOGGER.debug("error %s",error) - - - - #modified Andrea @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) - def ConfigureOpticalDevice (self, request : OpticalConfig, context:grpc.ServicerContext) -> Empty: - + def ConfigureOpticalDevice (self, request : OpticalConfig, context : grpc.ServicerContext) -> Empty: device_uuid = request.opticalconfig_id.opticalconfig_uuid - resources=[] - result=None - config =json.loads(request.config) - - - try: - context_client = ContextClient() - device = get_device( context_client, device_uuid, rw_copy=True, include_endpoints=True, include_components=False, include_config_rules=False) - if device is None: - raise NotFoundException('Device', device_uuid, extra_details='loading in ConfigureDevice') resources,conditions=extract_resources(config=config,device=device) driver : _Driver = get_driver(self.driver_instance_cache, device) - result = driver.SetConfig(resources=resources,conditions=conditions) - #todo - #add a control with the NETCONF get + #TODO: add a control with the NETCONF get #driver.GetConfig(resource_keys=filter_fields) - except Exception as e: LOGGER.info("error in configuring %s",e) - - - return Empty() - \ No newline at end of file diff --git a/src/device/service/drivers/__init__.py b/src/device/service/drivers/__init__.py index 4c0a89ebd..1e8cff605 100644 --- a/src/device/service/drivers/__init__.py +++ b/src/device/service/drivers/__init__.py @@ -167,19 +167,17 @@ if LOAD_ALL_DEVICE_DRIVERS: FilterFieldEnum.DRIVER: DeviceDriverEnum.DEVICEDRIVER_FLEXSCALE, } ])) + 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:[ - + FilterFieldEnum.DEVICE_TYPE: [ DeviceTypeEnum.OPTICAL_ROADM, DeviceTypeEnum.OPTICAL_TRANSPONDER - - ], + ], FilterFieldEnum.DRIVER : DeviceDriverEnum.DEVICEDRIVER_OC, } ])) diff --git a/src/device/service/drivers/oc_driver/templates/Tools.py b/src/device/service/drivers/oc_driver/templates/Tools.py index 1af7b9b7f..909bdd83b 100644 --- a/src/device/service/drivers/oc_driver/templates/Tools.py +++ b/src/device/service/drivers/oc_driver/templates/Tools.py @@ -11,6 +11,7 @@ # 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 re,logging import json import lxml.etree as ET -- GitLab From d5bb84dd9f53b483dcb31ec12a061abe21668703 Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Thu, 7 Mar 2024 10:08:40 +0000 Subject: [PATCH 08/13] Optical component: - Pre-merge cleanup --- manifests/opticalcontrollerservice.yaml | 12 +- src/device/service/Tools.py | 168 ++++++++---------- src/opticalcontroller/OpticalController.py | 6 +- src/opticalcontroller/RSA.py | 14 ++ src/opticalcontroller/dijsktra.py | 14 ++ src/opticalcontroller/tools.py | 2 - src/opticalcontroller/variables.py | 2 - .../service_handlers/oc/OCServiceHandler.py | 10 +- .../service/service_handlers/oc/OCTools.py | 12 +- 9 files changed, 120 insertions(+), 120 deletions(-) diff --git a/manifests/opticalcontrollerservice.yaml b/manifests/opticalcontrollerservice.yaml index fcf1be742..4b677ee4f 100644 --- a/manifests/opticalcontrollerservice.yaml +++ b/manifests/opticalcontrollerservice.yaml @@ -37,12 +37,12 @@ spec: env: - name: LOG_LEVEL value: "INFO" - readinessProbe: - exec: - command: ["/bin/grpc_health_probe", "-addr=:10060"] - livenessProbe: - exec: - command: ["/bin/grpc_health_probe", "-addr=:10060"] + #readinessProbe: + # exec: + # command: ["/bin/grpc_health_probe", "-addr=:10060"] + #livenessProbe: + # exec: + # command: ["/bin/grpc_health_probe", "-addr=:10060"] resources: requests: cpu: 500m diff --git a/src/device/service/Tools.py b/src/device/service/Tools.py index 35c542854..f3700e104 100644 --- a/src/device/service/Tools.py +++ b/src/device/service/Tools.py @@ -11,30 +11,27 @@ # 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 uuid import UUID, uuid4, uuid5 + import json, logging from typing import Any, Dict, List, Optional, Tuple, Union from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME -from common.method_wrappers.ServiceExceptions import InvalidArgumentException -from common.proto.context_pb2 import ConfigActionEnum, ConfigRule_ACL, Device, DeviceConfig, Link, Location +from common.DeviceTypes import DeviceTypeEnum +from common.method_wrappers.ServiceExceptions import InvalidArgumentException, NotFoundException +from common.proto.context_pb2 import ConfigActionEnum, ConfigRule_ACL, Device, DeviceConfig, EndPoint, Link, Location from common.proto.device_pb2 import MonitoringSettings from common.proto.kpi_sample_types_pb2 import KpiSampleType from common.tools.grpc.ConfigRules import update_config_rule_custom from common.tools.grpc.Tools import grpc_message_to_json +from common.type_checkers.Checkers import chk_length, chk_type from .driver_api._Driver import _Driver, RESOURCE_ENDPOINTS from .monitoring.MonitoringLoops import MonitoringLoops from .ErrorMessages import ( ERROR_BAD_RESOURCE, ERROR_DELETE, ERROR_GET, ERROR_GET_INIT, ERROR_MISSING_KPI, ERROR_SAMPLETYPE, ERROR_SET, ERROR_SUBSCRIBE, ERROR_UNSUBSCRIBE, ERROR_UNSUP_RESOURCE ) -from .drivers.oc_driver.OCDriver import OCDriver -from common.method_wrappers.ServiceExceptions import NotFoundException -from common.type_checkers.Checkers import chk_length, chk_type -from common.proto.context_pb2 import EndPoint LOGGER = logging.getLogger(__name__) - def get_endpoint_matching(device : Device, endpoint_uuid_or_name : str) -> EndPoint: for endpoint in device.device_endpoints: choices = {endpoint.endpoint_id.endpoint_uuid.uuid, endpoint.name} @@ -454,89 +451,74 @@ def update_endpoints(src_device : Device, dst_device : Device) -> None: dst_topology_id = dst_endpoint_id.topology_id if len(src_topology_uuid) > 0: dst_topology_id.topology_uuid.uuid = src_topology_uuid if len(src_context_uuid) > 0: dst_topology_id.context_id.context_uuid.uuid = src_context_uuid -def oc_default_endpoints( - device : Device, driver : _Driver, monitoring_loops : MonitoringLoops, - new_sub_devices : Dict[str, Device], new_sub_links : Dict[str, Link] -) -> List[str]: - - pass -#def get_enpoint_name (device:Device,endpoint_id:str): -# str(UUID(str_uuid_or_name)) - -def get_edit_target (device:Device,is_opticalband:bool)-> str: - if (is_opticalband): return "optical-band" - else : - if device.device_type =='optical-roadm': return 'media-channel' - else : return 'optical-channel' - -def is_key_existed( key:str ,keys_dic=dict,key_name_to_use= None ) -> dict: - dic={} - dic["resource_key"]=key + +def get_edit_target(device : Device, is_opticalband : bool) -> str: + if is_opticalband: return 'optical-band' + if device.device_type == DeviceTypeEnum.OPTICAL_ROADM: return 'media-channel' + return 'optical-channel' + +def is_key_existed(key : str, keys_dic = dict, key_name_to_use = None) -> dict: + dic = {} + dic['resource_key'] = key if key_name_to_use is not None: - dic["resource_key"]=key_name_to_use - if key in keys_dic : - dic["value"]=keys_dic[key] - else : - dic["value"]=None - return dic - -def extract_resources (config:dict,device:Device)-> list : - conditions={} - resources=[] - resources.append(is_key_existed("channel_namespace",config)) - resources.append(is_key_existed("add_transceiver",config)) - is_opticalband=False - if ( 'is_opticalband' in config): - is_opticalband=config['is_opticalband'] - conditions["is_opticalband"]=is_opticalband - conditions["edit_type"]=get_edit_target(device=device,is_opticalband=is_opticalband) - if ('flow' in config): - #for tuple_value in config['flow'][device.name]: - source_vals = [] - dest_vals = [] - for tuple_value in config['flow']: - source_port=None - destination_port=None - #resources.append({"resource_key":"source_port","value":source_port}) - #resources.append({"resource_key":"destination_port","value":destination_port}) - source_port_uuid,destination_port_uuid=tuple_value - if (source_port_uuid !='0'): - src_endpoint_obj = get_endpoint_matching(device, source_port_uuid) - source_port = src_endpoint_obj.name - source_vals.append(source_port) - if (destination_port_uuid !='0'): - dst_endpoint_obj = get_endpoint_matching(device, destination_port_uuid) - destination_port = dst_endpoint_obj.name - dest_vals.append(destination_port) - resources.append({"resource_key":"source_port","value":source_vals}) - resources.append({"resource_key":"destination_port","value":dest_vals}) - if ('new_config' in config): - lower_frequency=None - upper_frequency=None - resources.append(is_key_existed(key="target-output-power",keys_dic=config["new_config"])) - resources.append(is_key_existed(key="frequency",keys_dic=config["new_config"])) - resources.append(is_key_existed(key="operational-mode",keys_dic=config["new_config"])) - resources.append(is_key_existed(key="line-port",keys_dic=config["new_config"])) - resources.append(is_key_existed(key="band_type",keys_dic=config["new_config"],key_name_to_use='name')) - resources.append(is_key_existed("ob_id",config["new_config"],key_name_to_use='optical-band-parent')) - resources.append(is_key_existed(key="name",keys_dic=config["new_config"],key_name_to_use="channel_name")) - if not is_opticalband : - if 'frequency' in config['new_config'] and 'band' in config['new_config'] and conditions["edit_type"] == 'media-channel': - lower_frequency= int(int(config['new_config']['frequency']) - (int(config['new_config']['band'])/2)) - upper_frequency= int(int(config['new_config']['frequency']) + (int(config['new_config']['band'])/2)) - - #lower_frequency= (config['new_config']['frequency']- config['new_config']['band'])/2 - #upper_frequency=(config['new_config']['frequency']+ config['new_config']['band'])/2 - - resources.append(is_key_existed(key="flow_id",keys_dic=config["new_config"],key_name_to_use="index")) - #resources.append({"resource_key":"index","value":config["new_config"]["flow_id"] if "flow_id" in config["new_config"] else None}) - else : - lower_frequency=config['new_config']['low-freq'] if "low-freq" in config['new_config'] else None - upper_frequency=config['new_config']['up-freq'] if 'up-freq' in config['new_config'] else None - resources.append(is_key_existed(key="ob_id",keys_dic=config["new_config"],key_name_to_use="index")) - #resources.append({"resource_key":"index","value":config["new_config"]["ob_id"] if "ob_id" in config["new_config"] else None}) - - resources.append({"resource_key":"lower-frequency","value":lower_frequency}) - resources.append({"resource_key":"upper-frequency","value":upper_frequency}) - return [resources,conditions] - + dic['resource_key'] = key_name_to_use + if key in keys_dic: + dic['value'] = keys_dic[key] + else: + dic['value'] = None + return dic + +def extract_resources(config : dict, device : Device) -> list: + conditions = {} + resources = [] + resources.append(is_key_existed('channel_namespace', config)) + resources.append(is_key_existed('add_transceiver', config)) + is_opticalband = config.get('is_opticalband', False) + conditions['is_opticalband'] = is_opticalband + conditions['edit_type'] = get_edit_target(device, is_opticalband) + if 'flow' in config: + #for tuple_value in config['flow'][device.name]: + source_vals = [] + dest_vals = [] + for tuple_value in config['flow']: + source_port = None + destination_port = None + source_port_uuid, destination_port_uuid = tuple_value + if source_port_uuid != '0': + src_endpoint_obj = get_endpoint_matching(device, source_port_uuid) + source_port = src_endpoint_obj.name + source_vals.append(source_port) + if destination_port_uuid != '0': + dst_endpoint_obj = get_endpoint_matching(device, destination_port_uuid) + destination_port = dst_endpoint_obj.name + dest_vals.append(destination_port) + resources.append({'resource_key': 'source_port', 'value': source_vals}) + resources.append({'resource_key': 'destination_port', 'value': dest_vals }) + + if 'new_config' in config: + lower_frequency = None + upper_frequency = None + resources.append(is_key_existed('target-output-power', keys_dic=config['new_config'])) + resources.append(is_key_existed('frequency', keys_dic=config['new_config'])) + resources.append(is_key_existed('operational-mode', keys_dic=config['new_config'])) + resources.append(is_key_existed('line-port', keys_dic=config['new_config'])) + resources.append(is_key_existed('band_type', keys_dic=config['new_config'], key_name_to_use='name')) + resources.append(is_key_existed('ob_id', keys_dic=config['new_config'], key_name_to_use='optical-band-parent')) + resources.append(is_key_existed('name', keys_dic=config['new_config'], key_name_to_use='channel_name')) + if not is_opticalband: + if 'frequency' in config['new_config'] and 'band' in config['new_config'] and conditions['edit_type'] == 'media-channel': + lower_frequency = int(int(config['new_config']['frequency']) - (int(config['new_config']['band'])/2)) + upper_frequency = int(int(config['new_config']['frequency']) + (int(config['new_config']['band'])/2)) + #lower_frequency = (config['new_config']['frequency'] - config['new_config']['band'])/2 + #upper_frequency = (config['new_config']['frequency'] + config['new_config']['band'])/2 + resources.append(is_key_existed('flow_id', keys_dic=config['new_config'], key_name_to_use='index')) + #resources.append({'resource_key':'index','value':config['new_config']['flow_id'] if 'flow_id' in config['new_config'] else None}) + else: + lower_frequency = config['new_config']['low-freq'] if 'low-freq' in config['new_config'] else None + upper_frequency = config['new_config']['up-freq' ] if 'up-freq' in config['new_config'] else None + resources.append(is_key_existed('ob_id', keys_dic=config['new_config'], key_name_to_use='index')) + #resources.append({'resource_key':'index','value':config['new_config']['ob_id'] if 'ob_id' in config['new_config'] else None}) + resources.append({'resource_key': 'lower-frequency', 'value': lower_frequency}) + resources.append({'resource_key': 'upper-frequency', 'value': upper_frequency}) + + return [resources, conditions] diff --git a/src/opticalcontroller/OpticalController.py b/src/opticalcontroller/OpticalController.py index 0d571a9bd..c2805695a 100644 --- a/src/opticalcontroller/OpticalController.py +++ b/src/opticalcontroller/OpticalController.py @@ -238,8 +238,8 @@ if __name__ == '__main__': nodes_dict, links_dict = readTopologyData(nodes_json, topology_json) - #topologies,links= getTopology() - #print ("topologies{} and devices {}".format(topologies,links)) + #topologies, links = getTopology() + #print("topologies{} and devices {}".format(topologies,links)) rsa = RSA(nodes_dict, links_dict) - app.run(host='0.0.0.0', port=10060,debug=True) + app.run(host='0.0.0.0', port=10060, debug=True) diff --git a/src/opticalcontroller/RSA.py b/src/opticalcontroller/RSA.py index 138b5399c..9b12b1ac8 100644 --- a/src/opticalcontroller/RSA.py +++ b/src/opticalcontroller/RSA.py @@ -1,3 +1,17 @@ +# 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. + import dijsktra from tools import * from variables import * diff --git a/src/opticalcontroller/dijsktra.py b/src/opticalcontroller/dijsktra.py index 5be78c624..94975fd55 100644 --- a/src/opticalcontroller/dijsktra.py +++ b/src/opticalcontroller/dijsktra.py @@ -1,3 +1,17 @@ +# 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. + import sys class Vertex: diff --git a/src/opticalcontroller/tools.py b/src/opticalcontroller/tools.py index fc349b499..3b3223d81 100644 --- a/src/opticalcontroller/tools.py +++ b/src/opticalcontroller/tools.py @@ -1,4 +1,3 @@ - # Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. - import numpy as np from variables import * import json diff --git a/src/opticalcontroller/variables.py b/src/opticalcontroller/variables.py index 88e8ce513..cbb65200f 100644 --- a/src/opticalcontroller/variables.py +++ b/src/opticalcontroller/variables.py @@ -1,4 +1,3 @@ - # Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. - debug = 1 Fl = 184800 diff --git a/src/service/service/service_handlers/oc/OCServiceHandler.py b/src/service/service/service_handlers/oc/OCServiceHandler.py index 87a9a0075..6359f2a09 100644 --- a/src/service/service/service_handlers/oc/OCServiceHandler.py +++ b/src/service/service/service_handlers/oc/OCServiceHandler.py @@ -23,12 +23,11 @@ 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 from .ConfigRules import setup_config_rules, teardown_config_rules - -from common.proto.context_pb2 import EndPointId from .OCTools import convert_endpoints_to_flows, handle_flows_names + LOGGER = logging.getLogger(__name__) -METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'l3nm_emulated'}) +METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'oc'}) class OCServiceHandler(_ServiceHandler): def __init__( # pylint: disable=super-init-not-called @@ -38,9 +37,6 @@ class OCServiceHandler(_ServiceHandler): self.__task_executor = task_executor self.__settings_handler = SettingsHandler(service.service_config, **settings) - - - @metered_subclass_method(METRICS_POOL) def SetEndpoint( self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None @@ -58,7 +54,7 @@ class OCServiceHandler(_ServiceHandler): settings = self.__settings_handler.get('/settings') - # settings = self.__settings_handler.get('/settings') + # settings = self.__settings_handler.get('/settings') #flow is the new variable that stores input-output relationship diff --git a/src/service/service/service_handlers/oc/OCTools.py b/src/service/service/service_handlers/oc/OCTools.py index 529a1bc7f..2b202a8a9 100644 --- a/src/service/service/service_handlers/oc/OCTools.py +++ b/src/service/service/service_handlers/oc/OCTools.py @@ -11,11 +11,13 @@ # 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 service.service.service_handler_api.Tools import get_device_endpoint_uuids, get_endpoint_matching from typing import Dict, Any, List, Optional, Tuple import logging from common.proto.context_pb2 import ConfigRule, DeviceId, Service from common.tools.object_factory.Device import json_device_id + log = logging.getLogger(__name__) #def convert_endpoints_to_flows(endpoints : List[Tuple[str, str, Optional[str]]])->Dict[str: List[Tuple[str, str]]]: @@ -26,7 +28,7 @@ def convert_endpoints_to_flows(endpoints : List[Tuple[str, str, Optional[str]]]) entries = {} #tuple is in, out #end = len(endpoints) if isinstance(endpoints,list) else 0 - end=len(endpoints) + end = len(endpoints) i = 0 bidir = 0 log.debug("end={}".format(end)) @@ -115,14 +117,10 @@ def convert_endpoints_to_flows(endpoints : List[Tuple[str, str, Optional[str]]]) def get_device_endpint_name (endpoint_uuid:str,device_uuid:str,task_executor)->Tuple: - - - device_obj = task_executor.get_device(DeviceId(**json_device_id(device_uuid))) endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid) endpoint_name = endpoint_obj.name - - return (device_obj.name,endpoint_name) + return (device_obj.name, endpoint_name) def handle_flows_names (task_executor,flows:dict)->Dict : new_flows={} @@ -141,4 +139,4 @@ def handle_flows_names (task_executor,flows:dict)->Dict : if (device_name not in new_flows): new_flows[device_name]=[] new_flows[device_name].append((source_port,destination_port)) - return new_flows \ No newline at end of file + return new_flows -- GitLab From 6220b5d56d58b1e139eac8cfa49a5ffcdc474f2b Mon Sep 17 00:00:00 2001 From: sgambelluri Date: Thu, 7 Mar 2024 11:03:35 +0000 Subject: [PATCH 09/13] READM.md for testing --- ofc24/1.context.json | 19 ++ ofc24/2.device1.json | 91 +++++++++ ofc24/3.device2.json | 91 +++++++++ ofc24/4.device3_R1.json | 188 +++++++++++++++++++ ofc24/5.device4_R2.json | 189 +++++++++++++++++++ ofc24/6.links.json | 28 +++ ofc24/7.service-bidir.json | 22 +++ ofc24/7.service-unidir.json | 22 +++ ofc24/README.md | 10 + ofc24/plat_r1.xml | 120 ++++++++++++ ofc24/plat_r2.xml | 120 ++++++++++++ ofc24/startExtraNetConfigAgent.sh | 25 --- ofc24/start_topo.sh | 34 +++- ofc24/t1.xml | 298 ++++++++++++++++++++++++++++++ ofc24/t2.xml | 298 ++++++++++++++++++++++++++++++ 15 files changed, 1528 insertions(+), 27 deletions(-) create mode 100755 ofc24/1.context.json create mode 100755 ofc24/2.device1.json create mode 100755 ofc24/3.device2.json create mode 100755 ofc24/4.device3_R1.json create mode 100755 ofc24/5.device4_R2.json create mode 100755 ofc24/6.links.json create mode 100755 ofc24/7.service-bidir.json create mode 100755 ofc24/7.service-unidir.json create mode 100644 ofc24/README.md create mode 100755 ofc24/plat_r1.xml create mode 100755 ofc24/plat_r2.xml delete mode 100755 ofc24/startExtraNetConfigAgent.sh create mode 100755 ofc24/t1.xml create mode 100755 ofc24/t2.xml diff --git a/ofc24/1.context.json b/ofc24/1.context.json new file mode 100755 index 000000000..36b3c44fd --- /dev/null +++ b/ofc24/1.context.json @@ -0,0 +1,19 @@ +{ + "contexts": [ + { + "context_id": {"context_uuid": {"uuid": "admin"}}, + "topology_ids": [], + "service_ids": [] + } + ], + "topologies": [ + { + "topology_id": { + "context_id": {"context_uuid": {"uuid": "admin"}}, + "topology_uuid": {"uuid": "admin"} + }, + "device_ids": [], + "link_ids": [] + } + ] +} diff --git a/ofc24/2.device1.json b/ofc24/2.device1.json new file mode 100755 index 000000000..3e31f31eb --- /dev/null +++ b/ofc24/2.device1.json @@ -0,0 +1,91 @@ +{ + "devices": [ + { + "device_id": { + "device_uuid": { + "uuid": "T1" + } + }, + "device_type": "optical-transponder", + "device_drivers": [ + 11 + ], + "device_endpoints": [ + { + "endpoint_id": { + "device_id": { + "device_uuid": { + "uuid": "T1" + } + }, + "topology_id": { + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "topology_uuid": { + "uuid": "admin" + } + }, + "endpoint_uuid": { + "uuid": "1" + } + } + } + ], + "device_operational_status": 1, + "device_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "_connect/address", + "resource_value": "10.0.2.15" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/port", + "resource_value": "2023" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/settings", + "resource_value": { + "username": "admin", + "password": "admin", + "force_running": false, + "hostkey_verify": false, + "look_for_keys": false, + "allow_agent": false, + "commit_per_rule": false, + "device_params": { + "name": "default" + }, + "manager_params": { + "timeout": 120 + }, + "endpoints": [ + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "1" + } + ] + } + } + } + ] + } + } + ] +} \ No newline at end of file diff --git a/ofc24/3.device2.json b/ofc24/3.device2.json new file mode 100755 index 000000000..812affa7b --- /dev/null +++ b/ofc24/3.device2.json @@ -0,0 +1,91 @@ +{ + "devices": [ + { + "device_id": { + "device_uuid": { + "uuid": "T2" + } + }, + "device_type": "optical-transponder", + "device_drivers": [ + 11 + ], + "device_endpoints": [ + { + "endpoint_id": { + "device_id": { + "device_uuid": { + "uuid": "T2" + } + }, + "topology_id": { + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "topology_uuid": { + "uuid": "admin" + } + }, + "endpoint_uuid": { + "uuid": "6" + } + } + } + ], + "device_operational_status": 1, + "device_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "_connect/address", + "resource_value": "10.0.2.15" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/port", + "resource_value": "2024" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/settings", + "resource_value": { + "username": "admin", + "password": "admin", + "force_running": false, + "hostkey_verify": false, + "look_for_keys": false, + "allow_agent": false, + "commit_per_rule": false, + "device_params": { + "name": "default" + }, + "manager_params": { + "timeout": 120 + }, + "endpoints": [ + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "6" + } + ] + } + } + } + ] + } + } + ] +} \ No newline at end of file diff --git a/ofc24/4.device3_R1.json b/ofc24/4.device3_R1.json new file mode 100755 index 000000000..3a57ba79c --- /dev/null +++ b/ofc24/4.device3_R1.json @@ -0,0 +1,188 @@ +{ + "devices": [ + { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "device_type": "optical-roadm", + "device_drivers": [ + 11 + ], + "device_endpoints": [ + { + "endpoint_id": { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "topology_id": { + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "topology_uuid": { + "uuid": "admin" + } + }, + "endpoint_uuid": { + "uuid": "2" + } + } + }, + { + "endpoint_id": { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "topology_id": { + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "topology_uuid": { + "uuid": "admin" + } + }, + "endpoint_uuid": { + "uuid": "3" + } + } + }, + { + "endpoint_id": { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "topology_id": { + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "topology_uuid": { + "uuid": "admin" + } + }, + "endpoint_uuid": { + "uuid": "12" + } + } + }, + { + "endpoint_id": { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "topology_id": { + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "topology_uuid": { + "uuid": "admin" + } + }, + "endpoint_uuid": { + "uuid": "13" + } + } + } + ], + "device_operational_status": 1, + "device_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "_connect/address", + "resource_value": "10.0.2.15" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/port", + "resource_value": "2025" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/settings", + "resource_value": { + "username": "admin", + "password": "admin", + "force_running": false, + "hostkey_verify": false, + "look_for_keys": false, + "allow_agent": false, + "commit_per_rule": false, + "device_params": { + "name": "default" + }, + "manager_params": { + "timeout": 120 + }, + "endpoints": [ + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "2" + }, + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "3" + }, + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "12" + }, + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "13" + } + + ] + } + } + } + ] + } + } + ] +} \ No newline at end of file diff --git a/ofc24/5.device4_R2.json b/ofc24/5.device4_R2.json new file mode 100755 index 000000000..9b1968d09 --- /dev/null +++ b/ofc24/5.device4_R2.json @@ -0,0 +1,189 @@ +{ + "devices": [ + { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "device_type": "optical-roadm", + "device_drivers": [ + 11 + ], + "device_endpoints": [ + { + "endpoint_id": { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "topology_id": { + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "topology_uuid": { + "uuid": "admin" + } + }, + "endpoint_uuid": { + "uuid": "4" + } + } + }, + { + "endpoint_id": { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "topology_id": { + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "topology_uuid": { + "uuid": "admin" + } + }, + "endpoint_uuid": { + "uuid": "5" + } + } + }, + { + "endpoint_id": { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "topology_id": { + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "topology_uuid": { + "uuid": "admin" + } + }, + "endpoint_uuid": { + "uuid": "14" + } + } + }, + { + "endpoint_id": { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "topology_id": { + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "topology_uuid": { + "uuid": "admin" + } + }, + "endpoint_uuid": { + "uuid": "15" + } + } + } + + ], + "device_operational_status": 1, + "device_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "_connect/address", + "resource_value": "10.0.2.15" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/port", + "resource_value": "2026" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/settings", + "resource_value": { + "username": "admin", + "password": "admin", + "force_running": false, + "hostkey_verify": false, + "look_for_keys": false, + "allow_agent": false, + "commit_per_rule": false, + "device_params": { + "name": "default" + }, + "manager_params": { + "timeout": 120 + }, + "endpoints": [ + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "4" + }, + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "5" + }, + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "14" + }, + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "15" + } + + ] + } + } + } + ] + } + } + ] +} \ No newline at end of file diff --git a/ofc24/6.links.json b/ofc24/6.links.json new file mode 100755 index 000000000..eb2d004fc --- /dev/null +++ b/ofc24/6.links.json @@ -0,0 +1,28 @@ +{ "links": [ + {"link_id": {"link_uuid": {"uuid": "T1->R1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "T1"}}, "endpoint_uuid": {"uuid": "1"}}, + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "12"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R1->T1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "2"}}, + {"device_id": {"device_uuid": {"uuid": "T1"}}, "endpoint_uuid": {"uuid": "1"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R1->R2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "3"}}, + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "14"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R2->R1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "4"}}, + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "13"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "T2->R2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "T2"}}, "endpoint_uuid": {"uuid": "6"}}, + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "15"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R2->T2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "5"}}, + {"device_id": {"device_uuid": {"uuid": "T2"}}, "endpoint_uuid": {"uuid": "6"}} + ]} +] + +} diff --git a/ofc24/7.service-bidir.json b/ofc24/7.service-bidir.json new file mode 100755 index 000000000..05547a19d --- /dev/null +++ b/ofc24/7.service-bidir.json @@ -0,0 +1,22 @@ +{ + "services": [ + { + "service_id": { + "context_id": {"context_uuid": {"uuid": "admin"}}, + "service_uuid": {"uuid": "optical-connection"} + }, + "service_type": 6, + "service_status": {"service_status": 1}, + "service_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "T1"}}, "endpoint_uuid": {"uuid": "1"}}, + {"device_id": {"device_uuid": {"uuid": "T2"}}, "endpoint_uuid": {"uuid": "6"}} + ], + "service_constraints": [ + {"custom": {"constraint_type": "bandwidth[gbps]", "constraint_value": "100.0"}}, + {"custom": {"constraint_type": "bidirectionality", "constraint_value": "1"}}, + {"custom": {"constraint_type": "optical-band-width[GHz]", "constraint_value": "200"}} + ], + "service_config": {"config_rules": []} + } + ] +} diff --git a/ofc24/7.service-unidir.json b/ofc24/7.service-unidir.json new file mode 100755 index 000000000..d9b4e8847 --- /dev/null +++ b/ofc24/7.service-unidir.json @@ -0,0 +1,22 @@ +{ + "services": [ + { + "service_id": { + "context_id": {"context_uuid": {"uuid": "admin"}}, + "service_uuid": {"uuid": "optical-connection"} + }, + "service_type": 6, + "service_status": {"service_status": 1}, + "service_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "T1"}}, "endpoint_uuid": {"uuid": "1"}}, + {"device_id": {"device_uuid": {"uuid": "T2"}}, "endpoint_uuid": {"uuid": "6"}} + ], + "service_constraints": [ + {"custom": {"constraint_type": "bandwidth[gbps]", "constraint_value": "100.0"}}, + {"custom": {"constraint_type": "bidirectionality", "constraint_value": "0"}}, + {"custom": {"constraint_type": "optical-band-width[GHz]", "constraint_value": "200"}} + ], + "service_config": {"config_rules": []} + } + ] +} diff --git a/ofc24/README.md b/ofc24/README.md new file mode 100644 index 000000000..3d01142cb --- /dev/null +++ b/ofc24/README.md @@ -0,0 +1,10 @@ +# start topology , 2 Transponders Openconfig and 2 multi granular Roadms : + +sudo ./start_topo.sh + +# populate tfs context in (pushing the json files) following the file index , i.e : 1 , 2 +# last json is with ID 7 is the service , to check the service is onboarded successfully go into the srevice interface +# of tfs webGui +# to check if the devices are configured , run +screen -r tx with x = 1, 2,3 , 4 +# to release the terminal , press ctrl + a + d \ No newline at end of file diff --git a/ofc24/plat_r1.xml b/ofc24/plat_r1.xml new file mode 100755 index 000000000..47e135c2e --- /dev/null +++ b/ofc24/plat_r1.xml @@ -0,0 +1,120 @@ + + + + 2 + + 2 + + + + MG_ON_PORT_TYPE + + MG_ON_PORT_TYPE + MG_ON_OPTICAL_PORT_WAVEBAND + + + + MG_ON_PORT_DIRECTION + + MG_ON_PORT_DIRECTION + OUTPUT + + + + MG_ON_PORT_DEGREE + + MG_ON_PORT_DEGREE + D1 + + + + + + 12 + + 12 + + + + MG_ON_PORT_TYPE + + MG_ON_PORT_TYPE + MG_ON_OPTICAL_PORT_WAVEBAND + + + + MG_ON_PORT_DIRECTION + + MG_ON_PORT_DIRECTION + INPUT + + + + MG_ON_PORT_DEGREE + + MG_ON_PORT_DEGREE + D1 + + + + + + 3 + + 3 + + + + MG_ON_PORT_TYPE + + MG_ON_PORT_TYPE + MG_ON_OPTICAL_PORT_WAVEBAND + + + + MG_ON_PORT_DIRECTION + + MG_ON_PORT_DIRECTION + OUTPUT + + + + MG_ON_PORT_DEGREE + + MG_ON_PORT_DEGREE + D2 + + + + + + 13 + + 13 + + + + MG_ON_PORT_TYPE + + MG_ON_PORT_TYPE + MG_ON_OPTICAL_PORT_WAVEBAND + + + + MG_ON_PORT_DIRECTION + + MG_ON_PORT_DIRECTION + INPUT + + + + MG_ON_PORT_DEGREE + + MG_ON_PORT_DEGREE + D2 + + + + + + \ No newline at end of file diff --git a/ofc24/plat_r2.xml b/ofc24/plat_r2.xml new file mode 100755 index 000000000..dfaaf05ad --- /dev/null +++ b/ofc24/plat_r2.xml @@ -0,0 +1,120 @@ + + + + 4 + + 4 + + + + MG_ON_PORT_TYPE + + MG_ON_PORT_TYPE + MG_ON_OPTICAL_PORT_WAVEBAND + + + + MG_ON_PORT_DIRECTION + + MG_ON_PORT_DIRECTION + OUTPUT + + + + MG_ON_PORT_DEGREE + + MG_ON_PORT_DEGREE + D1 + + + + + + 14 + + 14 + + + + MG_ON_PORT_TYPE + + MG_ON_PORT_TYPE + MG_ON_OPTICAL_PORT_WAVEBAND + + + + MG_ON_PORT_DIRECTION + + MG_ON_PORT_DIRECTION + INPUT + + + + MG_ON_PORT_DEGREE + + MG_ON_PORT_DEGREE + D1 + + + + + + 5 + + 5 + + + + MG_ON_PORT_TYPE + + MG_ON_PORT_TYPE + MG_ON_OPTICAL_PORT_WAVEBAND + + + + MG_ON_PORT_DIRECTION + + MG_ON_PORT_DIRECTION + OUTPUT + + + + MG_ON_PORT_DEGREE + + MG_ON_PORT_DEGREE + D2 + + + + + + 15 + + 15 + + + + MG_ON_PORT_TYPE + + MG_ON_PORT_TYPE + MG_ON_OPTICAL_PORT_WAVEBAND + + + + MG_ON_PORT_DIRECTION + + MG_ON_PORT_DIRECTION + INPUT + + + + MG_ON_PORT_DEGREE + + MG_ON_PORT_DEGREE + D2 + + + + + + \ No newline at end of file diff --git a/ofc24/startExtraNetConfigAgent.sh b/ofc24/startExtraNetConfigAgent.sh deleted file mode 100755 index 79efe3773..000000000 --- a/ofc24/startExtraNetConfigAgent.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -Docker_Container=$1 -Docker_Port=$2 -if [ -n "$Docker_Container" ] && [ -n "$Docker_Port" ];then - sudo docker stop "$Docker_Container" -t 1 - - sudo docker rm "$Docker_Container" - - - echo "Creating TPs" - screen -dmS t1 -T xterm sh -c "docker run -p 10.0.2.15:"$Docker_Port":2022 -v ~/tfs-ctrl/tempOC/files:/files --name $Docker_Container -it asgamb1/oc23bgp.img:latest" - sleep 2 - if [ "$( docker container inspect -f '{{.State.Running}}' "$Docker_Container")" = "true" ]; then - - docker exec "$Docker_Container" cp /files/demoECOC21_4.xml demoECOC21.xml - - docker exec "$Docker_Container" /confd/examples.confd/OC23/startNetconfAgent.sh - else - echo "your container is not running yet" - fi -else - echo "Please define the docker container name and port" -fi - diff --git a/ofc24/start_topo.sh b/ofc24/start_topo.sh index 574d0c1d5..70b33a6d7 100755 --- a/ofc24/start_topo.sh +++ b/ofc24/start_topo.sh @@ -1,6 +1,8 @@ #!/bin/bash -asgamb1/flexscale-node.imgasgamb1/flexscale-node.imgasgamb1/flexscale-node.imgasgamb1/flexscale-node.img#!/bin/bash +IMAGE_NAME="asgamb1/oc23bgp.img:latest" +Docker_Container=$1 +Docker_Port="2022" sudo docker stop na1 -t 1 sudo docker stop na2 -t 1 sudo docker stop na3 -t 1 @@ -11,7 +13,31 @@ sudo docker rm na1 sudo docker rm na3 sudo docker rm na4 -echo "Creating NewAgent" +echo "Creating Transponder Agents" + +# if ! docker image inspect "$IMAGE_NAME" >/dev/null 2>&1 ; then +# echo "asgamb1/oc23bgp.img:latest not existed ! " +# screen -dmS t3 -T xterm sh -c "docker run -p 10.0.2.15:2025:2022 -v ~/tempOC/files:/files --name na -it $IMAGE_NAME bash" +# echo 'start downloading asgamb1/oc23bgp.img:latest , it may take few minutes ! .... ' +# while [ "$(docker image inspect asgamb1/oc23bgp.img:latest 2>/dev/null)" == "[]" ]; do +# sleep 1 +# done + +#fi + + + +screen -dmS t1 -T xterm sh -c "docker run -p 127.0.0.1:2023:2022 -v ~/tempOC/files:/files --name $Docker_Container -it asgamb1/oc23bgp.img:latest bash" +sleep 2 +if [ "$( docker container inspect -f '{{.State.Running}}' "$Docker_Container")" = "true" ]; then + + docker exec "$Docker_Container" cp /files/demoECOC21_4.xml demoECOC21.xml + + docker exec "$Docker_Container" /confd/examples.confd/OC23/startNetconfAgent.sh +else + echo "your container is not running yet" + + echo " It may take a while , Hang on ..." source "./startExtraNetConfigAgent.sh" "na1" "2023" sleep 3 @@ -19,5 +45,9 @@ sleep 3 source "./startExtraNetConfigAgent.sh" "na2" "2024" sleep 3 +R1 +bash -c "cp /tempOC/files/plat_r1.xml /confd/examples.confd/OC23/init_openconfig-platform.xml; ./startNetconfAgent.sh" +R2 +bash -c "cp /tempOC/files/plat_r2.xml /confd/examples.confd/OC23/init_openconfig-platform.xml; ./startNetconfAgent.sh" screen -dmS t3 -T xterm sh -c 'docker run -p 10.0.2.15:2025:2022 -v ~/tfs-ctrl/tempOC/files:/files --name na3 -it asgamb1/flexscale-node.img:latest ./startNetconfAgent.sh' screen -dmS t4 -T xterm sh -c 'docker run -p 10.0.2.15:2026:2022 -v ~/tfs-ctrl/tempOC/files:/files --name na4 -it asgamb1/flexscale-node.img:latest ./startNetconfAgent.sh' \ No newline at end of file diff --git a/ofc24/t1.xml b/ofc24/t1.xml new file mode 100755 index 000000000..712615df8 --- /dev/null +++ b/ofc24/t1.xml @@ -0,0 +1,298 @@ + + + + device + + device + + + MellanoxSwitch + SSSA-CNIT + 1.0.0 + 1.0.0 + 1.0.0 + 610610 + typex:OPERATING_SYSTEM + + + + channel-1 + + channel-1 + + + channel-1 + typex:OPTICAL_CHANNEL + + + + 191600000 + 100 + 0 + transceiver-1 + + + 191600000 + 0 + 0 + transceiver-1 + 1 + + 0 + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + + + + + + transceiver-1 + + transceiver-1 + + + transceiver-1 + typex:TRANSCEIVER + + + + true + typex:QSFP56_DD_TYPE1 + typex:ETH_400GBASE_ZR + typex:FEC_AUTO + typex:TYPE_DIGITAL_COHERENT_OPTIC + + + true + typex:QSFP56_DD_TYPE1 + typex:ETH_400GBASE_ZR + typex:FEC_AUTO + typex:TYPE_DIGITAL_COHERENT_OPTIC + Cisco + 400zr-QSFP-DD + 01 + 1567321 + + + + 1 + + 1 + channel-1 + + + + + + + + port-1 + + port-1 + + + port-1 + typex:PORT + + + + channel-1 + + channel-1 + + + channel-1 + + + + + + onos-index + + onos-index + 4 + + + onos-index + 4 + + + + odtn-port-type + + odtn-port-type + line + + + odtn-port-type + line + + + + + + + + + + + + + + 1 + + 1 + Logical channel 1 + DISABLED + type:PROT_OTN + NONE + + + 1 + Logical channel 1 + DISABLED + type:PROT_OTN + NONE + UP + + + + transceiver-1 + + + transceiver-1 + + + + + test1 + test1 + + + test1 + test1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0 + + + + + + 1 + + 1 + Optical channel assigned 100 + 100 + OPTICAL_CHANNEL + channel-1 + + + 1 + Optical channel assigned 100 + 100 + OPTICAL_CHANNEL + channel-1 + + + + + + + + 1 + + 1 + FEC1 + Ericsson + + + + 2 + + 2 + FEC2 + Ericsson + + + + + + diff --git a/ofc24/t2.xml b/ofc24/t2.xml new file mode 100755 index 000000000..3a35e7e87 --- /dev/null +++ b/ofc24/t2.xml @@ -0,0 +1,298 @@ + + + + device + + device + + + MellanoxSwitch + SSSA-CNIT + 1.0.0 + 1.0.0 + 1.0.0 + 610610 + typex:OPERATING_SYSTEM + + + + channel-6 + + channel-6 + + + channel-6 + typex:OPTICAL_CHANNEL + + + + 191600000 + 100 + 0 + transceiver-6 + + + 191600000 + 0 + 0 + transceiver-6 + 1 + + 0 + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + + + + + + transceiver-6 + + transceiver-6 + + + transceiver-6 + typex:TRANSCEIVER + + + + true + typex:QSFP56_DD_TYPE1 + typex:ETH_400GBASE_ZR + typex:FEC_AUTO + typex:TYPE_DIGITAL_COHERENT_OPTIC + + + true + typex:QSFP56_DD_TYPE1 + typex:ETH_400GBASE_ZR + typex:FEC_AUTO + typex:TYPE_DIGITAL_COHERENT_OPTIC + Cisco + 400zr-QSFP-DD + 01 + 1567321 + + + + 1 + + 1 + channel-6 + + + + + + + + port-6 + + port-6 + + + port-6 + typex:PORT + + + + channel-6 + + channel-6 + + + channel-6 + + + + + + onos-index + + onos-index + 4 + + + onos-index + 4 + + + + odtn-port-type + + odtn-port-type + line + + + odtn-port-type + line + + + + + + + + + + + + + + 4 + + 4 + Logical channel 4 + DISABLED + type:PROT_OTN + NONE + + + 4 + Logical channel 4 + DISABLED + type:PROT_OTN + NONE + UP + + + + transceiver-6 + + + transceiver-6 + + + + + test1 + test1 + + + test1 + test1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0 + + + + + + 1 + + 1 + Optical channel assigned 100 + 100 + OPTICAL_CHANNEL + channel-6 + + + 1 + Optical channel assigned 100 + 100 + OPTICAL_CHANNEL + channel-6 + + + + + + + + 1 + + 1 + FEC1 + Ericsson + + + + 2 + + 2 + FEC2 + Ericsson + + + + + + -- GitLab From 48d4900afa21541c4d296af1532b57d7154d1ca0 Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Thu, 7 Mar 2024 17:40:37 +0000 Subject: [PATCH 10/13] Merge branch 'develop-stable-pre-release3' of https://labs.etsi.org/rep/tfs/controller into feat/smartnics --- my_deploy.sh | 7 ++- src/opticalcontroller/dijsktra.py | 6 +- src/service/Dockerfile | 7 +-- src/service/service/__main__.py | 15 +---- .../service/task_scheduler/TaskExecutor.py | 56 ++++++++----------- src/service/service/tools/OpticalTools.py | 37 ++++++------ src/tests/ofc24/README.md | 25 ++++++--- src/tests/ofc24/start_topo.sh | 22 +++----- 8 files changed, 85 insertions(+), 90 deletions(-) diff --git a/my_deploy.sh b/my_deploy.sh index 524abc6cc..87f6e2491 100755 --- a/my_deploy.sh +++ b/my_deploy.sh @@ -20,10 +20,13 @@ export TFS_REGISTRY_IMAGES="http://localhost:32000/tfs/" # Set the list of components, separated by spaces, you want to build images for, and deploy. -export TFS_COMPONENTS="context device pathcomp opticalcontroller service slice webui " +export TFS_COMPONENTS="context device pathcomp service slice nbi webui load_generator" # Uncomment to activate Monitoring -#export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring"../ +#export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" + +# Uncomment to activate BGP-LS Speaker +#export TFS_COMPONENTS="${TFS_COMPONENTS} bgpls_speaker" # Uncomment to activate ZTP #export TFS_COMPONENTS="${TFS_COMPONENTS} ztp" diff --git a/src/opticalcontroller/dijsktra.py b/src/opticalcontroller/dijsktra.py index 94975fd55..a86d1d93d 100644 --- a/src/opticalcontroller/dijsktra.py +++ b/src/opticalcontroller/dijsktra.py @@ -12,6 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +# TODO: migrate to NetworkX: +# https://networkx.org/documentation/stable/index.html +# https://networkx.org/documentation/stable/reference/algorithms/shortest_paths.html + import sys class Vertex: @@ -233,4 +237,4 @@ if __name__ == '__main__': print ('The shortest path : %s' %(path[::-1]))""" p = shortest_path(g, g.get_vertex('a'), g.get_vertex('e')) - print(p) \ No newline at end of file + print(p) diff --git a/src/service/Dockerfile b/src/service/Dockerfile index c48f1ab0a..aed4ce64c 100644 --- a/src/service/Dockerfile +++ b/src/service/Dockerfile @@ -62,16 +62,15 @@ RUN python3 -m pip install -r requirements.txt # Add component files into working directory WORKDIR /var/teraflow -COPY src/service/. service/ -#COPY src/context/__init__.py context/__init__.py -#COPY src/context/client/. context/client/ -COPY src/context/. context/. +COPY src/context/__init__.py context/__init__.py +COPY src/context/client/. context/client/ COPY src/device/__init__.py device/__init__.py COPY src/device/client/. device/client/ COPY src/pathcomp/frontend/__init__.py pathcomp/frontend/__init__.py COPY src/pathcomp/frontend/client/. pathcomp/frontend/client/ COPY src/e2e_orchestrator/__init__.py e2e_orchestrator/__init__.py COPY src/e2e_orchestrator/client/. e2e_orchestrator/client/ +COPY src/service/. service/ # Start the service ENTRYPOINT ["python", "-m", "service.service"] diff --git a/src/service/service/__main__.py b/src/service/service/__main__.py index 31dbbdbe6..d096de8c6 100644 --- a/src/service/service/__main__.py +++ b/src/service/service/__main__.py @@ -12,12 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging, signal, sys, threading,os +import logging, signal, sys, threading from prometheus_client import start_http_server from common.Constants import ServiceNameEnum from common.Settings import ( ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_log_level, get_metrics_port, - wait_for_environment_variables,find_environment_variables) + wait_for_environment_variables +) from .ServiceService import ServiceService from .service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory from .service_handlers import SERVICE_HANDLERS @@ -43,18 +44,8 @@ def main(): get_env_var_name(ServiceNameEnum.DEVICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC), get_env_var_name(ServiceNameEnum.PATHCOMP, ENVVAR_SUFIX_SERVICE_HOST ), get_env_var_name(ServiceNameEnum.PATHCOMP, ENVVAR_SUFIX_SERVICE_PORT_GRPC), - get_env_var_name(ServiceNameEnum.PATHCOMP, ENVVAR_SUFIX_SERVICE_HOST), - get_env_var_name(ServiceNameEnum.PATHCOMP, ENVVAR_SUFIX_SERVICE_PORT_GRPC) - - ]) - #Commented for merging with develop branch - # variables= find_environment_variables([ - # get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER,ENVVAR_SUFIX_SERVICE_HOST), - # get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER,ENVVAR_SUFIX_SERVICE_PORT_GRPC), - # ]) - signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) diff --git a/src/service/service/task_scheduler/TaskExecutor.py b/src/service/service/task_scheduler/TaskExecutor.py index 487c61efe..8e5ad4ecc 100644 --- a/src/service/service/task_scheduler/TaskExecutor.py +++ b/src/service/service/task_scheduler/TaskExecutor.py @@ -12,11 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging , json +import json, logging from enum import Enum from typing import TYPE_CHECKING, Any, Dict, Optional, Union from common.method_wrappers.ServiceExceptions import NotFoundException -from common.proto.context_pb2 import Connection, ConnectionId, Device, DeviceDriverEnum, DeviceId, Service, ServiceId,OpticalConfig,OpticalConfigId +from common.proto.context_pb2 import ( + Connection, ConnectionId, Device, DeviceDriverEnum, DeviceId, Service, ServiceId, + OpticalConfig, OpticalConfigId +) from common.tools.context_queries.Connection import get_connection_by_id from common.tools.context_queries.Device import get_device from common.tools.context_queries.Service import get_service_by_id @@ -25,7 +28,8 @@ from common.tools.object_factory.Device import json_device_id from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient from service.service.service_handler_api.Exceptions import ( - UnsatisfiedFilterException, UnsupportedFilterFieldException, UnsupportedFilterFieldValueException) + UnsatisfiedFilterException, UnsupportedFilterFieldException, UnsupportedFilterFieldValueException +) from service.service.service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory, get_service_handler_class from service.service.tools.ObjectKeys import get_connection_key, get_device_key, get_service_key @@ -114,39 +118,27 @@ class TaskExecutor: self._store_grpc_object(CacheableObjectType.DEVICE, device_key, device) # New function Andrea for Optical Devices - def configure_optical_device(self,device:Device,settings:str,flows:list,is_opticalband:bool): - - + def configure_optical_device(self, device : Device, settings : str, flows : list, is_opticalband : bool): device_key = get_device_key(device.device_id) - myid=OpticalConfigId() - myid.opticalconfig_uuid=device.device_id.device_uuid.uuid - opticalconfig=OpticalConfig() - - setting =settings.value if settings else "" - - new_config={} + myid = OpticalConfigId() + myid.opticalconfig_uuid = device.device_id.device_uuid.uuid + opticalconfig = OpticalConfig() + setting = settings.value if settings else "" + new_config = {} try: - result=self._context_client.SelectOpticalConfig(myid) - - new_config=json.loads(result.config) - - if result is not None : - - new_config["new_config"]=setting - new_config["is_opticalband"]=is_opticalband - new_config["flow"]=flows - result.config = str(new_config) - opticalconfig.CopyFrom(result) - - self._device_client.ConfigureOpticalDevice(opticalconfig) - - self._store_grpc_object(CacheableObjectType.DEVICE, device_key, device) + result = self._context_client.SelectOpticalConfig(myid) + new_config = json.loads(result.config) + if result is not None : + new_config["new_config"] = setting + new_config["is_opticalband"] = is_opticalband + new_config["flow"] = flows + result.config = str(new_config) + opticalconfig.CopyFrom(result) + self._device_client.ConfigureOpticalDevice(opticalconfig) + self._store_grpc_object(CacheableObjectType.DEVICE, device_key, device) except Exception as e: LOGGER.info("error in config my config %s",e) - - - - + def get_device_controller(self, device : Device) -> Optional[Device]: #json_controller = None #for config_rule in device.device_config.config_rules: diff --git a/src/service/service/tools/OpticalTools.py b/src/service/service/tools/OpticalTools.py index a5529adc8..8b3e3153b 100644 --- a/src/service/service/tools/OpticalTools.py +++ b/src/service/service/tools/OpticalTools.py @@ -15,45 +15,46 @@ import json import requests -import uuid ,os +import uuid from common.Constants import * from typing import Dict, List from common.proto.context_pb2 import( - Device, DeviceId, Service, Connection, EndPointId, TopologyId, ContextId, Uuid, ConfigRule, ConfigActionEnum, ConfigRule_Custom) + Device, DeviceId, Service, Connection, EndPointId, TopologyId, ContextId, Uuid, + ConfigRule, ConfigActionEnum, ConfigRule_Custom +) from common.proto.pathcomp_pb2 import PathCompReply from typing import Dict, List, Optional, Tuple from common.Constants import ServiceNameEnum from common.Settings import ( - ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, find_environment_variables ,get_env_var_name) + ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, find_environment_variables, get_env_var_name +) from context.service.database.uuids.EndPoint import endpoint_get_uuid - - from service.service.tools.replies import reply_uni_txt, optical_band_uni_txt, reply_bid_txt, optical_band_bid_txt log = logging.getLogger(__name__) testing = False - -opticalcontrollers_url= find_environment_variables([ - get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER,ENVVAR_SUFIX_SERVICE_HOST), - get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER,ENVVAR_SUFIX_SERVICE_PORT_GRPC), - ]) -OPTICAL_IP=opticalcontrollers_url[get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER,ENVVAR_SUFIX_SERVICE_HOST)] -OPTICAL_PORT=opticalcontrollers_url[get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER,ENVVAR_SUFIX_SERVICE_PORT_GRPC)] -log.info(OPTICAL_IP,OPTICAL_PORT) -def get_uuids_from_names(devices: List[Device], device_name: str, port_name: str): +VAR_NAME_OPTICAL_CONTROLLER_HOST = get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER, ENVVAR_SUFIX_SERVICE_HOST) +VAR_NAME_OPTICAL_CONTROLLER_PORT = get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER, ENVVAR_SUFIX_SERVICE_PORT_GRPC) + +opticalcontrollers_url = find_environment_variables([ + VAR_NAME_OPTICAL_CONTROLLER_HOST, + VAR_NAME_OPTICAL_CONTROLLER_PORT, +]) +OPTICAL_IP = opticalcontrollers_url.get(VAR_NAME_OPTICAL_CONTROLLER_HOST) +OPTICAL_PORT = opticalcontrollers_url.get(VAR_NAME_OPTICAL_CONTROLLER_PORT) +log.info(str(OPTICAL_IP), str(OPTICAL_PORT)) + +def get_uuids_from_names(devices: List[Device], device_name: str, port_name: str): device_uuid = "" port_uuid = "" for device in devices: if device.name == device_name: - device_uuid = device.device_id.device_uuid.uuid - for ep in device.device_endpoints: if ep.name == port_name: port_uuid = ep.endpoint_id.endpoint_uuid.uuid - return device_uuid, port_uuid return "", "" @@ -296,4 +297,4 @@ def add_service_to_reply(reply : PathCompReply, service : Service)-> Service: def add_connection_to_reply(reply : PathCompReply)-> Connection: conn = reply.connections.add() - return conn \ No newline at end of file + return conn diff --git a/src/tests/ofc24/README.md b/src/tests/ofc24/README.md index 3d01142cb..93e95fc64 100644 --- a/src/tests/ofc24/README.md +++ b/src/tests/ofc24/README.md @@ -1,10 +1,21 @@ -# start topology , 2 Transponders Openconfig and 2 multi granular Roadms : +# OFC'24 - Test scenario +## Start Topology +Topology is composed of 2 transponders managed through OpenConfig and 2 Multi-granular ROAMDS +Strat the topology executing the following command: +```bash sudo ./start_topo.sh +``` -# populate tfs context in (pushing the json files) following the file index , i.e : 1 , 2 -# last json is with ID 7 is the service , to check the service is onboarded successfully go into the srevice interface -# of tfs webGui -# to check if the devices are configured , run -screen -r tx with x = 1, 2,3 , 4 -# to release the terminal , press ctrl + a + d \ No newline at end of file +## Populate the TFS context and topology +Pushing the JSON files following the file indexes, i.e, 1, 2, 3, ... +The last JSON file with ID 7 is the service. +To check the service is onboarded successfully go into the TFS WebUI and check the `Service` tab. + +## Check configuration in devices +Check if the devices are configured properly. +To check that, run, for each device (X={1, 2, 3, 4}): +```bash +screen -r tX +``` +To release the terminal, press `Ctrl + A + D` diff --git a/src/tests/ofc24/start_topo.sh b/src/tests/ofc24/start_topo.sh index 760f9ab23..c92406476 100755 --- a/src/tests/ofc24/start_topo.sh +++ b/src/tests/ofc24/start_topo.sh @@ -1,6 +1,4 @@ #!/bin/bash -<<<<<<< HEAD:ofc24/start_topo.sh -======= # Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,11 +12,11 @@ # 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. ->>>>>>> d5bb84dd9f53b483dcb31ec12a061abe21668703:src/tests/ofc24/start_topo.sh IMAGE_NAME="asgamb1/oc23bgp.img:latest" -Docker_Container=$1 -Docker_Port="2022" +DOCKER_CONTAINER=$1 +DOCKER_PORT="2022" + sudo docker stop na1 -t 1 sudo docker stop na2 -t 1 sudo docker stop na3 -t 1 @@ -43,16 +41,14 @@ echo "Creating Transponder Agents" -screen -dmS t1 -T xterm sh -c "docker run -p 127.0.0.1:2023:2022 -v ~/tempOC/files:/files --name $Docker_Container -it asgamb1/oc23bgp.img:latest bash" +screen -dmS t1 -T xterm sh -c "docker run -p 127.0.0.1:2023:2022 -v ~/tempOC/files:/files --name $DOCKER_CONTAINER -it asgamb1/oc23bgp.img:latest bash" sleep 2 -if [ "$( docker container inspect -f '{{.State.Running}}' "$Docker_Container")" = "true" ]; then - - docker exec "$Docker_Container" cp /files/demoECOC21_4.xml demoECOC21.xml - - docker exec "$Docker_Container" /confd/examples.confd/OC23/startNetconfAgent.sh +if [ "$( docker container inspect -f '{{.State.Running}}' "$DOCKER_CONTAINER")" = "true" ]; then + docker exec "$DOCKER_CONTAINER" cp /files/demoECOC21_4.xml demoECOC21.xml + docker exec "$DOCKER_CONTAINER" /confd/examples.confd/OC23/startNetconfAgent.sh else echo "your container is not running yet" - +fi echo " It may take a while , Hang on ..." source "./startExtraNetConfigAgent.sh" "na1" "2023" @@ -61,9 +57,7 @@ sleep 3 source "./startExtraNetConfigAgent.sh" "na2" "2024" sleep 3 -R1 bash -c "cp /tempOC/files/plat_r1.xml /confd/examples.confd/OC23/init_openconfig-platform.xml; ./startNetconfAgent.sh" -R2 bash -c "cp /tempOC/files/plat_r2.xml /confd/examples.confd/OC23/init_openconfig-platform.xml; ./startNetconfAgent.sh" screen -dmS t3 -T xterm sh -c 'docker run -p 10.0.2.15:2025:2022 -v ~/tfs-ctrl/tempOC/files:/files --name na3 -it asgamb1/flexscale-node.img:latest ./startNetconfAgent.sh' screen -dmS t4 -T xterm sh -c 'docker run -p 10.0.2.15:2026:2022 -v ~/tfs-ctrl/tempOC/files:/files --name na4 -it asgamb1/flexscale-node.img:latest ./startNetconfAgent.sh' -- GitLab From a6adad8bef6d49eeb1ec50292b4fef0be2e59841 Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Thu, 7 Mar 2024 17:52:12 +0000 Subject: [PATCH 11/13] Optical controller: -Pre-merge cleanup --- my_deploy.sh | 3 + .../service/ServiceServiceServicerImpl.py | 132 +++++++++--------- src/service/service/__main__.py | 2 +- .../service/task_scheduler/TaskExecutor.py | 3 +- 4 files changed, 70 insertions(+), 70 deletions(-) diff --git a/my_deploy.sh b/my_deploy.sh index 87f6e2491..7dd5e5c3e 100755 --- a/my_deploy.sh +++ b/my_deploy.sh @@ -28,6 +28,9 @@ export TFS_COMPONENTS="context device pathcomp service slice nbi webui load_gene # Uncomment to activate BGP-LS Speaker #export TFS_COMPONENTS="${TFS_COMPONENTS} bgpls_speaker" +# Uncomment to activate Optical Controller +#export TFS_COMPONENTS="${TFS_COMPONENTS} opticalcontroller" + # Uncomment to activate ZTP #export TFS_COMPONENTS="${TFS_COMPONENTS} ztp" diff --git a/src/service/service/ServiceServiceServicerImpl.py b/src/service/service/ServiceServiceServicerImpl.py index d9789be5d..557b80bae 100644 --- a/src/service/service/ServiceServiceServicerImpl.py +++ b/src/service/service/ServiceServiceServicerImpl.py @@ -248,80 +248,78 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): if len(service_with_uuids.service_endpoint_ids) >= num_expected_endpoints: pathcomp_request = PathCompRequest() pathcomp_request.services.append(service_with_uuids) # pylint: disable=no-member + if service.service_type == ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY: - context_id_x = json_context_id(DEFAULT_CONTEXT_NAME) - topology_id_x = json_topology_id( - DEFAULT_TOPOLOGY_NAME, context_id_x) - topology_details = context_client.GetTopologyDetails( - TopologyId(**topology_id_x)) - # devices = get_devices_in_topology(context_client, TopologyId(**topology_id_x), ContextId(**context_id_x)) - devices = topology_details.devices - context_uuid_x = topology_details.topology_id.context_id.context_uuid.uuid - topology_uuid_x = topology_details.topology_id.topology_uuid.uuid - devs = [] - ports = [] - for endpoint_id in service.service_endpoint_ids: - devs.append(endpoint_id.device_id.device_uuid.uuid) - ports.append(endpoint_id.endpoint_uuid.uuid) - src = devs[0] - dst = devs[1] - bidir = None - ob_band = None - bitrate = 100 - for constraint in service.service_constraints: - if "bandwidth" in constraint.custom.constraint_type: - bitrate = int(float(constraint.custom.constraint_value)) - elif "bidirectionality" in constraint.custom.constraint_type: - bidir = int(constraint.custom.constraint_value) - elif "optical-band-width" in constraint.custom.constraint_type: - ob_band = int(constraint.custom.constraint_value) - - - # to get the reply form the optical module - reply_txt = add_lightpath(src, dst, bitrate, bidir, ob_band) - - # reply with 2 transponders and 2 roadms - reply_json = json.loads(reply_txt) - optical_band_txt = "" - if "new_optical_band" in reply_json.keys(): - if reply_json["new_optical_band"] == 1: - if reply_json["parent_opt_band"]: - if "parent_opt_band" in reply_json.keys(): - parent_ob = reply_json["parent_opt_band"] - LOGGER.debug('Parent optical-band={}'.format(parent_ob)) - optical_band_txt = get_optical_band(parent_ob) - LOGGER.info('optical-band details={}'.format(optical_band_txt)) - else: - LOGGER.debug('expected optical band not found') + context_id_x = json_context_id(DEFAULT_CONTEXT_NAME) + topology_id_x = json_topology_id( + DEFAULT_TOPOLOGY_NAME, context_id_x) + topology_details = context_client.GetTopologyDetails( + TopologyId(**topology_id_x)) + # devices = get_devices_in_topology(context_client, TopologyId(**topology_id_x), ContextId(**context_id_x)) + devices = topology_details.devices + context_uuid_x = topology_details.topology_id.context_id.context_uuid.uuid + topology_uuid_x = topology_details.topology_id.topology_uuid.uuid + devs = [] + ports = [] + for endpoint_id in service.service_endpoint_ids: + devs.append(endpoint_id.device_id.device_uuid.uuid) + ports.append(endpoint_id.endpoint_uuid.uuid) + src = devs[0] + dst = devs[1] + bidir = None + ob_band = None + bitrate = 100 + for constraint in service.service_constraints: + if "bandwidth" in constraint.custom.constraint_type: + bitrate = int(float(constraint.custom.constraint_value)) + elif "bidirectionality" in constraint.custom.constraint_type: + bidir = int(constraint.custom.constraint_value) + elif "optical-band-width" in constraint.custom.constraint_type: + ob_band = int(constraint.custom.constraint_value) + + # to get the reply form the optical module + reply_txt = add_lightpath(src, dst, bitrate, bidir, ob_band) + + # reply with 2 transponders and 2 roadms + reply_json = json.loads(reply_txt) + optical_band_txt = "" + if "new_optical_band" in reply_json.keys(): + if reply_json["new_optical_band"] == 1: + if reply_json["parent_opt_band"]: + if "parent_opt_band" in reply_json.keys(): + parent_ob = reply_json["parent_opt_band"] + LOGGER.debug('Parent optical-band={}'.format(parent_ob)) + optical_band_txt = get_optical_band(parent_ob) + LOGGER.info('optical-band details={}'.format(optical_band_txt)) else: LOGGER.debug('expected optical band not found') else: - LOGGER.debug('Using existing optical band') + LOGGER.debug('expected optical band not found') else: LOGGER.debug('Using existing optical band') - if reply_txt is not None: - optical_reply = adapt_reply(devices, _service, reply_json, context_uuid_x, topology_uuid_x, optical_band_txt) - LOGGER.info('optical_reply={:s}'.format( - grpc_message_to_json_string(optical_reply))) - - tasks_scheduler.compose_from_pathcompreply( - optical_reply, is_delete=False) - else: - if num_disjoint_paths is None or num_disjoint_paths in {0, 1} : - pathcomp_request.shortest_path.Clear() # pylint: disable=no-member - else: - pathcomp_request.k_disjoint_path.num_disjoint = num_disjoint_paths # pylint: disable=no-member + else: + LOGGER.debug('Using existing optical band') + if reply_txt is not None: + optical_reply = adapt_reply(devices, _service, reply_json, context_uuid_x, topology_uuid_x, optical_band_txt) + LOGGER.info('optical_reply={:s}'.format( + grpc_message_to_json_string(optical_reply))) + + tasks_scheduler.compose_from_pathcompreply( + optical_reply, is_delete=False) + else: + if num_disjoint_paths is None or num_disjoint_paths in {0, 1} : + pathcomp_request.shortest_path.Clear() # pylint: disable=no-member + else: + pathcomp_request.k_disjoint_path.num_disjoint = num_disjoint_paths # pylint: disable=no-member - - pathcomp = PathCompClient() - pathcomp_reply = pathcomp.Compute(pathcomp_request) - pathcomp.close() - + pathcomp = PathCompClient() + pathcomp_reply = pathcomp.Compute(pathcomp_request) + pathcomp.close() # Feed TaskScheduler with this path computation reply. TaskScheduler identifies inter-dependencies among # the services and connections retrieved and produces a schedule of tasks (an ordered list of tasks to be # executed) to implement the requested create/update operation. - tasks_scheduler.compose_from_pathcompreply(pathcomp_reply, is_delete=False) + tasks_scheduler.compose_from_pathcompreply(pathcomp_reply, is_delete=False) tasks_scheduler.execute_all() return service_with_uuids.service_id @@ -347,7 +345,7 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): if service.service_type == ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY: devs = [] - + context_id_x = json_context_id(DEFAULT_CONTEXT_NAME) topology_id_x = json_topology_id( DEFAULT_TOPOLOGY_NAME, context_id_x) @@ -358,17 +356,15 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): devs.append(endpoint_id.device_id.device_uuid.uuid) src = get_device_name_from_uuid(devices, devs[0]) dst = get_device_name_from_uuid(devices, devs[1]) - + bitrate = int( float(service.service_constraints[0].custom.constraint_value)) if len(service.service_config.config_rules) > 0: c_rules_dict = json.loads( service.service_config.config_rules[0].custom.resource_value) if ("flow_id" in c_rules_dict): - flow_id = c_rules_dict["flow_id"] - + flow_id = c_rules_dict["flow_id"] reply = delete_lightpath(flow_id, src, dst, bitrate) - # Normal service # Feed TaskScheduler with this service and the sub-services and sub-connections related to this service. diff --git a/src/service/service/__main__.py b/src/service/service/__main__.py index d096de8c6..edd4d8f99 100644 --- a/src/service/service/__main__.py +++ b/src/service/service/__main__.py @@ -45,7 +45,7 @@ def main(): get_env_var_name(ServiceNameEnum.PATHCOMP, ENVVAR_SUFIX_SERVICE_HOST ), get_env_var_name(ServiceNameEnum.PATHCOMP, ENVVAR_SUFIX_SERVICE_PORT_GRPC), ]) - + signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) diff --git a/src/service/service/task_scheduler/TaskExecutor.py b/src/service/service/task_scheduler/TaskExecutor.py index 8e5ad4ecc..5ed8aefdb 100644 --- a/src/service/service/task_scheduler/TaskExecutor.py +++ b/src/service/service/task_scheduler/TaskExecutor.py @@ -117,7 +117,7 @@ class TaskExecutor: self._device_client.ConfigureDevice(device) self._store_grpc_object(CacheableObjectType.DEVICE, device_key, device) - # New function Andrea for Optical Devices + # New function Andrea for Optical Devices def configure_optical_device(self, device : Device, settings : str, flows : list, is_opticalband : bool): device_key = get_device_key(device.device_id) myid = OpticalConfigId() @@ -125,6 +125,7 @@ class TaskExecutor: opticalconfig = OpticalConfig() setting = settings.value if settings else "" new_config = {} + try: result = self._context_client.SelectOpticalConfig(myid) new_config = json.loads(result.config) -- GitLab From a1357f94c147db63e441f1c3d4f218be5f212e7c Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Thu, 7 Mar 2024 17:55:25 +0000 Subject: [PATCH 12/13] Optical controller: -Pre-merge cleanup --- src/service/service/ServiceServiceServicerImpl.py | 6 ++++-- src/service/service/task_scheduler/TaskExecutor.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/service/service/ServiceServiceServicerImpl.py b/src/service/service/ServiceServiceServicerImpl.py index 557b80bae..f65d5b59a 100644 --- a/src/service/service/ServiceServiceServicerImpl.py +++ b/src/service/service/ServiceServiceServicerImpl.py @@ -279,7 +279,7 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): # to get the reply form the optical module reply_txt = add_lightpath(src, dst, bitrate, bidir, ob_band) - + # reply with 2 transponders and 2 roadms reply_json = json.loads(reply_txt) optical_band_txt = "" @@ -300,7 +300,9 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): else: LOGGER.debug('Using existing optical band') if reply_txt is not None: - optical_reply = adapt_reply(devices, _service, reply_json, context_uuid_x, topology_uuid_x, optical_band_txt) + optical_reply = adapt_reply( + devices, _service, reply_json, context_uuid_x, topology_uuid_x, optical_band_txt + ) LOGGER.info('optical_reply={:s}'.format( grpc_message_to_json_string(optical_reply))) diff --git a/src/service/service/task_scheduler/TaskExecutor.py b/src/service/service/task_scheduler/TaskExecutor.py index 5ed8aefdb..b9715aae6 100644 --- a/src/service/service/task_scheduler/TaskExecutor.py +++ b/src/service/service/task_scheduler/TaskExecutor.py @@ -124,8 +124,8 @@ class TaskExecutor: myid.opticalconfig_uuid = device.device_id.device_uuid.uuid opticalconfig = OpticalConfig() setting = settings.value if settings else "" - new_config = {} + new_config = {} try: result = self._context_client.SelectOpticalConfig(myid) new_config = json.loads(result.config) -- GitLab From 9bbd885041d058b04954b4c827d89955f94eca20 Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Thu, 7 Mar 2024 17:56:44 +0000 Subject: [PATCH 13/13] TFS Deployment scripts: - Reduced wait timeout during deployments --- deploy/tfs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/tfs.sh b/deploy/tfs.sh index 3a01606ce..19c0d75a0 100755 --- a/deploy/tfs.sh +++ b/deploy/tfs.sh @@ -364,7 +364,7 @@ for COMPONENT in $TFS_COMPONENTS; do echo "Waiting for '$COMPONENT' component..." COMPONENT_OBJNAME=$(echo "${COMPONENT}" | sed "s/\_/-/") kubectl wait --namespace $TFS_K8S_NAMESPACE \ - --for='condition=available' --timeout=300s deployment/${COMPONENT_OBJNAME}service + --for='condition=available' --timeout=90s deployment/${COMPONENT_OBJNAME}service printf "\n" done -- GitLab