diff --git a/.context.log.swp b/.context.log.swp deleted file mode 100644 index 6a5328d3f841c922f1450e5517e2e576a481c914..0000000000000000000000000000000000000000 Binary files a/.context.log.swp and /dev/null differ diff --git a/my_deploy.sh b/my_deploy.sh index c05da4c5f332adebe2d3943cdfc4d086bd675bf5..d84430ecb258363868650b586d8796281e232642 100755 --- a/my_deploy.sh +++ b/my_deploy.sh @@ -99,7 +99,7 @@ export CRDB_DATABASE="tfs" export CRDB_DEPLOY_MODE="single" # Disable flag for dropping database, if it exists. -export CRDB_DROP_DATABASE_IF_EXISTS="YES" +export CRDB_DROP_DATABASE_IF_EXISTS="" # Disable flag for re-deploying CockroachDB from scratch. export CRDB_REDEPLOY="" diff --git a/proto/openconfig_device.proto b/proto/openconfig_device.proto index 913ac247eaab89efb7d6de9f64b2730378937738..7ecb591f7d1fb4e3a29e7a35cf61c7af19a09b0d 100644 --- a/proto/openconfig_device.proto +++ b/proto/openconfig_device.proto @@ -20,4 +20,5 @@ import "context.proto"; service OpenConfigService { rpc AddOpenConfigDevice (context.OpticalConfig) returns (context.OpticalConfigId) {} rpc ConfigureOpticalDevice(context.OpticalConfig) returns (context.Empty ) {} + rpc DisableOpticalDevice(context.OpticalConfig) returns (context.Empty ) {} } diff --git a/src/context/service/database/Device.py b/src/context/service/database/Device.py index 3664e400219391edb18bfb65a9866caae994858b..fefb48b3a0242dfb9907647fe7a84abd5b59220d 100644 --- a/src/context/service/database/Device.py +++ b/src/context/service/database/Device.py @@ -39,7 +39,7 @@ from .uuids.EndPoint import endpoint_get_uuid from .ConfigRule import compose_config_rules_data, upsert_config_rules from .Component import compose_components_data from .Events import notify_event_context, notify_event_device, notify_event_topology -from .models.OpticalEndPointModel import OpticalEndPointModel + LOGGER = logging.getLogger(__name__) diff --git a/src/context/service/database/OpticalConfig.py b/src/context/service/database/OpticalConfig.py index f4a32a29cb85fac24516980975be8dc0bf85192b..f068d758b08ac02660af915f9779a0553599f46d 100644 --- a/src/context/service/database/OpticalConfig.py +++ b/src/context/service/database/OpticalConfig.py @@ -70,6 +70,7 @@ def set_opticalconfig(db_engine : Engine, request : OpticalConfig): "frequency" : int(channel_params["frequency"]) if "frequency" in channel_params else 0, "operational_mode" : int(channel_params["operational-mode"]) if "operational-mode" in channel_params else 0, "target_output_power" : channel_params["target-output-power"] if "target-output-power" in channel_params else '', + "status":channel_params["status"] if "status" in channel_params else "" } ) diff --git a/src/context/service/database/OpticalLink.py b/src/context/service/database/OpticalLink.py index b6efabbff47361c3dbad655a76f57a0cfc5ad598..c22813edf9409172fef50f326beee8f1545e2216 100644 --- a/src/context/service/database/OpticalLink.py +++ b/src/context/service/database/OpticalLink.py @@ -25,7 +25,7 @@ from common.method_wrappers.ServiceExceptions import NotFoundException from common.tools.object_factory.Link import json_link_id from context.service.database.uuids.Topology import topology_get_uuid from .models.OpticalLinkModel import OpticalLinkModel,OpticalLinkEndPointModel -from .models.OpticalEndPointModel import OpticalEndPointModel + from .models.TopologyModel import TopologyOpticalLinkModel, TopologyModel from .uuids.OpticalEndPoint import optical_endpoint_get_uuid from .uuids.Link import link_get_uuid @@ -121,7 +121,7 @@ def optical_link_set(db_engine : Engine, messagebroker : MessageBroker, request }] - LOGGER.info(f"setting Optical link data {optical_link_data}") + def callback(session : Session) -> Tuple[bool, List[Dict]]: stmt = insert(OpticalLinkModel).values(optical_link_data) stmt = stmt.on_conflict_do_update( @@ -140,7 +140,7 @@ def optical_link_set(db_engine : Engine, messagebroker : MessageBroker, request if len(link_endpoints_data) > 0: - LOGGER.info(f"from OpticalLink Model endpoint data {link_endpoints_data}") + stmt = insert(OpticalLinkEndPointModel).values(link_endpoints_data) stmt = stmt.on_conflict_do_nothing( index_elements=[OpticalLinkEndPointModel.link_uuid, OpticalLinkEndPointModel.endpoint_uuid] @@ -180,13 +180,14 @@ def optical_link_set(db_engine : Engine, messagebroker : MessageBroker, request def optical_link_delete(db_engine : Engine, messagebroker : MessageBroker, request : LinkId) -> Empty: link_uuid = link_get_uuid(request, allow_random=False) + LOGGER.info(f"deleteing optical link {link_uuid}") def callback(session : Session) -> bool: - - query = query.filter_by(link_uuid=link_uuid) + num_deleted = session.query(OpticalLinkModel).filter_by(opticallink_uuid=link_uuid).delete() return num_deleted > 0 deleted = run_transaction(sessionmaker(bind=db_engine), callback) + LOGGER.info(f"deleted {deleted}") link_id = json_link_id(link_uuid) if deleted: notify_event_link(messagebroker, EventTypeEnum.EVENTTYPE_REMOVE, link_id) diff --git a/src/context/service/database/models/OpticalConfigModel.py b/src/context/service/database/models/OpticalConfigModel.py index 6af2d0bf57cd8e51a07d80e103184a81edde2d21..cd819bf861b6c9e0b9a70a5f29d777515dd4aab8 100644 --- a/src/context/service/database/models/OpticalConfigModel.py +++ b/src/context/service/database/models/OpticalConfigModel.py @@ -13,7 +13,7 @@ # limitations under the License. import json -from sqlalchemy import Column, String, Integer , ForeignKey +from sqlalchemy import Column, String, Integer , ForeignKey, Boolean from sqlalchemy.dialects.postgresql import ARRAY from sqlalchemy.orm import relationship from ._Base import _Base @@ -26,8 +26,10 @@ class OpticalConfigModel(_Base): interfaces = Column(String, nullable=True) channel_namespace = Column(String, nullable=True) endpoints = Column(ARRAY(String), nullable=True) + channels = relationship("OpticalChannelModel") + device_uuid = Column(ForeignKey("device.device_uuid",ondelete="CASCADE"),index=True ,nullable=False) device= relationship("DeviceModel", back_populates='optical_config') @@ -53,13 +55,14 @@ class OpticalConfigModel(_Base): class OpticalChannelModel(_Base): __tablename__ = 'optical_channel' - channel_uuid = Column(String, primary_key=True) - channel_name = Column (String,nullable=True) + channel_uuid = Column(String, primary_key=True) + channel_name = Column (String,nullable=True) frequency = Column(Integer, nullable=True) operational_mode = Column(Integer, nullable=True) + status = Column(String , nullable=True) target_output_power = Column(String, nullable=True) - opticalconfig_uuid = Column(ForeignKey('optical_config.opticalconfig_uuid', ondelete='CASCADE' ), primary_key=True) - opticalconfig = relationship('OpticalConfigModel', back_populates='channels') + opticalconfig_uuid = Column(ForeignKey('optical_config.opticalconfig_uuid', ondelete='CASCADE' ), primary_key=True) + opticalconfig = relationship('OpticalConfigModel', back_populates='channels') def dump_id (self ): return { "channel_uuid":self.channel_uuid @@ -71,5 +74,6 @@ class OpticalChannelModel(_Base): "frequency" : self.frequency, "target-output-power" : self.target_output_power, "operational-mode" : self.operational_mode, + "status":self.status } diff --git a/src/context/service/database/models/OpticalEndPointModel.py b/src/context/service/database/models/OpticalEndPointModel.py deleted file mode 100644 index 1500dbc60ffdb916889d8d6fad42a028c97776d6..0000000000000000000000000000000000000000 --- a/src/context/service/database/models/OpticalEndPointModel.py +++ /dev/null @@ -1,69 +0,0 @@ -# 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 operator -from sqlalchemy import CheckConstraint, Column, DateTime, Float, ForeignKey, Integer, String ,Boolean -from sqlalchemy.dialects.postgresql import UUID -from sqlalchemy.types import ARRAY -from sqlalchemy.orm import relationship -from typing import Dict -from ._Base import _Base - - - - -class OpticalEndPointModel(_Base): - __tablename__ = 'optical_endpoint' - - endpoint_uuid = Column(UUID(as_uuid=False), primary_key=True) - device_uuid = Column(ForeignKey('device.device_uuid', ondelete='CASCADE' ), nullable=False, index=True) - - name = Column(String, nullable=False) - endpoint_type = Column(String, nullable=False) - - created_at = Column(DateTime, nullable=False) - updated_at = Column(DateTime, nullable=False) - - #device = relationship('DeviceModel', back_populates='optical_endpoints') # lazy='selectin' - - #link_endpoints = relationship('LinkEndPointModel', back_populates='endpoint' ) - #service_endpoints = relationship('ServiceEndPointModel', back_populates='endpoint' ) - - def dump_id(self) -> Dict: - result = { - - 'device_id' : self.device.dump_id(), - 'endpoint_uuid': {'uuid': self.endpoint_uuid}, - } - return result - - def dump(self) -> Dict: - return { - 'endpoint_id' : self.dump_id(), - 'name' : self.name, - 'endpoint_type' : self.endpoint_type, - - } - - def dump_name(self) -> Dict: - return { - 'endpoint_id' : self.dump_id(), - 'device_name' : self.device.device_name, - 'endpoint_name': self.name, - 'endpoint_type': self.endpoint_type, - } \ No newline at end of file diff --git a/src/context/service/database/models/OpticalLinkModel.py b/src/context/service/database/models/OpticalLinkModel.py index 3a300d46b9ed085284e5b01e01ada622a7619855..97346704d60bc9d6c8a0cbca88746b529aa76261 100644 --- a/src/context/service/database/models/OpticalLinkModel.py +++ b/src/context/service/database/models/OpticalLinkModel.py @@ -42,7 +42,7 @@ class SlotType(TypeDecorator): return value def process_result_value(self, value, dialect): - logging.info(f"dict from slotType {value}") + if value is not None: value = json.loads(value) return value diff --git a/src/context/service/database/uuids/EndPoint.py b/src/context/service/database/uuids/EndPoint.py index aef2c6de4bfef2cee97400046de04a398d3628f3..61b0cbf9abe9a0987e027d7c4f45876542230dfe 100644 --- a/src/context/service/database/uuids/EndPoint.py +++ b/src/context/service/database/uuids/EndPoint.py @@ -23,14 +23,14 @@ import logging def endpoint_get_uuid( endpoint_id : EndPointId, endpoint_name : str = '', allow_random : bool = False ) -> Tuple[str, str, str]: - logging.info(f"endpoint_id is {endpoint_id}") + device_uuid = device_get_uuid(endpoint_id.device_id, allow_random=False) _,topology_uuid = topology_get_uuid(endpoint_id.topology_id, allow_random=False, allow_default=True) raw_endpoint_uuid = endpoint_id.endpoint_uuid.uuid if len(raw_endpoint_uuid) > 0: prefix_for_name = '{:s}/{:s}'.format(topology_uuid, device_uuid) - logging.info(f" e_raw_endpoint_uuid , e {raw_endpoint_uuid} and endpoint{get_uuid_from_string(raw_endpoint_uuid, prefix_for_name=prefix_for_name)}") + return topology_uuid, device_uuid, get_uuid_from_string(raw_endpoint_uuid, prefix_for_name=prefix_for_name) if len(endpoint_name) > 0: diff --git a/src/context/service/database/uuids/_Builder.py b/src/context/service/database/uuids/_Builder.py index 338b3ac9769fa02c9a976f091d799cc507e4d108..020263a4d8625102d659f22f9771f419827c030c 100644 --- a/src/context/service/database/uuids/_Builder.py +++ b/src/context/service/database/uuids/_Builder.py @@ -37,7 +37,7 @@ def get_uuid_from_string(str_uuid_or_name : Union[str, UUID], prefix_for_name : except: # pylint: disable=bare-except # produce a UUID within TFS namespace from parameter if prefix_for_name is not None: - logging.info(f"playing with its suit {prefix_for_name} and {str_uuid_or_name}") + str_uuid_or_name = '{:s}/{:s}'.format(prefix_for_name, str_uuid_or_name) return str(uuid5(NAMESPACE_TFS, str_uuid_or_name)) diff --git a/src/device/client/DeviceClient.py b/src/device/client/DeviceClient.py index 3fde3df778e32df20c863ff110a1eb572f38d177..56c25e5673c6bc0dea7f74b80c2d15026bdfdb4b 100644 --- a/src/device/client/DeviceClient.py +++ b/src/device/client/DeviceClient.py @@ -82,8 +82,15 @@ 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 : 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))) return response + + def DisableOpticalDevice(self, request : OpticalConfig) -> Empty: + LOGGER.debug('DisableOpticalDevice request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.openconfig_stub.DisableOpticalDevice(request) + LOGGER.debug('DisableOpticalDevice result: {:s}'.format(grpc_message_to_json_string(response))) + return response diff --git a/src/device/service/DeviceServiceServicerImpl.py b/src/device/service/DeviceServiceServicerImpl.py index 4f0ba5722ab6c66104e1aaaccba229c356911603..643563d16b2c20a3cdc7d6cc276edd2ee1346df2 100644 --- a/src/device/service/DeviceServiceServicerImpl.py +++ b/src/device/service/DeviceServiceServicerImpl.py @@ -60,8 +60,8 @@ 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] != DeviceDriverEnum.DEVICEDRIVER_OC: - check_no_endpoints(request.device_endpoints) + #if request.device_drivers[0] != DeviceDriverEnum.DEVICEDRIVER_OC: + check_no_endpoints(request.device_endpoints) t1 = time.time() diff --git a/src/device/service/OpenConfigServicer.py b/src/device/service/OpenConfigServicer.py index 12a64456374e53d2aae089ca95091870c4f47f69..fa634eed85e0200885dc40028fc5dd51afdc6df2 100644 --- a/src/device/service/OpenConfigServicer.py +++ b/src/device/service/OpenConfigServicer.py @@ -76,7 +76,7 @@ class OpenConfigServicer(DeviceServiceServicer): @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def ConfigureOpticalDevice (self, request : OpticalConfig, context : grpc.ServicerContext) -> Empty: device_uuid = request.device_id.device_uuid.uuid - resources=[] + resources:list[dict]=[] is_all_good=True config =json.loads(request.config) LOGGER.info(f" config from openconfigservicer {config}") @@ -103,3 +103,39 @@ class OpenConfigServicer(DeviceServiceServicer): except Exception as e: LOGGER.info("error in configuring %s",e) return Empty() + + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def DisableOpticalDevice (self, request : OpticalConfig, context : grpc.ServicerContext) -> Empty: + + LOGGER.info(f"Disable request from openconfigservicer {request}") + device_uuid = request.device_id.device_uuid.uuid + resources:list[dict]=[] + is_all_good=True + config =json.loads(request.config) + LOGGER.info(f"Disable config from openconfigservicer {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) + LOGGER.info(f"device is {device}") + if device is None: + raise NotFoundException('Device', device_uuid, extra_details='loading in ConfigureDevice') + resources,conditions=extract_resources(config=config,device=device) + LOGGER.info(f" Disable resources from openconfigservicer {resources} and conditions {conditions}") + driver : _Driver = get_driver(self.driver_instance_cache, device) + results = driver.DeleteConfig(resources=resources,conditions=conditions) + for result in results: + if not result : + is_all_good=False + LOGGER.info(f"resluts {results} and is_all_good {is_all_good}") + if is_all_good: + driver.GetConfig(resource_keys=[]) + #TODO: add a control with the NETCONF get + #driver.GetConfig(resource_keys=filter_fields) + except Exception as e: + LOGGER.info("error in Disable configuring %s",e) + return Empty() + + \ No newline at end of file diff --git a/src/device/service/Tools.py b/src/device/service/Tools.py index bd6a2070aa7763b3c7d22cdf8667eb949fcf6d66..1f6716713d9711dd4ccc7bcf46a9a1a1600b23d6 100644 --- a/src/device/service/Tools.py +++ b/src/device/service/Tools.py @@ -454,8 +454,9 @@ def update_endpoints(src_device : Device, dst_device : Device) -> None: if len(src_context_uuid) > 0: dst_topology_id.context_id.context_uuid.uuid = src_context_uuid 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' + if device.device_type == DeviceTypeEnum.OPTICAL_ROADM._value_: return 'media-channel' return 'optical-channel' def is_key_existed(key : str, keys_dic = dict, key_name_to_use = None) -> dict: @@ -469,14 +470,15 @@ def is_key_existed(key : str, keys_dic = dict, key_name_to_use = None) -> dict: dic['value'] = None return dic -def extract_resources(config : dict, device : Device) -> list: +def extract_resources(config : dict, device : Device) -> list[list[dict],dict]: conditions = {} - resources = [] + resources:list[dict] = [] 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 = [] @@ -503,20 +505,26 @@ def extract_resources(config : dict, device : Device) -> list: 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('status', keys_dic=config['new_config'] , key_name_to_use="admin-state")) 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 + if config['new_config']['frequency'] is not None and config['new_config']['band'] is not None: + 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)) + + 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}) diff --git a/src/device/service/drivers/oc_driver/OCDriver.py b/src/device/service/drivers/oc_driver/OCDriver.py index cbc10a7dd8fa0438af8bb5854c37f1ba8ed86021..ec1e313e688958aed2f2eee7b5f36ec868ed6c37 100644 --- a/src/device/service/drivers/oc_driver/OCDriver.py +++ b/src/device/service/drivers/oc_driver/OCDriver.py @@ -13,33 +13,32 @@ # limitations under the License. import json -import anytree, copy, logging, pytz, queue, re, threading +import logging, pytz, queue, re, threading #import lxml.etree as ET -from datetime import datetime, timedelta -from typing import Any, Dict, Iterator, List, Optional, Tuple, Union + +from typing import Any, List, Tuple, Union from apscheduler.executors.pool import ThreadPoolExecutor -import xml.etree.ElementTree as ET -from apscheduler.job import Job + from apscheduler.jobstores.memory import MemoryJobStore from apscheduler.schedulers.background import BackgroundScheduler from ncclient.manager import Manager, connect_ssh from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method from common.tools.client.RetryDecorator import delay_exponential -from common.type_checkers.Checkers import chk_length, chk_string, chk_type, chk_float +from common.type_checkers.Checkers import chk_type from device.service.driver_api.Exceptions import UnsupportedResourceKeyException from device.service.driver_api._Driver import _Driver -from device.service.driver_api.AnyTreeTools import TreeNode, get_subnode, set_subnode_value #dump_subtree +from device.service.driver_api.AnyTreeTools import TreeNode +from .templates.VPN.common import seperate_port_config #from .Tools import xml_pretty_print, xml_to_dict, xml_to_file -from .templates.Interfaces.interfaces import interface_template -from .templates.VPN.physical import create_optical_channel,add_transceiver,create_media_channel,create_optical_band + +from .templates.VPN.roadms import (create_media_channel,create_optical_band, disable_media_channel , disable_optical_band) +from .templates.VPN.transponder import (edit_optical_channel ,change_optical_channel_status) from .RetryDecorator import retry from context.client.ContextClient import ContextClient from common.proto.context_pb2 import ( - OpticalConfig, - ConfigActionEnum, Device, DeviceDriverEnum, DeviceId, DeviceList, DeviceOperationalStatusEnum, Empty - ,OpticalConfigId,Uuid) + OpticalConfig) from .templates.Tools import roadm_values_extractor, transponder_values_extractor -from .Tools import generate_uuid_from_numbers + DEBUG_MODE = False logging.getLogger('ncclient.manager').setLevel(logging.DEBUG if DEBUG_MODE else logging.WARNING) logging.getLogger('ncclient.transport.ssh').setLevel(logging.DEBUG if DEBUG_MODE else logging.WARNING) @@ -56,7 +55,7 @@ RE_GET_ENDPOINT_FROM_INTERFACE_XPATH = re.compile(r".*interface\[oci\:name\='([^ SAMPLE_EVICTION_SECONDS = 30.0 # seconds SAMPLE_RESOURCE_KEY = 'interfaces/interface/state/counters' -filter_fields= ["frequency","target-output-power","interface","operational-mode","line-port"] +transponder_filter_fields= ["frequency","target-output-power","operational-mode","line-port","admin-state"] MAX_RETRIES = 15 DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0) RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') @@ -161,22 +160,36 @@ 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=[] - - if (conditions['edit_type']=='optical-channel'): - #transponder - str_config_messages = create_optical_channel(resources) - elif (conditions['edit_type']=='optical-band'): - #roadm optical-band - str_config_messages = create_optical_band(resources) + if str_method == 'SetConfig': + if (conditions['edit_type']=='optical-channel'): + #transponder + str_config_messages = edit_optical_channel(resources) + elif (conditions['edit_type']=='optical-band'): + #roadm optical-band + str_config_messages = create_optical_band(resources) + else : + #roadm media-channel + str_config_messages=create_media_channel(resources) + #Disabling of the Configuration else : - #roadm media-channel - str_config_messages=create_media_channel(resources) - + # Device type is Transponder + if (conditions['edit_type'] == "optical-channel"): + _,ports,_=seperate_port_config(resources) + str_config_messages=change_optical_channel_status(state="DISABLED",ports=ports) + + # Device type is Roadm + elif (conditions['edit_type']=='optical-band'): + str_config_messages=disable_optical_band(resources=resources,state="DISABLED") + else : + str_config_messages=disable_media_channel(resources) + + + logging.info(f" edit messages {str_config_messages}") for str_config_message in str_config_messages: # configuration of the received templates @@ -200,15 +213,14 @@ class OCDriver(_Driver): self.__logger = logging.getLogger('{:s}:[{:s}:{:s}]'.format(str(__name__), str(self.address), str(self.port))) self.__lock = threading.Lock() - #self.__initial = TreeNode('.') - #self.__running = TreeNode('.') + self.__subscriptions = TreeNode('.') self.__started = threading.Event() self.__terminate = threading.Event() - self.__scheduler = BackgroundScheduler(daemon=True) # scheduler used to emulate sampling events + self.__scheduler = BackgroundScheduler(daemon=True) self.__scheduler.configure( jobstores = {'default': MemoryJobStore()}, - executors = {'default': ThreadPoolExecutor(max_workers=1)}, # important! 1 = avoid concurrent requests + executors = {'default': ThreadPoolExecutor(max_workers=1)}, job_defaults = {'coalesce': False, 'max_instances': 3}, timezone=pytz.utc) self._temp_address=f"{address}{port}" @@ -224,18 +236,18 @@ class OCDriver(_Driver): with self.__lock: if self.__started.is_set(): return True self.__netconf_handler.connect() - # Connect triggers activation of sampling events that will be scheduled based on subscriptions + self.__scheduler.start() self.__started.set() return True def Disconnect(self) -> bool: with self.__lock: - # Trigger termination of loops and processes + self.__terminate.set() - # If not started, assume it is already disconnected + if not self.__started.is_set(): return True - # Disconnect triggers deactivation of sampling events + self.__scheduler.shutdown() self.__netconf_handler.disconnect() return True @@ -252,55 +264,45 @@ class OCDriver(_Driver): chk_type('resources', resource_keys, list) results = [] opticalConfig= OpticalConfig() - - + with self.__lock: - - - context_client.connect() - config={} + config={} transceivers={} oc_values={} ports_result=[] - - try: - xml_data = self.__netconf_handler.get().data_xml - - if (self.__type == "optical-transponder"): - extracted_values=transponder_values_extractor(data_xml=xml_data,resource_keys=filter_fields,dic=config) - transceivers,optical_channels_params,channel_namespace,endpoints,ports_result=extracted_values - oc_values["channels"]=optical_channels_params - oc_values["transceivers"]=transceivers - oc_values["channel_namespace"]=channel_namespace - oc_values["endpoints"]=endpoints - oc_values["ports"]=ports_result - else : - extracted_values=roadm_values_extractor(data_xml=xml_data,resource_keys=filter_fields,dic=config) - ports_result = extracted_values[0] - - - - - except Exception as e: # pylint: disable=broad-except - MSG = 'Exception retrieving {:s}' - self.__logger.info("error from getConfig %s",e) - self.__logger.exception(MSG.format(e)) + xml_data = self.__netconf_handler.get().data_xml + + if (self.__type == "optical-transponder"): + extracted_values=transponder_values_extractor(data_xml=xml_data,resource_keys=transponder_filter_fields,dic=config) + transceivers,optical_channels_params,channel_namespace,endpoints,ports_result=extracted_values + oc_values["channels"]=optical_channels_params + oc_values["transceivers"]=transceivers + oc_values["channel_namespace"]=channel_namespace + oc_values["endpoints"]=endpoints + oc_values["ports"]=ports_result + else : + extracted_values=roadm_values_extractor(data_xml=xml_data,resource_keys=[],dic=config) + ports_result = extracted_values[0] + #results.append((resource_key, e)) # if validation fails, store the exception #///////////////////////// store optical configurtaion //////////////////////////////////////////////////////// - - - - + logging.info(f"parameters {oc_values}") opticalConfig.config=json.dumps(oc_values) if self.__device_uuid is not None: opticalConfig.device_id.device_uuid.uuid=self.__device_uuid - config_id=context_client.SetOpticalConfig(opticalConfig) - - context_client.close() + try: + context_client.connect() + config_id=context_client.SetOpticalConfig(opticalConfig) + + context_client.close() + except Exception as e: # pylint: disable=broad-except + MSG = 'Exception retrieving {:s}' + self.__logger.info("error from getConfig %s",e) + self.__logger.exception(MSG.format(e)) if(len(ports_result)>0) : results.extend(ports_result) @@ -323,7 +325,7 @@ class OCDriver(_Driver): return results @metered_subclass_method(METRICS_POOL) - def DeleteConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: + def DeleteConfig(self, resources : List[Tuple[str, Any]],conditions:dict) -> List[Union[bool, Exception]]: chk_type('resources', resources, list) if len(resources) == 0: return [] with self.__lock: @@ -331,9 +333,9 @@ class OCDriver(_Driver): with self.__netconf_handler.locked(target='candidate'): results = edit_config( self.__netconf_handler, self.__logger, resources, target='candidate', delete=True, - commit_per_rule=self.__netconf_handler.commit_per_rule) + commit_per_rule=self.__netconf_handler.commit_per_rule,conditions=conditions) else: - results = edit_config(self.__netconf_handler, self.__logger, resources, delete=True) + results = edit_config(self.__netconf_handler, self.__logger, resources, delete=True,conditions=conditions) return results diff --git a/src/device/service/drivers/oc_driver/templates/Tools.py b/src/device/service/drivers/oc_driver/templates/Tools.py index 704cb76a486ec383ab32d0b0dbb7027f0f383b91..1bd217b6cf9bf402cb5d3455d8bb820246663919 100644 --- a/src/device/service/drivers/oc_driver/templates/Tools.py +++ b/src/device/service/drivers/oc_driver/templates/Tools.py @@ -59,7 +59,29 @@ def generate_templates(resource_key: str, resource_value: str, channel:str) -> s #result_templates.append(create_physical_config(data)) return result_templates - + + +def extract_status (dic:dict,resource_key:str,xml_data:str,channel_name:str): + + xml_bytes = xml_data.encode("utf-8") + root = ET.fromstring(xml_bytes) + channel_name=channel_name if 'index' not in channel_name else channel_name['index'] + index=None + if channel_name.find('-') != -1 : + index= channel_name.split("-")[1] + + + namespaces = { "td": "http://openconfig.net/yang/terminal-device"} + channels = root.findall(f".//td:terminal-device/td:logical-channels/td:channel",namespaces) + for channel in channels : + + index_ele= channel.find(f".//td:config[td:index='{index}']/td:{resource_key}",namespaces) + if index_ele is not None : + dic["status"]=index_ele.text + print(index_ele.text) + return dic + + def extract_channel_xmlns (data_xml:str,is_opticalband:bool): xml_bytes = data_xml.encode("utf-8") root = ET.fromstring(xml_bytes) @@ -274,15 +296,17 @@ def transponder_values_extractor(data_xml:str,resource_keys:list,dic:dict): dic={} for resource_key in resource_keys : - if (resource_key != 'interface'): + if (resource_key != 'admin-state'): dic=extract_value(dic=dic,resource_key=resource_key,xml_data=data_xml ,channel_name=channel_name,channel_namespace=channel_namespace) - + else : + dic = extract_status(dic=dic,resource_key=resource_key,xml_data=data_xml, channel_name=channel_name) dic["name"]=channel_name endpoints.append({"endpoint_uuid":{"uuid":channel_name}}) optical_channels_params.append(dic) - transceivers_dic=extract_tranceiver(data_xml=data_xml,dic={}) + #transceivers_dic=extract_tranceiver(data_xml=data_xml,dic={}) + transceivers_dic={"transceiver":[]} #interfaces_dic=extract_interface(xml_data=data_xml,dic={}) if len(ports)>0 : for port in ports : diff --git a/src/device/service/drivers/oc_driver/templates/VPN/common.py b/src/device/service/drivers/oc_driver/templates/VPN/common.py new file mode 100644 index 0000000000000000000000000000000000000000..a1ad52ab7947c085700c0d558882358609e70aeb --- /dev/null +++ b/src/device/service/drivers/oc_driver/templates/VPN/common.py @@ -0,0 +1,53 @@ + +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from yattag import Doc, indent +import logging + + + + + + + + + + + + + + + + + + +def seperate_port_config(resources:list,unwanted_keys=[])->list[list,dict,str]: + config=[] + ports={} + index=None + for item in resources : + if len(unwanted_keys)>0: + 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: + # ports[item['resource_key']]=item['value'] + if (item['resource_key'] == 'destination_port' or item['resource_key'] == 'source_port'): + ports[item['resource_key']]=item['value'] + if (item['resource_key']=='index' and item['value'] is not None) : + index=item['value'] + + return [config,ports,index] + 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 9c894b1607c2bde5e8665dc02f9d19e79aa02817..cbe804c96569aa1f583e09dabce3f59cef6ecd39 100644 --- a/src/device/service/drivers/oc_driver/templates/VPN/physical.py +++ b/src/device/service/drivers/oc_driver/templates/VPN/physical.py @@ -34,13 +34,13 @@ def seperate_port_config(resources:list,unwanted_keys:list[str])->list[list,dict return [config,ports,index] -def create_optical_channel(resources): +def create_optical_channel(resources:list[dict],ports:list[dict],config:list[dict] ): - unwanted_keys=['destination_port','source_port','channel_namespace','optical-band-parent','index', 'name'] + #unwanted_keys=['destination_port','source_port','channel_namespace','optical-band-parent','index', 'name','admin-state'] results =[] - data={"name":i["value"] for i in resources if i["resource_key"]=="channel_name"} + data ={} 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) + #config,ports,index=seperate_port_config(resources,unwanted_keys=unwanted_keys) logging.info(f"ports are {ports}") port_val = "" if 'destination_port' in ports and ports['destination_port'][0] is not None: @@ -213,23 +213,25 @@ def create_media_channel (resources): results.append(result) return results - - +def change_optical_channel_status (channel_name:str,state:str,ports:list[dict]) : + 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] -def disable_optical_channel (index,state) : - results=[] doc, tag, text = Doc().tagtext() #with tag('config'): with tag('config',xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"): - with tag('components', xmlns="http://openconfig.net/yang/platform"): - with tag('terminal-device',xmlns="http://openconfig.net/yang/terminal-device"): - with tag("logical-channels"): - with tag('channel'): - with tag('index'):text("{}".format(index)) - with tag('config'): - with tag('admin-state'):text("{}".format(state)) + + with tag('terminal-device',xmlns="http://openconfig.net/yang/terminal-device"): + with tag("logical-channels"): + with tag('channel'): + with tag('index'):text("{}".format(port_val)) + with tag('config'): + with tag('admin-state'):text("{}".format(state)) result = indent( doc.getvalue(), @@ -241,3 +243,19 @@ def disable_optical_channel (index,state) : return results + +def edit_optical_channel (resources:list[dict]): + unwanted_keys=['destination_port','source_port','channel_namespace','optical-band-parent','index', 'name','admin-state'] + config,ports,index=seperate_port_config(resources,unwanted_keys=unwanted_keys) + results = [] + channel_name=next((i["value"] for i in resources if i["resource_key"]=="channel_name" and i["value"] != None),None) + admin_state= next((i["value"] for i in resources if i["resource_key"]== "admin-state" and i["value"] != None) , None) + + logging.info(f"admin state is {admin_state}") + if channel_name is not None : + if (admin_state is not None): + results.extend(change_optical_channel_status(channel_name=channel_name,state=admin_state,ports=ports)) + if admin_state is None : + results.extend(create_optical_channel(resources=resources,ports=ports,config=config) ) + + return results \ No newline at end of file diff --git a/src/device/service/drivers/oc_driver/templates/VPN/roadms.py b/src/device/service/drivers/oc_driver/templates/VPN/roadms.py new file mode 100644 index 0000000000000000000000000000000000000000..3a11efe15748b7eabc7aae24a4f9b4299ebc3baf --- /dev/null +++ b/src/device/service/drivers/oc_driver/templates/VPN/roadms.py @@ -0,0 +1,166 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + + +from yattag import Doc, indent +import logging +from .common import seperate_port_config + + + + +def create_media_channel (resources): + results=[] + unwanted_keys=['destination_port','source_port','channel_namespace','frequency','operational-mode', 'optical-band-parent'] + config,ports,index= seperate_port_config(resources,unwanted_keys=unwanted_keys) + + doc, tag, text = Doc().tagtext() + #with tag('config'): + with tag('config',xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"): + with tag('wavelength-router', xmlns="http://openconfig.net/yang/wavelength-router"): + with tag('media-channels'): + n = 0 + if 'destination_port' in ports: + n = len(ports['destination_port']) + else: + n = len(ports['source_port']) + for i in range(0, n): + #with tag('channel', operation="create"): + with tag('channel'): + with tag('index'):text(str(int(index)+i)) + with tag('config'): + #with tag('index'):text(index) + for resource in config: + + if resource['resource_key'] == "index": + with tag('index'):text(str(int(index)+i)) + else: + with tag(resource['resource_key']):text(resource['value']) + if ('destination_port' in ports) and (ports['destination_port'][i] is not None): + with tag('dest'): + with tag('config'): + with tag('port-name'):text(ports['destination_port'][i]) + if ('source_port' in ports) and (ports['source_port'][i] is not None): + with tag('source'): + with tag('config'): + with tag('port-name'):text(ports['source_port'][i]) + + + result = indent( + doc.getvalue(), + indentation = ' '*2, + newline = '' + ) + results.append(result) + return results + + + + +def create_optical_band (resources) : + results =[] + unwanted_keys=['destination_port','source_port','channel_namespace','frequency','optical-band-parent'] + config,ports,index= seperate_port_config(resources,unwanted_keys=unwanted_keys) + + doc, tag, text = Doc().tagtext() + #with tag('config'): + with tag('config',xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"): + with tag('wavelength-router', xmlns="http://openconfig.net/yang/wavelength-router"): + with tag('optical-bands',xmlns="http://flex-scale-project.eu/yang/flex-scale-mg-on"): + n = 0 + if 'destination_port' in ports: + n = len(ports['destination_port']) + else: + n = len(ports['source_port']) + for i in range(0, n): + #with tag('optical-band', operation="create"): + with tag('optical-band'): + if index is not None: + with tag('index'):text(str(int(index)+i)) + with tag('config'): + #if index is not None: + # with tag('index'):text(str(int(index)+i)) + for resource in config: + if resource['resource_key'] == "index": + with tag('index'):text(str(int(index)+i)) + else: + with tag(resource['resource_key']):text(resource['value']) + with tag('admin-status'):text('ENABLED') + #with tag('fiber-parent'):text(ports['destination_port'] if 'destination_port' in ports else ports['source_port']) + if ('destination_port' in ports) and (ports['destination_port'][i] is not None): + with tag('dest'): + with tag('config'): + with tag('port-name'):text(ports['destination_port'][i]) + if ('source_port' in ports) and (ports['source_port'][i] is not None): + with tag('source'): + with tag('config'): + with tag('port-name'):text(ports['source_port'][i]) + + + result = indent( + doc.getvalue(), + indentation = ' '*2, + newline = '' + ) + results.append(result) + return results + + +def disable_media_channel (resources): + + results=[] + unwanted_keys=['destination_port','source_port','channel_namespace','frequency','operational-mode', 'optical-band-parent'] + config,ports,index= seperate_port_config(resources,unwanted_keys=unwanted_keys) + + doc, tag, text = Doc().tagtext() + #with tag('config'): + with tag('config',xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"): + with tag('wavelength-router', xmlns="http://openconfig.net/yang/wavelength-router"): + with tag('media-channels'): + with tag("channel",operation="delete"): + with tag('index'):text(str(int(index))) + with tag('config'): + with tag('index'):text(str(int(index))) + + result = indent( + doc.getvalue(), + indentation = ' '*2, + newline = '' + ) + results.append(result) + return results + +def disable_optical_band (resources:list,state:str): + results=[] + unwanted_keys=['destination_port','source_port','channel_namespace','frequency','operational-mode', 'optical-band-parent'] + config,ports,index= seperate_port_config(resources,unwanted_keys=unwanted_keys) + doc, tag, text = Doc().tagtext() + #with tag('config'): + with tag('config',xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"): + with tag('wavelength-router', xmlns="http://openconfig.net/yang/wavelength-router"): + with tag('optical-bands',xmlns="http://flex-scale-project.eu/yang/flex-scale-mg-on"): + with tag('optical-band'): + if index is not None: + with tag('index'):text(index) + with tag('config'): + with tag('index'):text(index) + with tag('admin-status'):text(state) + result = indent( + doc.getvalue(), + indentation = ' '*2, + newline = '' + ) + results.append(result) + return results \ No newline at end of file diff --git a/src/device/service/drivers/oc_driver/templates/VPN/transponder.py b/src/device/service/drivers/oc_driver/templates/VPN/transponder.py new file mode 100644 index 0000000000000000000000000000000000000000..689cbff6b07d3bd7f8ecdd684678e7f716cd5d1f --- /dev/null +++ b/src/device/service/drivers/oc_driver/templates/VPN/transponder.py @@ -0,0 +1,157 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + + + +from yattag import Doc, indent +import logging + +from .common import seperate_port_config + +def add_transceiver (transceiver_name:str): + + doc, tag, text = Doc().tagtext() + with tag('config',xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"): + with tag('components', xmlns="http://openconfig.net/yang/platform"): + with tag('component'): + with tag('name'):text(transceiver_name) + with tag("config"): + with tag('name'):text(transceiver_name) + with tag("state"): + with tag('name'):text(transceiver_name) + with tag("type",('xmlns:oc-platform-types',"http://openconfig.net/yang/platform-types")):text("oc-platform-types:TRANSCEIVER") + with tag("transceiver",xmlns="http://openconfig.net/yang/platform/transceiver"): + with tag("config"): + with tag("enabled"):text("true") + with tag("form-factor-preconf",("xmlns:oc-opt-types","http://openconfig.net/yang/transport-types")):text("oc-opt-types:QSFP56_DD_TYPE1") + with tag("ethernet-pmd-preconf",("xmlns:oc-opt-types","http://openconfig.net/yang/transport-types")):text("oc-opt-types:ETH_400GBASE_ZR") + with tag("fec-mode",("xmlns:oc-platform-types","http://openconfig.net/yang/platform-types")):text("oc-platform-types:FEC_AUTO") + with tag("module-functional-type",("xmlns:oc-opt-types","http://openconfig.net/yang/transport-types")):text("oc-opt-types:TYPE_DIGITAL_COHERENT_OPTIC") + with tag("state"): + with tag("enabled"):text("true") + with tag("form-factor-preconf",("xmlns:oc-opt-types","http://openconfig.net/yang/transport-types")):text("oc-opt-types:QSFP56_DD_TYPE1") + with tag("ethernet-pmd-preconf",("xmlns:oc-opt-types","http://openconfig.net/yang/transport-types")):text("oc-opt-types:ETH_400GBASE_ZR") + with tag("fec-mode",("xmlns:oc-platform-types","http://openconfig.net/yang/platform-types")):text("oc-platform-types:FEC_AUTO") + with tag("module-functional-type",("xmlns:oc-opt-types","http://openconfig.net/yang/transport-types")):text("oc-opt-types:TYPE_DIGITAL_COHERENT_OPTIC") + with tag("vendor"):text("Cisco") + with tag("vendor-part"):text("400zr-QSFP-DD") + with tag("vendor-rev"):text("01") + with tag("serial-no"):text("1567321") + with tag("physical-channels"): + with tag("channel"): + with tag("index"):text("1") + with tag("config"): + with tag("index"):text("1") + with tag("associated-optical-channel"):text("channel-4") + result = indent( + doc.getvalue(), + indentation = ' '*2, + newline = '' + ) + + + return result + + +def create_optical_channel(resources:list[dict],ports:list[dict],config:list[dict] ): + + #unwanted_keys=['destination_port','source_port','channel_namespace','optical-band-parent','index', 'name','admin-state'] + results =[] + data ={} + 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(f"ports are {ports}") + 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] + + + doc, tag, text = Doc().tagtext() + #with tag('config'): + with tag('config',xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"): + with tag('components', xmlns="http://openconfig.net/yang/platform"): + with tag('component'): + with tag('name'):text("channel-{}".format(port_val)) + with tag('config'): + with tag('name'):text("channel-{}".format(port_val)) + with tag('optical-channel',xmlns=data["channel_namespace"]): + with tag('config'): + for resource in config: + with tag(resource['resource_key']):text(resource['value']) + with tag('terminal-device', xmlns="http://openconfig.net/yang/terminal-device"): + with tag('logical-channels'): + with tag('channel'): + with tag('index'):text("{}".format(port_val)) + with tag('config'): + with tag('index'):text("{}".format(port_val)) + with tag('admin-state'):text("ENABLED") + result = indent( + doc.getvalue(), + indentation = ' '*2, + newline = '' + ) + results.append(result) + + + return results + + +def change_optical_channel_status (state:str,ports:list[dict]) : + 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] + + results=[] + doc, tag, text = Doc().tagtext() + #with tag('config'): + with tag('config',xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"): + + with tag('terminal-device',xmlns="http://openconfig.net/yang/terminal-device"): + with tag("logical-channels"): + with tag('channel'): + with tag('index'):text("{}".format(port_val)) + with tag('config'): + with tag('admin-state'):text("{}".format(state)) + + result = indent( + doc.getvalue(), + indentation = ' '*2, + newline = '' + ) + results.append(result) + + + return results + + +def edit_optical_channel (resources:list[dict]): + unwanted_keys=['destination_port','source_port','channel_namespace','optical-band-parent','index', 'name','admin-state'] + config,ports,index=seperate_port_config(resources,unwanted_keys=unwanted_keys) + results = [] + channel_name=next((i["value"] for i in resources if i["resource_key"]=="channel_name" and i["value"] != None),None) + admin_state= next((i["value"] for i in resources if i["resource_key"]== "admin-state" and i["value"] != None) , None) + + logging.info(f"admin state is {admin_state}") + if channel_name is not None : + if (admin_state is not None): + results.extend(change_optical_channel_status(state=admin_state,ports=ports)) + if admin_state is None : + results.extend(create_optical_channel(resources=resources,ports=ports,config=config) ) + + return results \ No newline at end of file diff --git a/src/service/service/__main__.py b/src/service/service/__main__.py index c4b0f2a7a0af3e45473bf3dac05dfb5163fcf1fc..5a0d757da9857f8c017235607ba9f1f29e174151 100644 --- a/src/service/service/__main__.py +++ b/src/service/service/__main__.py @@ -56,7 +56,7 @@ def main(): ]) OPTICAL_IP = opticalcontrollers_url.get(VAR_NAME_OPTICAL_CONTROLLER_HOST) OPTICAL_PORT = opticalcontrollers_url.get(VAR_NAME_OPTICAL_CONTROLLER_PORT) - LOGGER.info(f"OPTICAL_IP:{OPTICAL_IP} OPTICAL_PORT:{OPTICAL_PORT}") + signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) diff --git a/src/service/service/service_handlers/oc/OCServiceHandler.py b/src/service/service/service_handlers/oc/OCServiceHandler.py index 6359f2a09e53cab1002acd55d477aeb2d9b393b0..4725af838b7c43868c691b1fe03c1a860452a7db 100644 --- a/src/service/service/service_handlers/oc/OCServiceHandler.py +++ b/src/service/service/service_handlers/oc/OCServiceHandler.py @@ -15,9 +15,10 @@ 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, 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 common.DeviceTypes import DeviceTypeEnum 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 @@ -85,32 +86,66 @@ class OCServiceHandler(_ServiceHandler): def DeleteEndpoint( self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None ) -> List[Union[bool, Exception]]: + + is_opticalband =False + flows = convert_endpoints_to_flows(endpoints) + LOGGER.info(f"from DeleteEndpoint Endpoints to delete {flows}") + chk_type('endpoints', endpoints, list) if len(endpoints) == 0: return [] - service_uuid = self.__service.service_id.service_uuid.uuid - settings = self.__settings_handler.get('/settings') - + + if self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid)): + is_opticalband =True + settings = self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid)) + else: + settings = self.__settings_handler.get('/settings') + + + LOGGER.info(f"from DeleteEndpoint settings {settings.value}") + results = [] - for endpoint in endpoints: + for device_uuid in flows.keys(): try: - device_uuid, endpoint_uuid = get_device_endpoint_uuids(endpoint) + channel_indexes= [] + dev_flows = flows[device_uuid] + LOGGER.info(f"from DeleteEndpoint dev_flows {dev_flows}") device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) - endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid) - endpoint_settings = self.__settings_handler.get_endpoint_settings(device_obj, endpoint_obj) - endpoint_name = endpoint_obj.name - - json_config_rules = 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) - + LOGGER.info(f"from DeleteEndpoint device type {device_obj.device_type}") + if (device_obj.device_type == DeviceTypeEnum.OPTICAL_TRANSPONDER._value_): + for endpoint in dev_flows: + src , dst = endpoint + src_enpoint_name='0' + dist_enpoint_name='0' + if src !="0": + src_endponit_obj =get_endpoint_matching(device_obj, src) + src_enpoint_name=src_endponit_obj.name + if dst !="0": + dst_endpoint_obj = get_endpoint_matching(device_obj, dst) + dist_enpoint_name=dst_endpoint_obj.name + channel_indexes.append((src_enpoint_name,dist_enpoint_name)) + else : + if (not is_opticalband): + if 'flow_id' in settings.value: + + channel_indexes.append(settings.value["flow_id"]) + else : + if "ob_id" in settings.value: + channel_indexes.append(settings.value["ob_id"]) + + + # 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) + LOGGER.info(f"from DeleteEndpoint channel_indexes {channel_indexes}") + self.__task_executor.deconfigure_optical_device(device=device_obj,channel_indexes=channel_indexes,is_opticalband=is_opticalband) 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/task_scheduler/TaskExecutor.py b/src/service/service/task_scheduler/TaskExecutor.py index d39119689b5938730bd35049f7399abc8495b926..51505d9f2c45d4ae266cbfdcc89ef30ccae7007b 100644 --- a/src/service/service/task_scheduler/TaskExecutor.py +++ b/src/service/service/task_scheduler/TaskExecutor.py @@ -33,6 +33,8 @@ from service.service.service_handler_api.Exceptions import ( 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 from service.service.tools.object_uuid import opticalconfig_get_uuid +from common.DeviceTypes import DeviceTypeEnum + if TYPE_CHECKING: from service.service.service_handler_api._ServiceHandler import _ServiceHandler @@ -129,7 +131,7 @@ class TaskExecutor: new_config = {} try: result = self._context_client.SelectOpticalConfig(optical_config_id) - LOGGER.info(f"configure_optical_device {result}") + new_config = json.loads(result.config) if result is not None : new_config["new_config"] = setting @@ -141,6 +143,46 @@ class TaskExecutor: self._store_grpc_object(CacheableObjectType.DEVICE, device_key, device) except Exception as e: LOGGER.info("error in configure_optical_device %s",e) + + # Deconfiguring Optical Devices ( CNIT ) + def deconfigure_optical_device(self, device : Device, channel_indexes :list,is_opticalband:bool): + + + + flows = [] + indexes={} + new_config = {} + optical_config_id = OpticalConfigId() + optical_config_id.opticalconfig_uuid = opticalconfig_get_uuid(device.device_id) + # if transponder the channel index is same as its endpoint + if device.device_type == DeviceTypeEnum.OPTICAL_TRANSPONDER._value_: + for index in channel_indexes : + flows.append(index) + # if Roadm the channel index is the flow_id ,or ob_id + else : + for index in channel_indexes: + if (not is_opticalband): + indexes["flow_id"]=index + else : + indexes["ob_id"]=index + + + try: + # for extractor in device service to extract the index , dummy data for freq and band required + indexes["frequency"]=None + indexes["band"]=None + + new_optical_config = OpticalConfig() + new_config["new_config"]=indexes + new_config["flow"] = flows + new_config["is_opticalband"] = is_opticalband + new_optical_config.config= json.dumps(new_config) + new_optical_config.opticalconfig_id.CopyFrom (optical_config_id) + new_optical_config.device_id.CopyFrom(device.device_id) + self._device_client.DisableOpticalDevice(new_optical_config) + + except Exception as e: + LOGGER.info("error in deconfigure_optical_device %s",e) def get_device_controller(self, device : Device) -> Optional[Device]: #json_controller = None diff --git a/src/tests/ofc24/r_t.sh b/src/tests/ofc24/r_t.sh index f5357fc37546bd5b406e72876b70768639bcf413..6cd0d9fab1711ae5f7a151844b7ee8227b7564fd 100644 --- a/src/tests/ofc24/r_t.sh +++ b/src/tests/ofc24/r_t.sh @@ -25,7 +25,7 @@ docker rm na3 docker rm t2 docker rm na2 -screen -dmS t1 -T xterm sh -c "docker run --name t1 -p 10.0.2.4:2023:2022 -v /home/tfs/tfs-ctrl/src/tests/ofc24/tempOC/files:/files -it asgamb1/oc23bgp.img:latest bash -c 'cp /files/platform_t1.xml demoECOC21.xml ; ./startNetconfAgent.sh'" +screen -dmS t1 -T xterm sh -c "docker run --name t1 -p 10.0.2.4:2023:2022 -v /home/tfs/tfs-ctrl/src/tests/ofc24/tempOC/files:/files -it asgamb1/oc23bgp.img:latest bash -c 'cp /files/transponders_x4.xml demoECOC21.xml ; ./startNetconfAgent.sh'" screen -dmS t3 -T xterm sh -c "docker run --name na3 -p 10.0.2.4:2025:2022 -v /home/tfs/tfs-ctrl/src/tests/ofc24/tempOC/files:/files -it asgamb1/flexscale-node.img:latest bash -c 'cp /files/platform_r1.xml init_openconfig-platform.xml ; ./startNetconfAgent.sh'" -screen -dmS t2 -T xterm sh -c "docker run --name t2 -p 10.0.2.4:2024:2022 -v /home/tfs/tfs-ctrl/src/tests/ofc24/tempOC/files:/files -it asgamb1/oc23bgp.img:latest bash -c 'cp /files/platform_t2.xml demoECOC21.xml ; ./startNetconfAgent.sh'" +screen -dmS t2 -T xterm sh -c "docker run --name t2 -p 10.0.2.4:2024:2022 -v /home/tfs/tfs-ctrl/src/tests/ofc24/tempOC/files:/files -it asgamb1/oc23bgp.img:latest bash -c 'cp /files/transponders_x4_2.xml demoECOC21.xml ; ./startNetconfAgent.sh'" screen -dmS t4 -T xterm sh -c "docker run --name na2 -p 10.0.2.4:2026:2022 -v /home/tfs/tfs-ctrl/src/tests/ofc24/tempOC/files:/files -it asgamb1/flexscale-node.img:latest bash -c 'cp /files/platform_r2.xml init_openconfig-platform.xml ; ./startNetconfAgent.sh'" \ No newline at end of file diff --git a/src/tests/ofc24/tempOC/files/transponders_x4.xml b/src/tests/ofc24/tempOC/files/transponders_x4.xml new file mode 100644 index 0000000000000000000000000000000000000000..fb55f02abefa6c5a444d3fecaa2ca049798f9483 --- /dev/null +++ b/src/tests/ofc24/tempOC/files/transponders_x4.xml @@ -0,0 +1,1039 @@ +<config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0"> + <components xmlns="http://openconfig.net/yang/platform"> + <component> + <name>device</name> + <config> + <name>device</name> + </config> + <state> + <name>MellanoxSwitch</name> + <mfg-name>SSSA-CNIT</mfg-name> + <hardware-version>1.0.0</hardware-version> + <firmware-version>1.0.0</firmware-version> + <software-version>1.0.0</software-version> + <serial-no>610610</serial-no> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:OPERATING_SYSTEM</type> + </state> + </component> + <component> + <name>channel-1</name> + <config> + <name>channel-1</name> + </config> + <state> + <name>channel-1</name> + <type xmlns:typex="http://openconfig.net/yang/transport-types">typex:OPTICAL_CHANNEL</type> + </state> + <optical-channel xmlns="http://openconfig.net/yang/terminal-device"> + <config> + <frequency>191600000</frequency> + <target-output-power>100</target-output-power> + <operational-mode>0</operational-mode> + <line-port>transceiver-1</line-port> + </config> + <state> + <frequency>191600000</frequency> + <target-output-power>0</target-output-power> + <operational-mode>0</operational-mode> + <line-port>transceiver-1</line-port> + <group-id>1</group-id> + <output-power> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </output-power> + <input-power> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </input-power> + <laser-bias-current> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </laser-bias-current> + <chromatic-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </chromatic-dispersion> + <polarization-mode-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </polarization-mode-dispersion> + <second-order-polarization-mode-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </second-order-polarization-mode-dispersion> + <polarization-dependent-loss> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </polarization-dependent-loss> + </state> + </optical-channel> + </component> + <component> + <name>channel-2</name> + <config> + <name>channel-2</name> + </config> + <state> + <name>channel-2</name> + <type xmlns:typex="http://openconfig.net/yang/transport-types">typex:OPTICAL_CHANNEL</type> + </state> + <optical-channel xmlns="http://openconfig.net/yang/terminal-device"> + <config> + <frequency>191600000</frequency> + <target-output-power>100</target-output-power> + <operational-mode>0</operational-mode> + <line-port>transceiver-2</line-port> + </config> + <state> + <frequency>191600000</frequency> + <target-output-power>0</target-output-power> + <operational-mode>0</operational-mode> + <line-port>transceiver-2</line-port> + <group-id>1</group-id> + <output-power> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </output-power> + <input-power> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </input-power> + <laser-bias-current> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </laser-bias-current> + <chromatic-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </chromatic-dispersion> + <polarization-mode-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </polarization-mode-dispersion> + <second-order-polarization-mode-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </second-order-polarization-mode-dispersion> + <polarization-dependent-loss> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </polarization-dependent-loss> + </state> + </optical-channel> + </component> + <component> + <name>channel-3</name> + <config> + <name>channel-3</name> + </config> + <state> + <name>channel-3</name> + <type xmlns:typex="http://openconfig.net/yang/transport-types">typex:OPTICAL_CHANNEL</type> + </state> + <optical-channel xmlns="http://openconfig.net/yang/terminal-device"> + <config> + <frequency>191600000</frequency> + <target-output-power>100</target-output-power> + <operational-mode>0</operational-mode> + <line-port>transceiver-3</line-port> + </config> + <state> + <frequency>191600000</frequency> + <target-output-power>0</target-output-power> + <operational-mode>0</operational-mode> + <line-port>transceiver-3</line-port> + <group-id>1</group-id> + <output-power> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </output-power> + <input-power> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </input-power> + <laser-bias-current> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </laser-bias-current> + <chromatic-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </chromatic-dispersion> + <polarization-mode-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </polarization-mode-dispersion> + <second-order-polarization-mode-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </second-order-polarization-mode-dispersion> + <polarization-dependent-loss> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </polarization-dependent-loss> + </state> + </optical-channel> + </component> + <component> + <name>channel-4</name> + <config> + <name>channel-4</name> + </config> + <state> + <name>channel-4</name> + <type xmlns:typex="http://openconfig.net/yang/transport-types">typex:OPTICAL_CHANNEL</type> + </state> + <optical-channel xmlns="http://openconfig.net/yang/terminal-device"> + <config> + <frequency>191600000</frequency> + <target-output-power>100</target-output-power> + <operational-mode>0</operational-mode> + <line-port>transceiver-4</line-port> + </config> + <state> + <frequency>191600000</frequency> + <target-output-power>0</target-output-power> + <operational-mode>0</operational-mode> + <line-port>transceiver-4</line-port> + <group-id>1</group-id> + <output-power> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </output-power> + <input-power> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </input-power> + <laser-bias-current> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </laser-bias-current> + <chromatic-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </chromatic-dispersion> + <polarization-mode-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </polarization-mode-dispersion> + <second-order-polarization-mode-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </second-order-polarization-mode-dispersion> + <polarization-dependent-loss> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </polarization-dependent-loss> + </state> + </optical-channel> + </component> + <component> + <name>transceiver-1</name> + <config> + <name>transceiver-1</name> + </config> + <state> + <name>transceiver-1</name> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:TRANSCEIVER</type> + </state> + <transceiver xmlns="http://openconfig.net/yang/platform/transceiver"> + <config> + <enabled>true</enabled> + <form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf> + <ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf> + <fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode> + <module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type> + </config> + <state> + <enabled>true</enabled> + <form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf> + <ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf> + <fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode> + <module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type> + <vendor>Cisco</vendor> + <vendor-part>400zr-QSFP-DD</vendor-part> + <vendor-rev>01</vendor-rev> + <serial-no>1567321</serial-no> + </state> + <physical-channels> + <channel> + <index>1</index> + <config> + <index>1</index> + <associated-optical-channel>channel-1</associated-optical-channel> + </config> + </channel> + </physical-channels> + </transceiver> + </component> + <component> + <name>transceiver-2</name> + <config> + <name>transceiver-2</name> + </config> + <state> + <name>transceiver-2</name> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:TRANSCEIVER</type> + </state> + <transceiver xmlns="http://openconfig.net/yang/platform/transceiver"> + <config> + <enabled>true</enabled> + <form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf> + <ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf> + <fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode> + <module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type> + </config> + <state> + <enabled>true</enabled> + <form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf> + <ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf> + <fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode> + <module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type> + <vendor>Cisco</vendor> + <vendor-part>400zr-QSFP-DD</vendor-part> + <vendor-rev>01</vendor-rev> + <serial-no>1567321</serial-no> + </state> + <physical-channels> + <channel> + <index>1</index> + <config> + <index>1</index> + <associated-optical-channel>channel-2</associated-optical-channel> + </config> + </channel> + </physical-channels> + </transceiver> + </component> + <component> + <name>transceiver-3</name> + <config> + <name>transceiver-3</name> + </config> + <state> + <name>transceiver-3</name> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:TRANSCEIVER</type> + </state> + <transceiver xmlns="http://openconfig.net/yang/platform/transceiver"> + <config> + <enabled>true</enabled> + <form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf> + <ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf> + <fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode> + <module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type> + </config> + <state> + <enabled>true</enabled> + <form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf> + <ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf> + <fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode> + <module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type> + <vendor>Cisco</vendor> + <vendor-part>400zr-QSFP-DD</vendor-part> + <vendor-rev>01</vendor-rev> + <serial-no>1567321</serial-no> + </state> + <physical-channels> + <channel> + <index>1</index> + <config> + <index>1</index> + <associated-optical-channel>channel-3</associated-optical-channel> + </config> + </channel> + </physical-channels> + </transceiver> + </component> + + <component> + <name>transceiver-4</name> + <config> + <name>transceiver-4</name> + </config> + <state> + <name>transceiver-4</name> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:TRANSCEIVER</type> + </state> + <transceiver xmlns="http://openconfig.net/yang/platform/transceiver"> + <config> + <enabled>true</enabled> + <form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf> + <ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf> + <fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode> + <module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type> + </config> + <state> + <enabled>true</enabled> + <form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf> + <ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf> + <fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode> + <module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type> + <vendor>Cisco</vendor> + <vendor-part>400zr-QSFP-DD</vendor-part> + <vendor-rev>01</vendor-rev> + <serial-no>1567321</serial-no> + </state> + <physical-channels> + <channel> + <index>1</index> + <config> + <index>1</index> + <associated-optical-channel>channel-4</associated-optical-channel> + </config> + </channel> + </physical-channels> + </transceiver> + </component> + <component> + <name>port-1</name> + <config> + <name>port-1</name> + </config> + <state> + <name>port-1</name> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:PORT</type> + </state> + <subcomponents> + <subcomponent> + <name>channel-1</name> + <config> + <name>channel-1</name> + </config> + <state> + <name>channel-1</name> + </state> + </subcomponent> + </subcomponents> + <properties> + <property> + <name>onos-index</name> + <config> + <name>onos-index</name> + <value>1</value> + </config> + <state> + <name>onos-index</name> + <value>1</value> + </state> + </property> + <property> + <name>odtn-port-type</name> + <config> + <name>odtn-port-type</name> + <value>line</value> + </config> + <state> + <name>odtn-port-type</name> + <value>line</value> + </state> + </property> + </properties> + </component> + <component> + <name>port-2</name> + <config> + <name>port-2</name> + </config> + <state> + <name>port-2</name> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:PORT</type> + </state> + <subcomponents> + <subcomponent> + <name>channel-2</name> + <config> + <name>channel-2</name> + </config> + <state> + <name>channel-2</name> + </state> + </subcomponent> + </subcomponents> + <properties> + <property> + <name>onos-index</name> + <config> + <name>onos-index</name> + <value>2</value> + </config> + <state> + <name>onos-index</name> + <value>2</value> + </state> + </property> + <property> + <name>odtn-port-type</name> + <config> + <name>odtn-port-type</name> + <value>line</value> + </config> + <state> + <name>odtn-port-type</name> + <value>line</value> + </state> + </property> + </properties> + </component> + <component> + <name>port-3</name> + <config> + <name>port-3</name> + </config> + <state> + <name>port-3</name> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:PORT</type> + </state> + <subcomponents> + <subcomponent> + <name>channel-3</name> + <config> + <name>channel-3</name> + </config> + <state> + <name>channel-3</name> + </state> + </subcomponent> + </subcomponents> + <properties> + <property> + <name>onos-index</name> + <config> + <name>onos-index</name> + <value>3</value> + </config> + <state> + <name>onos-index</name> + <value>3</value> + </state> + </property> + <property> + <name>odtn-port-type</name> + <config> + <name>odtn-port-type</name> + <value>line</value> + </config> + <state> + <name>odtn-port-type</name> + <value>line</value> + </state> + </property> + </properties> + </component> + <component> + <name>port-4</name> + <config> + <name>port-4</name> + </config> + <state> + <name>port-4</name> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:PORT</type> + </state> + <subcomponents> + <subcomponent> + <name>channel-4</name> + <config> + <name>channel-4</name> + </config> + <state> + <name>channel-4</name> + </state> + </subcomponent> + </subcomponents> + <properties> + <property> + <name>onos-index</name> + <config> + <name>onos-index</name> + <value>4</value> + </config> + <state> + <name>onos-index</name> + <value>4</value> + </state> + </property> + <property> + <name>odtn-port-type</name> + <config> + <name>odtn-port-type</name> + <value>line</value> + </config> + <state> + <name>odtn-port-type</name> + <value>line</value> + </state> + </property> + </properties> + </component> + </components> + <terminal-device xmlns="http://openconfig.net/yang/terminal-device"> + <logical-channels> + <!--Description: Optical logical link--> + <channel> + <!--Description: Line (OTN) Port--> + <index>1</index> + <config> + <index>1</index> + <description>Logical channel 1</description> + <admin-state>DISABLED</admin-state> + <logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type> + <loopback-mode>NONE</loopback-mode> + </config> + <state> + <index>1</index> + <description>Logical channel 1</description> + <admin-state>DISABLED</admin-state> + <logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type> + <loopback-mode>NONE</loopback-mode> + <link-state>UP</link-state> + </state> + <ingress> + <config> + <transceiver>transceiver-1</transceiver> + </config> + <state> + <transceiver>transceiver-1</transceiver> + </state> + </ingress> + <otn> + <config> + <tti-msg-expected>test1</tti-msg-expected> + <tti-msg-transmit>test1</tti-msg-transmit> + </config> + <state> + <tti-msg-expected>test1</tti-msg-expected> + <tti-msg-transmit>test1</tti-msg-transmit> + <tti-msg-auto>0</tti-msg-auto> + <tti-msg-recv>0</tti-msg-recv> + <rdi-msg>0</rdi-msg> + <errored-seconds>0</errored-seconds> + <severely-errored-seconds>0</severely-errored-seconds> + <unavailable-seconds>0</unavailable-seconds> + <code-violations>0</code-violations> + <fec-uncorrectable-words>0</fec-uncorrectable-words> + <fec-corrected-bytes>0</fec-corrected-bytes> + <fec-corrected-bits>0</fec-corrected-bits> + <background-block-errors>0</background-block-errors> + <pre-fec-ber> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + </pre-fec-ber> + <post-fec-ber> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + </post-fec-ber> + <q-value> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + <interval>0</interval> + </q-value> + <esnr> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + <interval>0</interval> + </esnr> + </state> + </otn> + <logical-channel-assignments> + <assignment> + <index>1</index> + <config> + <index>1</index> + <description>Optical channel assigned 100</description> + <allocation>100</allocation> + <assignment-type>OPTICAL_CHANNEL</assignment-type> + <optical-channel>channel-1</optical-channel> + </config> + <state> + <index>1</index> + <description>Optical channel assigned 100</description> + <allocation>100</allocation> + <assignment-type>OPTICAL_CHANNEL</assignment-type> + <optical-channel>channel-1</optical-channel> + </state> + </assignment> + </logical-channel-assignments> + </channel> + <!--Description: Optical logical link--> + <channel> + <!--Description: Line (OTN) Port--> + <index>2</index> + <config> + <index>2</index> + <description>Logical channel 2</description> + <admin-state>DISABLED</admin-state> + <logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type> + <loopback-mode>NONE</loopback-mode> + </config> + <state> + <index>2</index> + <description>Logical channel 2</description> + <admin-state>DISABLED</admin-state> + <logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type> + <loopback-mode>NONE</loopback-mode> + <link-state>UP</link-state> + </state> + <ingress> + <config> + <transceiver>transceiver-2</transceiver> + </config> + <state> + <transceiver>transceiver-2</transceiver> + </state> + </ingress> + <otn> + <config> + <tti-msg-expected>test1</tti-msg-expected> + <tti-msg-transmit>test1</tti-msg-transmit> + </config> + <state> + <tti-msg-expected>test1</tti-msg-expected> + <tti-msg-transmit>test1</tti-msg-transmit> + <tti-msg-auto>0</tti-msg-auto> + <tti-msg-recv>0</tti-msg-recv> + <rdi-msg>0</rdi-msg> + <errored-seconds>0</errored-seconds> + <severely-errored-seconds>0</severely-errored-seconds> + <unavailable-seconds>0</unavailable-seconds> + <code-violations>0</code-violations> + <fec-uncorrectable-words>0</fec-uncorrectable-words> + <fec-corrected-bytes>0</fec-corrected-bytes> + <fec-corrected-bits>0</fec-corrected-bits> + <background-block-errors>0</background-block-errors> + <pre-fec-ber> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + </pre-fec-ber> + <post-fec-ber> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + </post-fec-ber> + <q-value> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + <interval>0</interval> + </q-value> + <esnr> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + <interval>0</interval> + </esnr> + </state> + </otn> + <logical-channel-assignments> + <assignment> + <index>1</index> + <config> + <index>1</index> + <description>Optical channel assigned 100</description> + <allocation>100</allocation> + <assignment-type>OPTICAL_CHANNEL</assignment-type> + <optical-channel>channel-2</optical-channel> + </config> + <state> + <index>1</index> + <description>Optical channel assigned 100</description> + <allocation>100</allocation> + <assignment-type>OPTICAL_CHANNEL</assignment-type> + <optical-channel>channel-2</optical-channel> + </state> + </assignment> + </logical-channel-assignments> + </channel> + <!--Description: Optical logical link--> + <channel> + <!--Description: Line (OTN) Port--> + <index>3</index> + <config> + <index>3</index> + <description>Logical channel 3</description> + <admin-state>DISABLED</admin-state> + <logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type> + <loopback-mode>NONE</loopback-mode> + </config> + <state> + <index>3</index> + <description>Logical channel 3</description> + <admin-state>DISABLED</admin-state> + <logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type> + <loopback-mode>NONE</loopback-mode> + <link-state>UP</link-state> + </state> + <ingress> + <config> + <transceiver>transceiver-3</transceiver> + </config> + <state> + <transceiver>transceiver-3</transceiver> + </state> + </ingress> + <otn> + <config> + <tti-msg-expected>test1</tti-msg-expected> + <tti-msg-transmit>test1</tti-msg-transmit> + </config> + <state> + <tti-msg-expected>test1</tti-msg-expected> + <tti-msg-transmit>test1</tti-msg-transmit> + <tti-msg-auto>0</tti-msg-auto> + <tti-msg-recv>0</tti-msg-recv> + <rdi-msg>0</rdi-msg> + <errored-seconds>0</errored-seconds> + <severely-errored-seconds>0</severely-errored-seconds> + <unavailable-seconds>0</unavailable-seconds> + <code-violations>0</code-violations> + <fec-uncorrectable-words>0</fec-uncorrectable-words> + <fec-corrected-bytes>0</fec-corrected-bytes> + <fec-corrected-bits>0</fec-corrected-bits> + <background-block-errors>0</background-block-errors> + <pre-fec-ber> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + </pre-fec-ber> + <post-fec-ber> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + </post-fec-ber> + <q-value> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + <interval>0</interval> + </q-value> + <esnr> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + <interval>0</interval> + </esnr> + </state> + </otn> + <logical-channel-assignments> + <assignment> + <index>1</index> + <config> + <index>1</index> + <description>Optical channel assigned 100</description> + <allocation>100</allocation> + <assignment-type>OPTICAL_CHANNEL</assignment-type> + <optical-channel>channel-3</optical-channel> + </config> + <state> + <index>1</index> + <description>Optical channel assigned 100</description> + <allocation>100</allocation> + <assignment-type>OPTICAL_CHANNEL</assignment-type> + <optical-channel>channel-3</optical-channel> + </state> + </assignment> + </logical-channel-assignments> + </channel> + <!--Description: Optical logical link--> + <channel> + <!--Description: Line (OTN) Port--> + <index>4</index> + <config> + <index>4</index> + <description>Logical channel 4</description> + <admin-state>DISABLED</admin-state> + <logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type> + <loopback-mode>NONE</loopback-mode> + </config> + <state> + <index>4</index> + <description>Logical channel 4</description> + <admin-state>DISABLED</admin-state> + <logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type> + <loopback-mode>NONE</loopback-mode> + <link-state>UP</link-state> + </state> + <ingress> + <config> + <transceiver>transceiver-4</transceiver> + </config> + <state> + <transceiver>transceiver-4</transceiver> + </state> + </ingress> + <otn> + <config> + <tti-msg-expected>test1</tti-msg-expected> + <tti-msg-transmit>test1</tti-msg-transmit> + </config> + <state> + <tti-msg-expected>test1</tti-msg-expected> + <tti-msg-transmit>test1</tti-msg-transmit> + <tti-msg-auto>0</tti-msg-auto> + <tti-msg-recv>0</tti-msg-recv> + <rdi-msg>0</rdi-msg> + <errored-seconds>0</errored-seconds> + <severely-errored-seconds>0</severely-errored-seconds> + <unavailable-seconds>0</unavailable-seconds> + <code-violations>0</code-violations> + <fec-uncorrectable-words>0</fec-uncorrectable-words> + <fec-corrected-bytes>0</fec-corrected-bytes> + <fec-corrected-bits>0</fec-corrected-bits> + <background-block-errors>0</background-block-errors> + <pre-fec-ber> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + </pre-fec-ber> + <post-fec-ber> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + </post-fec-ber> + <q-value> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + <interval>0</interval> + </q-value> + <esnr> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + <interval>0</interval> + </esnr> + </state> + </otn> + <logical-channel-assignments> + <assignment> + <index>1</index> + <config> + <index>1</index> + <description>Optical channel assigned 100</description> + <allocation>100</allocation> + <assignment-type>OPTICAL_CHANNEL</assignment-type> + <optical-channel>channel-4</optical-channel> + </config> + <state> + <index>1</index> + <description>Optical channel assigned 100</description> + <allocation>100</allocation> + <assignment-type>OPTICAL_CHANNEL</assignment-type> + <optical-channel>channel-4</optical-channel> + </state> + </assignment> + </logical-channel-assignments> + </channel> + </logical-channels> + <operational-modes> + <mode> + <mode-id>1</mode-id> + <state> + <mode-id>1</mode-id> + <description>FEC1</description> + <vendor-id>Ericsson</vendor-id> + </state> + </mode> + <mode> + <mode-id>2</mode-id> + <state> + <mode-id>2</mode-id> + <description>FEC2</description> + <vendor-id>Ericsson</vendor-id> + </state> + </mode> + </operational-modes> + </terminal-device> +</config> + diff --git a/src/tests/ofc24/tempOC/files/transponders_x4_2.xml b/src/tests/ofc24/tempOC/files/transponders_x4_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..8d10c593b3c2166b16e8ecea383dadd69c3ac067 --- /dev/null +++ b/src/tests/ofc24/tempOC/files/transponders_x4_2.xml @@ -0,0 +1,1039 @@ +<config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0"> + <components xmlns="http://openconfig.net/yang/platform"> + <component> + <name>device</name> + <config> + <name>device</name> + </config> + <state> + <name>MellanoxSwitch</name> + <mfg-name>SSSA-CNIT</mfg-name> + <hardware-version>1.0.0</hardware-version> + <firmware-version>1.0.0</firmware-version> + <software-version>1.0.0</software-version> + <serial-no>610610</serial-no> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:OPERATING_SYSTEM</type> + </state> + </component> + <component> + <name>channel-5</name> + <config> + <name>channel-5</name> + </config> + <state> + <name>channel-5</name> + <type xmlns:typex="http://openconfig.net/yang/transport-types">typex:OPTICAL_CHANNEL</type> + </state> + <optical-channel xmlns="http://openconfig.net/yang/terminal-device"> + <config> + <frequency>191600000</frequency> + <target-output-power>100</target-output-power> + <operational-mode>0</operational-mode> + <line-port>transceiver-5</line-port> + </config> + <state> + <frequency>191600000</frequency> + <target-output-power>0</target-output-power> + <operational-mode>0</operational-mode> + <line-port>transceiver-5</line-port> + <group-id>1</group-id> + <output-power> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </output-power> + <input-power> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </input-power> + <laser-bias-current> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </laser-bias-current> + <chromatic-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </chromatic-dispersion> + <polarization-mode-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </polarization-mode-dispersion> + <second-order-polarization-mode-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </second-order-polarization-mode-dispersion> + <polarization-dependent-loss> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </polarization-dependent-loss> + </state> + </optical-channel> + </component> + <component> + <name>channel-6</name> + <config> + <name>channel-6</name> + </config> + <state> + <name>channel-6</name> + <type xmlns:typex="http://openconfig.net/yang/transport-types">typex:OPTICAL_CHANNEL</type> + </state> + <optical-channel xmlns="http://openconfig.net/yang/terminal-device"> + <config> + <frequency>191600000</frequency> + <target-output-power>100</target-output-power> + <operational-mode>0</operational-mode> + <line-port>transceiver-6</line-port> + </config> + <state> + <frequency>191600000</frequency> + <target-output-power>0</target-output-power> + <operational-mode>0</operational-mode> + <line-port>transceiver-6</line-port> + <group-id>1</group-id> + <output-power> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </output-power> + <input-power> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </input-power> + <laser-bias-current> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </laser-bias-current> + <chromatic-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </chromatic-dispersion> + <polarization-mode-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </polarization-mode-dispersion> + <second-order-polarization-mode-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </second-order-polarization-mode-dispersion> + <polarization-dependent-loss> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </polarization-dependent-loss> + </state> + </optical-channel> + </component> + <component> + <name>channel-7</name> + <config> + <name>channel-7</name> + </config> + <state> + <name>channel-7</name> + <type xmlns:typex="http://openconfig.net/yang/transport-types">typex:OPTICAL_CHANNEL</type> + </state> + <optical-channel xmlns="http://openconfig.net/yang/terminal-device"> + <config> + <frequency>191600000</frequency> + <target-output-power>100</target-output-power> + <operational-mode>0</operational-mode> + <line-port>transceiver-7</line-port> + </config> + <state> + <frequency>191600000</frequency> + <target-output-power>0</target-output-power> + <operational-mode>0</operational-mode> + <line-port>transceiver-7</line-port> + <group-id>1</group-id> + <output-power> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </output-power> + <input-power> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </input-power> + <laser-bias-current> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </laser-bias-current> + <chromatic-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </chromatic-dispersion> + <polarization-mode-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </polarization-mode-dispersion> + <second-order-polarization-mode-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </second-order-polarization-mode-dispersion> + <polarization-dependent-loss> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </polarization-dependent-loss> + </state> + </optical-channel> + </component> + <component> + <name>channel-8</name> + <config> + <name>channel-8</name> + </config> + <state> + <name>channel-8</name> + <type xmlns:typex="http://openconfig.net/yang/transport-types">typex:OPTICAL_CHANNEL</type> + </state> + <optical-channel xmlns="http://openconfig.net/yang/terminal-device"> + <config> + <frequency>191600000</frequency> + <target-output-power>100</target-output-power> + <operational-mode>0</operational-mode> + <line-port>transceiver-8</line-port> + </config> + <state> + <frequency>191600000</frequency> + <target-output-power>0</target-output-power> + <operational-mode>0</operational-mode> + <line-port>transceiver-8</line-port> + <group-id>1</group-id> + <output-power> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </output-power> + <input-power> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </input-power> + <laser-bias-current> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </laser-bias-current> + <chromatic-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </chromatic-dispersion> + <polarization-mode-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </polarization-mode-dispersion> + <second-order-polarization-mode-dispersion> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + </second-order-polarization-mode-dispersion> + <polarization-dependent-loss> + <instant>0</instant> + <avg>0</avg> + <min>0</min> + <max>0</max> + <interval>0</interval> + </polarization-dependent-loss> + </state> + </optical-channel> + </component> + <component> + <name>transceiver-5</name> + <config> + <name>transceiver-5</name> + </config> + <state> + <name>transceiver-5</name> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:TRANSCEIVER</type> + </state> + <transceiver xmlns="http://openconfig.net/yang/platform/transceiver"> + <config> + <enabled>true</enabled> + <form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf> + <ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf> + <fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode> + <module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type> + </config> + <state> + <enabled>true</enabled> + <form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf> + <ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf> + <fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode> + <module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type> + <vendor>Cisco</vendor> + <vendor-part>400zr-QSFP-DD</vendor-part> + <vendor-rev>01</vendor-rev> + <serial-no>1567321</serial-no> + </state> + <physical-channels> + <channel> + <index>1</index> + <config> + <index>1</index> + <associated-optical-channel>channel-5</associated-optical-channel> + </config> + </channel> + </physical-channels> + </transceiver> + </component> + <component> + <name>transceiver-6</name> + <config> + <name>transceiver-6</name> + </config> + <state> + <name>transceiver-6</name> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:TRANSCEIVER</type> + </state> + <transceiver xmlns="http://openconfig.net/yang/platform/transceiver"> + <config> + <enabled>true</enabled> + <form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf> + <ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf> + <fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode> + <module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type> + </config> + <state> + <enabled>true</enabled> + <form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf> + <ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf> + <fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode> + <module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type> + <vendor>Cisco</vendor> + <vendor-part>400zr-QSFP-DD</vendor-part> + <vendor-rev>01</vendor-rev> + <serial-no>1567321</serial-no> + </state> + <physical-channels> + <channel> + <index>1</index> + <config> + <index>1</index> + <associated-optical-channel>channel-6</associated-optical-channel> + </config> + </channel> + </physical-channels> + </transceiver> + </component> + <component> + <name>transceiver-7</name> + <config> + <name>transceiver-7</name> + </config> + <state> + <name>transceiver-7</name> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:TRANSCEIVER</type> + </state> + <transceiver xmlns="http://openconfig.net/yang/platform/transceiver"> + <config> + <enabled>true</enabled> + <form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf> + <ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf> + <fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode> + <module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type> + </config> + <state> + <enabled>true</enabled> + <form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf> + <ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf> + <fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode> + <module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type> + <vendor>Cisco</vendor> + <vendor-part>400zr-QSFP-DD</vendor-part> + <vendor-rev>01</vendor-rev> + <serial-no>1567321</serial-no> + </state> + <physical-channels> + <channel> + <index>1</index> + <config> + <index>1</index> + <associated-optical-channel>channel-7</associated-optical-channel> + </config> + </channel> + </physical-channels> + </transceiver> + </component> + + <component> + <name>transceiver-8</name> + <config> + <name>transceiver-8</name> + </config> + <state> + <name>transceiver-8</name> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:TRANSCEIVER</type> + </state> + <transceiver xmlns="http://openconfig.net/yang/platform/transceiver"> + <config> + <enabled>true</enabled> + <form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf> + <ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf> + <fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode> + <module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type> + </config> + <state> + <enabled>true</enabled> + <form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf> + <ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf> + <fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode> + <module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type> + <vendor>Cisco</vendor> + <vendor-part>400zr-QSFP-DD</vendor-part> + <vendor-rev>01</vendor-rev> + <serial-no>1567321</serial-no> + </state> + <physical-channels> + <channel> + <index>1</index> + <config> + <index>1</index> + <associated-optical-channel>channel-8</associated-optical-channel> + </config> + </channel> + </physical-channels> + </transceiver> + </component> + <component> + <name>port-5</name> + <config> + <name>port-5</name> + </config> + <state> + <name>port-5</name> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:PORT</type> + </state> + <subcomponents> + <subcomponent> + <name>channel-5</name> + <config> + <name>channel-5</name> + </config> + <state> + <name>channel-5</name> + </state> + </subcomponent> + </subcomponents> + <properties> + <property> + <name>onos-index</name> + <config> + <name>onos-index</name> + <value>5</value> + </config> + <state> + <name>onos-index</name> + <value>5</value> + </state> + </property> + <property> + <name>odtn-port-type</name> + <config> + <name>odtn-port-type</name> + <value>line</value> + </config> + <state> + <name>odtn-port-type</name> + <value>line</value> + </state> + </property> + </properties> + </component> + <component> + <name>port-6</name> + <config> + <name>port-6</name> + </config> + <state> + <name>port-6</name> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:PORT</type> + </state> + <subcomponents> + <subcomponent> + <name>channel-6</name> + <config> + <name>channel-6</name> + </config> + <state> + <name>channel-6</name> + </state> + </subcomponent> + </subcomponents> + <properties> + <property> + <name>onos-index</name> + <config> + <name>onos-index</name> + <value>6</value> + </config> + <state> + <name>onos-index</name> + <value>6</value> + </state> + </property> + <property> + <name>odtn-port-type</name> + <config> + <name>odtn-port-type</name> + <value>line</value> + </config> + <state> + <name>odtn-port-type</name> + <value>line</value> + </state> + </property> + </properties> + </component> + <component> + <name>port-7</name> + <config> + <name>port-7</name> + </config> + <state> + <name>port-7</name> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:PORT</type> + </state> + <subcomponents> + <subcomponent> + <name>channel-7</name> + <config> + <name>channel-7</name> + </config> + <state> + <name>channel-7</name> + </state> + </subcomponent> + </subcomponents> + <properties> + <property> + <name>onos-index</name> + <config> + <name>onos-index</name> + <value>7</value> + </config> + <state> + <name>onos-index</name> + <value>7</value> + </state> + </property> + <property> + <name>odtn-port-type</name> + <config> + <name>odtn-port-type</name> + <value>line</value> + </config> + <state> + <name>odtn-port-type</name> + <value>line</value> + </state> + </property> + </properties> + </component> + <component> + <name>port-8</name> + <config> + <name>port-8</name> + </config> + <state> + <name>port-8</name> + <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:PORT</type> + </state> + <subcomponents> + <subcomponent> + <name>channel-8</name> + <config> + <name>channel-8</name> + </config> + <state> + <name>channel-8</name> + </state> + </subcomponent> + </subcomponents> + <properties> + <property> + <name>onos-index</name> + <config> + <name>onos-index</name> + <value>8</value> + </config> + <state> + <name>onos-index</name> + <value>8</value> + </state> + </property> + <property> + <name>odtn-port-type</name> + <config> + <name>odtn-port-type</name> + <value>line</value> + </config> + <state> + <name>odtn-port-type</name> + <value>line</value> + </state> + </property> + </properties> + </component> + </components> + <terminal-device xmlns="http://openconfig.net/yang/terminal-device"> + <logical-channels> + <!--Description: Optical logical link--> + <channel> + <!--Description: Line (OTN) Port--> + <index>5</index> + <config> + <index>5</index> + <description>Logical channel 5</description> + <admin-state>DISABLED</admin-state> + <logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type> + <loopback-mode>NONE</loopback-mode> + </config> + <state> + <index>5</index> + <description>Logical channel 5</description> + <admin-state>DISABLED</admin-state> + <logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type> + <loopback-mode>NONE</loopback-mode> + <link-state>UP</link-state> + </state> + <ingress> + <config> + <transceiver>transceiver-5</transceiver> + </config> + <state> + <transceiver>transceiver-5</transceiver> + </state> + </ingress> + <otn> + <config> + <tti-msg-expected>test1</tti-msg-expected> + <tti-msg-transmit>test1</tti-msg-transmit> + </config> + <state> + <tti-msg-expected>test1</tti-msg-expected> + <tti-msg-transmit>test1</tti-msg-transmit> + <tti-msg-auto>0</tti-msg-auto> + <tti-msg-recv>0</tti-msg-recv> + <rdi-msg>0</rdi-msg> + <errored-seconds>0</errored-seconds> + <severely-errored-seconds>0</severely-errored-seconds> + <unavailable-seconds>0</unavailable-seconds> + <code-violations>0</code-violations> + <fec-uncorrectable-words>0</fec-uncorrectable-words> + <fec-corrected-bytes>0</fec-corrected-bytes> + <fec-corrected-bits>0</fec-corrected-bits> + <background-block-errors>0</background-block-errors> + <pre-fec-ber> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + </pre-fec-ber> + <post-fec-ber> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + </post-fec-ber> + <q-value> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + <interval>0</interval> + </q-value> + <esnr> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + <interval>0</interval> + </esnr> + </state> + </otn> + <logical-channel-assignments> + <assignment> + <index>1</index> + <config> + <index>1</index> + <description>Optical channel assigned 100</description> + <allocation>100</allocation> + <assignment-type>OPTICAL_CHANNEL</assignment-type> + <optical-channel>channel-5</optical-channel> + </config> + <state> + <index>1</index> + <description>Optical channel assigned 100</description> + <allocation>100</allocation> + <assignment-type>OPTICAL_CHANNEL</assignment-type> + <optical-channel>channel-5</optical-channel> + </state> + </assignment> + </logical-channel-assignments> + </channel> + <!--Description: Optical logical link--> + <channel> + <!--Description: Line (OTN) Port--> + <index>6</index> + <config> + <index>6</index> + <description>Logical channel 6</description> + <admin-state>DISABLED</admin-state> + <logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type> + <loopback-mode>NONE</loopback-mode> + </config> + <state> + <index>6</index> + <description>Logical channel 6</description> + <admin-state>DISABLED</admin-state> + <logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type> + <loopback-mode>NONE</loopback-mode> + <link-state>UP</link-state> + </state> + <ingress> + <config> + <transceiver>transceiver-6</transceiver> + </config> + <state> + <transceiver>transceiver-6</transceiver> + </state> + </ingress> + <otn> + <config> + <tti-msg-expected>test1</tti-msg-expected> + <tti-msg-transmit>test1</tti-msg-transmit> + </config> + <state> + <tti-msg-expected>test1</tti-msg-expected> + <tti-msg-transmit>test1</tti-msg-transmit> + <tti-msg-auto>0</tti-msg-auto> + <tti-msg-recv>0</tti-msg-recv> + <rdi-msg>0</rdi-msg> + <errored-seconds>0</errored-seconds> + <severely-errored-seconds>0</severely-errored-seconds> + <unavailable-seconds>0</unavailable-seconds> + <code-violations>0</code-violations> + <fec-uncorrectable-words>0</fec-uncorrectable-words> + <fec-corrected-bytes>0</fec-corrected-bytes> + <fec-corrected-bits>0</fec-corrected-bits> + <background-block-errors>0</background-block-errors> + <pre-fec-ber> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + </pre-fec-ber> + <post-fec-ber> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + </post-fec-ber> + <q-value> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + <interval>0</interval> + </q-value> + <esnr> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + <interval>0</interval> + </esnr> + </state> + </otn> + <logical-channel-assignments> + <assignment> + <index>1</index> + <config> + <index>1</index> + <description>Optical channel assigned 100</description> + <allocation>100</allocation> + <assignment-type>OPTICAL_CHANNEL</assignment-type> + <optical-channel>channel-6</optical-channel> + </config> + <state> + <index>1</index> + <description>Optical channel assigned 100</description> + <allocation>100</allocation> + <assignment-type>OPTICAL_CHANNEL</assignment-type> + <optical-channel>channel-6</optical-channel> + </state> + </assignment> + </logical-channel-assignments> + </channel> + <!--Description: Optical logical link--> + <channel> + <!--Description: Line (OTN) Port--> + <index>7</index> + <config> + <index>7</index> + <description>Logical channel 7</description> + <admin-state>DISABLED</admin-state> + <logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type> + <loopback-mode>NONE</loopback-mode> + </config> + <state> + <index>7</index> + <description>Logical channel 7</description> + <admin-state>DISABLED</admin-state> + <logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type> + <loopback-mode>NONE</loopback-mode> + <link-state>UP</link-state> + </state> + <ingress> + <config> + <transceiver>transceiver-7</transceiver> + </config> + <state> + <transceiver>transceiver-7</transceiver> + </state> + </ingress> + <otn> + <config> + <tti-msg-expected>test1</tti-msg-expected> + <tti-msg-transmit>test1</tti-msg-transmit> + </config> + <state> + <tti-msg-expected>test1</tti-msg-expected> + <tti-msg-transmit>test1</tti-msg-transmit> + <tti-msg-auto>0</tti-msg-auto> + <tti-msg-recv>0</tti-msg-recv> + <rdi-msg>0</rdi-msg> + <errored-seconds>0</errored-seconds> + <severely-errored-seconds>0</severely-errored-seconds> + <unavailable-seconds>0</unavailable-seconds> + <code-violations>0</code-violations> + <fec-uncorrectable-words>0</fec-uncorrectable-words> + <fec-corrected-bytes>0</fec-corrected-bytes> + <fec-corrected-bits>0</fec-corrected-bits> + <background-block-errors>0</background-block-errors> + <pre-fec-ber> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + </pre-fec-ber> + <post-fec-ber> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + </post-fec-ber> + <q-value> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + <interval>0</interval> + </q-value> + <esnr> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + <interval>0</interval> + </esnr> + </state> + </otn> + <logical-channel-assignments> + <assignment> + <index>1</index> + <config> + <index>1</index> + <description>Optical channel assigned 100</description> + <allocation>100</allocation> + <assignment-type>OPTICAL_CHANNEL</assignment-type> + <optical-channel>channel-7</optical-channel> + </config> + <state> + <index>1</index> + <description>Optical channel assigned 100</description> + <allocation>100</allocation> + <assignment-type>OPTICAL_CHANNEL</assignment-type> + <optical-channel>channel-7</optical-channel> + </state> + </assignment> + </logical-channel-assignments> + </channel> + <!--Description: Optical logical link--> + <channel> + <!--Description: Line (OTN) Port--> + <index>8</index> + <config> + <index>8</index> + <description>Logical channel 8</description> + <admin-state>DISABLED</admin-state> + <logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type> + <loopback-mode>NONE</loopback-mode> + </config> + <state> + <index>8</index> + <description>Logical channel 8</description> + <admin-state>DISABLED</admin-state> + <logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type> + <loopback-mode>NONE</loopback-mode> + <link-state>UP</link-state> + </state> + <ingress> + <config> + <transceiver>transceiver-8</transceiver> + </config> + <state> + <transceiver>transceiver-8</transceiver> + </state> + </ingress> + <otn> + <config> + <tti-msg-expected>test1</tti-msg-expected> + <tti-msg-transmit>test1</tti-msg-transmit> + </config> + <state> + <tti-msg-expected>test1</tti-msg-expected> + <tti-msg-transmit>test1</tti-msg-transmit> + <tti-msg-auto>0</tti-msg-auto> + <tti-msg-recv>0</tti-msg-recv> + <rdi-msg>0</rdi-msg> + <errored-seconds>0</errored-seconds> + <severely-errored-seconds>0</severely-errored-seconds> + <unavailable-seconds>0</unavailable-seconds> + <code-violations>0</code-violations> + <fec-uncorrectable-words>0</fec-uncorrectable-words> + <fec-corrected-bytes>0</fec-corrected-bytes> + <fec-corrected-bits>0</fec-corrected-bits> + <background-block-errors>0</background-block-errors> + <pre-fec-ber> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + </pre-fec-ber> + <post-fec-ber> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + </post-fec-ber> + <q-value> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + <interval>0</interval> + </q-value> + <esnr> + <instant>0.0</instant> + <avg>0.0</avg> + <min>0.0</min> + <max>0.0</max> + <interval>0</interval> + </esnr> + </state> + </otn> + <logical-channel-assignments> + <assignment> + <index>1</index> + <config> + <index>1</index> + <description>Optical channel assigned 100</description> + <allocation>100</allocation> + <assignment-type>OPTICAL_CHANNEL</assignment-type> + <optical-channel>channel-8</optical-channel> + </config> + <state> + <index>1</index> + <description>Optical channel assigned 100</description> + <allocation>100</allocation> + <assignment-type>OPTICAL_CHANNEL</assignment-type> + <optical-channel>channel-8</optical-channel> + </state> + </assignment> + </logical-channel-assignments> + </channel> + </logical-channels> + <operational-modes> + <mode> + <mode-id>1</mode-id> + <state> + <mode-id>1</mode-id> + <description>FEC1</description> + <vendor-id>Ericsson</vendor-id> + </state> + </mode> + <mode> + <mode-id>2</mode-id> + <state> + <mode-id>2</mode-id> + <description>FEC2</description> + <vendor-id>Ericsson</vendor-id> + </state> + </mode> + </operational-modes> + </terminal-device> +</config> + diff --git a/src/webui/service/main/routes.py b/src/webui/service/main/routes.py index 9f700283dfba45e5db1750137c9cbdd447246b5d..64c134d10ce80c2e41365728bf192467b16a99ae 100644 --- a/src/webui/service/main/routes.py +++ b/src/webui/service/main/routes.py @@ -155,6 +155,7 @@ def topology(): 'source': link.link_endpoint_ids[0].device_id.device_uuid.uuid, 'target': link.link_endpoint_ids[1].device_id.device_uuid.uuid, }) + optical_links = [] for link in response.optical_links: if len(link.link_endpoint_ids) != 2: @@ -167,7 +168,7 @@ def topology(): 'source': link.link_endpoint_ids[0].device_id.device_uuid.uuid, 'target': link.link_endpoint_ids[1].device_id.device_uuid.uuid, }) - LOGGER.info(f"optical links {optical_links}") + return jsonify({'devices': devices, 'links': links ,'optical_links':optical_links}) except: # pylint: disable=bare-except LOGGER.exception('Error retrieving topology') diff --git a/src/webui/service/optical_link/routes.py b/src/webui/service/optical_link/routes.py index 7be81410ebb7f82c303fa028b0aff4d4484c14a0..2db55fd492027be2965f8f2580c069761ebf4715 100644 --- a/src/webui/service/optical_link/routes.py +++ b/src/webui/service/optical_link/routes.py @@ -70,15 +70,12 @@ def detail(link_uuid: str): context_client.close() return render_template('optical_link/detail.html',link=link_obj, device_names=device_names, endpoints_data=endpoints_data) + @optical_link.get('<path:link_uuid>/delete') def delete(link_uuid): try: - # first, check if link exists! - # request: LinkId = LinkId() - # request.link_uuid.uuid = link_uuid - # response: Link = client.GetLink(request) - # TODO: finalize implementation + request = LinkId() request.link_uuid.uuid = link_uuid # pylint: disable=no-member @@ -91,3 +88,23 @@ def delete(link_uuid): flash(f'Problem deleting link "{link_uuid}": {e.details()}', 'danger') current_app.logger.exception(e) return redirect(url_for('optical_link.home')) + + +@optical_link.get("delete_all") +def delete_all () : + + try : + context_client.connect() + optical_link_list:OpticalLinkList = context_client.GetOpticalLinkList(Empty()) + for optical_link in optical_link_list.optical_links: + + context_client.DeleteOpticalLink(optical_link.link_id) + context_client.close() + flash(f"All Optical Link Deleted Successfully",'success') + except Exception as e : + flash(f"Problem in delete all optical link => {e}",'danger') + return redirect(url_for('optical_link.home')) + + + + \ No newline at end of file diff --git a/src/webui/service/opticalconfig/forms.py b/src/webui/service/opticalconfig/forms.py index 30c1332790fa92bcf936035c0e5a8a666f878fe0..efce6b59cb41abc522658c187f276a4015cb4b9f 100644 --- a/src/webui/service/opticalconfig/forms.py +++ b/src/webui/service/opticalconfig/forms.py @@ -19,4 +19,9 @@ class AddTrancseiver (FlaskForm): submit = SubmitField('Add') class UpdateInterfaceForm (FlaskForm): ip=StringField("IP Address") - prefix_length=StringField("Prefix Length") \ No newline at end of file + prefix_length=StringField("Prefix Length") + + +class UpdateStatusForm (FlaskForm): + + status=SelectField("Device Status", choices=[('', 'Select...'), ('DISABLED', 'DISABLED'), ('ENABLED', 'ENABLED')]) \ No newline at end of file diff --git a/src/webui/service/opticalconfig/routes.py b/src/webui/service/opticalconfig/routes.py index d55c44105dc51ebddf3c83f27d18de7740de24b0..1bc3ddc1d830772ae0e157ed164c66e0eebf34a0 100644 --- a/src/webui/service/opticalconfig/routes.py +++ b/src/webui/service/opticalconfig/routes.py @@ -7,7 +7,7 @@ from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient from service.client.ServiceClient import ServiceClient from slice.client.SliceClient import SliceClient -from .forms import UpdateDeviceForm ,AddTrancseiver ,UpdateInterfaceForm +from .forms import UpdateDeviceForm ,AddTrancseiver ,UpdateInterfaceForm ,UpdateStatusForm from common.tools.context_queries.OpticalConfig import opticalconfig_get_uuid , device_get_uuid @@ -55,6 +55,9 @@ def home() : return render_template( 'opticalconfig/home.html', config=config) + + + @opticalconfig.route('<path:config_uuid>/detail',methods=['GET']) def show_details(config_uuid): opticalconfigId=OpticalConfigId() @@ -65,30 +68,33 @@ def show_details(config_uuid): response = context_client.SelectOpticalConfig(opticalconfigId) context_client.close() if (response and response.opticalconfig_id.opticalconfig_uuid !=''): - LOGGER.info("response %s",response) + LOGGER.info("response from show detail %s",response) opticalConfig = OpticalConfig() opticalConfig.CopyFrom(response) config =json.loads(opticalConfig.config) - LOGGER.info("config details %s",config) + LOGGER.info("config details from show detail %s",config) interfaces=config["interfaces"] - new_config={} + device_name="" if ("device_name" in config): device_name= config["device_name"] for channel in config['channels'] : - + new_config={} new_config["name"]=channel['name'] new_config['operationalMode']=channel['operational-mode'] if 'operational-mode' in channel else '' new_config['targetOutputPower']=channel['target-output-power'] if 'target-output-power' in channel else '' new_config["frequency"]=channel['frequency'] if 'frequency' in channel else '' new_config['line_port']=channel["line-port"] if 'line-port' in channel else '' + new_config["status"] = channel['status'] if 'status' in channel else "" device_details.append(new_config) - LOGGER.info("config details %s",device_details) + LOGGER.info("device details %s",device_details) return render_template('opticalconfig/details.html', device=device_details,config_id=config_uuid,device_name=device_name) + + @opticalconfig.route('<path:opticalconfig_uuid>/delete', methods=['GET']) def delete_opitcalconfig (opticalconfig_uuid) : try : @@ -103,6 +109,7 @@ def delete_opitcalconfig (opticalconfig_uuid) : current_app.logger.exception(e) return redirect(url_for('opticalconfig.home')) + @opticalconfig.route('/update_opticalconfig', methods=['POST']) def update_externally () : @@ -242,6 +249,7 @@ def update(config_uuid,channel_name): except Exception as e: # pylint: disable=broad-except flash(f'Problem updating the device. {e}', 'danger') return render_template('myabout/update.html', device=response, form=form, submit_text='Update Device',channel_name=channel_name) + @opticalconfig.route('<path:config_uuid>/<path:interface_name>/update_interface', methods=['GET', 'POST']) def update_interface (config_uuid,interface_name): form = UpdateInterfaceForm() @@ -284,6 +292,7 @@ def add_transceiver (config_uuid): context_client.close() opticlConfig=OpticalConfig() opticlConfig.CopyFrom(response) + if addtrancseiver.validate_on_submit(): config["add_transceiver"]=addtrancseiver.transceiver.data opticlConfig.config=json.dumps(config) @@ -299,6 +308,43 @@ def add_transceiver (config_uuid): return render_template('opticalconfig/add_transceiver.html',form=addtrancseiver, submit_text='Add Trancseiver') + +@opticalconfig.route('<path:config_uuid>/<path:channel_name>/update_status', methods=['GET','POST']) +def update_status (config_uuid,channel_name): + + config={} + form=UpdateStatusForm() + + opticalconfigId=OpticalConfigId() + opticalconfigId.opticalconfig_uuid=config_uuid + context_client.connect() + response = context_client.SelectOpticalConfig(opticalconfigId) + context_client.close() + opticlConfig=OpticalConfig() + opticlConfig.CopyFrom(response) + config=json.loads(opticlConfig.config) + new_config={} + port="" + if form.validate_on_submit(): + if channel_name: + port = channel_name.split('-')[1] + new_config["status"]=form.status.data + new_config["name"]=channel_name + config["flow"]=[(port,'0')] + config["new_config"]=new_config + opticlConfig.config=json.dumps(config) + + try: + LOGGER.info(f"update status {opticlConfig}") + device_client.connect() + device_client.ConfigureOpticalDevice(opticlConfig) + device_client.close() + flash(f' device was updated.', 'success') + return redirect(url_for('opticalconfig.show_details',config_uuid=config_uuid)) + except Exception as e: # pylint: disable=broad-except + flash(f'Problem updating the device. {e}', 'danger') + return render_template('opticalconfig/update_status.html',form=form , channel_name=channel_name, submit_text='Update Device Status') + - + \ No newline at end of file diff --git a/src/webui/service/templates/js/topology.js b/src/webui/service/templates/js/topology.js index fa2cfb41b3dc30a804ea1167787f19736c7358cd..a06ad47242c4d464c4ad502f34162c81f0d89c45 100644 --- a/src/webui/service/templates/js/topology.js +++ b/src/webui/service/templates/js/topology.js @@ -51,7 +51,7 @@ const svg = d3.select('#topology') ; // svg objects -var link, node; +var link, node ,optical_link; // values for all forces forceProperties = { @@ -69,6 +69,7 @@ var simulation = d3.forceSimulation(); // load the data d3.json("{{ url_for('main.topology') }}", function(data) { + console.log(data) // set the data and properties of link lines and node circles link = svg.append("g").attr("class", "links")//.style('stroke', '#aaa') .selectAll("line") @@ -85,6 +86,7 @@ d3.json("{{ url_for('main.topology') }}", function(data) { .attr("stroke-dasharray", function(l) { return l.name.toLowerCase().includes('mgmt') ? "5,5" : "0"; }); + optical_link = svg.append("g").attr("class", "links").style('stroke', '#aaa') .selectAll("line") .data(data.optical_links) @@ -99,7 +101,8 @@ d3.json("{{ url_for('main.topology') }}", function(data) { }) .attr("stroke-dasharray", function(l) { return l.name.toLowerCase().includes('mgmt') ? "5,5" : "0"; - }); + }); + node = svg.append("g").attr("class", "devices").attr('r', 20).style('fill', '#69b3a2') .selectAll("circle") .data(data.devices) @@ -116,6 +119,8 @@ d3.json("{{ url_for('main.topology') }}", function(data) { node.append("title").text(function(n) { return n.name; }); // link tooltip link.append("title").text(function(l) { return l.name; }); + // optical link tooltip + optical_link.append("title").text(function(l) { return l.name; }); // link style //link @@ -131,7 +136,7 @@ d3.json("{{ url_for('main.topology') }}", function(data) { .id(function(d) {return d.id;}) .distance(forceProperties.link.distance) .iterations(forceProperties.link.iterations) - .links(forceProperties.link.enabled ? data.links : [])) + .links(forceProperties.link.enabled ? data.links.length>0? data.links : data.optical_links.length>0?data.optical_links:[]:[])) .force("charge", d3.forceManyBody() .strength(forceProperties.charge.strength * forceProperties.charge.enabled) .distanceMin(forceProperties.charge.distanceMin) @@ -162,6 +167,12 @@ function ticked() { .attr('x2', function(d) { return d.target.x; }) .attr('y2', function(d) { return d.target.y; }); + optical_link + .attr('x1', function(d) { return d.source.x; }) + .attr('y1', function(d) { return d.source.y; }) + .attr('x2', function(d) { return d.target.x; }) + .attr('y2', function(d) { return d.target.y; }); + node .attr('x', function(d) { return d.x-icon_width/2; }) .attr('y', function(d) { return d.y-icon_height/2; }); diff --git a/src/webui/service/templates/optical_link/detail.html b/src/webui/service/templates/optical_link/detail.html index 537c437a822fcb352194ae61b67a9e50e46a313d..9b790435fd4a3628d0bbfebce41e1648e5e169be 100644 --- a/src/webui/service/templates/optical_link/detail.html +++ b/src/webui/service/templates/optical_link/detail.html @@ -116,7 +116,7 @@ <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">No</button> <a type="button" class="btn btn-danger" - href="{{ url_for('link.delete', link_uuid=link.link_id.link_uuid.uuid) }}"><i + href="{{ url_for('optical_link.delete', link_uuid=link.link_id.link_uuid.uuid) }}"><i class="bi bi-exclamation-diamond"></i>Yes</a> </div> </div> diff --git a/src/webui/service/templates/optical_link/home.html b/src/webui/service/templates/optical_link/home.html index e5aca56952182f74148f0093f1aa2971d4886855..ad80ce547e35b535ee654c80812c6ca5a771fe49 100644 --- a/src/webui/service/templates/optical_link/home.html +++ b/src/webui/service/templates/optical_link/home.html @@ -20,15 +20,17 @@ <h1>Optical Links</h1> <div class="row"> - <div class="col"> - <!-- <a href="#" class="btn btn-primary" style="margin-bottom: 10px;"> - <i class="bi bi-plus"></i> - Add New Link - </a> --> - </div> + <div class="col"> {{ links | length }} links found in context <i>{{ session['context_uuid'] }}</i> </div> + <div class="col-sm-3"> + <!-- <button type="button" class="btn btn-danger"><i class="bi bi-x-square"></i>Delete link</button> --> + <button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteModal"> + <i class="bi bi-x-square"></i> + Delete All Optical Links + </button> + </div> <!-- <div class="col"> <form> <div class="input-group"> @@ -93,6 +95,28 @@ </tr> {% endif %} </tbody> + </table> +<div class="modal fade" id="deleteModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" + aria-labelledby="staticBackdropLabel" aria-hidden="true"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="staticBackdropLabel">Delete All Optical links?</h5> + <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> + </div> + <div class="modal-body"> + Are you sure you want to delete all the links ? + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">No</button> + <a type="button" class="btn btn-danger" + href="{{ url_for('optical_link.delete_all') }}"><i + class="bi bi-exclamation-diamond"></i>Yes</a> + </div> + </div> + </div> +</div> + {% endblock %} \ No newline at end of file diff --git a/src/webui/service/templates/opticalconfig/details.html b/src/webui/service/templates/opticalconfig/details.html index 4d39ef62b820970ad2f258280598c3e2ce0f4b5a..e2048d7db0800ca322480743511a4900cb15759b 100644 --- a/src/webui/service/templates/opticalconfig/details.html +++ b/src/webui/service/templates/opticalconfig/details.html @@ -78,7 +78,17 @@ <span>Line Port:</span> <span class="font-weight-bold" style="font-weight: 700;">{{channel.line_port}}</span> </div> - + {% if channel.status%} + <div class="col-sm-4"> + <span>Channel Status :</span> + <span class="font-weight-bold" style="font-weight:700 ;">{{channel.status}}</span> + <span> + <a id="update" class="btn btn-secondary" href="{{ url_for('opticalconfig.update_status',config_uuid=config_id,channel_name=channel.name.index)}}"> + <i class="bi bi-pencil-square"></i> + </a> + </span> + </div> + {%endif %} <div class="col-sm-12 hr bg-primary" style="height:1px; margin:5px 0;"></div> {% endfor %} diff --git a/src/webui/service/templates/opticalconfig/update_status.html b/src/webui/service/templates/opticalconfig/update_status.html new file mode 100644 index 0000000000000000000000000000000000000000..72612f86b62126fb7b36ef66fa89658cf5b9c45f --- /dev/null +++ b/src/webui/service/templates/opticalconfig/update_status.html @@ -0,0 +1,51 @@ + +{% extends 'base.html' %} + +{% block content %} +<h1>Update Channel Status </h1> +<br /> +<div> + channel : <span class="font-weight-bold">{{channel_name}}</span> +</div> +<form id="update_status" method="POST"> + {{ form.hidden_tag() }} + <fieldset> + <div class="row mb-3 "> + <div class="col-12"> + {{ form.status.label(class="col-sm-2 col-form-label") }} + <div class="col-sm-10"> + {% if form.status.errors %} + {{ form.status(class="form-control is-invalid") }} + <div class="invalid-feedback"> + {% for error in form.status.errors %} + <span>{{ error }}</span> + {% endfor %} + </div> + {% else %} + + {{ form.status(class="col-sm-7 form-control") }} + + {% endif %} + </div> + + </div> + <div class="row gx-2"> + <div class="col-5"> + <button type="submit" class="btn btn-primary" > + <i class="bi bi-plus-circle-fill"></i> + {{ submit_text }} + </button> + <div class="col-5"> + + <button type="button" class="btn btn-block btn-secondary" onclick="javascript: history.back()"> + <i class="bi bi-box-arrow-in-left"></i> + Cancel + </button> + </div> + </div> + </div> + + </div> + </fieldset> +</form> +{% endblock %} \ No newline at end of file diff --git a/test.py b/test.py index 47133fe9fd323d86af1ff9e6f5f3601b6f3f437a..5ebb095a0fc9d85b0e66580418cd3696b926eff8 100644 --- a/test.py +++ b/test.py @@ -6,58 +6,65 @@ from typing import Optional, Union from uuid import UUID, uuid4, uuid5 import logging -NAMESPACE_TFS = UUID('200e3a1f-2223-534f-a100-758e29c37f40') -print (uuid5(NAMESPACE_TFS, '1')) -def extract_roadm_ports (xml_data:str): - pattern = r'\bMG_ON_OPTICAL_PORT_WAVEBAND\b' - xml_bytes = xml_data.encode("utf-8") - root = ET.fromstring(xml_bytes) - with open('xml.log', 'w') as f: - print(xml_bytes, file=f) - - namespace = {'oc': 'http://openconfig.net/yang/platform'} - ports = [] - components = root.findall('.//oc:component',namespace) - print(f"component {components}") - - - for component in components: - - properties = component.find(".//oc:properties",namespace) - - if (properties is not None): - for property in properties : - value = property.find(".//oc:value",namespace) - - if (re.search(pattern,value.text)): - name_element= component.find(".//oc:name",namespace) - print (f"name {name_element.text}") - - - -def extract_ports_based_on_type (xml_data:str): - pattern = r':\s*PORT\b' - - xml_bytes = xml_data.encode("utf-8") - root = ET.fromstring(xml_bytes) - - namespace = {'oc': 'http://openconfig.net/yang/platform', 'typex': 'http://openconfig.net/yang/platform-types'} - ports = [] - components = root.findall(".//oc:state[oc:type]",namespace) - for component in components: - type_ele = component.find(".//oc:type",namespace) - match = re.search(pattern, type_ele.text) - if match is not None : - name= component.find(".//oc:name",namespace) - print(name.text) - print("/////////////") - + +edit_config_t = ''' + <config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> + <terminal-device xmlns="http://openconfig.net/yang/terminal-device"> + <logical-channels> + <channel> + <index>1</index> + <config> + <admin-state>DISABLED</admin-state> + </config> + </channel> + </logical-channels> + </terminal-device> + </config> +''' + +edit_config_r_media_channel = ''' + <config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> + <wavelength-router xmlns="http://openconfig.net/yang/wavelength-router"> + <media-channels > + <channel operation="delete" > + <index>1</index> + <config> + <index>1</index> + </config> + </channel> + </media-channels> + </wavelength-router> + </config> +''' +edit_config_r_optical_band = ''' +<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> + <wavelength-router xmlns="http://openconfig.net/yang/wavelength-router"> + <optical-bands xmlns="http://flex-scale-project.eu/yang/flex-scale-mg-on" > + <optical-band > + <index>1</index> + <config> + <index>1</index> + <admin-status>DISABLED</admin-status> + </config> + + </optical-band> + </optical-bands> + </wavelength-router> +</config> +''' + + + + + + + device = { 'host': '10.0.2.4', # IP address or hostname of the remote machine - 'port': 2025, # SSH port (default: 22) + 'port': 2026, # SSH port (default: 22) 'username': 'admin', # SSH username 'password': 'admin', # SSH password 'device_params': {'name': 'default'}, @@ -66,36 +73,28 @@ device = { ,"look_for_keys":False } - -def extract_value (xml_data): +def extract_status (xml_data:str,index:int): xml_bytes = xml_data.encode("utf-8") root = ET.fromstring(xml_bytes) - namespace = {'oc': 'http://openconfig.net/yang/platform', - 'td': 'http://openconfig.net/yang/terminal-device'} - - element = root.find('.//oc:component[oc:name="channel-4"]', namespace) - if element is not None: - parameter= element.find('.//td:frequency',namespace) - if (parameter is not None): - print(parameter.text) - else : - print("parameter is None") - - else: - print(" element not found.") + namespaces = { "td": "http://openconfig.net/yang/terminal-device"} + channels = root.findall(f".//td:terminal-device/td:logical-channels/td:channel",namespaces) + for channel in channels : + + index_ele= channel.find(f".//td:config[td:index='{index}']/td:admin-state",namespaces) + if index_ele is not None : + + print(index_ele.text) + + + if __name__ == '__main__': - # with manager.connect(**device) as m: + with manager.connect(**device) as m: # # Perform operations on the remote machine using the 'm' object # # For example, you can retrieve the running configuration: - # #result =m.edit_config(target='running',config=edit_config) - # running_config = m.get_config('running').data_xml + #result =m.edit_config(target='running',config=edit_config_r_optical_band) + #print(result,file=open("context.log",'w')) + running_config = m.get_config('running').data_xml - # #extract_roadm_ports(running_config) - # x,y= [1,3] - # print (x) - nodes = { - "t13":{"name":"t1","value":1}, - "t2":{"name":"t2","value":2} - } - for n in nodes : - print (n) + # extract_status(running_config,index=1) + print(running_config,file=open("xml.log",'w')) + \ No newline at end of file