Create task FIND-CREATE for network 95/5595/1
authortierno <alfonso.tiernosepulveda@telefonica.com>
Tue, 17 Oct 2017 21:15:08 +0000 (23:15 +0200)
committertierno <alfonso.tiernosepulveda@telefonica.com>
Tue, 17 Oct 2017 22:11:07 +0000 (00:11 +0200)
Change-Id: I67c42fb0af92955117a0539e516dbb4f19b5b346
Signed-off-by: tierno <alfonso.tiernosepulveda@telefonica.com>
openmanod
osm_ro/nfvo.py
osm_ro/vim_thread.py

index 059dcdd..145fd24 100755 (executable)
--- a/openmanod
+++ b/openmanod
@@ -48,7 +48,7 @@ import osm_ro
 
 __author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes"
 __date__ = "$26-aug-2014 11:09:29$"
-__version__ = "0.5.35-r545"
+__version__ = "0.5.36-r546"
 version_date = "Oct 2017"
 database_version = 27      # expected database schema version
 
index df046f4..bd5b5d6 100644 (file)
@@ -2823,19 +2823,15 @@ def create_instance(mydb, tenant_id, instance_dict):
                     create_network = True
                     lookfor_network = False
 
-                if lookfor_network and create_network:
-                    # TODO create two tasks FIND + CREATE with their relationship
-                    task_action = "FIND"
-                    task_params = (lookfor_filter,)
-                    # task_action = "CREATE"
-                    # task_params = (net_vim_name, net_type, sce_net.get('ip_profile', None))
-                    # task
+                task_extra = {}
+                if create_network:
+                    task_action = "CREATE"
+                    task_extra["params"] = (net_vim_name, net_type, sce_net.get('ip_profile', None))
+                    if lookfor_network:
+                        task_extra["find"] = (lookfor_filter,)
                 elif lookfor_network:
                     task_action = "FIND"
-                    task_params = (lookfor_filter,)
-                elif create_network:
-                    task_action = "CREATE"
-                    task_params = (net_vim_name, net_type, sce_net.get('ip_profile', None))
+                    task_extra["params"] = (lookfor_filter,)
 
                 # fill database content
                 net_uuid = str(uuid4())
@@ -2860,7 +2856,7 @@ def create_instance(mydb, tenant_id, instance_dict):
                     "action": task_action,
                     "item": "instance_nets",
                     "item_id": net_uuid,
-                    "extra": yaml.safe_dump({"params": task_params}, default_flow_style=True, width=256)
+                    "extra": yaml.safe_dump(task_extra, default_flow_style=True, width=256)
                 }
                 net2task_id['scenario'][sce_net['uuid']][datacenter_id] = task_index
                 task_index += 1
