Commit 72bbd345 authored by Mohammad Ismaeel's avatar Mohammad Ismaeel
Browse files

Roadm endpoints auto discovery

parent 0c72ae9c
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -72,9 +72,9 @@ def set_opticalconfig(db_engine : Engine, request : OpticalConfig):
           {
                                    "opticalconfig_uuid": request.opticalconfig_id.opticalconfig_uuid,
                                    "transcievers"      : transceivers,
                                    "interfaces"        : json.dumps(config["interfaces"]["interface"]),
                                    "channel_namespace" : config["channel_namespace"],
                                    "endpoints"         : [json.dumps(endpoint) for endpoint in config["endpoints"]],}
                                    "interfaces"        :"",
                                    "channel_namespace" : config.get("channel_namespace",None),
                                    "endpoints"         : [json.dumps(endpoint) for endpoint in config.get("endpoints",[])],}
                                   
        )
            
+2 −2
Original line number Diff line number Diff line
@@ -38,9 +38,9 @@ class OpticalConfigModel(_Base):
        return {
            "channels"          : [channel.dump() for channel in self.channels],
            "transceivers"      : {"transceiver": [transciever for transciever in self.transcievers]},
            "interfaces"        : {"interface": json.loads(self.interfaces)},
            "interfaces"        : {"interface":json.loads(self.interfaces) if self.interfaces else ''},
            "channel_namespace" : self.channel_namespace,
            "endpoints"         : [json.loads(endpoint) for endpoint in self.endpoints],
            "endpoints"         : [json.loads(endpoint) for endpoint in self.endpoints if endpoint],
            
        }
        
+29 −19
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ from common.proto.context_pb2 import (
    OpticalConfig,
    ConfigActionEnum, Device, DeviceDriverEnum, DeviceId, DeviceList, DeviceOperationalStatusEnum, Empty
    ,OpticalConfigId,Uuid)
from .templates.Tools import extractor
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)
@@ -83,6 +83,7 @@ class NetconfSessionHandler:
        self.__manager_params   = settings.get('manager_params', {})
        self.__nc_params        = settings.get('nc_params', {})
        self.__message_renderer = settings.get('message_renderer','jinja')
      
        self.__manager : Manager   = None
        self.__candidate_supported = False
       
@@ -198,6 +199,7 @@ class OCDriver(_Driver):
        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.__initial = TreeNode('.')
        #self.__running = TreeNode('.')
        self.__subscriptions = TreeNode('.')
@@ -212,12 +214,11 @@ class OCDriver(_Driver):
        self._temp_address=f"{address}{port}"
        self.__out_samples = queue.Queue()
        self.__netconf_handler = NetconfSessionHandler(self.address, self.port, **(self.settings))
      
        self.__type = self.settings.get("type","optical-transponder")
        self.__device_uuid=device_uuid
      
        self.Connect()
        #self.GetConfig()
        #self.__samples_cache = SamplesCache(self.__netconf_handler, self.__logger)
        logging.info(f"settings {settings}")
        
    def Connect(self) -> bool:
        with self.__lock:
@@ -251,21 +252,35 @@ class OCDriver(_Driver):
        chk_type('resources', resource_keys, list)
        results = []
        opticalConfig= OpticalConfig()
        j=0
        
        
        with self.__lock:
           
     
            context_client.connect()
            config={}
            channels_lst=[]
            
            transceivers={}
            oc_values={}
            ports_result=[]
          
            try:
                xml_data = self.__netconf_handler.get().data_xml
                transceivers,interfaces,channels_lst,channel_namespace,endpoints,ports_result=extractor(data_xml=xml_data,resource_keys=filter_fields,dic=config)     
                
                logging.info(f"xml response {xml_data}")
                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}'
@@ -276,15 +291,10 @@ class OCDriver(_Driver):
          #///////////////////////// store optical configurtaion  ////////////////////////////////////////////////////////
            
            
            value_dic={}
            value_dic["channels"]=channels_lst
            value_dic["transceivers"]=transceivers  
            value_dic["interfaces"]=interfaces        
            value_dic["channel_namespace"]=channel_namespace
            value_dic["endpoints"]=endpoints
            value_dic["ports"]=ports_result
            logging.info(f"parameters {value_dic}")
            opticalConfig.config=json.dumps(value_dic)
          
           
            logging.info(f"parameters {oc_values}")
            opticalConfig.config=json.dumps(oc_values)
            opticalConfig.opticalconfig_id.opticalconfig_uuid=self.__device_uuid if self.__device_uuid is not None else ""
            config_id=context_client.SetOpticalConfig(opticalConfig)
           
