X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=RO-SDN-arista%2Fosm_rosdn_arista%2Fwimconn_arista.py;h=cde8e211c923af9594cac9bcac6b45a0c81c7819;hb=refs%2Fchanges%2F32%2F8732%2F3;hp=b0e5b13729e1aed3407063d527e8091ea6bc2f9a;hpb=9c701472268e45cce315060d4c5fb2f165feb7cf;p=osm%2FRO.git diff --git a/RO-SDN-arista/osm_rosdn_arista/wimconn_arista.py b/RO-SDN-arista/osm_rosdn_arista/wimconn_arista.py index b0e5b137..cde8e211 100644 --- a/RO-SDN-arista/osm_rosdn_arista/wimconn_arista.py +++ b/RO-SDN-arista/osm_rosdn_arista/wimconn_arista.py @@ -38,6 +38,7 @@ import difflib import logging import uuid from enum import Enum +from requests import RequestException from cvprac.cvp_client import CvpClient from cvprac.cvp_client_errors import CvpLoginError, CvpSessionLogOutError, CvpApiError @@ -117,11 +118,12 @@ class AristaSdnConnector(SdnConnectorBase): __VLAN_PARAM = "vlan" __VNI_PARAM = "vni" __SEPARATOR = '_' + __MANAGED_BY_OSM = '## Managed by OSM ' __OSM_PREFIX = "osm_" __OSM_METADATA = "OSM_metadata" __METADATA_PREFIX = '!## Service' - __EXC_TASK_EXEC_WAIT = 1 - __ROLLB_TASK_EXEC_WAIT = 5 + __EXC_TASK_EXEC_WAIT = 10 + __ROLLB_TASK_EXEC_WAIT = 10 def __init__(self, wim, wim_account, config=None, logger=None): """ @@ -405,7 +407,12 @@ class AristaSdnConnector(SdnConnectorBase): for s in self.s_api: if (len(cls_perSw[s]) > 0): for cl in cls_perSw[s]: - if len(cls_perSw[s][0]['config']) == 0: + # Fix 1030 SDN-ARISTA Key error note when deploy a NS + # Added protection to check that 'note' exists and additionally + # verify that it is managed by OSM + if (not cls_perSw[s][0]['config'] or + not cl.get('note') or + self.__MANAGED_BY_OSM not in cl['note']): continue note = cl['note'] t_id = note.split(self.__SEPARATOR)[1] @@ -497,6 +504,8 @@ class AristaSdnConnector(SdnConnectorBase): Provide the parameter http_code """ try: + self.logger.debug("invoked create_connectivity_service '{}' ports: {}". + format(service_type, connection_points)) self.__get_Connection() self.__check_service(service_type, connection_points, @@ -558,6 +567,7 @@ class AristaSdnConnector(SdnConnectorBase): vlan_processed = False vlan_id = '' i = 0 + processed_connection_points = [] for cp in connection_points: i += 1 encap_info = cp.get(self.__ENCAPSULATION_INFO_PARAM) @@ -584,26 +594,33 @@ class AristaSdnConnector(SdnConnectorBase): if not switch_id: point_mac = encap_info.get(self.__MAC_PARAM) switches = self.__lldp_find_neighbor("chassisId", point_mac) - - if len(switches) == 0: - raise SdnConnectorError(message="Connection point MAC address {} not found in the switches".format(point_mac), - http_code=406) self.logger.debug("Found connection point for MAC {}: {}". format(point_mac, switches)) - port_channel = self.__get_switch_po(switch['name'], - switch['interface']) - if len(port_channel) > 0: - interface = port_channel[0] - else: - interface = switch['interface'] else: interface = encap_info.get(self.__SW_PORT_PARAM) switches = [{'name': switch_id, 'interface': interface}] + if len(switches) == 0: + raise SdnConnectorError(message="Connection point MAC address {} not found in the switches".format(point_mac), + http_code=406) + + # remove those connections that are equal. This happens when several sriovs are located in the same + # compute node interface, that is, in the same switch and interface + switches = [x for x in switches if x not in processed_connection_points] + if not switches: + continue + processed_connection_points += switches + for switch in switches: + if not switch_id: + port_channel = self.__get_switch_po(switch['name'], + switch['interface']) + if len(port_channel) > 0: + interface = port_channel[0] + else: + interface = switch['interface'] if not interface: raise SdnConnectorError(message="Connection point switch port empty for switch_dpid {}".format(switch_id), http_code=406) - for switch in switches: # it should be only one switch where the mac is attached if encap_type == 'dot1q': # SRIOV configLet for Leaf switch mac's attached to @@ -736,9 +753,10 @@ class AristaSdnConnector(SdnConnectorBase): for t_id in res[1]['tasks']: tasks[t_id] = {'workOrderId': t_id} if not toDelete_in_cvp: - note_msg = "## Managed by OSM {}{}{}##".format(self.__SEPARATOR, - t_id, - self.__SEPARATOR) + note_msg = "{}{}{}{}##".format(self.__MANAGED_BY_OSM, + self.__SEPARATOR, + t_id, + self.__SEPARATOR) self.client.api.add_note_to_configlet( cls_perSw[s][0]['key'], note_msg) @@ -759,8 +777,8 @@ class AristaSdnConnector(SdnConnectorBase): except Exception as ex: try: self.__rollbackConnection(cls_perSw, - allLeafConfigured=True, - allLeafModified=True) + allLeafConfigured, + allLeafModified) except Exception as e: self.logger.info("Exception rolling back in updating connection: {}". format(e)) @@ -897,6 +915,10 @@ class AristaSdnConnector(SdnConnectorBase): else: changed = True if 'taskIds' in str(dev_action): + # Fix 1030 SDN-ARISTA Key error note when deploy a NS + if not dev_action['data']['taskIds']: + raise Exception("No taskIds found: Device {} Configlets couldnot be updated".format( + up_device['hostname'])) for taskId in dev_action['data']['taskIds']: updated.append({up_device['hostname']: "Configlets-{}".format( @@ -978,7 +1000,8 @@ class AristaSdnConnector(SdnConnectorBase): resp = self.client.api.update_configlet( configlet['config'], configlet['data']['key'], - configlet['data']['name']) + configlet['data']['name'], + wait_task_ids=True) elif to_create: operation = 'create' resp = self.client.api.add_configlet( @@ -1200,7 +1223,8 @@ class AristaSdnConnector(SdnConnectorBase): SdnConnectorError: In case of error. """ try: - self.logger.debug('invoked edit_connectivity_service for service {}'.format(service_uuid)) + self.logger.debug('invoked edit_connectivity_service for service {}. ports: {}'.format(service_uuid, + connection_points)) if not service_uuid: raise SdnConnectorError(message='Unable to perform operation, missing or empty uuid', @@ -1408,7 +1432,8 @@ class AristaSdnConnector(SdnConnectorBase): if self.client is None: self.client = self.__connect() self.client.api.get_cvp_info() - except CvpSessionLogOutError: + except (CvpSessionLogOutError, RequestException) as e: + self.logger.debug("Connection error '{}'. Reconnecting".format(e)) self.client = self.__connect() self.client.api.get_cvp_info() @@ -1426,7 +1451,7 @@ class AristaSdnConnector(SdnConnectorBase): else: port = 443 - client.connect([host], + client.connect([host], self.__user, self.__passwd, protocol=protocol or "https",