diff --git a/src/device/service/drivers/oc_driver/OCDriver.py b/src/device/service/drivers/oc_driver/OCDriver.py index 31c2b533fe57fbc9d97ebfddb08413a106f17c34..6351f26e57d00e98ac5a011c5f22b5abf7066395 100644 --- a/src/device/service/drivers/oc_driver/OCDriver.py +++ b/src/device/service/drivers/oc_driver/OCDriver.py @@ -15,10 +15,8 @@ import json import logging, pytz, queue, re, threading #import lxml.etree as ET - from typing import Any, List, Tuple, Union from apscheduler.executors.pool import ThreadPoolExecutor - from apscheduler.jobstores.memory import MemoryJobStore from apscheduler.schedulers.background import BackgroundScheduler from ncclient.manager import Manager, connect_ssh @@ -30,16 +28,16 @@ from device.service.driver_api._Driver import _Driver 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.VPN.roadms import (create_media_channel,create_optical_band, disable_media_channel - , delete_optical_band,create_media_channel_v2) -from .templates.VPN.transponder import (edit_optical_channel ,change_optical_channel_status) +from .templates.VPN.roadms import ( + create_optical_band, disable_media_channel, delete_optical_band, create_media_channel_v2 +) +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) -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 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 + 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,13 +54,14 @@ 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' -transponder_filter_fields= ["frequency","target-output-power","operational-mode","line-port","admin-state"] +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') context_client= ContextClient() port_xml_filter=f"/components/component[state[type='oc-platform-types:PORT']]/*" transceiver_xml_filter="/components/component[state[type='oc-platform-types:TRANSCEIVER']]/*" + class NetconfSessionHandler: def __init__(self, address : str, port : int, **settings) -> None: self.__lock = threading.RLock() @@ -110,10 +109,10 @@ class NetconfSessionHandler: @property def vendor(self): return self.__vendor - + @property def version(self): return self.__version - + @property def message_renderer(self): return self.__message_renderer @@ -121,7 +120,6 @@ class NetconfSessionHandler: def get(self, filter=None, with_defaults=None): # pylint: disable=redefined-builtin with self.__lock: config=self.__manager.get(filter=filter, with_defaults=with_defaults) - return config @RETRY_DECORATOR @@ -129,21 +127,16 @@ class NetconfSessionHandler: self, config, target='running', default_operation=None, test_option=None, error_option=None, format='xml' # pylint: disable=redefined-builtin ): - - response = None with self.__lock: response= self.__manager.edit_config( config, target=target, default_operation=default_operation, test_option=test_option, error_option=error_option, format=format) - + str_respones = str(response) if re.search(r'<ok/>', str_respones): - return True - - return False - + return False @RETRY_DECORATOR def locked(self, target): @@ -152,7 +145,7 @@ class NetconfSessionHandler: @RETRY_DECORATOR def commit(self, confirmed=False, timeout=None, persist=None, persist_id=None): return self.__manager.commit(confirmed=confirmed, timeout=timeout, persist=persist, persist_id=persist_id) - + DRIVER_NAME = 'oc' METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME}) def edit_config( # edit the configuration of openconfig devices @@ -175,8 +168,8 @@ def edit_config( else : #roadm media-channel str_config_messages=create_media_channel_v2(resources) - #Disabling of the Configuration - else : + #Disabling of the Configuration + else: # Device type is Transponder if (conditions['edit_type'] == "optical-channel"): _,ports,_=seperate_port_config(resources) @@ -187,35 +180,27 @@ def edit_config( str_config_messages=delete_optical_band(resources) else : str_config_messages=disable_media_channel(resources) - - - - for str_config_message in str_config_messages: - # configuration of the received templates - if str_config_message is None: raise UnsupportedResourceKeyException("CONFIG") - - result= netconf_handler.edit_config( # configure the device - config=str_config_message, target=target, default_operation=default_operation, - test_option=test_option, error_option=error_option, format=format) - if commit_per_rule: - netconf_handler.commit() # configuration commit - + # configuration of the received templates + if str_config_message is None: raise UnsupportedResourceKeyException("CONFIG") + result= netconf_handler.edit_config( # configure the device + config=str_config_message, target=target, default_operation=default_operation, + test_option=test_option, error_option=error_option, format=format) + if commit_per_rule: + netconf_handler.commit() # configuration commit + #results[i] = True results.append(result) - + return results - class OCDriver(_Driver): def __init__(self, address : str, port : int,device_uuid=None, **settings) -> None: super().__init__(DRIVER_NAME, address, port, **settings) self.__logger = logging.getLogger('{:s}:[{:s}:{:s}]'.format(str(__name__), str(self.address), str(self.port))) self.__lock = threading.Lock() - - - self.__subscriptions = TreeNode('.') + self.__started = threading.Event() self.__terminate = threading.Event() self.__scheduler = BackgroundScheduler(daemon=True) @@ -225,31 +210,24 @@ class OCDriver(_Driver): job_defaults = {'coalesce': False, 'max_instances': 3}, timezone=pytz.utc) self._temp_address=f"{address}{port}" - self.__out_samples = queue.Queue() self.__netconf_handler = NetconfSessionHandler(self.address, self.port, **(self.settings)) self.__type = self.settings.get("type","optical-transponder") - self.__device_uuid=device_uuid - self.__pending_tasks=[] + self.__device_uuid = device_uuid self.Connect() - def Connect(self) -> bool: with self.__lock: if self.__started.is_set(): return True self.__netconf_handler.connect() - self.__scheduler.start() self.__started.set() return True def Disconnect(self) -> bool: with self.__lock: - self.__terminate.set() - if not self.__started.is_set(): return True - self.__scheduler.shutdown() self.__netconf_handler.disconnect() return True @@ -261,95 +239,90 @@ class OCDriver(_Driver): @metered_subclass_method(METRICS_POOL) def GetConfig(self, resource_keys : List[str] = []) -> List[Tuple[str, Union[Any, None, Exception]]]: - - chk_type('resources', resource_keys, list) results = [] opticalConfig= OpticalConfig() - - with self.__lock: - - config={} - transceivers={} - oc_values={} - ports_result=[] - oc_values["type"]=self.__type - try: + with self.__lock: + config = {} + transceivers = {} + oc_values = {} + ports_result = [] + oc_values["type"] = self.__type + 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=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 - elif (self.__type =='openroadm') : - extracted_values=openroadm_values_extractor(data_xml=xml_data,resource_keys=[],dic=oc_values) + 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 + elif (self.__type =='openroadm'): + extracted_values=openroadm_values_extractor(data_xml=xml_data, resource_keys=[], dic=oc_values) ports_result = extracted_values[1] - - - - else : - extracted_values=roadm_values_extractor(data_xml=xml_data,resource_keys=[],dic=config) + else: + extracted_values = roadm_values_extractor(data_xml=xml_data, resource_keys=[], dic=config) ports_result = extracted_values[0] oc_values['optical_bands']=extracted_values[1] oc_values['media_channels']=extracted_values[2] - #results.append((resource_key, e)) # if validation fails, store the exception - + #results.append((resource_key, e)) # if validation fails, store the exception + #///////////////////////// store optical configurtaion //////////////////////////////////////////////////////// - - + opticalConfig.config=json.dumps(oc_values) if self.__device_uuid is not None: - opticalConfig.device_id.device_uuid.uuid=self.__device_uuid results.append((f"/opticalconfigs/opticalconfig/{self.__device_uuid}",{"opticalconfig":opticalConfig})) # 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) + 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) return results @metered_subclass_method(METRICS_POOL) def SetConfig(self, resources : List[Tuple[str, Any]],conditions:dict) -> List[Union[bool, Exception]]: - if len(resources) == 0: return [] - results=[] + results = [] with self.__lock: - if self.__netconf_handler.use_candidate: - with self.__netconf_handler.locked(target='candidate'): - results = edit_config( - self.__netconf_handler, self.__logger, resources,conditions, target='candidate', - commit_per_rule=self.__netconf_handler.commit_per_rule - ,) + if self.__netconf_handler.use_candidate: + with self.__netconf_handler.locked(target='candidate'): + results = edit_config( + self.__netconf_handler, self.__logger, resources, conditions, target='candidate', + commit_per_rule=self.__netconf_handler.commit_per_rule + ) else: - results = edit_config(self.__netconf_handler, self.__logger, resources,conditions=conditions - ) + results = edit_config( + self.__netconf_handler, self.__logger, resources, conditions=conditions + ) return results @metered_subclass_method(METRICS_POOL) - def DeleteConfig(self, resources : List[Tuple[str, Any]],conditions:dict,optical_device_configuration=None) -> List[Union[bool, Exception]]: + def DeleteConfig( + self, resources : List[Tuple[str, Any]], conditions : dict, + optical_device_configuration = None + ) -> List[Union[bool, Exception]]: chk_type('resources', resources, list) if len(resources) == 0: return [] - + with self.__lock: if self.__netconf_handler.use_candidate: 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,conditions=conditions) + commit_per_rule=self.__netconf_handler.commit_per_rule, conditions=conditions + ) else: - results = edit_config(self.__netconf_handler, self.__logger, resources, delete=True,conditions=conditions) + results = edit_config( + self.__netconf_handler, self.__logger, resources, delete=True, conditions=conditions + ) return results diff --git a/src/service/service/service_handlers/oc/ConfigRules.py b/src/service/service/service_handlers/oc/ConfigRules.py deleted file mode 100644 index 44245705ecdb48d33c9152328a352d736cc3dd27..0000000000000000000000000000000000000000 --- a/src/service/service/service_handlers/oc/ConfigRules.py +++ /dev/null @@ -1,255 +0,0 @@ -# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import Dict, List -from common.tools.object_factory.ConfigRule import json_config_rule_delete, json_config_rule_set -from service.service.service_handler_api.AnyTreeTools import TreeNode - -def setup_config_rules( - service_uuid : str, connection_uuid : str, device_uuid : str, endpoint_uuid : str, endpoint_name : str, - service_settings : TreeNode, endpoint_settings : TreeNode -) -> List[Dict]: - - if service_settings is None: return [] - if endpoint_settings is None: return [] - - json_settings : Dict = service_settings.value - json_endpoint_settings : Dict = endpoint_settings.value - - service_short_uuid = service_uuid.split('-')[-1] - network_instance_name = '{:s}-NetInst'.format(service_short_uuid) - network_interface_desc = '{:s}-NetIf'.format(service_uuid) - network_subinterface_desc = '{:s}-NetSubIf'.format(service_uuid) - - mtu = json_settings.get('mtu', 1450 ) # 1512 - #address_families = json_settings.get('address_families', [] ) # ['IPV4'] - bgp_as = json_settings.get('bgp_as', 0 ) # 65000 - bgp_route_target = json_settings.get('bgp_route_target', '0:0') # 65000:333 - - #router_id = json_endpoint_settings.get('router_id', '0.0.0.0') # '10.95.0.10' - route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0' ) # '60001:801' - sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0 ) # 1 - vlan_id = json_endpoint_settings.get('vlan_id', 1 ) # 400 - address_ip = json_endpoint_settings.get('address_ip', '0.0.0.0') # '2.2.2.1' - address_prefix = json_endpoint_settings.get('address_prefix', 24 ) # 30 - if_subif_name = '{:s}.{:d}'.format(endpoint_name, vlan_id) - - json_config_rules = [ - json_config_rule_set( - '/network_instance[{:s}]'.format(network_instance_name), { - 'name': network_instance_name, 'description': network_interface_desc, 'type': 'L3VRF', - 'route_distinguisher': route_distinguisher, - #'router_id': router_id, 'address_families': address_families, - }), - json_config_rule_set( - '/interface[{:s}]'.format(endpoint_name), { - 'name': endpoint_name, 'description': network_interface_desc, 'mtu': mtu, - }), - json_config_rule_set( - '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_name, sub_interface_index), { - 'name': endpoint_name, 'index': sub_interface_index, - 'description': network_subinterface_desc, 'vlan_id': vlan_id, - 'address_ip': address_ip, 'address_prefix': address_prefix, - }), - json_config_rule_set( - '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), { - 'name': network_instance_name, 'id': if_subif_name, 'interface': endpoint_name, - 'subinterface': sub_interface_index, - }), - json_config_rule_set( - '/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), { - 'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP', 'as': bgp_as, - }), - json_config_rule_set( - '/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), { - 'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP', - 'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE', - }), - json_config_rule_set( - '/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format( - network_instance_name), { - 'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP', - 'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE', - }), - json_config_rule_set( - '/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), { - 'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name), - }), - json_config_rule_set( - '/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format( - network_instance_name, bgp_route_target), { - 'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name), - 'ext_community_member' : 'route-target:{:s}'.format(bgp_route_target), - }), - json_config_rule_set( - '/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), { - 'policy_name': '{:s}_import'.format(network_instance_name), - }), - json_config_rule_set( - '/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format( - network_instance_name, '3'), { - 'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3', - 'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name), - 'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE', - }), - json_config_rule_set( - # pylint: disable=duplicate-string-formatting-argument - '/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format( - network_instance_name, network_instance_name), { - 'name': network_instance_name, 'import_policy': '{:s}_import'.format(network_instance_name), - }), - json_config_rule_set( - '/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), { - 'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name), - }), - json_config_rule_set( - '/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format( - network_instance_name, bgp_route_target), { - 'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name), - 'ext_community_member' : 'route-target:{:s}'.format(bgp_route_target), - }), - json_config_rule_set( - '/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), { - 'policy_name': '{:s}_export'.format(network_instance_name), - }), - json_config_rule_set( - '/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format( - network_instance_name, '3'), { - 'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3', - 'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name), - 'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE', - }), - json_config_rule_set( - # pylint: disable=duplicate-string-formatting-argument - '/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format( - network_instance_name, network_instance_name), { - 'name': network_instance_name, 'export_policy': '{:s}_export'.format(network_instance_name), - }), - ] - - return json_config_rules - -def teardown_config_rules( - service_uuid : str, connection_uuid : str, device_uuid : str, endpoint_uuid : str, endpoint_name : str, - service_settings : TreeNode, endpoint_settings : TreeNode -) -> List[Dict]: - - if service_settings is None: return [] - if endpoint_settings is None: return [] - - json_settings : Dict = service_settings.value - json_endpoint_settings : Dict = endpoint_settings.value - - #mtu = json_settings.get('mtu', 1450 ) # 1512 - #address_families = json_settings.get('address_families', [] ) # ['IPV4'] - #bgp_as = json_settings.get('bgp_as', 0 ) # 65000 - bgp_route_target = json_settings.get('bgp_route_target', '0:0') # 65000:333 - - #router_id = json_endpoint_settings.get('router_id', '0.0.0.0') # '10.95.0.10' - #route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0' ) # '60001:801' - sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0 ) # 1 - vlan_id = json_endpoint_settings.get('vlan_id', 1 ) # 400 - #address_ip = json_endpoint_settings.get('address_ip', '0.0.0.0') # '2.2.2.1' - #address_prefix = json_endpoint_settings.get('address_prefix', 24 ) # 30 - - if_subif_name = '{:s}.{:d}'.format(endpoint_name, vlan_id) - service_short_uuid = service_uuid.split('-')[-1] - network_instance_name = '{:s}-NetInst'.format(service_short_uuid) - #network_interface_desc = '{:s}-NetIf'.format(service_uuid) - #network_subinterface_desc = '{:s}-NetSubIf'.format(service_uuid) - - json_config_rules = [ - json_config_rule_delete( - '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), { - 'name': network_instance_name, 'id': if_subif_name, - }), - json_config_rule_delete( - '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_name, sub_interface_index), { - 'name': endpoint_name, 'index': sub_interface_index, - }), - json_config_rule_delete( - '/interface[{:s}]'.format(endpoint_name), { - 'name': endpoint_name, - }), - json_config_rule_delete( - '/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format( - network_instance_name), { - 'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP', - 'address_family': 'IPV4', - }), - json_config_rule_delete( - '/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), { - 'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP', - 'address_family': 'IPV4', - }), - json_config_rule_delete( - '/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), { - 'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP', - }), - json_config_rule_delete( - # pylint: disable=duplicate-string-formatting-argument - '/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format( - network_instance_name, network_instance_name), { - 'name': network_instance_name, - }), - json_config_rule_delete( - '/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format( - network_instance_name, '3'), { - 'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3', - }), - json_config_rule_delete( - '/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), { - 'policy_name': '{:s}_import'.format(network_instance_name), - }), - json_config_rule_delete( - '/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format( - network_instance_name, bgp_route_target), { - 'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name), - 'ext_community_member' : 'route-target:{:s}'.format(bgp_route_target), - }), - json_config_rule_delete( - '/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), { - 'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name), - }), - json_config_rule_delete( - # pylint: disable=duplicate-string-formatting-argument - '/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format( - network_instance_name, network_instance_name), { - 'name': network_instance_name, - }), - json_config_rule_delete( - '/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format( - network_instance_name, '3'), { - 'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3', - }), - json_config_rule_delete( - '/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), { - 'policy_name': '{:s}_export'.format(network_instance_name), - }), - json_config_rule_delete( - '/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format( - network_instance_name, bgp_route_target), { - 'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name), - 'ext_community_member' : 'route-target:{:s}'.format(bgp_route_target), - }), - json_config_rule_delete( - '/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), { - 'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name), - }), - json_config_rule_delete( - '/network_instance[{:s}]'.format(network_instance_name), { - 'name': network_instance_name - }), - ] - return json_config_rules diff --git a/src/service/service/service_handlers/oc/OCServiceHandler.py b/src/service/service/service_handlers/oc/OCServiceHandler.py index 1d15c5df257f17662cb8a90718c042acb3614f03..277080d6589d08e9765b16962b2cc5737c2c50af 100644 --- a/src/service/service/service_handlers/oc/OCServiceHandler.py +++ b/src/service/service/service_handlers/oc/OCServiceHandler.py @@ -13,19 +13,20 @@ # limitations under the License. import json, logging -from anytree import RenderTree 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 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.Tools import get_endpoint_matching from service.service.service_handler_api._ServiceHandler import _ServiceHandler from service.service.service_handler_api.SettingsHandler import SettingsHandler from service.service.task_scheduler.TaskExecutor import TaskExecutor -from .ConfigRules import setup_config_rules, teardown_config_rules -from .OCTools import convert_endpoints_to_flows, endpoints_to_flows, handle_flows_names , check_media_channel_existance +from .OCTools import ( + convert_endpoints_to_flows, endpoints_to_flows, + #handle_flows_names, check_media_channel_existance +) LOGGER = logging.getLogger(__name__) @@ -51,11 +52,9 @@ class OCServiceHandler(_ServiceHandler): settings=None 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') bidir = settings.value.get("bidir") @@ -64,62 +63,44 @@ class OCServiceHandler(_ServiceHandler): #flow is the new variable that stores input-output relationship #flows = convert_endpoints_to_flows(endpoints) - flows = endpoints_to_flows(endpoints, bidir, is_opticalband) - #handled_flows=handle_flows_names(flows=flows,task_executor=self.__task_executor) - - results = [] - #new cycle for setting optical devices - for device_uuid in flows.keys(): + #new cycle for setting optical devices + for device_uuid, dev_flows in flows.items(): try: - dev_flows = flows[device_uuid] device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) - - - if (settings): - + if settings: self.__task_executor.configure_optical_device(device_obj, settings, dev_flows, is_opticalband) results.append(True) except Exception as e: # pylint: disable=broad-except LOGGER.exception('Unable to configure Device({:s})'.format(str(device_uuid))) results.append(e) - + return results @metered_subclass_method(METRICS_POOL) 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) - - chk_type('endpoints', endpoints, list) if len(endpoints) == 0: return [] - 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') - - - dev_flows=[] results = [] - for device_uuid in flows.keys(): + for device_uuid, dev_flows in flows.items(): try: channel_indexes= [] - dev_flows = flows[device_uuid] - - device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) if (device_obj.device_type == DeviceTypeEnum.OPTICAL_TRANSPONDER._value_): @@ -134,21 +115,19 @@ class OCServiceHandler(_ServiceHandler): 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"]) - elif is_opticalband: - if "ob_id" in settings.value: - channel_indexes.append(settings.value["ob_id"]) - - if len(channel_indexes)>0: - errors=self.__task_executor.deconfigure_optical_device(device=device_obj - ,channel_indexes=channel_indexes - ,is_opticalband=is_opticalband - - ,dev_flow=dev_flows) + else: + if not is_opticalband: + if 'flow_id' in settings.value: + channel_indexes.append(settings.value["flow_id"]) + elif is_opticalband: + if "ob_id" in settings.value: + channel_indexes.append(settings.value["ob_id"]) + + if len(channel_indexes) > 0: + errors = self.__task_executor.deconfigure_optical_device( + device=device_obj, channel_indexes=channel_indexes, + is_opticalband=is_opticalband, dev_flow=dev_flows + ) # if (len(errors)==0): # service_id =self.__service.service_id # if not is_opticalband : @@ -199,29 +178,21 @@ class OCServiceHandler(_ServiceHandler): def DeleteConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: chk_type('resources', resources, list) if len(resources) == 0: return [] - service_id =self.__service.service_id + service_id = self.__service.service_id + results = [] for resource in resources: try: self.__settings_handler.delete(resource[0]) - # self.__task_executor.delete_setting(service_id,"/settings","value") except Exception as e: # pylint: disable=broad-except LOGGER.exception('Unable to DeleteConfig({:s})'.format(str(resource))) results.append(e) return results - - + def check_media_channel(self,connection_uuid): - if self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid)): - - return False + return False else: - - return True - - - - \ No newline at end of file + return True diff --git a/src/service/service/service_handlers/oc/OCTools.py b/src/service/service/service_handlers/oc/OCTools.py index 6853458c90591ce742a53c71f85a9780b49f2af4..e9097c7e7136303586edc1d7c1dc56d89ad0b3dc 100644 --- a/src/service/service/service_handlers/oc/OCTools.py +++ b/src/service/service/service_handlers/oc/OCTools.py @@ -12,11 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -from service.service.service_handler_api.Tools import get_device_endpoint_uuids, get_endpoint_matching -from typing import Dict, Any, List, Optional, Tuple -import logging , json -from common.proto.context_pb2 import ConfigRule, DeviceId, Service +import logging, json +from typing import Dict, List, Optional, Tuple +from common.proto.context_pb2 import DeviceId, Service from common.tools.object_factory.Device import json_device_id +from service.service.service_handler_api.Tools import get_endpoint_matching log = logging.getLogger(__name__) @@ -286,7 +286,6 @@ def conn_flows(endpoints : List[Tuple[str, str, Optional[str]]], bidir : int): entries[device_uuid].append(entry_tuple) i = i + 2 else: - return {} #rx tp endpoint = endpoints[i] @@ -296,51 +295,48 @@ def conn_flows(endpoints : List[Tuple[str, str, Optional[str]]], bidir : int): entry_tuple = endpoint_uuid, "0", entries[device_uuid].append(entry_tuple) return entries - def endpoints_to_flows(endpoints : List[Tuple[str, str, Optional[str]]], bidir : int, is_ob: bool)->Dict: - if is_ob: entries = ob_flows(endpoints, bidir) else: entries = conn_flows(endpoints, bidir) return entries - -def get_device_endpint_name (endpoint_uuid:str,device_uuid:str,task_executor)->Tuple: +def get_device_endpint_name(endpoint_uuid : str, device_uuid : str, task_executor) -> Tuple: device_obj = task_executor.get_device(DeviceId(**json_device_id(device_uuid))) endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid) endpoint_name = endpoint_obj.name return (device_obj.name, endpoint_name) -def handle_flows_names (task_executor,flows:dict)->Dict : - new_flows={} - for index,( device_uuid_key , device_endpoints_list) in enumerate(flows.items()): +def handle_flows_names(task_executor, flows : dict) -> Dict: + new_flows = {} + for index, (device_uuid_key, device_endpoints_list) in enumerate(flows.items()): for endpoint_tupple in device_endpoints_list: - source_port=None - destination_port=None - device_name="" - source_endpoint,destination_endpoint =endpoint_tupple - if (source_endpoint !='0'): - if get_device_endpint_name(source_endpoint,device_uuid_key,task_executor) is not None: - device_name,source_port=get_device_endpint_name(source_endpoint,device_uuid_key,task_executor) - if (destination_endpoint !='0'): - if get_device_endpint_name(destination_endpoint,device_uuid_key,task_executor) is not None: - device_name,destination_port=get_device_endpint_name(destination_endpoint,device_uuid_key,task_executor) - if (device_name not in new_flows): - new_flows[device_name]=[] - new_flows[device_name].append((source_port,destination_port)) + source_port = None + destination_port = None + device_name = "" + source_endpoint, destination_endpoint = endpoint_tupple + if source_endpoint != '0': + if get_device_endpint_name(source_endpoint, device_uuid_key, task_executor) is not None: + device_name, source_port = get_device_endpint_name( + source_endpoint, device_uuid_key, task_executor + ) + if destination_endpoint != '0': + if get_device_endpint_name(destination_endpoint, device_uuid_key, task_executor) is not None: + device_name, destination_port = get_device_endpint_name( + destination_endpoint, device_uuid_key, task_executor + ) + if device_name not in new_flows: + new_flows[device_name] = [] + new_flows[device_name].append((source_port, destination_port)) return new_flows - -def check_media_channel_existance (service:Service): - has_media_channel=False +def check_media_channel_existance(service : Service): + has_media_channel = False for config_rule in service.service_config.config_rules: - - if isinstance(config_rule.custom.resource_value,str): - settings=json.dumps(config_rule.custom.resource_value) - if "flow_id" in settings : - has_media_channel=True - + if isinstance(config_rule.custom.resource_value, str): + settings = json.dumps(config_rule.custom.resource_value) + if "flow_id" in settings: + has_media_channel = True return has_media_channel - \ No newline at end of file diff --git a/src/webui/service/templates/link/detail.html b/src/webui/service/templates/link/detail.html index 77936f0c759cf1bbb3707b21ee492b164c5896ef..fe0ecfc77c3e8b0bb4872f9a60e488c6c5fd71cd 100644 --- a/src/webui/service/templates/link/detail.html +++ b/src/webui/service/templates/link/detail.html @@ -20,7 +20,7 @@ <h1>Link {{ link.name }} ({{ link.link_id.link_uuid.uuid }})</h1> <div class="row mb-3"> <div class="col-sm-3"> - <button type="button" class="btn btn-success" onclick="window.location.href='{{ url_for('optical_link.home') }}'"> + <button type="button" class="btn btn-success" onclick="window.location.href='{{ url_for('link.home') }}'"> <i class="bi bi-box-arrow-in-left"></i> Back to link list </button> @@ -102,7 +102,6 @@ </table> - <!-- Modal --> <div class="modal fade" id="deleteModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true"> diff --git a/src/webui/service/templates/link/home.html b/src/webui/service/templates/link/home.html index d504a43568880be39079586cbb4a86518b222b76..a020871db3a06a658404b74c056091cce47ec0eb 100644 --- a/src/webui/service/templates/link/home.html +++ b/src/webui/service/templates/link/home.html @@ -78,7 +78,7 @@ </td> <td> - <a href="{{ url_for('optical_link.detail', link_uuid=link.link_id.link_uuid.uuid) }}"> + <a href="{{ url_for('link.detail', link_uuid=link.link_id.link_uuid.uuid) }}"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16"> <path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/> <path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>