index 1fba7a6..22a882e 100644 (file)
 """"
 This is thread that interacts with a VIM. It processes TASKs sequentially against a single VIM.
 The tasks are stored at database in table vim_actions
-The task content is:
+The task content are (M: stored at memory, D: stored at database):
     MD  instance_action_id:  reference a global action over an instance-scenario: database instance_actions
     MD  task_index:     index number of the task. This with the previous are a key
     MD  datacenter_vim_id:  should contain the uuid of the VIM managed by this thread
     MD  vim_id:     id of the vm,net,etc at VIM
-    MD  action:     CREATE, DELETE, LOOK, TODO: LOOK_CREATE
+    MD  action:     CREATE, DELETE, FIND
     MD  item:       database table name, can be instance_vms, instance_nets, TODO: datacenter_flavors, datacenter_images
     MD  item_id:    uuid of the referenced entry in the preious table
     MD  status:     SCHEDULED,BUILD,DONE,FAILED,SUPERSEDED
     MD  extra:      text with yaml format at database, dict at memory with:
-            params:     list with the params to be sent to the VIM for CREATE or LOOK. For DELETE the vim_id is taken from other related tasks
+            params:     list with the params to be sent to the VIM for CREATE or FIND. For DELETE the vim_id is taken from other related tasks
+            find:       (only for CREATE tasks) if present it should FIND before creating and use if existing. Contains the FIND params
             depends_on: list with the 'task_index'es of tasks that must be completed before. e.g. a vm depends on a net
             sdn_net_id: used for net.
             tries:
@@ -78,6 +79,10 @@ class VimThreadException(Exception):
     pass
 
 
+class VimThreadExceptionNotFound(VimThreadException):
+    pass
+
+
 class vim_thread(threading.Thread):
     REFRESH_BUILD = 5      # 5 seconds
     REFRESH_ACTIVE = 60    # 1 minute
@@ -520,7 +525,8 @@ class vim_thread(threading.Thread):
                 for to_supersede in self.grouped_tasks.get(action_key, ()):
                     if to_supersede["action"] == "FIND" and to_supersede.get("vim_id"):
                         task["vim_id"] = to_supersede["vim_id"]
-                    if to_supersede["action"] == "CREATE" and to_supersede.get("vim_id"):
+                    if to_supersede["action"] == "CREATE" and to_supersede.get("vim_id") and \
+                            to_supersede["extra"].get("created", True):
                         need_delete_action = True
                         task["vim_id"] = to_supersede["vim_id"]
                         if to_supersede["extra"].get("sdn_vim_id"):
@@ -621,48 +627,6 @@ class vim_thread(threading.Thread):
             return error_text[:max_length//2-3] + " ... " + error_text[-max_length//2+3:]
         return error_text
 
-    def new_net(self, task):
-        try:
-            task_id = task["instance_action_id"] + "." + str(task["task_index"])
-            params = task["params"]
-            vim_net_id = self.vim.new_network(*params)
-
-            net_name = params[0]
-            net_type = params[1]
-
-            network = None
-            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, "region": self.vim["config"]["datacenter_id"]}
-
-                vim_net = self.vim.get_network(vim_net_id)
-                if vim_net.get('encapsulation') != 'vlan':
-                    raise vimconn.vimconnException(
-                        "net '{}' defined as type '{}' has not vlan encapsulation '{}'".format(
-                            net_name, net_type, vim_net['encapsulation']))
-                network["vlan"] = vim_net.get('segmentation_id')
-                try:
-                    with self.db_lock:
-                        sdn_net_id = self.ovim.new_network(network)
-                except (ovimException, Exception) as e:
-                    self.logger.error("task=%s cannot create SDN network vim_net_id=%s input='%s' ovimException='%s'",
-                                      str(task_id), vim_net_id, str(network), str(e))
-            task["status"] = "DONE"
-            task["extra"]["vim_info"] = {}
-            task["extra"]["sdn_net_id"] = sdn_net_id
-            task["error_msg"] = None
-            task["vim_id"] = vim_net_id
-            instance_element_update = {"vim_net_id": vim_net_id, "sdn_net_id": sdn_net_id, "status": "BUILD", "error_msg": None}
-            return True, instance_element_update
-        except vimconn.vimconnException as e:
-            self.logger.error("Error creating NET, task=%s: %s", str(task_id), str(e))
-            task["status"] = "FAILED"
-            task["vim_id"] = None
-            task["error_msg"] = self._format_vim_error_msg(str(e))
-            instance_element_update = {"vim_net_id": None, "sdn_net_id": None, "status": "VIM_ERROR", "error_msg": task["error_msg"]}
-            return False, instance_element_update
-
     def new_vm(self, task):
         try:
             params = task["params"]
@@ -704,6 +668,7 @@ class vim_thread(threading.Thread):
             task["vim_info"] = {}
             task["vim_interfaces"] = {}
             task["extra"]["interfaces"] = task_interfaces
+            task["extra"]["created"] = True
             task["error_msg"] = None
             task["status"] = "DONE"
             task["vim_id"] = vim_vm_id
@@ -747,6 +712,105 @@ class vim_thread(threading.Thread):
             task["status"] = "FAILED"
             return False, None
 
+    def _get_net_internal(self, task, filter_param):
+        vim_nets = self.vim.get_network_list(filter_param)
+        if not vim_nets:
+            raise VimThreadExceptionNotFound("Network not found with this criteria: '{}'".format(filter))
+        elif len(vim_nets) > 1:
+            raise VimThreadException("More than one network found with this criteria: '{}'".format(filter))
+        vim_net_id = vim_nets[0]["id"]
+
+        # Discover if this network is managed by a sdn controller
+        sdn_net_id = None
+        with self.db_lock:
+            result = self.db.get_rows(SELECT=('sdn_net_id',), FROM='instance_nets',
+                                      WHERE={'vim_net_id': vim_net_id, 'instance_scenario_id': None,
+                                             'datacenter_tenant_id': self.datacenter_tenant_id})
+        if result:
+            sdn_net_id = result[0]['sdn_net_id']
+
+        task["status"] = "DONE"
+        task["extra"]["vim_info"] = {}
+        task["extra"]["created"] = False
+        task["extra"]["sdn_net_id"] = sdn_net_id
+        task["error_msg"] = None
+        task["vim_id"] = vim_net_id
+        instance_element_update = {"vim_net_id": vim_net_id, "created": False, "status": "BUILD",
+                                   "error_msg": None}
+        return instance_element_update
+
+    def get_net(self, task):
+        try:
+            task_id = task["instance_action_id"] + "." + str(task["task_index"])
+            params = task["params"]
+            filter_param = params[0]
+            instance_element_update = self._get_net_internal(task, filter_param)
+            return True, instance_element_update
+
+        except (vimconn.vimconnException, VimThreadException) as e:
+            self.logger.error("Error looking for  NET, task=%s: %s", str(task_id), str(e))
+            task["status"] = "FAILED"
+            task["vim_id"] = None
+            task["error_msg"] = self._format_vim_error_msg(str(e))
+            instance_element_update = {"vim_net_id": None, "status": "VIM_ERROR",
+                                       "error_msg": task["error_msg"]}
+            return False, instance_element_update
+
+    def new_net(self, task):
+        try:
+            task_id = task["instance_action_id"] + "." + str(task["task_index"])
+            # FIND
+            if task["extra"].get("find"):
+                action_text = "finding"
+                filter_param = task["extra"]["find"][0]
+                try:
+                    instance_element_update = self._get_net_internal(task, filter_param)
+                    return True, instance_element_update
+                except VimThreadExceptionNotFound:
+                    pass
+            # CREATE
+            params = task["params"]
+            action_text = "creating"
+            vim_net_id = self.vim.new_network(*params)
+
+            net_name = params[0]
+            net_type = params[1]
+
+            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, "region": self.vim["config"]["datacenter_id"]}
+
+                vim_net = self.vim.get_network(vim_net_id)
+                if vim_net.get('encapsulation') != 'vlan':
+                    raise vimconn.vimconnException(
+                        "net '{}' defined as type '{}' has not vlan encapsulation '{}'".format(
+                            net_name, net_type, vim_net['encapsulation']))
+                network["vlan"] = vim_net.get('segmentation_id')
+                try:
+                    with self.db_lock:
+                        sdn_net_id = self.ovim.new_network(network)
+                except (ovimException, Exception) as e:
+                    self.logger.error("task=%s cannot create SDN network vim_net_id=%s input='%s' ovimException='%s'",
+                                      str(task_id), vim_net_id, str(network), str(e))
+            task["status"] = "DONE"
+            task["extra"]["vim_info"] = {}
+            task["extra"]["sdn_net_id"] = sdn_net_id
+            task["extra"]["created"] = True
+            task["error_msg"] = None
+            task["vim_id"] = vim_net_id
+            instance_element_update = {"vim_net_id": vim_net_id, "sdn_net_id": sdn_net_id, "status": "BUILD",
+                                       "created": True, "error_msg": None}
+            return True, instance_element_update
+        except vimconn.vimconnException as e:
+            self.logger.error("Error {} NET, task=%s: %s", action_text, str(task_id), str(e))
+            task["status"] = "FAILED"
+            task["vim_id"] = None
+            task["error_msg"] = self._format_vim_error_msg(str(e))
+            instance_element_update = {"vim_net_id": None, "sdn_net_id": None, "status": "VIM_ERROR",
+                                       "error_msg": task["error_msg"]}
+            return False, instance_element_update
+
     def del_net(self, task):
         net_vim_id = task["vim_id"]
         sdn_net_id = task["extra"].get("sdn_net_id")
@@ -775,42 +839,3 @@ class vim_thread(threading.Thread):
                 return True, None
         task["status"] = "FAILED"
         return False, None
-
-    def get_net(self, task):
-        try:
-            task_id = task["instance_action_id"] + "." + str(task["task_index"])
-            params = task["params"]
-            filter = params[0]
-            vim_nets = self.vim.get_network_list(filter)
-            if not vim_nets:
-                raise VimThreadException("Network not found with this criteria: '{}'".format(filter))
-            elif len(vim_nets) > 1:
-                raise VimThreadException("More than one network found with this criteria: '{}'".format(filter))
-            vim_net_id = vim_nets[0]["id"]
-
-            # Discover if this network is managed by a sdn controller
-            sdn_net_id = None
-            with self.db_lock:
-                result = self.db.get_rows(SELECT=('sdn_net_id',), FROM='instance_nets',
-                    WHERE={'vim_net_id': vim_net_id, 'instance_scenario_id': None,
-                           'datacenter_tenant_id': self.datacenter_tenant_id})
-            if result:
-                sdn_net_id = result[0]['sdn_net_id']
-
-            task["status"] = "DONE"
-            task["extra"]["vim_info"] = {}
-            task["extra"]["created"] = False
-            task["extra"]["sdn_net_id"] = sdn_net_id
-            task["error_msg"] = None
-            task["vim_id"] = vim_net_id
-            instance_element_update = {"vim_net_id": vim_net_id, "created": False, "status": "BUILD",
-                                       "error_msg": None}
-            return True, instance_element_update
-        except (vimconn.vimconnException, VimThreadException) as e:
-            self.logger.error("Error looking for  NET, task=%s: %s", str(task_id), str(e))
-            task["status"] = "FAILED"
-            task["vim_id"] = None
-            task["error_msg"] = self._format_vim_error_msg(str(e))
-            instance_element_update = {"vim_net_id": None, "status": "VIM_ERROR",
-                                       "error_msg": task["error_msg"]}
-            return False, instance_element_update