diff --git a/deploy/tfs.sh b/deploy/tfs.sh index 3a01606ce32369d0f0968282569eaf4ed59d778c..19c0d75a095bc5dc239d1d95237378bcf2fbb8da 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/manifests/opticalcontrollerservice.yaml b/manifests/opticalcontrollerservice.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4b677ee4f7287b0790aaa0b19f034db03978fac0 --- /dev/null +++ b/manifests/opticalcontrollerservice.yaml @@ -0,0 +1,72 @@ +# 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: + name: opticalcontrollerservice +spec: + selector: + matchLabels: + app: opticalcontrollerservice + replicas: 1 + template: + metadata: + labels: + app: opticalcontrollerservice + spec: + terminationGracePeriodSeconds: 5 + containers: + - 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: + app: opticalcontrollerservice +spec: + type: ClusterIP + selector: + app: opticalcontrollerservice + ports: + - name: grpc + protocol: TCP + port: 10060 + targetPort: 10060 + - name: metrics + protocol: TCP + port: 9192 + targetPort: 9192 diff --git a/my_deploy.sh b/my_deploy.sh index 0c5ba03c5b9f63038a622f44ab2dfaaf1e7e6ada..7dd5e5c3ee13cbce2b701b5b4e703823dfb2c28f 100755 --- a/my_deploy.sh +++ b/my_deploy.sh @@ -25,9 +25,12 @@ export TFS_COMPONENTS="context device pathcomp service slice nbi webui load_gene # Uncomment to activate Monitoring #export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" -# Uncomment to activate bgpls_speaker +# 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/ofc24 b/ofc24 new file mode 120000 index 0000000000000000000000000000000000000000..baae92c8e249f4abfbbcf9739c9162087fefbacd --- /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 d5022ac292f04cd2e9b80f690be3077e7aedd868..8a6b019dc99863da32631425d954afbaf167f1b7 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 GetOpticalConfig (Empty ) returns (OpticalConfigList ) {} + rpc SetOpticalConfig (OpticalConfig ) returns (OpticalConfigId ) {} + rpc SelectOpticalConfig(OpticalConfigId) returns (OpticalConfig ) {} + + rpc SetOpticalLink (OpticalLink ) returns (Empty ) {} + rpc GetOpticalLink (OpticalLinkId ) returns (OpticalLink ) {} + rpc GetFiber (FiberId ) returns (Fiber ) {} } // ----- Generic ------------------------------------------------------------------------------------------------------- @@ -203,6 +213,7 @@ enum DeviceDriverEnum { DEVICEDRIVER_GNMI_OPENCONFIG = 8; DEVICEDRIVER_FLEXSCALE = 9; DEVICEDRIVER_IETF_ACTN = 10; + DEVICEDRIVER_OC = 11; } 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,53 @@ message AuthenticationResult { ContextId context_id = 1; bool authenticated = 2; } + +// ---------------- Experimental ------------------------ +message OpticalConfigId { + string opticalconfig_uuid = 1; +} +message OpticalConfig { + OpticalConfigId opticalconfig_id = 1; + string config = 2; +} + +message OpticalConfigList { + repeated OpticalConfig opticalconfigs = 1; +} + +// ---- Optical Link ---- + +message OpticalLinkId { + Uuid optical_link_uuid = 1; +} + +message FiberId { + Uuid fiber_uuid = 1; +} + +message Fiber { + string ID = 10; + string src_port = 1; + string dst_port = 2; + string local_peer_port = 3; + string remote_peer_port = 4; + repeated int32 c_slots = 5; + repeated int32 l_slots = 6; + repeated int32 s_slots = 7; + float length = 8; + bool used = 9; + FiberId fiber_uuid = 11; + +} +message OpticalLinkDetails { + float length = 1; + string source = 2; + string target = 3; + repeated Fiber fibers = 4; +} + +message OpticalLink { + string name = 1; + OpticalLinkDetails details = 2; + OpticalLinkId optical_link_uuid = 3; +} diff --git a/proto/openconfig_device.proto b/proto/openconfig_device.proto new file mode 100644 index 0000000000000000000000000000000000000000..913ac247eaab89efb7d6de9f64b2730378937738 --- /dev/null +++ b/proto/openconfig_device.proto @@ -0,0 +1,23 @@ +// 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"; + +service OpenConfigService { + 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 new file mode 100755 index 0000000000000000000000000000000000000000..17af5483c59e4d97a5534b388d006f5be00030e5 --- /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 diff --git a/src/common/Constants.py b/src/common/Constants.py index c7ba01f69978fd3c601dcfe30180015d524b1100..a1913a951aeaa968a594fc3bafcb49581459a0e0 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 @@ -87,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/common/tools/descriptor/Tools.py b/src/common/tools/descriptor/Tools.py index b4a76ff4f00d0f6886895cca0ab6f27f7aa8aa43..e95fc756052bf792f0009518b19991b8e87bac68 100644 --- a/src/common/tools/descriptor/Tools.py +++ b/src/common/tools/descriptor/Tools.py @@ -15,6 +15,7 @@ import copy, json 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) @@ -95,7 +96,8 @@ 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) diff --git a/src/context/client/ContextClient.py b/src/context/client/ContextClient.py index 13d9dc0035b45845bf11367e02c8830b5151c1d6..48a635cccd19f5985721a6a737fb8a2e5bd260b2 100644 --- a/src/context/client/ContextClient.py +++ b/src/context/client/ContextClient.py @@ -26,7 +26,9 @@ 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, + 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 @@ -436,3 +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 ////////////////// + + @RETRY_DECORATOR + 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('SetOpticalConfig result: {:s}'.format(grpc_message_to_json_string(response))) + return response + + @RETRY_DECORATOR + 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('SelectOpticalConfig request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.SelectOpticalConfig(request) + 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 5aad7f9c9ff3a6fd063b1f364256e760f47e1c33..a102fa17629bd866d96883230a542a6e7a4d92ff 100644 --- a/src/context/service/ContextServiceServicerImpl.py +++ b/src/context/service/ContextServiceServicerImpl.py @@ -23,7 +23,9 @@ 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, + 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 @@ -43,6 +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 LOGGER = logging.getLogger(__name__) @@ -296,3 +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(self.db_engine) + return OpticalConfigList(OpticalConfigs=result) + + @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/Device.py b/src/context/service/database/Device.py index 3aff20ade14532dcb7fbf8ec1033c084aaeead3c..737ad7add7a27580503e7f812e3064b879c191b5 100644 --- a/src/context/service/database/Device.py +++ b/src/context/service/database/Device.py @@ -21,7 +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) + 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 @@ -103,10 +105,12 @@ 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) + 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/OpticalConfig.py b/src/context/service/database/OpticalConfig.py new file mode 100644 index 0000000000000000000000000000000000000000..9e7552bc111e40245bb649d2eb1ffa910c6f8588 --- /dev/null +++ b/src/context/service/database/OpticalConfig.py @@ -0,0 +1,88 @@ +# 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.dialects.postgresql import insert +from sqlalchemy.engine import Engine +from sqlalchemy.orm import Session, sessionmaker +from sqlalchemy_cockroachdb import run_transaction +from common.proto.context_pb2 import OpticalConfig, OpticalConfigId +from .models.OpticalConfigModel import OpticalConfigModel + +LOGGER = logging.getLogger(__name__) + +def get_opticalconfig(db_engine : Engine): + def callback(session:Session): + optical_configs = list() + results = session.query(OpticalConfigModel).all() + for obj in results: + 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 = [] + 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 = [ + { + "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} + +def select_opticalconfig(db_engine:Engine,request:OpticalConfigId): + def callback(session : Session) -> OpticalConfig: + 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) diff --git a/src/context/service/database/Service.py b/src/context/service/database/Service.py index fc196ddded291aa82c8f9df932c15611d13121e4..337bf592f785db97d5924aa7da17772c35eac1b2 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 @@ -84,6 +86,9 @@ def service_set(db_engine : Engine, messagebroker : MessageBroker, request : Ser 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) + 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 new file mode 100644 index 0000000000000000000000000000000000000000..10cf197f9a8a728b8fd02bdcdaf255677551bf17 --- /dev/null +++ b/src/context/service/database/models/OpticalConfigModel.py @@ -0,0 +1,42 @@ +# 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 +from sqlalchemy import Column, String, Integer +from sqlalchemy.dialects.postgresql import ARRAY +from ._Base import _Base + +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): + 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 8e15bf058599eeed0629fc1249af0d052183db28..2ccdda2725a7f7bb13ba296d4eca25f88b1e73d1 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 ce198f8c1f795f25da547e2d5974059062489709..01ed68c1708dc617a46edc31e94fc07d79e278e1 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 32fa685b953232808acba273e7d30514922c04eb..3fde3df778e32df20c863ff110a1eb572f38d177 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,8 +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 7592e5b58f45d7745a045643f4669e4d957134f3..76fb6545430f4802d7d37c0c35a35a0539aa200e 100644 --- a/src/device/service/DeviceServiceServicerImpl.py +++ b/src/device/service/DeviceServiceServicerImpl.py @@ -20,7 +20,8 @@ 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 @@ -60,9 +61,9 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): 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() context_client = ContextClient() @@ -143,12 +144,12 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): device.device_operational_status = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED # temporary line - if (request.device_drivers[0]== 9 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 5be11cb31ec69825a2b6009159e5202b54936009..1060449f185330faa0a71ff062ad2bbd0086b2e4 100644 --- a/src/device/service/OpenConfigServicer.py +++ b/src/device/service/OpenConfigServicer.py @@ -12,18 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -import grpc, logging, os, time -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, MyConfig, MyConfigId, - MyConfig, MyConfigList + Device, DeviceId, DeviceOperationalStatusEnum, Empty, OpticalConfig, OpticalConfig ) -from common.proto.device_pb2 import MonitoringSettings 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 @@ -31,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__) @@ -54,14 +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 : MyConfig, context : grpc.ServicerContext) -> DeviceId: - + def AddOpenConfigDevice(self, request : OpticalConfig, 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,61 +59,37 @@ 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) @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)) + def ConfigureOpticalDevice (self, request : OpticalConfig, context : grpc.ServicerContext) -> Empty: + device_uuid = request.opticalconfig_id.opticalconfig_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( context_client, device_uuid, rw_copy=True, include_endpoints=True, include_components=False, 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 + #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) - - - 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 8ccb77afa712d77a66f4d971340f93231bbaf0a6..f3700e10488228387145a2c4c8574a899675aade 100644 --- a/src/device/service/Tools.py +++ b/src/device/service/Tools.py @@ -12,30 +12,26 @@ # 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} @@ -456,76 +452,73 @@ def update_endpoints(src_device : Device, dst_device : Device) -> None: 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 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): +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 = 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 - #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'): + 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'): + 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': '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/device/service/drivers/__init__.py b/src/device/service/drivers/__init__.py index 09c4d33b70ffce893ce9ea08b2e67e0a12d350ef..1e8cff6052d840af2aa57ff22793380f06f16356 100644 --- a/src/device/service/drivers/__init__.py +++ b/src/device/service/drivers/__init__.py @@ -172,11 +172,9 @@ if LOAD_ALL_DEVICE_DRIVERS: from .oc_driver.OCDriver import OCDriver # pylint: disable=wrong-import-position DRIVERS.append( (OCDriver, [ - { # Real Packet Router, specifying OpenConfig Driver => use OpenConfigDriver FilterFieldEnum.DEVICE_TYPE: [ - DeviceTypeEnum.NETCONFIG_AGENT, DeviceTypeEnum.OPTICAL_ROADM, DeviceTypeEnum.OPTICAL_TRANSPONDER ], diff --git a/src/device/service/drivers/oc_driver/OCDriver.py b/src/device/service/drivers/oc_driver/OCDriver.py index 512ec49baa66ed7a5cb4062c2ddf34bff81f9cde..16f00cfb4c7b80d807882ab5b4c95b36b28db8f6 100644 --- a/src/device/service/drivers/oc_driver/OCDriver.py +++ b/src/device/service/drivers/oc_driver/OCDriver.py @@ -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 @@ -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,15 +239,15 @@ 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() + opticalConfig= OpticalConfig() j=0 with self.__lock: - self.__logger.info(" resources_key %s",resource_keys) + context_client.connect() config={} channels_lst=[] @@ -301,12 +273,10 @@ 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.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/Tools.py b/src/device/service/drivers/oc_driver/templates/Tools.py index 4370495c912dafbc2c5165e00fc79ec885536a4d..909bdd83bf4c189da0a778268ce40119cca7c452 100644 --- a/src/device/service/drivers/oc_driver/templates/Tools.py +++ b/src/device/service/drivers/oc_driver/templates/Tools.py @@ -92,7 +92,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 +121,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 +228,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 ba0de7ea6fded64b457ffa348f80ca294c89cfdf..355858d2da891d96777d111f481c070fe3036d44 100644 --- a/src/device/service/drivers/oc_driver/templates/VPN/physical.py +++ b/src/device/service/drivers/oc_driver/templates/VPN/physical.py @@ -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 e8e0e2164a81f6ea621decba92350b04cdcba814..c2805695a75933c73d4ad367176bee8b504d4460 100644 --- a/src/opticalcontroller/OpticalController.py +++ b/src/opticalcontroller/OpticalController.py @@ -198,7 +198,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 +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) - LOGGER.info(rsa.init_link_slots(testing)) - 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/opticalcontroller/RSA.py b/src/opticalcontroller/RSA.py index acf080d7f9c223766409551051b7cacae1610db1..9b12b1ac8d9302c2bb622b2d4b81924b5453036c 100644 --- a/src/opticalcontroller/RSA.py +++ b/src/opticalcontroller/RSA.py @@ -322,11 +322,14 @@ class RSA(): return fiber_list def get_link_by_name (self, key): + result = None for link in self.links_dict["links"]: if link["optical_link"]["name"] == key: if debug: print(link) - return link + result = link + break + return result def get_fiber_details(self, link_key, fiber_id): for link in self.links_dict["links"]: @@ -787,6 +790,13 @@ 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 + 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 print("INFO: TP to TP connection") if band is None: temp_links2 = [] @@ -806,13 +816,7 @@ class RSA(): temp_path.append(roadm_dst) temp_path.append(t_dst) existing_ob = self.get_optical_bands(roadm_src, roadm_dst) - 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 + if len(existing_ob) > 0: print("INFO: Evaluating existing OB {}".format(existing_ob)) @@ -875,13 +879,13 @@ 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) - 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 + # 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 if debug: print(temp_links) diff --git a/src/opticalcontroller/json_files/tfs.json b/src/opticalcontroller/json_files/tfs.json index a108ed13ee5fe85c974e41e8ff6fe5ed5dd7d2ed..31803b893b5639e957be33465599573baa475ca2 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/service/service/ServiceServiceServicerImpl.py b/src/service/service/ServiceServiceServicerImpl.py index b06295deee528656ae30ed33e4dacc7d7d04a178..f65d5b59a0d9a81c44f4d04683eb87e7773efa4a 100644 --- a/src/service/service/ServiceServiceServicerImpl.py +++ b/src/service/service/ServiceServiceServicerImpl.py @@ -255,6 +255,7 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): 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 @@ -289,7 +290,7 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): 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)) + LOGGER.info('optical-band details={}'.format(optical_band_txt)) else: LOGGER.debug('expected optical band not found') else: @@ -302,22 +303,20 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): optical_reply = adapt_reply( devices, _service, reply_json, context_uuid_x, topology_uuid_x, optical_band_txt ) - LOGGER.debug('optical_reply={:s}'.format( + LOGGER.info('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}: + 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))) # 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 @@ -348,7 +347,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) @@ -359,16 +358,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) - 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 # 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 f2b6e38d6181a0c56b4f1dfca3116717d1400ced..edd4d8f9973e20d0df6e2d99ba8164d5d68f068d 100644 --- a/src/service/service/__main__.py +++ b/src/service/service/__main__.py @@ -17,7 +17,8 @@ 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 +) from .ServiceService import ServiceService from .service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory from .service_handlers import SERVICE_HANDLERS diff --git a/src/service/service/service_handler_api/FilterFields.py b/src/service/service/service_handler_api/FilterFields.py index e771e24f17b2ea97c61158b65cb62c87ee9f37c5..633f41b63c71727d9ead0ee57b79002dc3a6cd97 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 8ae42639315287cada0ca288cd5593240819cfc5..6359f2a09e53cab1002acd55d477aeb2d9b393b0 100644 --- a/src/service/service/service_handlers/oc/OCServiceHandler.py +++ b/src/service/service/service_handlers/oc/OCServiceHandler.py @@ -15,14 +15,14 @@ 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 .ConfigRules import setup_config_rules, teardown_config_rules from .OCTools import convert_endpoints_to_flows, handle_flows_names LOGGER = logging.getLogger(__name__) @@ -53,30 +53,32 @@ class OCServiceHandler(_ServiceHandler): else: settings = self.__settings_handler.get('/settings') - LOGGER.debug("settings={}".format(settings)) - # settings = self.__settings_handler.get('/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)) + + 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) - + return results @metered_subclass_method(METRICS_POOL) @@ -86,14 +88,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 f40cb65bef2af5b69628c4167218bed59c92e317..2b202a8a9ce2183342fc23f3563cc16d81abcd5d 100644 --- a/src/service/service/service_handlers/oc/OCTools.py +++ b/src/service/service/service_handlers/oc/OCTools.py @@ -17,6 +17,7 @@ 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,6 +27,7 @@ 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) if isinstance(endpoints,list) else 0 end = len(endpoints) i = 0 bidir = 0 diff --git a/src/service/service/task_scheduler/TaskExecutor.py b/src/service/service/task_scheduler/TaskExecutor.py index 6d24da4c0be05e1687536a836219bbfa15052504..b9715aae637bb8845077bfc2b8b9b9d1bb030645 100644 --- a/src/service/service/task_scheduler/TaskExecutor.py +++ b/src/service/service/task_scheduler/TaskExecutor.py @@ -12,12 +12,13 @@ # 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, MyConfig, MyConfigId + 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 @@ -27,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 @@ -110,7 +112,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,28 +120,25 @@ class TaskExecutor: # 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 = 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) - new_config = eval(result.config) - LOGGER.info("result %s",result) + 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 + 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) - + opticalconfig.CopyFrom(result) + self._device_client.ConfigureOpticalDevice(opticalconfig) self._store_grpc_object(CacheableObjectType.DEVICE, device_key, device) except Exception as e: - LOGGER.debug("error in config my config %s",e) + LOGGER.info("error in config my config %s",e) def get_device_controller(self, device : Device) -> Optional[Device]: #json_controller = None diff --git a/src/service/service/tools/OpticalTools.py b/src/service/service/tools/OpticalTools.py index 227be2765fbd6bbc779e53505b833fc8bf08873f..8b3e3153beb53063b17ae7998e8a7d49f8abd64e 100644 --- a/src/service/service/tools/OpticalTools.py +++ b/src/service/service/tools/OpticalTools.py @@ -19,33 +19,42 @@ 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 +) 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 = True - +testing = False -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 "", "" @@ -134,6 +143,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 +186,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 +194,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 +233,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 +273,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) diff --git a/src/tests/ofc24/1.context.json b/src/tests/ofc24/1.context.json new file mode 100755 index 0000000000000000000000000000000000000000..36b3c44fd61fdec9d208a82a11d5a16c3671d004 --- /dev/null +++ b/src/tests/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/src/tests/ofc24/2.device1.json b/src/tests/ofc24/2.device1.json new file mode 100755 index 0000000000000000000000000000000000000000..3e31f31eb84630415f96b6af1e6ae5d34bdb1c89 --- /dev/null +++ b/src/tests/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/src/tests/ofc24/3.device2.json b/src/tests/ofc24/3.device2.json new file mode 100755 index 0000000000000000000000000000000000000000..812affa7b8540b67f83d6f3c9bb9b5442c44fd0d --- /dev/null +++ b/src/tests/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/src/tests/ofc24/4.device3_R1.json b/src/tests/ofc24/4.device3_R1.json new file mode 100755 index 0000000000000000000000000000000000000000..3a57ba79cd2ff8aa6d4b666ac382932ade2f20e0 --- /dev/null +++ b/src/tests/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/src/tests/ofc24/5.device4_R2.json b/src/tests/ofc24/5.device4_R2.json new file mode 100755 index 0000000000000000000000000000000000000000..9b1968d095c3e2c28c058b22f7295d7d1cbda380 --- /dev/null +++ b/src/tests/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/src/tests/ofc24/6.links.json b/src/tests/ofc24/6.links.json new file mode 100755 index 0000000000000000000000000000000000000000..eb2d004fc8e5484c5ae9eaafa6ec86efb49eb729 --- /dev/null +++ b/src/tests/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/src/tests/ofc24/7.service-bidir.json b/src/tests/ofc24/7.service-bidir.json new file mode 100755 index 0000000000000000000000000000000000000000..05547a19d2d375d2a8202266b1a1a5ffcfe46eb6 --- /dev/null +++ b/src/tests/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/src/tests/ofc24/7.service-unidir.json b/src/tests/ofc24/7.service-unidir.json new file mode 100755 index 0000000000000000000000000000000000000000..d9b4e88479c17aaf03f65d08b8d4b0ca22121e74 --- /dev/null +++ b/src/tests/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/src/tests/ofc24/README.md b/src/tests/ofc24/README.md new file mode 100644 index 0000000000000000000000000000000000000000..93e95fc642273bf852c829d6fae14cddf8ccba96 --- /dev/null +++ b/src/tests/ofc24/README.md @@ -0,0 +1,21 @@ +# 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 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/plat_r1.xml b/src/tests/ofc24/plat_r1.xml new file mode 100755 index 0000000000000000000000000000000000000000..47e135c2e3752de21dbe2f17550026e9622f4de1 --- /dev/null +++ b/src/tests/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/src/tests/ofc24/plat_r2.xml b/src/tests/ofc24/plat_r2.xml new file mode 100755 index 0000000000000000000000000000000000000000..dfaaf05ad7134a950ec11f411037b9a058b7d719 --- /dev/null +++ b/src/tests/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/src/tests/ofc24/startExtraNetConfigAgent.sh b/src/tests/ofc24/startExtraNetConfigAgent.sh new file mode 100755 index 0000000000000000000000000000000000000000..d9428585ef1040bb0440bf6db100b7f2bc71c970 --- /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/src/tests/ofc24/start_topo.sh b/src/tests/ofc24/start_topo.sh new file mode 100755 index 0000000000000000000000000000000000000000..c924064763c14e4da45344cd21f4d9c81c9640a9 --- /dev/null +++ b/src/tests/ofc24/start_topo.sh @@ -0,0 +1,63 @@ +#!/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. + +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 +sudo docker stop na4 -t 1 + +sudo docker rm na2 +sudo docker rm na1 +sudo docker rm na3 +sudo docker rm na4 + +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" +fi + +echo " It may take a while , Hang on ..." +source "./startExtraNetConfigAgent.sh" "na1" "2023" +sleep 3 + +source "./startExtraNetConfigAgent.sh" "na2" "2024" +sleep 3 + +bash -c "cp /tempOC/files/plat_r1.xml /confd/examples.confd/OC23/init_openconfig-platform.xml; ./startNetconfAgent.sh" +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' diff --git a/src/tests/ofc24/t1.xml b/src/tests/ofc24/t1.xml new file mode 100755 index 0000000000000000000000000000000000000000..712615df8dd821ff8e79df9785d6d29324a25b7d --- /dev/null +++ b/src/tests/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/src/tests/ofc24/t2.xml b/src/tests/ofc24/t2.xml new file mode 100755 index 0000000000000000000000000000000000000000..3a35e7e87eac7b14cd2bfa693560cc653f3719b9 --- /dev/null +++ b/src/tests/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 + + + + + +