Bug 412 - Fixed an unitialized vnfr access in vnf config primitive
[osm/SO.git] / rwcm / plugins / rwconman / rift / tasklets / rwconmantasklet / jujuconf.py
index 1e9397e..6cf549a 100644 (file)
@@ -25,8 +25,9 @@ import rift.mano.utils.juju_api as juju
 from . import riftcm_config_plugin
 
 
-# Charm service name accepts only a to z and -.
 def get_vnf_unique_name(nsr_name, vnfr_name, member_vnf_index):
+    """Get the unique VNF name.
+    Charm names accepts only a to z and non-consecutive - characters."""
     name = "{}-{}-{}".format(nsr_name, vnfr_name, member_vnf_index)
     new_name = ''
     for c in name:
@@ -35,7 +36,7 @@ def get_vnf_unique_name(nsr_name, vnfr_name, member_vnf_index):
         elif not c.isalpha():
             c = "-"
         new_name += c
-    return new_name.lower()
+    return re.sub('\-+', '-', new_name.lower())
 
 
 class JujuConfigPlugin(riftcm_config_plugin.RiftCMConfigPluginBase):
@@ -175,7 +176,7 @@ class JujuConfigPlugin(riftcm_config_plugin.RiftCMConfigPluginBase):
                           'tags': {},
                           'active': False,
                           'config': vnf_config,
-                          'vnfr_name' : agent_vnfr.name})
+                          'vnfr_name': agent_vnfr.name})
         self._log.debug("jujuCA: Charm %s for vnf %s to be deployed as %s",
                         charm, agent_vnfr.name, vnf_unique_name)
 
@@ -185,13 +186,15 @@ class JujuConfigPlugin(riftcm_config_plugin.RiftCMConfigPluginBase):
                                 'launchpad/packages/vnfd',
                                 self._project.name,
                                 agent_vnfr.vnfr_msg.vnfd.id,
-                                'charms/trusty',
+                                'charms',
                                 charm)
             self._log.debug("jujuCA: Charm dir is {}".format(path))
             if not os.path.isdir(path):
-                self._log.error("jujuCA: Did not find the charm directory at {}".
-                                format(path))
+                msg = "jujuCA: Did not find the charm directory at {}".format(path)
+                self._log.error(msg)
                 path = None
+                # Return from here instead of forwarding the config request to juju_api
+                raise Exception(msg)
         except Exception as e:
             self.log.exception(e)
             return False
@@ -199,12 +202,13 @@ class JujuConfigPlugin(riftcm_config_plugin.RiftCMConfigPluginBase):
         if vnf_unique_name not in self._tasks:
             self._tasks[vnf_unique_name] = {}
 
-        self._tasks[vnf_unique_name]['deploy'] = self.loop.create_task(
-            self.api.deploy_service(charm, vnf_unique_name, path=path))
-
         self._log.debug("jujuCA: Deploying service %s",
                         vnf_unique_name)
-
+        yield from self.api.deploy_application(
+            charm,
+            vnf_unique_name,
+            path=path,
+        )
         return True
 
     @asyncio.coroutine
@@ -239,23 +243,22 @@ class JujuConfigPlugin(riftcm_config_plugin.RiftCMConfigPluginBase):
             vnfr = agent_vnfr.vnfr
             service = vnfr['vnf_juju_name']
 
-            self._log.debug ("jujuCA: Terminating VNFr %s, %s",
-                             agent_vnfr.name, service)
-            self._tasks[service]['destroy'] = self.loop.create_task(
-                    self.api.destroy_service(service)
-                )
+            self._log.debug("jujuCA: Terminating VNFr {}, {}".format(
+                agent_vnfr.name,
+                service,
+            ))
+            yield from self.api.remove_application(service)
 
             del self._juju_vnfs[agent_vnfr.id]
-            self._log.debug ("jujuCA: current vnfrs={}".
-                             format(self._juju_vnfs))
+            self._log.debug("jujuCA: current vnfrs={}".
+                            format(self._juju_vnfs))
             if service in self._tasks:
                 tasks = []
                 for action in self._tasks[service].keys():
-                    #if self.check_task_status(service, action):
                     tasks.append(action)
                 del tasks
         except KeyError as e:
