Adds SFC CRUD interface to the VIM connector
[osm/RO.git] / osm_ro / vim_thread.py
index a56dd64..9f396a2 100644 (file)
 # contact with: nfvlabs@tid.es
 ##
 
 # contact with: nfvlabs@tid.es
 ##
 
-'''
+""""
 This is thread that interact with the host and the libvirt to manage VM
 One thread will be launched per host 
 This is thread that interact with the host and the libvirt to manage VM
 One thread will be launched per host 
-'''
-__author__ = "Alfonso Tierno, Pablo Montes"
-__date__ = "$10-feb-2017 12:07:15$"
+"""
 
 import threading
 import time
 
 import threading
 import time
@@ -36,18 +34,23 @@ import vimconn
 from db_base import db_base_Exception
 from lib_osm_openvim.ovim import ovimException
 
 from db_base import db_base_Exception
 from lib_osm_openvim.ovim import ovimException
 
+__author__ = "Alfonso Tierno, Pablo Montes"
+__date__ = "$10-feb-2017 12:07:15$"
 
 # from logging import Logger
 # import auxiliary_functions as af
 
 
 
 # from logging import Logger
 # import auxiliary_functions as af
 
 
-def is_task_id(id):
-    return True if id[:5] == "TASK." else False
+def is_task_id(task_id):
+    return True if task_id[:5] == "TASK." else False
 
 
 class vim_thread(threading.Thread):
 
 
 class vim_thread(threading.Thread):
+    REFRESH_BUILD = 5      # 5 seconds
+    REFRESH_ACTIVE = 60    # 1 minute
 
 
-    def __init__(self, vimconn, task_lock, name=None, datacenter_name=None, datacenter_tenant_id=None, db=None, db_lock=None, ovim=None):
+    def __init__(self, vimconn, task_lock, name=None, datacenter_name=None, datacenter_tenant_id=None,
+                 db=None, db_lock=None, ovim=None):
         """Init a thread.
         Arguments:
             'id' number of thead
         """Init a thread.
         Arguments:
             'id' number of thead
@@ -147,7 +150,7 @@ class vim_thread(threading.Thread):
                                     self.logger.error("ovimException deleting external_port={} ".format(
                                         task_interface["sdn_port_id"]) + str(e), exc_info=True)
                                     # TODO Set error_msg at instance_nets
                                     self.logger.error("ovimException deleting external_port={} ".format(
                                         task_interface["sdn_port_id"]) + str(e), exc_info=True)
                                     # TODO Set error_msg at instance_nets
-                            vim_net_id = interface.pop("vim_net_id")
+                            vim_net_id = interface["vim_net_id"]
                             sdn_net_id = None
                             sdn_port_name = None
                             with self.db_lock:
                             sdn_net_id = None
                             sdn_port_name = None
                             with self.db_lock:
@@ -160,7 +163,7 @@ class vim_thread(threading.Thread):
                                     FROM="instance_interfaces as ii left join instance_nets as ine on "
                                          "ii.instance_net_id=ine.uuid left join instance_vms as iv on "
                                          "ii.instance_vm_id=iv.uuid",
                                     FROM="instance_interfaces as ii left join instance_nets as ine on "
                                          "ii.instance_net_id=ine.uuid left join instance_vms as iv on "
                                          "ii.instance_vm_id=iv.uuid",
-                                    SELECT=("ii.uuid as iface_id", "ine.uuid as net_id", "iv.uuid as vm_id", "sdn_net_id"),
+                                    SELECT=("ii.uuid as iface_id", "ine.uuid as net_id", "iv.uuid as vm_id", "sdn_net_id", "vim_net_id"),
                                     WHERE=where_)
                             if len(db_ifaces)>1:
                                 self.logger.critical("Refresing interfaces. "
                                     WHERE=where_)
                             if len(db_ifaces)>1:
                                 self.logger.critical("Refresing interfaces. "
@@ -171,6 +174,14 @@ class vim_thread(threading.Thread):
                                 continue
                             else:
                                 db_iface = db_ifaces[0]
                                 continue
                             else:
                                 db_iface = db_ifaces[0]
+                                #If there is no sdn_net_id, check if it is because an already created vim network is being used
+                                #in that case, the sdn_net_id will be in that entry of the instance_nets table
+                                if not db_iface.get("sdn_net_id"):
+                                    result = self.db.get_rows(SELECT=('sdn_net_id',), FROM='instance_nets',
+                                                                  WHERE={'vim_net_id': db_iface.get("vim_net_id"), 'instance_scenario_id': None, "datacenter_tenant_id":  self.datacenter_tenant_id})
+                                    if len(result) == 1:
+                                        db_iface["sdn_net_id"] = result[0]['sdn_net_id']
+
                                 if db_iface.get("sdn_net_id") and interface.get("compute_node") and interface.get("pci"):
                                     sdn_net_id = db_iface["sdn_net_id"]
                                     sdn_port_name = sdn_net_id + "." + db_iface["vm_id"]
                                 if db_iface.get("sdn_net_id") and interface.get("compute_node") and interface.get("pci"):
                                     sdn_net_id = db_iface["sdn_net_id"]
                                     sdn_port_name = sdn_net_id + "." + db_iface["vm_id"]
@@ -195,19 +206,20 @@ class vim_thread(threading.Thread):
                                             exc_info=True)
                                         # TODO Set error_msg at instance_nets
                                 with self.db_lock:
                                             exc_info=True)
                                         # TODO Set error_msg at instance_nets
                                 with self.db_lock:
+                                    vim_net_id = interface.pop("vim_net_id")
                                     self.db.update_rows('instance_interfaces', UPDATE=interface,
                                                     WHERE={'uuid': db_iface["iface_id"]})
                                     self.db.update_rows('instance_interfaces', UPDATE=interface,
                                                     WHERE={'uuid': db_iface["iface_id"]})
+                                    interface["vim_net_id"] = vim_net_id
                                 # TODO insert instance_id
                                 # TODO insert instance_id
-                            interface["vim_net_id"] = vim_net_id
 
                     task["vim_info"] = vim_info
                     if task["vim_info"]["status"] == "BUILD":
 
                     task["vim_info"] = vim_info
                     if task["vim_info"]["status"] == "BUILD":
-                        self._insert_refresh(task, now+5)  # 5seconds
+                        self._insert_refresh(task, now + self.REFRESH_BUILD)
                     else:
                     else:
-                        self._insert_refresh(task, now+300) # 5minutes
+                        self._insert_refresh(task, now + self.REFRESH_ACTIVE)
             except vimconn.vimconnException as e:
                 self.logger.error("vimconnException Exception when trying to refresh vms " + str(e))
             except vimconn.vimconnException as e:
                 self.logger.error("vimconnException Exception when trying to refresh vms " + str(e))
-                self._insert_refresh(task, now + 300)  # 5minutes
+                self._insert_refresh(task, now + self.REFRESH_ACTIVE)
 
         if net_to_refresh_list:
             try:
 
         if net_to_refresh_list:
             try:
@@ -269,12 +281,12 @@ class vim_thread(threading.Thread):
 
                     task["vim_info"] = vim_info
                     if task["vim_info"]["status"] == "BUILD":
 
                     task["vim_info"] = vim_info
                     if task["vim_info"]["status"] == "BUILD":
-                        self._insert_refresh(task, now+5)    # 5seconds
+                        self._insert_refresh(task, now + self.REFRESH_BUILD)
                     else:
                     else:
-                        self._insert_refresh(task, now+300)  # 5minutes
+                        self._insert_refresh(task, now + self.REFRESH_ACTIVE)
             except vimconn.vimconnException as e:
                 self.logger.error("vimconnException Exception when trying to refresh nets " + str(e))
             except vimconn.vimconnException as e:
                 self.logger.error("vimconnException Exception when trying to refresh nets " + str(e))
-                self._insert_refresh(task, now + 300)  # 5minutes
+                self._insert_refresh(task, now + self.REFRESH_ACTIVE)
 
         if not items_to_refresh:
             time.sleep(1)
 
         if not items_to_refresh:
             time.sleep(1)
@@ -400,7 +412,7 @@ class vim_thread(threading.Thread):
             sdn_net_id = None
             sdn_controller = self.vim.config.get('sdn-controller')
             if sdn_controller and (net_type == "data" or net_type == "ptp"):
             sdn_net_id = None
             sdn_controller = self.vim.config.get('sdn-controller')
             if sdn_controller and (net_type == "data" or net_type == "ptp"):
-                network = {"name": net_name, "type": net_type}
+                network = {"name": net_name, "type": net_type, "region": self.vim["config"]["datacenter_id"]}
 
                 vim_net = self.vim.get_network(net_id)
                 if vim_net.get('encapsulation') != 'vlan':
 
                 vim_net = self.vim.get_network(net_id)
                 if vim_net.get('encapsulation') != 'vlan':
@@ -547,6 +559,20 @@ class vim_thread(threading.Thread):
             self._remove_refresh("get-net", net_id)
             result = self.vim.delete_network(net_id)
             if sdn_net_id:
             self._remove_refresh("get-net", net_id)
             result = self.vim.delete_network(net_id)
             if sdn_net_id:
+                #Delete any attached port to this sdn network
+                #At this point, there will be ports associated to this network in case it was manually done using 'openmano vim-net-sdn-attach'
+                try:
+                    port_list = self.ovim.get_ports(columns={'uuid'}, filter={'name': 'external_port', 'net_id': sdn_net_id})
+                except ovimException as e:
+                    raise vimconn.vimconnException(
+                        "ovimException obtaining external ports for net {}. ".format(sdn_net_id) + str(e))
+
+                for port in port_list:
+                    try:
+                        self.ovim.delete_port(port['uuid'])
+                    except ovimException as e:
+                        raise vimconn.vimconnException(
+                            "ovimException deleting port {} for net {}. ".format(port['uuid'], sdn_net_id) + str(e))
                 with self.db_lock:
                     self.ovim.delete_network(sdn_net_id)
             return True, result
                 with self.db_lock:
                     self.ovim.delete_network(sdn_net_id)
             return True, result