VNFFG fixed some issues
[osm/RO.git] / osm_ro / vimconn_openstack.py
index 65e17b5..fd16f54 100644 (file)
@@ -36,7 +36,7 @@ __author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes, xFlow Research, Igor
 __date__  = "$22-sep-2017 23:59:59$"
 
 import vimconn
-import json
+import json
 import logging
 import netaddr
 import time
@@ -75,8 +75,8 @@ netStatus2manoFormat={'ACTIVE':'ACTIVE','PAUSED':'PAUSED','INACTIVE':'INACTIVE',
 supportedClassificationTypes = ['legacy_flow_classifier']
 
 #global var to have a timeout creating and deleting volumes
-volume_timeout = 60
-server_timeout = 300
+volume_timeout = 600
+server_timeout = 600
 
 class vimconnector(vimconn.vimconnector):
     def __init__(self, uuid, name, tenant_id, tenant_name, url, url_admin=None, user=None, passwd=None,
@@ -493,10 +493,11 @@ class vimconnector(vimconn.vimconnector):
         self.logger.debug("Getting network from VIM filter: '%s'", str(filter_dict))
         try:
             self._reload_connection()
-            if self.api_version3 and "tenant_id" in filter_dict:
-                filter_dict['project_id'] = filter_dict.pop('tenant_id') #TODO check
-            net_dict=self.neutron.list_networks(**filter_dict)
-            net_list=net_dict["networks"]
+            filter_dict_os = filter_dict.copy()
+            if self.api_version3 and "tenant_id" in filter_dict_os:
+                filter_dict_os['project_id'] = filter_dict_os.pop('tenant_id')  #T ODO check
+            net_dict = self.neutron.list_networks(**filter_dict_os)
+            net_list = net_dict["networks"]
             self.__net_os2mano(net_list)
             return net_list
         except (neExceptions.ConnectionFailed, ksExceptions.ClientException, neExceptions.NeutronException, ConnectionError) as e:
@@ -714,7 +715,7 @@ class vimconnector(vimconn.vimconnector):
                 new_flavor=self.nova.flavors.create(name,
                                 ram,
                                 vcpus,
-                                flavor_data.get('disk',1),
+                                flavor_data.get('disk',0),
                                 is_public=flavor_data.get('is_public', True)
                             )
                 #add metadata
@@ -840,9 +841,9 @@ class vimconnector(vimconn.vimconnector):
         self.logger.debug("Getting image list from VIM filter: '%s'", str(filter_dict))
         try:
             self._reload_connection()
-            filter_dict_os=filter_dict.copy()
+            filter_dict_os = filter_dict.copy()
             #First we filter by the available filter fields: name, id. The others are removed.
-            filter_dict_os.pop('checksum',None)
+            filter_dict_os.pop('checksum', None)
             image_list = self.nova.images.findall(**filter_dict_os)
             if len(image_list) == 0:
                 return []
@@ -851,7 +852,7 @@ class vimconnector(vimconn.vimconnector):
             for image in image_list:
                 try:
                     image_class = self.glance.images.get(image.id)
-                    if 'checksum' not in filter_dict or image_class['checksum']==filter_dict.get('checksum'):
+                    if 'checksum' not in filter_dict or image_class['checksum'] == filter_dict.get('checksum'):
                         filtered_list.append(image_class.copy())
                 except gl1Exceptions.HTTPNotFound:
                     pass
@@ -1033,7 +1034,7 @@ class vimconnector(vimconn.vimconnector):
                 if net.get("mac_address"):
                     port_dict["mac_address"]=net["mac_address"]
                 new_port = self.neutron.create_port({"port": port_dict })
-                created_items[("port", str(new_port["port"]["id"]))] = True
+                created_items["port:" + str(new_port["port"]["id"])] = True
                 net["mac_adress"] = new_port["port"]["mac_address"]
                 net["vim_id"] = new_port["port"]["id"]
                 # if try to use a network without subnetwork, it will return a emtpy list
@@ -1088,7 +1089,7 @@ class vimconnector(vimconn.vimconnector):
                     else:
                         volume = self.cinder.volumes.create(size=disk['size'], name=name + '_vd' +
                                     chr(base_disk_index))
-                    created_items[("volume", str(volume.id))] = True
+                    created_items["volume:" + str(volume.id)] = True
                     block_device_mapping['_vd' +  chr(base_disk_index)] = volume.id
                     base_disk_index += 1
 
@@ -1283,10 +1284,11 @@ class vimconnector(vimconn.vimconnector):
                 if not v:  # skip already deleted
                     continue
                 try:
-                    if k[0] == "port":
-                        self.neutron.delete_port(k[1])
+                    k_item, _, k_id = k.partition(":")
+                    if k_item == "port":
+                        self.neutron.delete_port(k_id)
                 except Exception as e:
-                    self.logger.error("Error deleting port: " + type(e).__name__ + ": "+  str(e))
+                    self.logger.error("Error deleting port: {}: {}".format(type(e).__name__, e))
 
             # #commented because detaching the volumes makes the servers.delete not work properly ?!?
             # #dettach volumes attached
@@ -1308,13 +1310,14 @@ class vimconnector(vimconn.vimconnector):
                     if not v:  # skip already deleted
                         continue
                     try:
-                        if k[0] == "volume":
-                            if self.cinder.volumes.get(k[1]).status != 'available':
+                        k_item, _, k_id = k.partition(":")
+                        if k_item == "volume":
+                            if self.cinder.volumes.get(k_id).status != 'available':
                                 keep_waiting = True
                             else:
-                                self.cinder.volumes.delete(k[1])
+                                self.cinder.volumes.delete(k_id)
                     except Exception as e:
-                        self.logger.error("Error deleting volume: " + type(e).__name__ + ": " + str(e))
+                        self.logger.error("Error deleting volume: {}: {}".format(type(e).__name__, e))
                 if keep_waiting:
                     time.sleep(1)
                     elapsed_time += 1
@@ -1689,7 +1692,7 @@ class vimconnector(vimconn.vimconnector):
             classification_dict = definition
             classification_dict['name'] = name
 
-            new_class = self.neutron.create_flow_classifier(
+            new_class = self.neutron.create_sfc_flow_classifier(
                 {'flow_classifier': classification_dict})
             return new_class['flow_classifier']['id']
         except (neExceptions.ConnectionFailed, ksExceptions.ClientException,
@@ -1715,11 +1718,12 @@ class vimconnector(vimconn.vimconnector):
         self.logger.debug("Getting Classifications from VIM filter: '%s'",
                           str(filter_dict))
         try:
+            filter_dict_os = filter_dict.copy()
             self._reload_connection()
-            if self.api_version3 and "tenant_id" in filter_dict:
-                filter_dict['project_id'] = filter_dict.pop('tenant_id')
-            classification_dict = self.neutron.list_flow_classifier(
-                **filter_dict)
+            if self.api_version3 and "tenant_id" in filter_dict_os:
+                filter_dict_os['project_id'] = filter_dict_os.pop('tenant_id')
+            classification_dict = self.neutron.list_sfc_flow_classifiers(
+                **filter_dict_os)
             classification_list = classification_dict["flow_classifiers"]
             self.__classification_os2mano(classification_list)
             return classification_list
@@ -1731,7 +1735,7 @@ class vimconnector(vimconn.vimconnector):
         self.logger.debug("Deleting Classification '%s' from VIM", class_id)
         try:
             self._reload_connection()
-            self.neutron.delete_flow_classifier(class_id)
+            self.neutron.delete_sfc_flow_classifier(class_id)
             return class_id
         except (neExceptions.ConnectionFailed, neExceptions.NeutronException,
                 ksExceptions.ClientException, neExceptions.NeutronException,
@@ -1746,9 +1750,7 @@ class vimconnector(vimconn.vimconnector):
             self._reload_connection()
             correlation = None
             if sfc_encap:
-                # TODO(igordc): must be changed to NSH in Queens
-                # (MPLS is a workaround)
-                correlation = 'mpls'
+                correlation = 'nsh'
             if len(ingress_ports) != 1:
                 raise vimconn.vimconnNotSupportedException(
                     "OpenStack VIM connector can only have "
@@ -1762,13 +1764,13 @@ class vimconnector(vimconn.vimconnector):
                         'egress': egress_ports[0],
                         'service_function_parameters': {
                             'correlation': correlation}}
-            new_sfi = self.neutron.create_port_pair({'port_pair': sfi_dict})
+            new_sfi = self.neutron.create_sfc_port_pair({'port_pair': sfi_dict})
             return new_sfi['port_pair']['id']
         except (neExceptions.ConnectionFailed, ksExceptions.ClientException,
                 neExceptions.NeutronException, ConnectionError) as e:
             if new_sfi:
                 try:
-                    self.neutron.delete_port_pair_group(
+                    self.neutron.delete_sfc_port_pair(
                         new_sfi['port_pair']['id'])
                 except Exception:
                     self.logger.error(
@@ -1796,9 +1798,10 @@ class vimconnector(vimconn.vimconnector):
                           "VIM filter: '%s'", str(filter_dict))
         try:
             self._reload_connection()
-            if self.api_version3 and "tenant_id" in filter_dict:
-                filter_dict['project_id'] = filter_dict.pop('tenant_id')
-            sfi_dict = self.neutron.list_port_pair(**filter_dict)
+            filter_dict_os = filter_dict.copy()
+            if self.api_version3 and "tenant_id" in filter_dict_os:
+                filter_dict_os['project_id'] = filter_dict_os.pop('tenant_id')
+            sfi_dict = self.neutron.list_sfc_port_pairs(**filter_dict_os)
             sfi_list = sfi_dict["port_pairs"]
             self.__sfi_os2mano(sfi_list)
             return sfi_list
@@ -1811,7 +1814,7 @@ class vimconnector(vimconn.vimconnector):
                           "from VIM", sfi_id)
         try:
             self._reload_connection()
-            self.neutron.delete_port_pair(sfi_id)
+            self.neutron.delete_sfc_port_pair(sfi_id)
             return sfi_id
         except (neExceptions.ConnectionFailed, neExceptions.NeutronException,
                 ksExceptions.ClientException, neExceptions.NeutronException,
@@ -1826,25 +1829,23 @@ class vimconnector(vimconn.vimconnector):
             self._reload_connection()
             correlation = None
             if sfc_encap:
-                # TODO(igordc): must be changed to NSH in Queens
-                # (MPLS is a workaround)
-                correlation = 'mpls'
+                correlation = 'nsh'
             for instance in sfis:
                 sfi = self.get_sfi(instance)
-                if sfi.get('sfc_encap') != correlation:
+                if sfi.get('sfc_encap') != sfc_encap:
                     raise vimconn.vimconnNotSupportedException(
                         "OpenStack VIM connector requires all SFIs of the "
                         "same SF to share the same SFC Encapsulation")
             sf_dict = {'name': name,
                        'port_pairs': sfis}
-            new_sf = self.neutron.create_port_pair_group({
+            new_sf = self.neutron.create_sfc_port_pair_group({
                 'port_pair_group': sf_dict})
             return new_sf['port_pair_group']['id']
         except (neExceptions.ConnectionFailed, ksExceptions.ClientException,
                 neExceptions.NeutronException, ConnectionError) as e:
             if new_sf:
                 try:
-                    self.neutron.delete_port_pair_group(
+                    self.neutron.delete_sfc_port_pair_group(
                         new_sf['port_pair_group']['id'])
                 except Exception:
                     self.logger.error(
@@ -1870,9 +1871,10 @@ class vimconnector(vimconn.vimconnector):
                           str(filter_dict))
         try:
             self._reload_connection()
-            if self.api_version3 and "tenant_id" in filter_dict:
-                filter_dict['project_id'] = filter_dict.pop('tenant_id')
-            sf_dict = self.neutron.list_port_pair_group(**filter_dict)
+            filter_dict_os = filter_dict.copy()
+            if self.api_version3 and "tenant_id" in filter_dict_os:
+                filter_dict_os['project_id'] = filter_dict_os.pop('tenant_id')
+            sf_dict = self.neutron.list_sfc_port_pair_groups(**filter_dict_os)
             sf_list = sf_dict["port_pair_groups"]
             self.__sf_os2mano(sf_list)
             return sf_list
@@ -1884,7 +1886,7 @@ class vimconnector(vimconn.vimconnector):
         self.logger.debug("Deleting Service Function '%s' from VIM", sf_id)
         try:
             self._reload_connection()
-            self.neutron.delete_port_pair_group(sf_id)
+            self.neutron.delete_sfc_port_pair_group(sf_id)
             return sf_id
         except (neExceptions.ConnectionFailed, neExceptions.NeutronException,
                 ksExceptions.ClientException, neExceptions.NeutronException,
@@ -1897,26 +1899,24 @@ class vimconnector(vimconn.vimconnector):
         try:
             new_sfp = None
             self._reload_connection()
-            if not sfc_encap:
-                raise vimconn.vimconnNotSupportedException(
-                    "OpenStack VIM connector only supports "
-                    "SFC-Encapsulated chains")
-            # TODO(igordc): must be changed to NSH in Queens
-            # (MPLS is a workaround)
-            correlation = 'mpls'
+            # In networking-sfc the MPLS encapsulation is legacy
+            # should be used when no full SFC Encapsulation is intended
+            sfc_encap = 'mpls'
+            if sfc_encap:
+                correlation = 'nsh'
             sfp_dict = {'name': name,
                         'flow_classifiers': classifications,
                         'port_pair_groups': sfs,
                         'chain_parameters': {'correlation': correlation}}
             if spi:
                 sfp_dict['chain_id'] = spi
-            new_sfp = self.neutron.create_port_chain({'port_chain': sfp_dict})
+            new_sfp = self.neutron.create_sfc_port_chain({'port_chain': sfp_dict})
             return new_sfp["port_chain"]["id"]
         except (neExceptions.ConnectionFailed, ksExceptions.ClientException,
                 neExceptions.NeutronException, ConnectionError) as e:
             if new_sfp:
                 try:
-                    self.neutron.delete_port_chain(new_sfp['port_chain']['id'])
+                    self.neutron.delete_sfc_port_chain(new_sfp['port_chain']['id'])
                 except Exception:
                     self.logger.error(
                         'Creation of Service Function Path failed, with '
@@ -1941,9 +1941,10 @@ class vimconnector(vimconn.vimconnector):
                           "'%s'", str(filter_dict))
         try:
             self._reload_connection()
-            if self.api_version3 and "tenant_id" in filter_dict:
-                filter_dict['project_id'] = filter_dict.pop('tenant_id')
-            sfp_dict = self.neutron.list_port_chain(**filter_dict)
+            filter_dict_os = filter_dict.copy()
+            if self.api_version3 and "tenant_id" in filter_dict_os:
+                filter_dict_os['project_id'] = filter_dict_os.pop('tenant_id')
+            sfp_dict = self.neutron.list_sfc_port_chains(**filter_dict_os)
             sfp_list = sfp_dict["port_chains"]
             self.__sfp_os2mano(sfp_list)
             return sfp_list
@@ -1956,7 +1957,7 @@ class vimconnector(vimconn.vimconnector):
             "Deleting Service Function Path '%s' from VIM", sfp_id)
         try:
             self._reload_connection()
-            self.neutron.delete_port_chain(sfp_id)
+            self.neutron.delete_sfc_port_chain(sfp_id)
             return sfp_id
         except (neExceptions.ConnectionFailed, neExceptions.NeutronException,
                 ksExceptions.ClientException, neExceptions.NeutronException,