Commit b3e60dfc authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Pre-merge code cleanup

parent 5db023b9
Loading
Loading
Loading
Loading
+76 −103
Original line number Diff line number Diff line
@@ -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 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, 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)
@@ -63,6 +61,7 @@ RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION,
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()
@@ -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,8 +127,6 @@ 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(
@@ -139,12 +135,9 @@ class NetconfSessionHandler:

        str_respones = str(response)  
        if re.search(r'<ok/>', str_respones):
        
           return True
    
        return False


    @RETRY_DECORATOR
    def locked(self, target):
        return self.__manager.locked(target=target)
@@ -188,14 +181,9 @@ def edit_config(
        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)
@@ -207,15 +195,12 @@ def edit_config(

    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.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,26 +239,22 @@ 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:

                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)     
                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     
@@ -290,9 +264,6 @@ 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]

                    
                    
                else:
                    extracted_values = roadm_values_extractor(data_xml=xml_data, resource_keys=[], dic=config)
                    ports_result = extracted_values[0]
@@ -303,28 +274,23 @@ class OCDriver(_Driver):

            #///////////////////////// 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)    

        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 = []
        with self.__lock:
@@ -333,14 +299,18 @@ class OCDriver(_Driver):
                    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 []

@@ -349,7 +319,10 @@ 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,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
+0 −255
Original line number Diff line number Diff line
# 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
+29 −58

File changed.

Preview size limit exceeded, changes collapsed.

+31 −35

File changed.

Preview size limit exceeded, changes collapsed.

+1 −2
Original line number Diff line number Diff line
@@ -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">
Loading