From 5935a40dcdec7b472a5390f38b65b9a0695cb73a Mon Sep 17 00:00:00 2001 From: ismaeel <mohammad.ismaael@cnit.it> Date: Tue, 1 Oct 2024 04:16:29 +0000 Subject: [PATCH] Openroadm Model --- .context.log.swn | Bin 0 -> 24576 bytes my_deploy.sh | 2 +- src/context/service/database/OpticalConfig.py | 63 +++++- .../models/OpticalConfig/RoadmModel.py | 40 +++- .../service/database/uuids/OpticalConfig.py | 15 ++ .../service/drivers/oc_driver/OCDriver.py | 5 +- .../templates/descovery_tool/open_roadm.py | 199 ++++++++++++++++++ .../templates/descovery_tool/roadms.py | 119 +---------- src/webui/service/__init__.py | 6 +- src/webui/service/qkd_app/routes.py | 18 +- test.py | 74 ++++++- 11 files changed, 400 insertions(+), 141 deletions(-) create mode 100644 .context.log.swn create mode 100644 src/device/service/drivers/oc_driver/templates/descovery_tool/open_roadm.py diff --git a/.context.log.swn b/.context.log.swn new file mode 100644 index 0000000000000000000000000000000000000000..438f657217b971861a154b8bd3b81b1b02507337 GIT binary patch literal 24576 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 XYjumxt0qBAeTBHBINcn%(`)H}>|g?r literal 0 HcmV?d00001 diff --git a/my_deploy.sh b/my_deploy.sh index bb78bece5..68b6bb044 100755 --- a/my_deploy.sh +++ b/my_deploy.sh @@ -20,7 +20,7 @@ export TFS_REGISTRY_IMAGES="http://localhost:32000/tfs/" # Set the list of components, separated by spaces, you want to build images for, and deploy. -export TFS_COMPONENTS="context device pathcomp opticalcontroller service slice webui nbi " +export TFS_COMPONENTS="context device pathcomp opticalcontroller qkd_app service slice webui nbi " # Uncomment to activate Monitoring (old) #export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" diff --git a/src/context/service/database/OpticalConfig.py b/src/context/service/database/OpticalConfig.py index d502a0a43..b370375d3 100644 --- a/src/context/service/database/OpticalConfig.py +++ b/src/context/service/database/OpticalConfig.py @@ -22,9 +22,10 @@ from sqlalchemy_cockroachdb import run_transaction from common.proto.context_pb2 import OpticalConfig, OpticalConfigId , Empty , EventTypeEnum from .models.OpticalConfig.OpticalConfigModel import OpticalConfigModel from .models.OpticalConfig.TransponderModel import TransponderTypeModel ,OpticalChannelModel -from .models.OpticalConfig.RoadmModel import RoadmTypeModel, ChannelModel +from .models.OpticalConfig.RoadmModel import RoadmTypeModel, ChannelModel , ORInterfaceModel from context.service.database.uuids.OpticalConfig import ( - channel_get_uuid , opticalconfig_get_uuid ,transponder_get_uuid,roadm_get_uuid + channel_get_uuid , opticalconfig_get_uuid ,transponder_get_uuid,roadm_get_uuid, + interface_get_uuid ) from .Events import notify_event_opticalconfig @@ -55,6 +56,7 @@ def set_opticalconfig(db_engine : Engine, request : OpticalConfig): device_id = request.device_id device_uuid = request.device_id.device_uuid.uuid channels = [] + interfaces=[] transponder=[] roadms=[] @@ -165,7 +167,29 @@ def set_opticalconfig(db_engine : Engine, request : OpticalConfig): "roadm_uuid":roadm_get_uuid(device_id), "opticalconfig_uuid":opticalconfig_uuid, }) + if config_type == DeviceTypeEnum.OPEN_ROADM._value_: + if 'interfaces' in config : + for interface in config['interfaces']: + interfaces.append({ + "interface_uuid" :interface_get_uuid(interface['name']), + 'name' : interface["name"], + "type" : interface["type"], + "administrative_state": interface["administrative_state"], + "circuit_pack_name" : interface["circuit_pack_name"], + "port" : interface["port"], + "interface_list" : interface["interface_list"], + "frequency" : interface["frequency"], + "width" : interface["width"], + "roadm_uuid" : roadm_get_uuid(device_id), + + } + ) + roadms.append({ + "roadm_uuid":roadm_get_uuid(device_id), + "opticalconfig_uuid":opticalconfig_uuid, + }) + LOGGER.info(f"open_roadm") @@ -258,13 +282,46 @@ def set_opticalconfig(db_engine : Engine, request : OpticalConfig): src_port=stmt.excluded.src_port, channel_index=stmt.excluded.channel_index, optical_band_parent = stmt.excluded.optical_band_parent + ) ) stmt = stmt.returning(ChannelModel.channel_uuid) opticalChannel_id = session.execute(stmt).fetchone() - + + if config_type == DeviceTypeEnum.OPEN_ROADM._value_: + + if (len(roadms)>0): + stmt = insert(RoadmTypeModel).values(roadms) + + stmt = stmt.on_conflict_do_update( + index_elements=[RoadmTypeModel.roadm_uuid], + set_=dict( + interfaces=stmt.excluded.interfaces + ) + ) + stmt = stmt.returning(RoadmTypeModel.roadm_uuid) + roadm_id = session.execute(stmt).fetchone() + + if len(interface) >0 : + stmt = insert(ORInterfaceModel).values(interface) + stmt = stmt.on_conflict_do_update( + index_elements=[ORInterfaceModel.interface_uuid ], + set_=dict( + name= stmt.excluded.name , + frequency = stmt.excluded.frequency, + administrative_state = stmt.excluded.administrative_state, + type=stmt.excluded.type, + circuit_pack_name=stmt.excluded.circuit_pack_name, + port=stmt.excluded.port, + interface_list=stmt.excluded.interface_list, + width=stmt.excluded.width, + ) + + ) + stmt = stmt.returning(ORInterfaceModel.interface_uuid) + opticalChannel_id = session.execute(stmt).fetchone() opticalconfig_id = run_transaction(sessionmaker(bind=db_engine), callback) diff --git a/src/context/service/database/models/OpticalConfig/RoadmModel.py b/src/context/service/database/models/OpticalConfig/RoadmModel.py index 6a3add335..6d1ec19fa 100644 --- a/src/context/service/database/models/OpticalConfig/RoadmModel.py +++ b/src/context/service/database/models/OpticalConfig/RoadmModel.py @@ -28,7 +28,7 @@ class RoadmTypeModel (_Base): roadm_uuid = Column(String, primary_key=True) channels = relationship("ChannelModel") - circuits = Column (String,nullable=True) + interfaces = relationship ("ORInterfaceModel") opticalconfig_uuid = Column(ForeignKey('optical_config.opticalconfig_uuid', ondelete='CASCADE' ),index=True ,nullable=False) opticalconfig = relationship('OpticalConfigModel', back_populates='roadms') @@ -41,7 +41,8 @@ class RoadmTypeModel (_Base): def dump (self): return { "channels" : [channel.dump() for channel in self.channels], - "roadm_uuid" : self.dump_id() + "roadm_uuid" : self.dump_id(), + "interfaces" :[] } class ChannelModel(_Base): @@ -81,3 +82,38 @@ class ChannelModel(_Base): "channel_index":self.channel_index } +class ORInterfaceModel (_Base): + + __tablename__ = 'open_roadm_interface' + interface_uuid = Column(String, primary_key=True) + name = Column(String, nullable=False ,unique=True ) + type = Column(String , nullable=True) + administrative_state = Column(String,nullable=True) + circuit_pack_name = Column(String,nullable=True) + port = Column(String,nullable=True) + interface_list = Column(String ,nullable=True) + frequency = Column(Integer ,nullable=True) + width = Column(Integer ,nullable=True) + + roadm_uuid = Column(ForeignKey('roadm_type.roadm_uuid', ondelete='CASCADE' ),nullable=False) + roadm = relationship('RoadmTypeModel',back_populates='interfaces') + + + def dump_id (self ): + return { + "interface_uuid":self.interface_uuid + } + + def dump(self): + return { + "name" : self.name, + "type" : self.type, + "administrative_state" : self.administrative_state, + "circuit_pack_name" : self.circuit_pack_name, + "port" : self.port, + "interface_list" : self.interface_list, + + "frequency" : self.frequency, + "width" : self.width + + } \ No newline at end of file diff --git a/src/context/service/database/uuids/OpticalConfig.py b/src/context/service/database/uuids/OpticalConfig.py index 7bf75a9a2..398e8d731 100644 --- a/src/context/service/database/uuids/OpticalConfig.py +++ b/src/context/service/database/uuids/OpticalConfig.py @@ -17,6 +17,21 @@ def channel_get_uuid( ], extra_details=['Channel name is required to produce a channel UUID']) +def interface_get_uuid( + interface_name :str , allow_random : bool = False +) -> str: + + + if len(interface_name) > 0: + return get_uuid_from_string(interface_name) + if allow_random: return get_uuid_random() + + raise InvalidArgumentsException([ + ('interface uuid', interface_name), + + ], extra_details=['interface name is required to produce a interface UUID']) + + def transponder_get_uuid( opticalconfig_id :str , allow_random : bool = False diff --git a/src/device/service/drivers/oc_driver/OCDriver.py b/src/device/service/drivers/oc_driver/OCDriver.py index a94907928..8959178b8 100644 --- a/src/device/service/drivers/oc_driver/OCDriver.py +++ b/src/device/service/drivers/oc_driver/OCDriver.py @@ -39,7 +39,8 @@ from context.client.ContextClient import ContextClient from common.proto.context_pb2 import ( OpticalConfig) from .templates.descovery_tool.transponders import transponder_values_extractor -from .templates.descovery_tool.roadms import roadm_values_extractor ,openroadm_values_extractor,extract_media_channels +from .templates.descovery_tool.roadms import roadm_values_extractor ,extract_media_channels +from .templates.descovery_tool.open_roadm import openroadm_values_extractor 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) @@ -290,6 +291,8 @@ class OCDriver(_Driver): elif (self.__type =='openroadm') : extracted_values=openroadm_values_extractor(data_xml=xml_data,resource_keys=[],dic=oc_values) ports_result = extracted_values[1] + oc_values['interfaces']=extracted_values[0]['interfaces'] + diff --git a/src/device/service/drivers/oc_driver/templates/descovery_tool/open_roadm.py b/src/device/service/drivers/oc_driver/templates/descovery_tool/open_roadm.py new file mode 100644 index 000000000..337207072 --- /dev/null +++ b/src/device/service/drivers/oc_driver/templates/descovery_tool/open_roadm.py @@ -0,0 +1,199 @@ + +# 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 re,logging +import json +import lxml.etree as ET +from typing import Collection, Dict, Any + +def extract_roadm_circuits_pack (xml_data:str): + + + 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://org/openroadm/device"} + + circuits = root.findall('.//oc:circuit-packs',namespace) + + circuits_list =[] + # print(f"component {components}") + + if (circuits is not None): + for circuit in circuits: + circuit_info ={} + circuit_ports=[] + circuit_name = circuit.find(".//oc:circuit-pack-name",namespace) + circuit_type=circuit.find(".//oc:circuit-pack-type",namespace) + circuit_adminstrative_status=circuit.find(".//oc:administrative-state",namespace) + circuit_equipment_state=circuit.find("./oc:equipment-state",namespace) + circuit_mode=circuit.find("./oc:circuit-pack-mode",namespace) + slot= circuit.find("./oc:slot",namespace) + shelf= circuit.find("./oc:shelf",namespace) + ports = circuit.findall("./oc:ports",namespace) + + + if (ports is not None): + + for port in ports : + port_info={} + port_name=port.find('./oc:port-name',namespace) + port_qual= port.find("./oc:port-qual",namespace) + + if port_name is not None : + port_info["port_name"]=port_name.text + if port_qual is not None : + port_info["port_qual"]=port_qual.text + circuit_ports.append(port_info) + # if port_info["port_qual"] == 'roadm-external': + # circuit_ports.append(port_info) + if (circuit_name is not None): + circuit_info["circuit_name"]=circuit_name.text + if (circuit_type is not None): + circuit_info["circuit_type"]=circuit_type.text + if (circuit_adminstrative_status is not None): + circuit_info["circuit_adminstrative_status"]=circuit_adminstrative_status.text + if (circuit_equipment_state is not None): + circuit_info["circuit_equipment_state"]=circuit_equipment_state.text + if (circuit_mode is not None): + circuit_info["circuit_mode"]=circuit_mode.text + if (slot is not None): + circuit_info["slot"]=slot.text + if (shelf is not None): + circuit_info["shelf"]=shelf.text + logging.info(f"circuit_ports {circuit_ports}") + circuit_info["ports"]=circuit_ports + + circuits_list.append(circuit_info) + + + + return circuits_list + + + +def extract_openroadm_info(xml_data:str): + roadm_info={"node-id":None,"node-number":None,"node-type":None,'clli':None} + xml_bytes = xml_data.encode("utf-8") + root = ET.fromstring(xml_bytes) + namespace = {'oc': "http://org/openroadm/device"} + info = root.findall('.//oc:info',namespace) + if info is not None : + for i in info : + node_id= i.find('.//oc:node-id',namespace) + node_number= i.find('.//oc:node-number',namespace) + node_type=i.find('.//oc:node-type',namespace) + clli=i.find('.//oc:clli',namespace) + if (node_id is not None): + roadm_info['node-id']=node_id.text + if (node_number is not None): + roadm_info['node-number']=node_number.text + if (node_type is not None): + roadm_info['node-type']=node_type.text + if (clli is not None): + roadm_info['clli']=clli.text + + return roadm_info + + +def extract_openroadm_interface (xml_data:str): + or_interfaces=[] + + 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://org/openroadm/device" + , 'mc':"http://org/openroadm/media-channel-interfaces" + ,'nmc':"http://org/openroadm/network-media-channel-interfaces"} + + interfaces = root.findall('.//oc:interface',namespace) + for interface in interfaces : + mc = interface.find('.//mc:mc-ttp',namespace) + name = interface.find('.//oc:name',namespace) + description = interface.find('.//oc:description',namespace) + type='' + administrative_state=interface.find('.//oc:administrative-state',namespace) + circuit_pack_name=interface.find('.//oc:supporting-circuit-pack-name',namespace) + port=interface.find('.//oc:supporting-port',namespace) + interface_list =interface.find('.//oc:supporting-interface-list',namespace) + + + if mc is not None : + print (mc) + frequency = mc.find('.//mc:min-freq',namespace) + width=mc.find('.//mc:width',namespace) + mc= { + 'name':name.text if name is not None else None, + 'description':description.text if description is not None else None , + 'type':"media_channel", + 'administrative_state':administrative_state.text if administrative_state is not None else None, + 'circuit_pack_name':circuit_pack_name.text if circuit_pack_name is not None else None, + 'port':port.text if port is not None else None , + 'interface_list': interface_list.text if interface_list is not None else None, + 'frequency': frequency.text if frequency is not None else None, + 'width':width.text if width is not None else None + } + or_interfaces.append(mc) + + else : + nmc = interface.find('.//nmc:nmc-ctp',namespace) + if nmc is not None : + frequency = nmc.find('.//nmc:frequency',namespace) + width=nmc.find('.//nmc:width',namespace) + nmc= { + 'name':name.text if name is not None else None, + 'description':description.text if description is not None else None , + 'type':"network_media_channel", + 'administrative_state':administrative_state.text if administrative_state is not None else None, + 'circuit_pack_name':circuit_pack_name.text if circuit_pack_name is not None else None, + 'port':port.text if port is not None else None , + 'interface_list': interface_list.text if interface_list is not None else None, + 'frequency': frequency.text if frequency is not None else None, + 'width':width.text if width is not None else None + } + or_interfaces.append(nmc) + return or_interfaces + + +def openroadm_values_extractor (data_xml:str,resource_keys:list,dic:dict): + ports_result=[] + openroadm_info= extract_openroadm_info(data_xml) + circuits_list = extract_roadm_circuits_pack(data_xml) + interfaces = extract_openroadm_interface(data_xml) + dic["openroadm_info"]=openroadm_info + dic["circuits"]=circuits_list + dic['interfaces']=interfaces + + for circuit in circuits_list : + + for port in circuit['ports']: + if port is not None and 'port_name' in port : + resource_key = '/endpoints/endpoint[{:s}]'.format(port["port_name"]) + resource_value = {'uuid': port["port_name"], 'type':port["port_qual"] if "port_qual" in port else None} + ports_result.append((resource_key, resource_value)) + return [dic,ports_result] + + + + + + + \ No newline at end of file diff --git a/src/device/service/drivers/oc_driver/templates/descovery_tool/roadms.py b/src/device/service/drivers/oc_driver/templates/descovery_tool/roadms.py index a1ef517b6..3140d5aa1 100644 --- a/src/device/service/drivers/oc_driver/templates/descovery_tool/roadms.py +++ b/src/device/service/drivers/oc_driver/templates/descovery_tool/roadms.py @@ -208,121 +208,4 @@ def roadm_values_extractor (data_xml:str,resource_keys:list,dic:dict): return [ports_result,optical_bands,media_cahannels] - - #/////////////// OpenRoadm ////////////// - - -def extract_roadm_circuits_pack (xml_data:str): - - - 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://org/openroadm/device"} - - circuits = root.findall('.//oc:circuit-packs',namespace) - - circuits_list =[] - # print(f"component {components}") - - if (circuits is not None): - for circuit in circuits: - circuit_info ={} - circuit_ports=[] - circuit_name = circuit.find(".//oc:circuit-pack-name",namespace) - circuit_type=circuit.find(".//oc:circuit-pack-type",namespace) - circuit_adminstrative_status=circuit.find(".//oc:administrative-state",namespace) - circuit_equipment_state=circuit.find("./oc:equipment-state",namespace) - circuit_mode=circuit.find("./oc:circuit-pack-mode",namespace) - slot= circuit.find("./oc:slot",namespace) - shelf= circuit.find("./oc:shelf",namespace) - ports = circuit.findall("./oc:ports",namespace) - - - if (ports is not None): - - for port in ports : - port_info={} - port_name=port.find('./oc:port-name',namespace) - port_qual= port.find("./oc:port-qual",namespace) - - if port_name is not None : - port_info["port_name"]=port_name.text - if port_qual is not None : - port_info["port_qual"]=port_qual.text - circuit_ports.append(port_info) - # if port_info["port_qual"] == 'roadm-external': - # circuit_ports.append(port_info) - if (circuit_name is not None): - circuit_info["circuit_name"]=circuit_name.text - if (circuit_type is not None): - circuit_info["circuit_type"]=circuit_type.text - if (circuit_adminstrative_status is not None): - circuit_info["circuit_adminstrative_status"]=circuit_adminstrative_status.text - if (circuit_equipment_state is not None): - circuit_info["circuit_equipment_state"]=circuit_equipment_state.text - if (circuit_mode is not None): - circuit_info["circuit_mode"]=circuit_mode.text - if (slot is not None): - circuit_info["slot"]=slot.text - if (shelf is not None): - circuit_info["shelf"]=shelf.text - logging.info(f"circuit_ports {circuit_ports}") - circuit_info["ports"]=circuit_ports - - circuits_list.append(circuit_info) - - - - return circuits_list - - - -def extract_openroadm_info(xml_data:str): - roadm_info={"node-id":None,"node-number":None,"node-type":None,'clli':None} - xml_bytes = xml_data.encode("utf-8") - root = ET.fromstring(xml_bytes) - namespace = {'oc': "http://org/openroadm/device"} - info = root.findall('.//oc:info',namespace) - if info is not None : - for i in info : - node_id= i.find('.//oc:node-id',namespace) - node_number= i.find('.//oc:node-number',namespace) - node_type=i.find('.//oc:node-type',namespace) - clli=i.find('.//oc:clli',namespace) - if (node_id is not None): - roadm_info['node-id']=node_id.text - if (node_number is not None): - roadm_info['node-number']=node_number.text - if (node_type is not None): - roadm_info['node-type']=node_type.text - if (clli is not None): - roadm_info['clli']=clli.text - - return roadm_info - -def openroadm_values_extractor (data_xml:str,resource_keys:list,dic:dict): - ports_result=[] - openroadm_info= extract_openroadm_info(data_xml) - circuits_list = extract_roadm_circuits_pack(data_xml) - dic["openroadm_info"]=openroadm_info - dic["circuits"]=circuits_list - - for circuit in circuits_list : - - for port in circuit['ports']: - if port is not None and 'port_name' in port : - resource_key = '/endpoints/endpoint[{:s}]'.format(port["port_name"]) - resource_value = {'uuid': port["port_name"], 'type':port["port_qual"] if "port_qual" in port else None} - ports_result.append((resource_key, resource_value)) - return [dic,ports_result] - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/src/webui/service/__init__.py b/src/webui/service/__init__.py index 9c04ac749..6a08fbbbc 100644 --- a/src/webui/service/__init__.py +++ b/src/webui/service/__init__.py @@ -19,7 +19,7 @@ from flask_healthz import healthz, HealthError from common.tools.grpc.Tools import grpc_message_to_json from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient -#from qkd_app.client.QKDAppClient import QKDAppClient +from qkd_app.client.QKDAppClient import QKDAppClient def get_working_context() -> str: return session['context_uuid'] if 'context_uuid' in session else '---' @@ -116,8 +116,8 @@ def create_app(use_config=None, web_app_root=None): from webui.service.link.routes import link # pylint: disable=import-outside-toplevel app.register_blueprint(link) - # from webui.service.qkd_app.routes import qkd_app as _qkd_app # pylint: disable=import-outside-toplevel - # app.register_blueprint(_qkd_app) + from webui.service.qkd_app.routes import qkd_app as _qkd_app # pylint: disable=import-outside-toplevel + app.register_blueprint(_qkd_app) from webui.service.policy_rule.routes import policy_rule # pylint: disable=import-outside-toplevel app.register_blueprint(policy_rule) diff --git a/src/webui/service/qkd_app/routes.py b/src/webui/service/qkd_app/routes.py index 121c43f0a..39ddd9d41 100644 --- a/src/webui/service/qkd_app/routes.py +++ b/src/webui/service/qkd_app/routes.py @@ -12,16 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -# import grpc, json, logging +import grpc, json, logging -# from flask import current_app, render_template, Blueprint, flash, session, redirect, url_for -# from common.proto.context_pb2 import Empty, Link, LinkId, LinkList -# from common.proto.qkd_app_pb2 import App, QKDAppStatusEnum, QKDAppTypesEnum -# from common.tools.context_queries.Context import get_context -# from common.tools.context_queries.Device import get_device -# from common.tools.context_queries.Topology import get_topology -# from context.client.ContextClient import ContextClient -# from qkd_app.client.QKDAppClient import QKDAppClient +from flask import current_app, render_template, Blueprint, flash, session, redirect, url_for +from common.proto.context_pb2 import Empty, Link, LinkId, LinkList +from common.proto.qkd_app_pb2 import App, QKDAppStatusEnum, QKDAppTypesEnum +from common.tools.context_queries.Context import get_context +from common.tools.context_queries.Device import get_device +from common.tools.context_queries.Topology import get_topology +from context.client.ContextClient import ContextClient +from qkd_app.client.QKDAppClient import QKDAppClient LOGGER = logging.getLogger(__name__) diff --git a/test.py b/test.py index a96de8a65..4a5d82ee8 100644 --- a/test.py +++ b/test.py @@ -142,6 +142,71 @@ device = { } + +def extract_openroadm_interface (xml_data:str): + or_interfaces=[] + + 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://org/openroadm/device" + , 'mc':"http://org/openroadm/media-channel-interfaces" + ,'nmc':"http://org/openroadm/network-media-channel-interfaces"} + + interfaces = root.findall('.//oc:interface',namespace) + for interface in interfaces : + mc = interface.find('.//mc:mc-ttp',namespace) + name = interface.find('.//oc:name',namespace) + description = interface.find('.//oc:description',namespace) + type='' + administrative_state=interface.find('.//oc:administrative-state',namespace) + circuit_pack_name=interface.find('.//oc:supporting-circuit-pack-name',namespace) + port=interface.find('.//oc:supporting-port',namespace) + interface_list =interface.find('.//oc:supporting-interface-list',namespace) + + + if mc is not None : + print (mc) + frequency = mc.find('.//mc:min-freq',namespace) + width=mc.find('.//mc:width',namespace) + mc= { + 'name':name.text if name is not None else None, + 'description':description.text if description is not None else None , + 'type':"media_channel", + 'administrative_state':administrative_state.text if administrative_state is not None else None, + 'circuit_pack_name':circuit_pack_name.text if circuit_pack_name is not None else None, + 'port':port.text if port is not None else None , + 'interface_list': interface_list.text if interface_list is not None else None, + 'frequency': frequency.text if frequency is not None else None, + 'width':width.text if width is not None else None + } + or_interfaces.append(mc) + + else : + nmc = interface.find('.//nmc:nmc-ctp',namespace) + if nmc is not None : + frequency = nmc.find('.//nmc:frequency',namespace) + width=nmc.find('.//nmc:width',namespace) + nmc= { + 'name':name.text if name is not None else None, + 'description':description.text if description is not None else None , + 'type':"network_media_channel", + 'administrative_state':administrative_state.text if administrative_state is not None else None, + 'circuit_pack_name':circuit_pack_name.text if circuit_pack_name is not None else None, + 'port':port.text if port is not None else None , + 'interface_list': interface_list.text if interface_list is not None else None, + 'frequency': frequency.text if frequency is not None else None, + 'width':width.text if width is not None else None + } + or_interfaces.append(nmc) + return or_interfaces + + + + if __name__ == '__main__': @@ -152,9 +217,10 @@ if __name__ == '__main__': ,hostkey_verify=device['hostkey_verify'] ,allow_agent=device['allow_agent'] ,look_for_keys=device['look_for_keys']) as m : - edit_result = m.edit_config (target="running",config=create_connec ) + #edit_result = m.edit_config (target="running",config=create_nmc ) result = m.get_config (source="running").data_xml - #ports = extract_roadm_ports(result) + interfaces=extract_roadm_interface(result) + print(interfaces) # optical_band_namespaces="http://flex-scale-project.eu/yang/flex-scale-mg-on" #namespaces={"oc":"http://openconfig.net/yang/wavelength-router"} #obj=extract_media_channels(result,namespaces) @@ -167,8 +233,8 @@ if __name__ == '__main__': #print(f"optical_bands {obj1}") #print(f"circuits {circuits}") - with open("xml.log","w") as f: - print (result,file=f) + # with open("xml.log","w") as f: + # print (result,file=f) -- GitLab