-            self._log.debug ("jujuCA: Termiating charm service for VNFr {}, e={}".
+            self._log.debug ("jujuCA: Terminating charm service for VNFr {}, e={}".
                              format(agent_vnfr.name, e))
         except Exception as e:
             self._log.error("jujuCA: Exception terminating charm service for VNFR {}: {}".
@@ -270,35 +273,6 @@ class JujuConfigPlugin(riftcm_config_plugin.RiftCMConfigPluginBase):
         """
         return True
 
-    def check_task_status(self, service, action):
-        #self.log.debug("jujuCA: check task status for %s, %s" % (service, action))
-        try:
-            task = self._tasks[service][action]
-            if task.done():
-                self.log.debug("jujuCA: Task for %s, %s done" % (service, action))
-                e = task.exception()
-                if e:
-                    self.log.error("jujuCA: Error in task for {} and {} : {}".
-                                   format(service, action, e))
-                    raise Exception(e)
-                r= task.result()
-                if r:
-                    self.log.debug("jujuCA: Task for {} and {}, returned {}".
-                                   format(service, action,r))
-                return True
-            else:
-                self.log.debug("jujuCA: task {}, {} not done".
-                               format(service, action))
-                return False
-        except KeyError as e:
-            self.log.error("jujuCA: KeyError for task for {} and {}: {}".
-                           format(service, action, e))
-        except Exception as e:
-            self.log.error("jujuCA: Error for task for {} and {}: {}".
-                           format(service, action, e))
-            raise
-        return True
-
     @asyncio.coroutine
     def _vnf_config_primitive(self, nsr_id, vnfr_id, primitive,
                               vnf_config=None, wait=False):
@@ -317,6 +291,7 @@ class JujuConfigPlugin(riftcm_config_plugin.RiftCMConfigPluginBase):
         self._log.debug("VNF config= %s", vnf_config.as_dict())
 
         try:
+            vnfr = self._juju_vnfs[vnfr_id].vnfr
             service = vnfr['vnf_juju_name']
             self._log.debug("VNF config %s", vnf_config)
             configs = vnf_config.config_primitive
@@ -360,10 +335,7 @@ class JujuConfigPlugin(riftcm_config_plugin.RiftCMConfigPluginBase):
                                             "params {} for service {}".
                                             format(params, service))
 
-                            rc = yield from self.api.apply_config(
-                                params,
-                                service=service,
-                                wait=True)
+                            rc = yield from self.api.apply_config(params, application=service)
 
                             if rc:
                                 rc = "completed"
@@ -387,9 +359,10 @@ class JujuConfigPlugin(riftcm_config_plugin.RiftCMConfigPluginBase):
                                         format(config.name, service, params))
 
                         resp = yield from self.api.execute_action(
+                            service,
                             config.name,
-                            params,
-                            service=service)
+                            **params,
+                        )
 
                         if resp:
                             if 'error' in resp:
@@ -447,7 +420,7 @@ class JujuConfigPlugin(riftcm_config_plugin.RiftCMConfigPluginBase):
             primitive)
 
         self._log.debug("VNFR {} primitive {} exec status: {}".
-                        format(vnfr.name, primitive.name, rc))
+                        format(vnfr_id, primitive.name, rc))
         output.execution_status = rc
         output.execution_id = exec_id
         output.execution_error_details = err
@@ -561,6 +534,7 @@ class JujuConfigPlugin(riftcm_config_plugin.RiftCMConfigPluginBase):
 
         try:
             vnfr = self._juju_vnfs[agent_vnfr.id].vnfr
+            service = vnfr['vnf_juju_name']
         except KeyError:
             self._log.debug("Did not find VNFR %s in Juju plugin",
                             agent_vnfr.name)
@@ -585,12 +559,10 @@ class JujuConfigPlugin(riftcm_config_plugin.RiftCMConfigPluginBase):
                             format(vnfr_msg.name))
             return True
 
-        service = vnfr['vnf_juju_name']
-        rc = yield from self.api.is_service_up(service=service)
+        rc = yield from self.api.is_application_up(application=service)
         if not rc:
             return False
 
-        action_ids = []
         try:
             if vnfr_msg.mgmt_interface.ip_address:
                 vnfr['tags'].update({'rw_mgmt_ip': vnfr_msg.mgmt_interface.ip_address})
@@ -622,9 +594,6 @@ class JujuConfigPlugin(riftcm_config_plugin.RiftCMConfigPluginBase):
                         self._log.error(msg)
                         return False
 
-                    elif rc == "pending":
-                        action_ids.append(eid)
-
                 elif primitive.name:
                     config = {}
                     if primitive.name == 'config':
@@ -641,40 +610,40 @@ class JujuConfigPlugin(riftcm_config_plugin.RiftCMConfigPluginBase):
 
                             rc = yield from self.api.apply_config(
                                 config,
-                                service=service)
+                                application=service,
+                            )
                             if rc is False:
-                                self.log.error("Service {} is in error state".
-                                               format(service))
+                                self.log.error("Service {} is in error state".format(service))
                                 return False
-
-                    # Apply any actions specified as part of initial config
                     else:
-                        self._log.debug("(%s) Initial config action "
-                                        "primitive %s",
-                                        vnfr['vnf_juju_name'], primitive)
-                        action = primitive.name
-                        params = {}
-                        for param in primitive.parameter:
-                            val = self.xlate(param.value, vnfr['tags'])
-                            params.update({param.name: val})
-
-                            self._log.info("(%s) Action %s with params %s",
-                                           vnfr['vnf_juju_name'], action,
-                                           params)
-
-                        resp = yield from self.api.execute_action(
-                            action,
-                            params,
-                            service=service)
-                        if 'error' in resp:
-                            self._log.error("Applying initial config on {}"
-                                            " failed for {} with {}: {}".
-                                            format(vnfr['vnf_juju_name'],
-                                                   action, params, resp))
-                            return False
-
-                        action_ids.append(resp['action']['tag'])
-
+                        # Apply any actions specified as part of initial config
+                        for primitive in vnfr['config'].initial_config_primitive:
+                            if primitive.name != 'config':
+                                self._log.debug("jujuCA:(%s) Initial config action primitive %s",
+                                                vnfr['vnf_juju_name'], primitive)
+                                action = primitive.name
+                                params = {}
+                                for param in primitive.parameter:
+                                    val = self.xlate(param.value, vnfr['tags'])
+                                    params.update({param.name: val})
+
+                                self._log.info("jujuCA:(%s) Action %s with params %s",
+                                               vnfr['vnf_juju_name'], action, params)
+                                self._log.debug("executing action")
+                                resp = yield from self.api.execute_action(
+                                    service,
+                                    action,
+                                    **params,
+                                )
+                                self._log.debug("executed action")
+                                if 'error' in resp:
+                                    self._log.error("Applying initial config on {} failed for {} with {}: {}".
+                                                    format(vnfr['vnf_juju_name'], action, params, resp))
+                                    return False
+        except KeyError as e:
+            self._log.info("Juju config agent(%s): VNFR %s not managed by Juju",
+                           vnfr['vnf_juju_name'], agent_vnfr.id)
+            return False
         except Exception as e:
             self._log.exception("jujuCA:(%s) Exception juju "
                                 "apply_initial_config for VNFR {}: {}".
@@ -682,25 +651,6 @@ class JujuConfigPlugin(riftcm_config_plugin.RiftCMConfigPluginBase):
                                        agent_vnfr.id, e))
             return False
 
-        # Check if all actions completed
-        pending = True
-        while pending:
-            pending = False
-            for act in action_ids:
-                resp = yield from self.api.get_action_status(act)
-                if 'error' in resp:
-                    self._log.error("Initial config failed for action {}: {}".
-                                    format(act, resp))
-                    return False
-
-                if resp['status'] == 'failed':
-                    self._log.error("Initial config action failed for "
-                                    "action {}: {}".format(act, resp))
-                    return False
-
-                if resp['status'] == 'pending':
-                    pending = True
-
         return True
 
     def add_vnfr_managed(self, agent_vnfr):
@@ -728,7 +678,7 @@ class JujuConfigPlugin(riftcm_config_plugin.RiftCMConfigPluginBase):
 
             vnfr = self._juju_vnfs[vnfr_id].vnfr
             service = vnfr['vnf_juju_name']
-            resp = self.api.is_service_active(service=service)
+            resp = self.api.is_application_active(application=service)
             self._juju_vnfs[vnfr_id]['active'] = resp
             self._log.debug("jujuCA: Service state for {} is {}".
                             format(service, resp))
@@ -757,12 +707,13 @@ class JujuConfigPlugin(riftcm_config_plugin.RiftCMConfigPluginBase):
 
         rc = 'configuring'
 
-        if not self.check_task_status(service, 'deploy'):
-            return rc
-
         try:
-            resp = yield from self.api.get_service_status(service=service)
-            self._log.debug("jujuCA: Get service %s status? %s", service, resp)
+            # Get the status of the application
+            resp = yield from self.api.get_application_status(service)
+
+            # No status means the application is still pending deployment
+            if resp is None:
+                return rc
 
             if resp == 'error':
                 return 'error'