Get version from installed package if available instead of code
[osm/LCM.git] / osm_lcm / ns.py
index 1148a82..de1c6a0 100644 (file)
@@ -21,6 +21,7 @@ import yaml
 import logging
 import logging.handlers
 import traceback
+import json
 from jinja2 import Environment, Template, meta, TemplateError, TemplateNotFound, TemplateSyntaxError
 
 from osm_lcm import ROclient
@@ -455,8 +456,7 @@ class NsLcm(LcmBase):
                 if isinstance(vld_params["ns-net"], dict):
                     for vld_id, instance_scenario_id in vld_params["ns-net"].items():
                         RO_vld_ns_net = {"instance_scenario_id": instance_scenario_id, "osm_id": vld_id}
-                if RO_vld_ns_net:
-                    populate_dict(RO_ns_params, ("networks", vld_params["name"], "use-network"), RO_vld_ns_net)            
+                        populate_dict(RO_ns_params, ("networks", vld_params["name"], "use-network"), RO_vld_ns_net)
             if "vnfd-connection-point-ref" in vld_params:
                 for cp_params in vld_params["vnfd-connection-point-ref"]:
                     # look for interface
@@ -629,15 +629,16 @@ class NsLcm(LcmBase):
             else:
                 raise LcmException("ns_update_vnfr: Not found member_vnf_index={} from VIM info".format(vnf_index))
 
-    @staticmethod
-    def _get_ns_config_info(vca_deployed_list):
+    def _get_ns_config_info(self, nsr_id):
         """
         Generates a mapping between vnf,vdu elements and the N2VC id
-        :param vca_deployed_list: List of database _admin.deploy.VCA that contains this list
+        :param nsr_id: id of nsr to get last  database _admin.deployed.VCA that contains this list
         :return: a dictionary with {osm-config-mapping: {}} where its element contains:
             "<member-vnf-index>": <N2VC-id>  for a vnf configuration, or
             "<member-vnf-index>.<vdu.id>.<vdu replica(0, 1,..)>": <N2VC-id>  for a vdu configuration
         """
+        db_nsr = self.db.get_one("nsrs", {"_id": nsr_id})
+        vca_deployed_list = db_nsr["_admin"]["deployed"]["VCA"]
         mapping = {}
         ns_config_info = {"osm-config-mapping": mapping}
         for vca in vca_deployed_list:
@@ -961,6 +962,33 @@ class NsLcm(LcmBase):
 
         return ip_address
 
+    async def _wait_dependent_n2vc(self, nsr_id, vca_deployed_list, vca_index):
+        """
+        Wait until dependent VCA deployments have been finished. NS wait for VNFs and VDUs. VNFs for VDUs
+        """
+        my_vca = vca_deployed_list[vca_index]
+        if my_vca.get("vdu_id") or my_vca.get("kdu_name"):
+            return
+        timeout = 300
+        while timeout >= 0:
+            for index, vca_deployed in enumerate(vca_deployed_list):
+                if index == vca_index:
+                    continue
+                if not my_vca.get("member-vnf-index") or \
+                        (vca_deployed.get("member-vnf-index") == my_vca.get("member-vnf-index")):
+                    if not vca_deployed.get("instantiation"):
+                        break   # wait
+                    if vca_deployed["instantiation"] == "FAILED":
+                        raise LcmException("Configuration aborted because dependent charm/s has failed")
+            else:
+                return
+            await asyncio.sleep(10)
+            timeout -= 1
+            db_nsr = self.db.get_one("nsrs", {"_id": nsr_id})
+            vca_deployed_list = db_nsr["_admin"]["deployed"]["VCA"]
+
+        raise LcmException("Configuration aborted because dependent charm/s timeout")
+
     async def instantiate_N2VC(self, logging_text, vca_index, nsi_id, db_nsr, db_vnfr, vdu_id,
                                kdu_name, vdu_index, config_descriptor, deploy_params, base_folder):
         nsr_id = db_nsr["_id"]
@@ -972,9 +1000,6 @@ class NsLcm(LcmBase):
             'filter': {'_id': nsr_id},
             'path': db_update_entry
         }
-        logging_text += "member_vnf_index={} vdu_id={}, vdu_index={} ".format(db_vnfr["member-vnf-index-ref"],
-                                                                              vdu_id, vdu_index)
-
         step = ""
         try:
             vnfr_id = None
@@ -1065,15 +1090,18 @@ class NsLcm(LcmBase):
                     step = "Install configuration Software, getting public ssh key"
                     pub_key = await self.n2vc.get_ee_ssh_public__key(ee_id=ee_id, db_dict=db_dict)
 
-                    step = "Insert public key into VM"
+                    step = "Insert public key into VM user={} ssh_key={}".format(user, pub_key)
                 else:
                     step = "Waiting to VM being up and getting IP address"
                 self.logger.debug(logging_text + step)
 
                 # n2vc_redesign STEP 5.1
                 # wait for RO (ip-address) Insert pub_key into VM
-                rw_mgmt_ip = await self.wait_vm_up_insert_key_ro(logging_text, nsr_id, vnfr_id, vdu_id, vdu_index,
-                                                                 user=user, pub_key=pub_key)
+                if vnfr_id:
+                    rw_mgmt_ip = await self.wait_vm_up_insert_key_ro(logging_text, nsr_id, vnfr_id, vdu_id, vdu_index,
+                                                                     user=user, pub_key=pub_key)
+                else:
+                    rw_mgmt_ip = None   # This is for a NS configuration
 
                 self.logger.debug(logging_text + ' VM_ip_address={}'.format(rw_mgmt_ip))
 
@@ -1093,11 +1121,12 @@ class NsLcm(LcmBase):
             # add config if not present for NS charm
             initial_config_primitive_list = self._get_initial_config_primitive_list(initial_config_primitive_list,
                                                                                     vca_deployed)
-
+            if initial_config_primitive_list:
+                await self._wait_dependent_n2vc(nsr_id, vca_deployed_list, vca_index)
             for initial_config_primitive in initial_config_primitive_list:
                 # adding information on the vca_deployed if it is a NS execution environment
                 if not vca_deployed["member-vnf-index"]:
-                    deploy_params["ns_config_info"] = self._get_ns_config_info(vca_deployed_list)
+                    deploy_params["ns_config_info"] = json.dumps(self._get_ns_config_info(nsr_id))
                 # TODO check if already done
                 primitive_params_ = self._map_primitive_params(initial_config_primitive, {}, deploy_params)
 
@@ -1112,9 +1141,11 @@ class NsLcm(LcmBase):
                 # TODO register in database that primitive is done
 
             step = "instantiated at VCA"
+            self.update_db_2("nsrs", nsr_id, {db_update_entry + "instantiation": "COMPLETED"})
             self.logger.debug(logging_text + step)
 
         except Exception as e:  # TODO not use Exception but N2VC exception
+            self.update_db_2("nsrs", nsr_id, {db_update_entry + "instantiation": "FAILED"})
             raise Exception("{} {}".format(step, e)) from e
             # TODO raise N2VC exception with 'step' extra information
 
@@ -1312,7 +1343,7 @@ class NsLcm(LcmBase):
                 descriptor_config = vnfd.get("vnf-configuration")
                 if descriptor_config and descriptor_config.get("juju"):
                     self._deploy_n2vc(
-                        logging_text=logging_text,
+                        logging_text=logging_text + "member_vnf_index={} ".format(member_vnf_index),
                         db_nsr=db_nsr,
                         db_vnfr=db_vnfr,
                         nslcmop_id=nslcmop_id,
@@ -1354,7 +1385,8 @@ class NsLcm(LcmBase):
                         for vdu_index in range(int(vdud.get("count", 1))):
                             # TODO vnfr_params["rw_mgmt_ip"] = vdur["ip-address"]
                             self._deploy_n2vc(
-                                logging_text=logging_text,
+                                logging_text=logging_text + "member_vnf_index={}, vdu_id={}, vdu_index={} ".format(
+                                    member_vnf_index, vdu_id, vdu_index),
                                 db_nsr=db_nsr,
                                 db_vnfr=db_vnfr,
                                 nslcmop_id=nslcmop_id,
@@ -1944,6 +1976,13 @@ class NsLcm(LcmBase):
             # or op_index (operationState != 'COMPLETED')
             return self._reintent_or_skip_suboperation(db_nslcmop, op_index)
 
+    # Function to return execution_environment id
+
+    def _get_ee_id(self, vnf_index, vdu_id, vca_deployed_list):
+        for vca in vca_deployed_list:
+            if vca["member-vnf-index"] == vnf_index and vca["vdu_id"] == vdu_id:
+                return vca["ee_id"]
+
     # Helper methods for terminate()
 
     async def _terminate_action(self, db_nslcmop, nslcmop_id, nsr_id):
@@ -1951,6 +1990,8 @@ class NsLcm(LcmBase):
             Called from terminate() before deleting instance
             Calls action() to execute the primitive """
         logging_text = "Task ns={} _terminate_action={} ".format(nsr_id, nslcmop_id)
+        db_nsr = self.db.get_one("nsrs", {"_id": nsr_id})
+        vca_deployed_list = db_nsr["_admin"]["deployed"]["VCA"]
         db_vnfrs_list = self.db.get_list("vnfrs", {"nsr-id-ref": nsr_id})
         db_vnfds = {}
         # Loop over VNFRs
@@ -2002,8 +2043,7 @@ class NsLcm(LcmBase):
                 #         " primitive={} fails with error {}".format(
                 #             vnf_index, seq.get("name"), result_detail))
 
-                # TODO: find ee_id
-                ee_id = None
+                ee_id = self._get_ee_id(vnf_index, vdu_id, vca_deployed_list)
                 try:
                     await self.n2vc.exec_primitive(
                         ee_id=ee_id,