+65 −19
Original line number Diff line number Diff line
@@ -238,40 +238,33 @@ def has_opticalbands(xml_data:str):
    return has_opticalbands
  
def extract_ports_based_on_type (xml_data:str):
    pattern = r'\bPORT\b'
    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:type',namespace)

    
    components = root.findall(".//oc:state[oc:type]",namespace)
    for component in components:
       
         
        if component is not None and re.search(pattern,component.text):
            
           
            name_element = component.getprevious()  
         type_ele = component.find(".//oc:type",namespace)
         match = re.search(pattern, type_ele.text)
         if match is not None :
            name_element= component.find(".//oc:name",namespace)
            port_name =name_element.text       
            port_index=name_element.text.split("-")[1]
            port = (port_name,port_index)
            ports.append(port)
    return ports  
    
def extractor(data_xml:str,resource_keys:list,dic:dict):
def transponder_values_extractor(data_xml:str,resource_keys:list,dic:dict):
   
    endpoints=[]
    is_opticalband=has_opticalbands(xml_data=data_xml)
   
    channel_namespace=extract_channel_xmlns(data_xml=data_xml,is_opticalband=is_opticalband)
    # channel_names=extract_channels_based_on_type(xml_data=data_xml) 
    # if len(channel_names)==0 :
    channel_names= extract_channels_based_on_channelnamespace(xml_data=data_xml,channel_namespace=channel_namespace,is_opticalband=is_opticalband)
    ports = extract_ports_based_on_type(data_xml)
   
    lst_dic=[]
    optical_channels_params=[]
    ports_result=[]
    if (is_opticalband):
        endpoints=channel_names
@@ -282,13 +275,15 @@ def extractor(data_xml:str,resource_keys:list,dic:dict):
            for resource_key in resource_keys  :
                
                if (resource_key != 'interface'):
                    dic=extract_value(dic=dic,resource_key=resource_key,xml_data=data_xml,channel_name=channel_name,channel_namespace=channel_namespace)  
                  
                    dic=extract_value(dic=dic,resource_key=resource_key,xml_data=data_xml
                                      ,channel_name=channel_name,channel_namespace=channel_namespace)  
                 
            dic["name"]=channel_name
            endpoints.append({"endpoint_uuid":{"uuid":channel_name}})
            lst_dic.append(dic)                
            optical_channels_params.append(dic)                
    transceivers_dic=extract_tranceiver(data_xml=data_xml,dic={})
    interfaces_dic=extract_interface(xml_data=data_xml,dic={})
    #interfaces_dic=extract_interface(xml_data=data_xml,dic={})
    if len(ports)>0 :
      for port in ports :
        endpoint_name,endpoint_id=port
@@ -297,4 +292,55 @@ def extractor(data_xml:str,resource_keys:list,dic:dict):
        ports_result.append((resource_key, resource_value))
      
   
    return [transceivers_dic,interfaces_dic,lst_dic,channel_namespace,endpoints,ports_result]
 No newline at end of file
    return [transceivers_dic,optical_channels_params,channel_namespace,endpoints,ports_result]
  
#########################################################################  
  
#################################### ROADMAs ############################
  
##########################################################################  

def extract_roadm_ports (xml_data:str):
  
    ports =[]
    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)
                    ports.append(name_element.text)
    return ports                



  
def roadm_values_extractor (data_xml:str,resource_keys:list,dic:dict):
     ports_result=[]
     ports = extract_roadm_ports(data_xml)
     
     if len(ports)>0 :
      for port in ports :
        
        resource_key = '/endpoints/endpoint[{:s}]'.format(port)
        resource_value = {'uuid': port, 'type':'MG_ON_OPTICAL_PORT_WAVEBAND'}
        ports_result.append((resource_key, resource_value))
      
     return [ports_result]   
 No newline at end of file