+ ns["ssh_keys"] = []
+ for pubkeyfile in ssh_keys.split(","):
+ with open(pubkeyfile, "r") as f:
+ ns["ssh_keys"].append(f.read())
+ if timeout:
+ ns["timeout_ns_deploy"] = timeout
+ if config:
+ ns_config = yaml.safe_load(config)
+ if "vim-network-name" in ns_config:
+ ns_config["vld"] = ns_config.pop("vim-network-name")
+ if "vld" in ns_config:
+ if not isinstance(ns_config["vld"], list):
+ raise ClientException(
+ "Error at --config 'vld' must be a list of dictionaries"
+ )
+ for vld in ns_config["vld"]:
+ if not isinstance(vld, dict):
+ raise ClientException(
+ "Error at --config 'vld' must be a list of dictionaries"
+ )
+ if vld.get("vim-network-name"):
+ if isinstance(vld["vim-network-name"], dict):
+ vim_network_name_dict = {}
+ for vim_account, vim_net in vld["vim-network-name"].items():
+ vim_network_name_dict[
+ get_vim_account_id(vim_account)
+ ] = vim_net
+ vld["vim-network-name"] = vim_network_name_dict
+ if "wim_account" in vld and vld["wim_account"] is not None:
+ vld["wimAccountId"] = get_wim_account_id(vld.pop("wim_account"))
+ if "vnf" in ns_config:
+ for vnf in ns_config["vnf"]:
+ if vnf.get("vim_account"):
+ vnf["vimAccountId"] = get_vim_account_id(vnf.pop("vim_account"))
+
+ if "additionalParamsForNs" in ns_config:
+ if not isinstance(ns_config["additionalParamsForNs"], dict):
+ raise ClientException(
+ "Error at --config 'additionalParamsForNs' must be a dictionary"
+ )
+ if "additionalParamsForVnf" in ns_config:
+ if not isinstance(ns_config["additionalParamsForVnf"], list):
+ raise ClientException(
+ "Error at --config 'additionalParamsForVnf' must be a list"
+ )
+ for additional_param_vnf in ns_config["additionalParamsForVnf"]:
+ if not isinstance(additional_param_vnf, dict):
+ raise ClientException(
+ "Error at --config 'additionalParamsForVnf' items must be dictionaries"
+ )
+ if not additional_param_vnf.get("member-vnf-index"):
+ raise ClientException(
+ "Error at --config 'additionalParamsForVnf' items must contain "
+ "'member-vnf-index'"
+ )
+ if "wim_account" in ns_config:
+ wim_account = ns_config.pop("wim_account")
+ if wim_account is not None:
+ ns["wimAccountId"] = get_wim_account_id(wim_account)
+ # rest of parameters without any transformation or checking
+ # "timeout_ns_deploy"
+ # "placement-engine"
+ ns.update(ns_config)
+
+ # print(yaml.safe_dump(ns))
+ try:
+ self._apiResource = "/ns_instances_content"
+ self._apiBase = "{}{}{}".format(
+ self._apiName, self._apiVersion, self._apiResource
+ )
+ headers = self._client._headers
+ headers["Content-Type"] = "application/yaml"
+ self._http.set_http_header(headers)
+ http_code, resp = self._http.post_cmd(
+ endpoint=self._apiBase, postfields_dict=ns
+ )
+ # print('HTTP CODE: {}'.format(http_code))
+ # print('RESP: {}'.format(resp))
+ # if http_code in (200, 201, 202, 204):
+ if resp:
+ resp = json.loads(resp)
+ if not resp or "id" not in resp:
+ raise ClientException(
+ "unexpected response from server - {} ".format(resp)
+ )
+ if wait:
+ # Wait for status for NS instance creation
+ self._wait(resp.get("nslcmop_id"), wait)
+ print(resp["id"])
+ return resp["id"]
+ # else:
+ # msg = ""
+ # if resp:
+ # try:
+ # msg = json.loads(resp)
+ # except ValueError:
+ # msg = resp
+ # raise ClientException(msg)
+ except ClientException as exc:
+ message = "failed to create ns: {} nsd: {}\nerror:\n{}".format(
+ nsr_name, nsd_name, str(exc)
+ )
+ raise ClientException(message)
+
+ def list_op(self, name, filter=None):
+ """Returns the list of operations of a NS"""
+ self._logger.debug("")
+ ns = self.get(name)
+ try:
+ self._apiResource = "/ns_lcm_op_occs"
+ self._apiBase = "{}{}{}".format(
+ self._apiName, self._apiVersion, self._apiResource
+ )
+ filter_string = ""
+ if filter:
+ filter_string = "&{}".format(filter)
+ http_code, resp = self._http.get2_cmd(
+ "{}?nsInstanceId={}{}".format(self._apiBase, ns["_id"], filter_string)
+ )
+ # print('HTTP CODE: {}'.format(http_code))
+ # print('RESP: {}'.format(resp))
+ if http_code == 200:
+ if resp:
+ resp = json.loads(resp)
+ return resp
+ else:
+ raise ClientException("unexpected response from server")
+ else:
+ msg = resp or ""
+ # if resp:
+ # try:
+ # resp = json.loads(resp)
+ # msg = resp['detail']
+ # except ValueError:
+ # msg = resp
+ raise ClientException(msg)
+ except ClientException as exc:
+ message = "failed to get operation list of NS {}:\nerror:\n{}".format(
+ name, str(exc)
+ )
+ raise ClientException(message)
+
+ def get_op(self, operationId):
+ """Returns the status of an operation"""
+ self._logger.debug("")
+ self._client.get_token()
+ try:
+ self._apiResource = "/ns_lcm_op_occs"
+ self._apiBase = "{}{}{}".format(
+ self._apiName, self._apiVersion, self._apiResource
+ )
+ http_code, resp = self._http.get2_cmd(
+ "{}/{}".format(self._apiBase, operationId)
+ )
+ # print('HTTP CODE: {}'.format(http_code))
+ # print('RESP: {}'.format(resp))
+ if http_code == 200:
+ if resp:
+ resp = json.loads(resp)
+ return resp
+ else:
+ raise ClientException("unexpected response from server")
+ else:
+ msg = resp or ""
+ # if resp:
+ # try:
+ # resp = json.loads(resp)
+ # msg = resp['detail']
+ # except ValueError:
+ # msg = resp
+ raise ClientException(msg)
+ except ClientException as exc:
+ message = "failed to get status of operation {}:\nerror:\n{}".format(
+ operationId, str(exc)
+ )
+ raise ClientException(message)
+
+ def exec_op(
+ self,
+ name,
+ op_name,
+ op_data=None,
+ wait=False,
+ ):
+ """Executes an operation on a NS"""
+ self._logger.debug("")
+ ns = self.get(name)
+ try:
+ ns = self.get(name)
+ self._apiResource = "/ns_instances"
+ self._apiBase = "{}{}{}".format(
+ self._apiName, self._apiVersion, self._apiResource
+ )
+ endpoint = "{}/{}/{}".format(self._apiBase, ns["_id"], op_name)
+ # print('OP_NAME: {}'.format(op_name))
+ # print('OP_DATA: {}'.format(json.dumps(op_data)))
+ http_code, resp = self._http.post_cmd(
+ endpoint=endpoint, postfields_dict=op_data
+ )
+ # print('HTTP CODE: {}'.format(http_code))
+ # print('RESP: {}'.format(resp))
+ # if http_code in (200, 201, 202, 204):
+ if resp:
+ resp = json.loads(resp)
+ if not resp or "id" not in resp:
+ raise ClientException(
+ "unexpected response from server - {}".format(resp)
+ )
+ if wait:
+ # Wait for status for NS instance action
+ # For the 'action' operation, 'id' is used
+ self._wait(resp.get("id"), wait)
+ return resp["id"]
+ # else:
+ # msg = ""
+ # if resp:
+ # try:
+ # msg = json.loads(resp)
+ # except ValueError:
+ # msg = resp
+ # raise ClientException(msg)
+ except ClientException as exc:
+ message = "failed to exec operation {}:\nerror:\n{}".format(name, str(exc))
+ raise ClientException(message)
+
+ def cancel_op(self, operation_id, cancel_mode, wait=False):
+ """Cancels an LCM operation"""
+ self._client.get_token()
+ self._apiResource = "/ns_lcm_op_occs"
+ self._apiBase = "{}{}{}".format(
+ self._apiName, self._apiVersion, self._apiResource
+ )
+ endpoint = "{}/{}/cancel".format(self._apiBase, operation_id)
+ op_data = {"cancelMode": cancel_mode}
+ try:
+ http_code, resp = self._http.post_cmd(
+ endpoint=endpoint, postfields_dict=op_data
+ )
+ if http_code == 202:
+ if wait:
+ self._wait(operation_id, wait, deleteFlag=True, entity="OPCANCEL")
+ else:
+ print("Cancellation in progress")
+ else:
+ msg = resp or ""
+ raise ClientException(msg)
+ except ClientException as exc:
+ message = "failed to exec operation {}:\nerror:\n{}".format(
+ operation_id, str(exc)
+ )
+ raise ClientException(message)