X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=osm_lcm%2Fns.py;h=c4488230f286bf1dcdb735bb0adec73e015c0f2b;hb=a508819e00e382aca98e2ead4e8aad9cf6b8b950;hp=5ca6354c6f78c78b85de83c29750b05070d37a04;hpb=9f9c6f2e8b8e978deaa4fb6e1482c0656ce4bd45;p=osm%2FLCM.git diff --git a/osm_lcm/ns.py b/osm_lcm/ns.py index 5ca6354..c448823 100644 --- a/osm_lcm/ns.py +++ b/osm_lcm/ns.py @@ -383,6 +383,11 @@ class NsLcm(LcmBase): populate_dict(RO_ns_params, ("vnfs", vnf_params["member-vnf-index"], "networks", internal_vld_params["name"], "ip-profile"), ip_profile_2_RO(internal_vld_params["ip-profile"])) + if internal_vld_params.get("provider-network"): + + populate_dict(RO_ns_params, ("vnfs", vnf_params["member-vnf-index"], "networks", + internal_vld_params["name"], "provider-network"), + internal_vld_params["provider-network"].copy()) for icp_params in get_iterable(internal_vld_params, "internal-connection-point"): # look for interface @@ -416,6 +421,11 @@ class NsLcm(LcmBase): populate_dict(RO_ns_params, ("networks", vld_params["name"], "ip-profile"), ip_profile_2_RO(vld_params["ip-profile"])) + if vld_params.get("provider-network"): + + populate_dict(RO_ns_params, ("networks", vld_params["name"], "provider-network"), + vld_params["provider-network"].copy()) + if "wimAccountId" in vld_params and vld_params["wimAccountId"] is not None: populate_dict(RO_ns_params, ("networks", vld_params["name"], "wim_account"), wim_account_2_RO(vld_params["wimAccountId"])), @@ -431,6 +441,7 @@ class NsLcm(LcmBase): RO_vld_sites.append({"netmap-use": vld_params["vim-network-name"]}) if RO_vld_sites: populate_dict(RO_ns_params, ("networks", vld_params["name"], "sites"), RO_vld_sites) + if vld_params.get("vim-network-id"): RO_vld_sites = [] if isinstance(vld_params["vim-network-id"], dict): @@ -621,6 +632,57 @@ 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): + """ + 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 + :return: a dictionary with {osm-config-mapping: {}} where its element contains: + "": for a vnf configuration, or + "..": for a vdu configuration + """ + mapping = {} + ns_config_info = {"osm-config-mapping": mapping} + for vca in vca_deployed_list: + if not vca["member-vnf-index"]: + continue + if not vca["vdu_id"]: + mapping[vca["member-vnf-index"]] = vca["application"] + else: + mapping["{}.{}.{}".format(vca["member-vnf-index"], vca["vdu_id"], vca["vdu_count_index"])] =\ + vca["application"] + return ns_config_info + + @staticmethod + def _get_initial_config_primitive_list(desc_primitive_list, vca_deployed): + """ + Generates a list of initial-config-primitive based on the list provided by the descriptor. It includes internal + primitives as verify-ssh-credentials, or config when needed + :param desc_primitive_list: information of the descriptor + :param vca_deployed: information of the deployed, needed for known if it is related to an NS, VNF, VDU and if + this element contains a ssh public key + :return: The modified list. Can ba an empty list, but always a list + """ + if desc_primitive_list: + primitive_list = desc_primitive_list.copy() + else: + primitive_list = [] + # look for primitive config, and get the position. None if not present + config_position = None + for index, primitive in enumerate(primitive_list): + if primitive["name"] == "config": + config_position = index + break + + # for NS, add always a config primitive if not present (bug 874) + if not vca_deployed["member-vnf-index"] and config_position is None: + primitive_list.insert(0, {"name": "config", "parameter": []}) + config_position = 0 + # for VNF/VDU add verify-ssh-credentials after config + if vca_deployed["member-vnf-index"] and config_position is not None and vca_deployed.get("ssh-public-key"): + primitive_list.insert(config_position + 1, {"name": "verify-ssh-credentials", "parameter": []}) + return primitive_list + async def instantiate_RO(self, logging_text, nsr_id, nsd, db_nsr, db_nslcmop, db_vnfrs, db_vnfds_ref, n2vc_key_list): @@ -805,12 +867,20 @@ class NsLcm(LcmBase): step = "Deployed at VIM" self.logger.debug(logging_text + step) - # wait for ip addres at RO, and optionally, insert public key in virtual machine - # returns IP address - async def insert_key_ro(self, logging_text, nsr_id, vnfr_id, vdu_id, vdu_index, pub_key=None, user=None): - - self.logger.debug(logging_text + "Starting insert_key_ro") + async def wait_vm_up_insert_key_ro(self, logging_text, nsr_id, vnfr_id, vdu_id, vdu_index, pub_key=None, user=None): + """ + Wait for ip addres at RO, and optionally, insert public key in virtual machine + :param logging_text: prefix use for logging + :param nsr_id: + :param vnfr_id: + :param vdu_id: + :param vdu_index: + :param pub_key: public ssh key to inject, None to skip + :param user: user to apply the public ssh key + :return: IP address + """ + # self.logger.debug(logging_text + "Starting wait_vm_up_insert_key_ro") ro_nsr_id = None ip_address = None nb_tries = 0 @@ -849,11 +919,11 @@ class NsLcm(LcmBase): if not target_vdu_id: continue - self.logger.debug(logging_text + "IP address={}".format(ip_address)) + # self.logger.debug(logging_text + "IP address={}".format(ip_address)) # inject public key into machine if pub_key and user: - self.logger.debug(logging_text + "Inserting RO key") + # self.logger.debug(logging_text + "Inserting RO key") try: ro_vm_id = "{}-{}".format(db_vnfr["member-vnf-index-ref"], target_vdu_id) # TODO add vdu_index result_dict = await self.RO.create_action( @@ -872,10 +942,12 @@ class NsLcm(LcmBase): result.get("description"))) break except ROclient.ROClientException as e: + if not nb_tries: + self.logger.debug(logging_text + "error injecting key: {}. Retrying until {} seconds". + format(e, 20*10)) nb_tries += 1 - if nb_tries >= 10: + if nb_tries >= 20: raise LcmException("Reaching max tries injecting key. Error: {}".format(e)) - self.logger.debug(logging_text + "error injecting key: {}".format(e)) else: break @@ -885,16 +957,15 @@ class NsLcm(LcmBase): kdu_name, vdu_index, config_descriptor, deploy_params, base_folder): nsr_id = db_nsr["_id"] db_update_entry = "_admin.deployed.VCA.{}.".format(vca_index) + vca_deployed_list = db_nsr["_admin"]["deployed"]["VCA"] vca_deployed = db_nsr["_admin"]["deployed"]["VCA"][vca_index] db_dict = { 'collection': 'nsrs', '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) + logging_text += "member_vnf_index={} vdu_id={}, vdu_index={} ".format(db_vnfr["member-vnf-index-ref"], + vdu_id, vdu_index) step = "" try: @@ -937,7 +1008,7 @@ class NsLcm(LcmBase): ) else: - step = "register execution envioronment" + step = "register execution environment" # TODO wait until deployed by RO, when IP address has been filled. By pooling???? credentials = {} # TODO db_credentials["ip_address"] # get username @@ -981,22 +1052,24 @@ class NsLcm(LcmBase): # if SSH access is required, then get execution environment SSH public required = deep_get(config_descriptor, ("config-access", "ssh-access", "required")) + pub_key = None + user = None if is_proxy_charm and required: - - pub_key = None + user = deep_get(config_descriptor, ("config-access", "ssh-access", "default-user")) + 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 ) - user = deep_get(config_descriptor, ("config-access", "ssh-access", "default-user")) - # insert pub_key into VM - # n2vc_redesign STEP 5.1 step = "Insert public key into VM" - self.logger.debug(logging_text + step) + else: + step = "Waiting to VM being up and getting IP address" + self.logger.debug(logging_text + step) - # wait for RO (ip-address) - rw_mgmt_ip = await self.insert_key_ro( + # 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=logging_text, nsr_id=nsr_id, vnfr_id=vnfr_id, @@ -1005,22 +1078,29 @@ class NsLcm(LcmBase): user=user, pub_key=pub_key ) + self.logger.debug(logging_text + ' VM_ip_address={}'.format(rw_mgmt_ip)) - # store rw_mgmt_ip in deploy params for later substitution - self.logger.debug('rw_mgmt_ip={}'.format(rw_mgmt_ip)) + # store rw_mgmt_ip in deploy params for later replacement deploy_params["rw_mgmt_ip"] = rw_mgmt_ip # n2vc_redesign STEP 6 Execute initial config primitive - initial_config_primitive_list = config_descriptor.get('initial-config-primitive', []) step = 'execute initial config primitive' + initial_config_primitive_list = config_descriptor.get('initial-config-primitive') # sort initial config primitives by 'seq' try: initial_config_primitive_list.sort(key=lambda val: int(val['seq'])) - except Exception: - self.logger.warn(logging_text + 'Cannot sort by "seq" field' + step) + except Exception as e: + self.logger.error(logging_text + step + ": " + str(e)) + + # add config if not present for NS charm + initial_config_primitive_list = self._get_initial_config_primitive_list(initial_config_primitive_list, + vca_deployed) 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) # TODO check if already done primitive_params_ = self._map_primitive_params(initial_config_primitive, {}, deploy_params) step = "execute primitive '{}' params '{}'".format(initial_config_primitive["name"], primitive_params_) @@ -1077,13 +1157,11 @@ class NsLcm(LcmBase): nslcmop_operation_state = None db_vnfrs = {} # vnf's info indexed by member-index # n2vc_info = {} - # n2vc_key_list = [] # list of public keys to be injected as authorized to VMs task_instantiation_list = [] exc = None try: # wait for any previous tasks in process - step = "Waiting for previous tasks" - self.logger.debug(logging_text + step) + step = "Waiting for previous operations to terminate" await self.lcm_tasks.waitfor_related_HA('ns', 'nslcmops', nslcmop_id) # STEP 0: Reading database (nslcmops, nsrs, nsds, vnfrs, vnfds) @@ -1171,6 +1249,9 @@ class NsLcm(LcmBase): # n2vc_redesign STEP 1 Get VCA public ssh-key # feature 1429. Add n2vc public key to needed VMs n2vc_key = await self.n2vc.get_public_key() + n2vc_key_list = [n2vc_key] + if self.vca_config.get("public_key"): + n2vc_key_list.append(self.vca_config["public_key"]) # n2vc_redesign STEP 2 Deploy Network Scenario task_ro = asyncio.ensure_future( @@ -1182,7 +1263,7 @@ class NsLcm(LcmBase): db_nslcmop=db_nslcmop, db_vnfrs=db_vnfrs, db_vnfds_ref=db_vnfds_ref, - n2vc_key_list=[n2vc_key] + n2vc_key_list=n2vc_key_list ) ) self.lcm_tasks.register("ns", nsr_id, nslcmop_id, "instantiate_RO", task_ro) @@ -1315,6 +1396,7 @@ class NsLcm(LcmBase): kdu_name = None vdu_index = 0 vdu_name = None + # Get additional parameters deploy_params = {} if db_nsr.get("additionalParamsForNs"): @@ -1483,9 +1565,9 @@ class NsLcm(LcmBase): db_dict = {"collection": "nsrs", "filter": {"_id": nsr_id}, "path": "_admin.deployed.K8s." "{}".format(index)} if k8sclustertype == "chart": - task = self.k8sclusterhelm.install(cluster_uuid=cluster_uuid, - kdu_model=kdumodel, atomic=True, params=desc_params, - db_dict=db_dict, timeout=300) + task = self.k8sclusterhelm.install(cluster_uuid=cluster_uuid, kdu_model=kdumodel, + atomic=True, params=desc_params, + db_dict=db_dict, timeout=300) else: # TODO I need the juju connector in place pass @@ -1516,6 +1598,7 @@ class NsLcm(LcmBase): # TODO Write in data base if db_nsr_update: self.update_db_2("nsrs", nsr_id, db_nsr_update) + def _deploy_n2vc(self, logging_text, db_nsr, db_vnfr, nslcmop_id, nsr_id, nsi_id, vnfd_id, vdu_id, kdu_name, member_vnf_index, vdu_index, vdu_name, deploy_params, descriptor_config, base_folder, task_instantiation_list): @@ -1883,6 +1966,7 @@ class NsLcm(LcmBase): pending_tasks = [] try: # wait for any previous tasks in process + step = "Waiting for previous operations to terminate" await self.lcm_tasks.waitfor_related_HA("ns", 'nslcmops', nslcmop_id) step = "Getting nslcmop={} from db".format(nslcmop_id) @@ -2153,6 +2237,11 @@ class NsLcm(LcmBase): width=256) elif isinstance(calculated_params[param_name], str) and calculated_params[param_name].startswith("!!yaml "): calculated_params[param_name] = calculated_params[param_name][7:] + + # add always ns_config_info if primitive name is config + if primitive_desc["name"] == "config": + if "ns_config_info" in instantiation_params: + calculated_params["ns_config_info"] = instantiation_params["ns_config_info"] return calculated_params async def _ns_execute_primitive(self, db_deployed, member_vnf_index, vdu_id, vdu_name, vdu_count_index, @@ -2230,6 +2319,7 @@ class NsLcm(LcmBase): exc = None try: # wait for any previous tasks in process + step = "Waiting for previous operations to terminate" await self.lcm_tasks.waitfor_related_HA('ns', 'nslcmops', nslcmop_id) step = "Getting information from database" @@ -2301,9 +2391,10 @@ class NsLcm(LcmBase): if kdu.get("k8scluster-type") == "chart": output = await self.k8sclusterhelm.upgrade(cluster_uuid=kdu.get("k8scluster-uuid"), - kdu_instance=kdu.get("kdu-instance"), - atomic=True, kdu_model=kdu_model, - params=desc_params, db_dict=db_dict, timeout=300) + kdu_instance=kdu.get("kdu-instance"), + atomic=True, kdu_model=kdu_model, + params=desc_params, db_dict=db_dict, + timeout=300) elif kdu.get("k8scluster-type") == "juju": # TODO Juju connector needed pass @@ -2458,6 +2549,7 @@ class NsLcm(LcmBase): vnfr_scaled = False try: # wait for any previous tasks in process + step = "Waiting for previous operations to terminate" await self.lcm_tasks.waitfor_related_HA('ns', 'nslcmops', nslcmop_id) step = "Getting nslcmop from database" @@ -2477,9 +2569,9 @@ class NsLcm(LcmBase): ####### nsr_deployed = db_nsr["_admin"].get("deployed") vnf_index = db_nslcmop["operationParams"].get("member_vnf_index") - vdu_id = db_nslcmop["operationParams"].get("vdu_id") - vdu_count_index = db_nslcmop["operationParams"].get("vdu_count_index") - vdu_name = db_nslcmop["operationParams"].get("vdu_name") + # vdu_id = db_nslcmop["operationParams"].get("vdu_id") + # vdu_count_index = db_nslcmop["operationParams"].get("vdu_count_index") + # vdu_name = db_nslcmop["operationParams"].get("vdu_name") ####### RO_nsr_id = nsr_deployed["RO"]["nsr_id"]