- nsd = db_nsr["nsd"]
- nsr_name = db_nsr["name"] # TODO short-name??
-
- step = "Getting vnfrs from db"
- db_vnfrs_list = self.db.get_list("vnfrs", {"nsr-id-ref": nsr_id})
- db_vnfds_ref = {}
- db_vnfds = {}
- db_vnfds_index = {}
- for vnfr in db_vnfrs_list:
- db_vnfrs[vnfr["member-vnf-index-ref"]] = vnfr
- vnfd_id = vnfr["vnfd-id"]
- vnfd_ref = vnfr["vnfd-ref"]
- if vnfd_id not in db_vnfds:
- step = "Getting vnfd={} id='{}' from db".format(vnfd_id, vnfd_ref)
- vnfd = self.db.get_one("vnfds", {"_id": vnfd_id})
- db_vnfds_ref[vnfd_ref] = vnfd
- db_vnfds[vnfd_id] = vnfd
- db_vnfds_index[vnfr["member-vnf-index-ref"]] = db_vnfds[vnfd_id]
-
- # Get or generates the _admin.deployed,VCA list
- vca_deployed_list = None
- vca_model_name = None
- if db_nsr["_admin"].get("deployed"):
- vca_deployed_list = db_nsr["_admin"]["deployed"].get("VCA")
- vca_model_name = db_nsr["_admin"]["deployed"].get("VCA-model-name")
- if vca_deployed_list is None:
- vca_deployed_list = []
- db_nsr_update["_admin.deployed.VCA"] = vca_deployed_list
- populate_dict(db_nsr, ("_admin", "deployed", "VCA"), vca_deployed_list)
- elif isinstance(vca_deployed_list, dict):
- # maintain backward compatibility. Change a dict to list at database
- vca_deployed_list = list(vca_deployed_list.values())
- db_nsr_update["_admin.deployed.VCA"] = vca_deployed_list
- populate_dict(db_nsr, ("_admin", "deployed", "VCA"), vca_deployed_list)
-
- db_nsr_update["detailed-status"] = "creating"
- db_nsr_update["operational-status"] = "init"
- if not isinstance(deep_get(db_nsr, ("_admin", "deployed", "RO", "vnfd")), list):
- populate_dict(db_nsr, ("_admin", "deployed", "RO", "vnfd"), [])
- db_nsr_update["_admin.deployed.RO.vnfd"] = []
-
- # set state to INSTANTIATED. When instantiated NBI will not delete directly
- db_nsr_update["_admin.nsState"] = "INSTANTIATED"
- self.update_db_2("nsrs", nsr_id, db_nsr_update)
-
- # Deploy charms
- # The parameters we'll need to deploy a charm
- number_to_configure = 0
-
- def deploy_charm(vnf_index, vdu_id, vdu_name, vdu_count_index, charm_params, n2vc_info, native_charm=False):
- """An inner function to deploy the charm from either ns, vnf or vdu
- For ns both vnf_index and vdu_id are None.
- For vnf only vdu_id is None
- For vdu both vnf_index and vdu_id contain a value
- """
- # if not charm_params.get("rw_mgmt_ip") and vnf_index: # if NS skip mgmt_ip checking
- # raise LcmException("ns/vnfd/vdu has not management ip address to configure it")
-
- machine_spec = {}
- if native_charm:
- machine_spec["username"] = charm_params.get("username")
- machine_spec["hostname"] = charm_params.get("rw_mgmt_ip")
-
- # Note: The charm needs to exist on disk at the location
- # specified by charm_path.
- descriptor = vnfd if vnf_index else nsd
- base_folder = descriptor["_admin"]["storage"]
- storage_params = self.fs.get_params()
- charm_path = "{}{}/{}/charms/{}".format(
- storage_params["path"],
- base_folder["folder"],
- base_folder["pkg-dir"],
- proxy_charm
- )
-
- # ns_name will be ignored in the current version of N2VC
- # but will be implemented for the next point release.
- model_name = nsr_id
- vdu_id_text = (str(vdu_id) if vdu_id else "") + "-"
- vnf_index_text = (str(vnf_index) if vnf_index else "") + "-"
- application_name = self.n2vc.FormatApplicationName(nsr_name, vnf_index_text, vdu_id_text)
-
- vca_index = len(vca_deployed_list)
- # trunk name and add two char index at the end to ensure that it is unique. It is assumed no more than
- # 26*26 charm in the same NS
- application_name = application_name[0:48]
- application_name += chr(97 + vca_index // 26) + chr(97 + vca_index % 26)
- vca_deployed_ = {
- "member-vnf-index": vnf_index,
- "vdu_id": vdu_id,
- "model": model_name,
- "application": application_name,
- "operational-status": "init",
- "detailed-status": "",
- "step": "initial-deploy",
- "vnfd_id": vnfd_id,
- "vdu_name": vdu_name,
- "vdu_count_index": vdu_count_index,
- }
- vca_deployed_list.append(vca_deployed_)
- db_nsr_update["_admin.deployed.VCA.{}".format(vca_index)] = vca_deployed_
- self.update_db_2("nsrs", nsr_id, db_nsr_update)
-
- self.logger.debug("Task create_ns={} Passing artifacts path '{}' for {}".format(nsr_id, charm_path,
- proxy_charm))
- if not n2vc_info:
- n2vc_info["nsr_id"] = nsr_id
- n2vc_info["nslcmop_id"] = nslcmop_id
- n2vc_info["n2vc_event"] = asyncio.Event(loop=self.loop)
- n2vc_info["lcmOperationType"] = "instantiate"
- n2vc_info["deployed"] = vca_deployed_list
- n2vc_info["db_update"] = db_nsr_update
- task = asyncio.ensure_future(
- self.n2vc.DeployCharms(
- model_name, # The network service name
- application_name, # The application name
- descriptor, # The vnf/nsd descriptor
- charm_path, # Path to charm
- charm_params, # Runtime params, like mgmt ip
- machine_spec, # for native charms only
- self.n2vc_callback, # Callback for status changes
- n2vc_info, # Callback parameter
- None, # Callback parameter (task)
- )
- )
- task.add_done_callback(functools.partial(self.n2vc_callback, model_name, application_name, None, None,
- n2vc_info))
- self.lcm_tasks.register("ns", nsr_id, nslcmop_id, "create_charm:" + application_name, task)
-
- step = "Looking for needed vnfd to configure with proxy charm"
- self.logger.debug(logging_text + step)
-
- for c_vnf in get_iterable(nsd, "constituent-vnfd"):
- vnfd_id = c_vnf["vnfd-id-ref"]
- vnf_index = str(c_vnf["member-vnf-index"])
- vnfd = db_vnfds_ref[vnfd_id]
-
- # Get additional parameters
- vnfr_params = {}
- if db_vnfrs[vnf_index].get("additionalParamsForVnf"):
- vnfr_params = db_vnfrs[vnf_index]["additionalParamsForVnf"].copy()
- for k, v in vnfr_params.items():
- if isinstance(v, str) and v.startswith("!!yaml "):
- vnfr_params[k] = yaml.safe_load(v[7:])
-
- step = "deploying proxy charms for configuration"
- # Check if this VNF has a charm configuration
- vnf_config = vnfd.get("vnf-configuration")
- if vnf_config and vnf_config.get("juju"):
- proxy_charm = vnf_config["juju"]["charm"]
- if vnf_config["juju"].get("proxy") is False:
- # native_charm, will be deployed after VM. Skip
- proxy_charm = None
-
- if proxy_charm:
- if not vca_model_name:
- step = "creating VCA model name '{}'".format(nsr_id)
- self.logger.debug(logging_text + step)
- await self.n2vc.CreateNetworkService(nsr_id)
- vca_model_name = nsr_id
- db_nsr_update["_admin.deployed.VCA-model-name"] = nsr_id
- self.update_db_2("nsrs", nsr_id, db_nsr_update)
- step = "deploying proxy charm to configure vnf {}".format(vnf_index)
- vnfr_params["rw_mgmt_ip"] = db_vnfrs[vnf_index]["ip-address"]
- charm_params = {
- "user_values": vnfr_params,
- "rw_mgmt_ip": db_vnfrs[vnf_index]["ip-address"],
- "initial-config-primitive": {} # vnf_config.get('initial-config-primitive') or {}
- }
-
- # Login to the VCA. If there are multiple calls to login(),
- # subsequent calls will be a nop and return immediately.
- await self.n2vc.login()
-
- deploy_charm(vnf_index, None, None, None, charm_params, n2vc_info)
- number_to_configure += 1
-
- # Deploy charms for each VDU that supports one.
- for vdu_index, vdu in enumerate(get_iterable(vnfd, 'vdu')):
- vdu_config = vdu.get('vdu-configuration')
- proxy_charm = None
-
- if vdu_config and vdu_config.get("juju"):
- proxy_charm = vdu_config["juju"]["charm"]
- if vdu_config["juju"].get("proxy") is False:
- # native_charm, will be deployed after VM. Skip
- proxy_charm = None
- if proxy_charm:
- if not vca_model_name:
- step = "creating VCA model name"
- await self.n2vc.CreateNetworkService(nsr_id)
- vca_model_name = nsr_id
- db_nsr_update["_admin.deployed.VCA-model-name"] = nsr_id
- self.update_db_2("nsrs", nsr_id, db_nsr_update)
- step = "deploying proxy charm to configure member_vnf_index={} vdu={}".format(vnf_index,
- vdu["id"])
- await self.n2vc.login()
- vdur = db_vnfrs[vnf_index]["vdur"][vdu_index]
- # TODO for the moment only first vdu_id contains a charm deployed
- if vdur["vdu-id-ref"] != vdu["id"]:
- raise LcmException("Mismatch vdur {}, vdu {} at index {} for member_vnf_index={}"
- .format(vdur["vdu-id-ref"], vdu["id"], vdu_index, vnf_index))
- vnfr_params["rw_mgmt_ip"] = vdur["ip-address"]
- charm_params = {
- "user_values": vnfr_params,
- "rw_mgmt_ip": vdur["ip-address"],
- "initial-config-primitive": {} # vdu_config.get('initial-config-primitive') or {}
- }
- deploy_charm(vnf_index, vdu["id"], vdur.get("name"), vdur["count-index"],
- charm_params, n2vc_info)
- number_to_configure += 1
-
- # Check if this NS has a charm configuration
-
- ns_config = nsd.get("ns-configuration")
- if ns_config and ns_config.get("juju"):
- proxy_charm = ns_config["juju"]["charm"]
- if ns_config["juju"].get("proxy") is False:
- # native_charm, will be deployed after VM. Skip
- proxy_charm = None
- if proxy_charm:
- step = "deploying proxy charm to configure ns"
- # TODO is NS magmt IP address needed?
-
- # Get additional parameters
- additional_params = {}
- if db_nsr.get("additionalParamsForNs"):
- additional_params = db_nsr["additionalParamsForNs"].copy()
- for k, v in additional_params.items():
- if isinstance(v, str) and v.startswith("!!yaml "):
- additional_params[k] = yaml.safe_load(v[7:])
-
- # additional_params["rw_mgmt_ip"] = db_nsr["ip-address"]
- charm_params = {
- "user_values": additional_params,
- # "rw_mgmt_ip": db_nsr["ip-address"],
- "initial-config-primitive": {} # ns_config.get('initial-config-primitive') or {}
- }
-
- # Login to the VCA. If there are multiple calls to login(),
- # subsequent calls will be a nop and return immediately.
- await self.n2vc.login()
- deploy_charm(None, None, None, None, charm_params, n2vc_info)
- number_to_configure += 1
-
- db_nsr_update["operational-status"] = "running"
-
- # Wait until all charms has reached blocked or active status
- step = "waiting proxy charms to be ready"
- if number_to_configure:
- # wait until all charms are configured.
- # steps are:
- # initial-deploy
- # get-ssh-public-key
- # generate-ssh-key
- # retry-get-ssh-public-key
- # ssh-public-key-obtained
- while time() <= start_deploy + self.total_deploy_timeout:
- if db_nsr_update:
- self.update_db_2("nsrs", nsr_id, db_nsr_update)
- if db_nslcmop_update:
- self.update_db_2("nslcmops", nslcmop_id, db_nslcmop_update)
-
- all_active = True
- for vca_index, vca_deployed in enumerate(vca_deployed_list):
- database_entry = "_admin.deployed.VCA.{}.".format(vca_index)
- if vca_deployed["step"] == "initial-deploy":
- if vca_deployed["operational-status"] in ("active", "blocked"):
- step = "execute charm primitive get-ssh-public-key for member_vnf_index={} vdu_id={}" \
- .format(vca_deployed["member-vnf-index"],
- vca_deployed["vdu_id"])
- self.logger.debug(logging_text + step)
- try:
- primitive_id = await self.n2vc.ExecutePrimitive(
- vca_deployed["model"],
- vca_deployed["application"],
- "get-ssh-public-key",
- None,
- )
- vca_deployed["step"] = db_nsr_update[database_entry + "step"] = "get-ssh-public-key"
- vca_deployed["primitive_id"] = db_nsr_update[database_entry + "primitive_id"] =\
- primitive_id
- db_nsr_update[database_entry + "operational-status"] =\
- vca_deployed["operational-status"]
- except PrimitiveDoesNotExist:
- ssh_public_key = None
- vca_deployed["step"] = db_nsr_update[database_entry + "step"] =\
- "ssh-public-key-obtained"
- vca_deployed["ssh-public-key"] = db_nsr_update[database_entry + "ssh-public-key"] =\
- ssh_public_key
- step = "charm ssh-public-key for member_vnf_index={} vdu_id={} not needed".format(
- vca_deployed["member-vnf-index"], vca_deployed["vdu_id"])
- self.logger.debug(logging_text + step)
-
- elif vca_deployed["step"] in ("get-ssh-public-key", "retry-get-ssh-public-key"):
- primitive_id = vca_deployed["primitive_id"]
- primitive_status = await self.n2vc.GetPrimitiveStatus(vca_deployed["model"],
- primitive_id)
- if primitive_status in ("completed", "failed"):
- primitive_result = await self.n2vc.GetPrimitiveOutput(vca_deployed["model"],
- primitive_id)
- vca_deployed["primitive_id"] = db_nsr_update[database_entry + "primitive_id"] = None
- if primitive_status == "completed" and isinstance(primitive_result, dict) and \
- primitive_result.get("pubkey"):
- ssh_public_key = primitive_result.get("pubkey")
- vca_deployed["step"] = db_nsr_update[database_entry + "step"] =\
- "ssh-public-key-obtained"
- vca_deployed["ssh-public-key"] = db_nsr_update[database_entry + "ssh-public-key"] =\
- ssh_public_key
- n2vc_key_list.append(ssh_public_key)
- step = "charm ssh-public-key for member_vnf_index={} vdu_id={} is '{}'".format(
- vca_deployed["member-vnf-index"], vca_deployed["vdu_id"], ssh_public_key)
- self.logger.debug(logging_text + step)
- else: # primitive_status == "failed":
- if vca_deployed["step"] == "get-ssh-public-key":
- step = "execute charm primitive generate-ssh-public-key for member_vnf_index="\
- "{} vdu_id={}".format(vca_deployed["member-vnf-index"],
- vca_deployed["vdu_id"])
- self.logger.debug(logging_text + step)
- vca_deployed["step"] = db_nsr_update[database_entry + "step"] =\
- "generate-ssh-key"
- primitive_id = await self.n2vc.ExecutePrimitive(
- vca_deployed["model"],
- vca_deployed["application"],
- "generate-ssh-key",
- None,
- )
- vca_deployed["primitive_id"] = db_nsr_update[database_entry + "primitive_id"] =\
- primitive_id
- else: # failed for second time
- raise LcmException(
- "error executing primitive get-ssh-public-key: {}".format(primitive_result))
-
- elif vca_deployed["step"] == "generate-ssh-key":
- primitive_id = vca_deployed["primitive_id"]
- primitive_status = await self.n2vc.GetPrimitiveStatus(vca_deployed["model"],
- primitive_id)
- if primitive_status in ("completed", "failed"):
- primitive_result = await self.n2vc.GetPrimitiveOutput(vca_deployed["model"],
- primitive_id)
- vca_deployed["primitive_id"] = db_nsr_update[
- database_entry + "primitive_id"] = None
- if primitive_status == "completed":
- step = "execute primitive get-ssh-public-key again for member_vnf_index={} "\
- "vdu_id={}".format(vca_deployed["member-vnf-index"],
- vca_deployed["vdu_id"])
- self.logger.debug(logging_text + step)
- vca_deployed["step"] = db_nsr_update[database_entry + "step"] = \
- "retry-get-ssh-public-key"
- primitive_id = await self.n2vc.ExecutePrimitive(
- vca_deployed["model"],
- vca_deployed["application"],
- "get-ssh-public-key",
- None,
- )
- vca_deployed["primitive_id"] = db_nsr_update[database_entry + "primitive_id"] =\
- primitive_id
-
- else: # primitive_status == "failed":
- raise LcmException("error executing primitive generate-ssh-key: {}"
- .format(primitive_result))
-
- if vca_deployed["step"] != "ssh-public-key-obtained":
- all_active = False
-
- if all_active: