diff options
author | Yan Yang <yangyanyj@chinamobile.com> | 2018-08-02 07:33:29 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2018-08-02 07:33:29 +0000 |
commit | 92b02ff3cd72a5adf361cf692dd19799e98bc620 (patch) | |
tree | 8c36b2d22eca29a75a5761a9140d93a17fe8261a | |
parent | c9e02c282656ccb6ea61ab7104de427ff63130c2 (diff) | |
parent | 2a2dc6eca1b90fb2a8ef2a663b4235a4e1735285 (diff) |
Merge "Remove useless codes for nfvo-lcm"
-rw-r--r-- | lcm/packages/__init__.py | 13 | ||||
-rw-r--r-- | lcm/packages/nf_package.py | 437 | ||||
-rw-r--r-- | lcm/packages/ns_package.py | 108 | ||||
-rw-r--r-- | lcm/packages/sdc_nf_package.py | 226 | ||||
-rw-r--r-- | lcm/packages/tests/__init__.py | 13 | ||||
-rw-r--r-- | lcm/packages/tests/test_nf.py | 770 | ||||
-rw-r--r-- | lcm/packages/tests/test_ns.py | 247 | ||||
-rw-r--r-- | lcm/packages/tests/test_sdc_nf.py | 347 | ||||
-rw-r--r-- | lcm/packages/urls.py | 32 | ||||
-rw-r--r-- | lcm/packages/views.py | 143 | ||||
-rw-r--r-- | lcm/urls.py | 1 |
11 files changed, 0 insertions, 2337 deletions
diff --git a/lcm/packages/__init__.py b/lcm/packages/__init__.py deleted file mode 100644 index 5580cc3d..00000000 --- a/lcm/packages/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2016 ZTE Corporation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. diff --git a/lcm/packages/nf_package.py b/lcm/packages/nf_package.py deleted file mode 100644 index 17ce388c..00000000 --- a/lcm/packages/nf_package.py +++ /dev/null @@ -1,437 +0,0 @@ -# Copyright 2016-2017 ZTE Corporation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import json -import logging -import os -import sys -import threading -import time -import traceback -import uuid - -from lcm.pub.config.config import IMAGE_ROOT_PATH, IGNORE_DEL_IMG_WEHN_DEL_CSAR -from lcm.pub.database.models import NfPackageModel, VnfPackageFileModel, NfInstModel -from lcm.pub.exceptions import NSLCMException -from lcm.pub.msapi.catalog import P_STATUS_DELETEFAILED, P_STATUS_DELETING -from lcm.pub.msapi.catalog import P_STATUS_NORMAL, P_STATUS_ONBOARDING, P_STATUS_ONBOARDFAILED -from lcm.pub.msapi.catalog import STATUS_ONBOARDED, P_STATUS_ENABLED -from lcm.pub.msapi.catalog import get_download_url_from_catalog -from lcm.pub.msapi.catalog import query_csar_from_catalog, set_csar_state -from lcm.pub.msapi.catalog import query_rawdata_from_catalog, delete_csar_from_catalog -from lcm.pub.msapi.extsys import get_vims -from lcm.pub.nfvi.vim.vimadaptor import VimAdaptor -from lcm.pub.utils import fileutil -from lcm.pub.utils import toscautil -from lcm.pub.utils.jobutil import JobUtil -from lcm.pub.utils.values import ignore_case_get - -logger = logging.getLogger(__name__) - -SUPPORT_MULTI_VIM, UNSUPPORT_MULTI_VIM = 1, 0 -ZTE_PRIVATE = 0 -DEPLOY_TYPE_IAAS = 1 -IMAGE_FILE = 2 -IMAGE_STATUS_ENABLE = "Enable" -MAX_RETRY_TIMES = 300 -SLEEP_INTERVAL_SECONDS = 2 -IMAGE_ACTIVE = 'active' -JOB_ERROR = 255 - - -class NfOnBoardingThread(threading.Thread): - """ - NF package onBoarding - """ - - def __init__(self, csar_id, vim_ids, lab_vim_id, job_id): - threading.Thread.__init__(self) - self.csar_id = csar_id - self.vim_ids = vim_ids - self.lab_vim_id = lab_vim_id - self.job_id = job_id - - self.csar_info = None - self.nfd = None - self.nfd_id = None - self.img_save_path = os.path.join(IMAGE_ROOT_PATH, self.job_id) - - self.need_rollback_when_failed = False - - def run(self): - try: - self.on_boarding() - except NSLCMException as e: - self.rollback_on_boarding() - JobUtil.add_job_status(self.job_id, JOB_ERROR, e.message) - except: - logger.error(traceback.format_exc()) - logger.error(str(sys.exc_info())) - self.rollback_on_boarding() - JobUtil.add_job_status(self.job_id, JOB_ERROR, "Failed to onBoarding CSAR(%s)" % self.csar_id) - - def on_boarding(self): - JobUtil.create_job( - inst_type='nf', - jobaction='on_boarding', - inst_id=self.csar_id, - job_id=self.job_id) - JobUtil.add_job_status(self.job_id, 5, "Start CSAR(%s) onBoarding." % self.csar_id) - self.on_boarding_pre_deal() - self.nf_package_save() - self.need_rollback_when_failed = True - nf_images = self.download_nf_images() - self.upload_nf_images(nf_images) - set_csar_state(self.csar_id, "onBoardState", STATUS_ONBOARDED) - set_csar_state(self.csar_id, "processState", P_STATUS_NORMAL) - set_csar_state(self.csar_id, "operationalState", P_STATUS_ENABLED) - JobUtil.add_job_status(self.job_id, 100, "CSAR(%s) onBoarding successfully." % self.csar_id) - - def on_boarding_pre_deal(self): - JobUtil.add_job_status(self.job_id, 10, "Check status of CSAR(%s) from catalog." % self.csar_id) - - self.csar_info = query_csar_from_catalog(self.csar_id) - - on_board_state = ignore_case_get(self.csar_info, "onBoardState") - if on_board_state == STATUS_ONBOARDED: - raise NSLCMException("CSAR(%s) already onBoarded." % self.csar_id) - - process_state = ignore_case_get(self.csar_info, "processState") - if process_state == P_STATUS_ONBOARDING: - raise NSLCMException("CSAR(%s) is onBoarding now." % self.csar_id) - - JobUtil.add_job_status(self.job_id, 20, "Get model of CSAR(%s) from catalog." % self.csar_id) - - raw_data = query_rawdata_from_catalog(self.csar_id) - self.nfd = toscautil.convert_vnfd_model(raw_data["rawData"]) # convert to inner json - self.nfd = json.JSONDecoder().decode(self.nfd) - self.nfd_id = self.nfd["metadata"]["id"] - if NfPackageModel.objects.filter(vnfdid=self.nfd_id): - raise NSLCMException("NFD(%s) already exists." % self.nfd_id) - - def nf_package_save(self): - JobUtil.add_job_status(self.job_id, 30, "Save CSAR(%s) to database." % self.csar_id) - vnfd_ver = self.nfd["metadata"].get("vnfd_version") - if not vnfd_ver: - vnfd_ver = self.nfd["metadata"].get("vnfdVersion") - NfPackageModel( - uuid=str(uuid.uuid4()), - nfpackageid=self.csar_id, - vnfdid=self.nfd_id, - vendor=self.nfd["metadata"].get("vendor", "undefined"), - vnfdversion=vnfd_ver, - vnfversion=self.nfd["metadata"].get("version", "undefined"), - vnfdmodel=json.JSONEncoder().encode(self.nfd) - ).save() - - def download_nf_images(self): - nf_images = [] - for image_file in self.nfd["image_files"]: - img_name = image_file["properties"]["name"] - img_relative_path = image_file["properties"]["file_url"] - img_type = image_file["properties"]["disk_format"] - img_desc = image_file.get("description", "") - img_url, img_local_path = get_download_url_from_catalog(self.csar_id, img_relative_path) - JobUtil.add_job_status(self.job_id, 50, "Start to download Image(%s)." % img_name) - is_download_ok, img_save_full_path = fileutil.download_file_from_http(img_url, self.img_save_path, img_name) - if not is_download_ok: - raise NSLCMException("Failed to download image from %s" % img_url) - logger.debug("Download Image(%s) to %s successfully.", img_name, img_save_full_path) - nf_images.append({ - "image_url": img_url, - "img_name": img_name, - "img_save_full_path": img_save_full_path, - "img_type": img_type, - "img_desc": img_desc}) - return nf_images - - def upload_nf_images(self, nf_images): - vims = get_vims() - if self.lab_vim_id and (not self.vim_ids): - self.vim_ids = [self.lab_vim_id] - for vim_id in self.vim_ids: - sel_vim = [vim for vim in vims if vim["vimId"] == vim_id] - if not sel_vim: - logger.warn("VIMID(%s) does not exist.", vim_id) - continue - vim_api = VimAdaptor({ - "vimid": vim_id, - "vimtype": sel_vim[0]["type"], - "url": sel_vim[0]["url"], - "user": sel_vim[0]["userName"], - "passwd": sel_vim[0]["password"], - "tenant": sel_vim[0]["tenant"]}) - for nf_image in nf_images: - self.upload_one_nf_image(vim_api, nf_image, vim_id, sel_vim) - fileutil.delete_dirs(self.img_save_path) - - def upload_one_nf_image(self, vim_api, nf_image, vim_id, sel_vim): - JobUtil.add_job_status(self.job_id, 80, "Start to upload Image(%s) to VIM(%s)." % - (nf_image["img_name"], vim_id)) - ret = vim_api.create_image({ - "image_url": nf_image["image_url"], - "image_name": nf_image["img_name"], - "image_path": nf_image["img_save_full_path"], - "image_type": nf_image["img_type"]}) - if ret[0] != 0: - raise NSLCMException("Failed to create image:%s" % ret[1]) - image_id = ret[1]["id"] - - self.wait_until_upload_done(vim_api, image_id) - - VnfPackageFileModel( - vnfpid=self.csar_id, - filename=nf_image["img_name"], - filetype=IMAGE_FILE, - imageid=image_id, - vimid=vim_id, - vimuser=sel_vim[0]["userName"], - tenant=sel_vim[0]["tenant"], - purpose=nf_image["img_desc"], - status=IMAGE_STATUS_ENABLE).save() - - def wait_until_upload_done(self, vim_api, image_id): - retry_times = 0 - image_create_success = False - - while retry_times < MAX_RETRY_TIMES: - retry_times += 1 - ret = vim_api.get_image(image_id=image_id) - if ret[0] != 0: - logging.warn("Failed to query image:%s", ret[1]) - continue - if ret[1]["status"] == IMAGE_ACTIVE: - image_create_success = True - break - time.sleep(SLEEP_INTERVAL_SECONDS) - - if not image_create_success: - timeout_seconds = MAX_RETRY_TIMES * SLEEP_INTERVAL_SECONDS - raise NSLCMException("Failed to create image:timeout(%s seconds.)" % timeout_seconds) - - def rollback_on_boarding(self): - if not self.need_rollback_when_failed: - return - try: - set_csar_state(self.csar_id, "processState", P_STATUS_ONBOARDFAILED) - NfPackageModel.objects.filter(nfpackageid=self.csar_id).delete() - VnfPackageFileModel.objects.filter(vnfpid=self.csar_id).delete() - fileutil.delete_dirs(self.img_save_path) - except: - logger.error(traceback.format_exc()) - logger.error(str(sys.exc_info())) - - -###################################################################################################################### - - -class NfPkgDeleteThread(threading.Thread): - """ - NF Package Deleting - """ - - def __init__(self, csar_id, job_id): - threading.Thread.__init__(self) - self.csar_id = csar_id - self.job_id = job_id - - def run(self): - try: - self.delete_csar() - except NSLCMException as e: - set_csar_state(self.csar_id, "processState", P_STATUS_DELETEFAILED) - JobUtil.add_job_status(self.job_id, JOB_ERROR, e.message) - except: - logger.error(traceback.format_exc()) - logger.error(str(sys.exc_info())) - set_csar_state(self.csar_id, "processState", P_STATUS_DELETEFAILED) - JobUtil.add_job_status(self.job_id, JOB_ERROR, "Failed to delete CSAR(%s)" % self.csar_id) - - def delete_csar(self): - JobUtil.create_job( - inst_type='nf', - jobaction='delete', - inst_id=self.csar_id, - job_id=self.job_id) - JobUtil.add_job_status(self.job_id, 5, "Start to delete CSAR(%s)." % self.csar_id) - if query_csar_from_catalog(self.csar_id, "processState") == P_STATUS_DELETING: - JobUtil.add_job_status(self.job_id, 100, "CSAR(%s) is deleting now." % self.csar_id) - return - - if NfInstModel.objects.filter(package_id=self.csar_id): - ret = set_csar_state(self.csar_id, "deletionPending", True) - JobUtil.add_job_status(self.job_id, 100, ret[1]) - return - - NfPackage().delete_csar(self.csar_id, self.job_id) - - -class NfPkgDeletePendingThread(threading.Thread): - """ - NF Package Delete Pending - """ - - def __init__(self, csar_id, job_id): - threading.Thread.__init__(self) - self.csar_id = csar_id - self.job_id = job_id - - def run(self): - try: - self.delete_pending_csar() - except NSLCMException as e: - set_csar_state(self.csar_id, "processState", P_STATUS_DELETEFAILED) - JobUtil.add_job_status(self.job_id, JOB_ERROR, e.message) - except: - logger.error(traceback.format_exc()) - logger.error(str(sys.exc_info())) - set_csar_state(self.csar_id, "processState", P_STATUS_DELETEFAILED) - JobUtil.add_job_status(self.job_id, JOB_ERROR, "Failed to delete CSAR(%s)" % self.csar_id) - - def delete_pending_csar(self): - JobUtil.create_job( - inst_type='nf', - jobaction='delete_pending', - inst_id=self.csar_id, - job_id=self.job_id) - JobUtil.add_job_status(self.job_id, 5, "Start to delete pending CSAR(%s)." % self.csar_id) - - if not NfPackageModel.objects.filter(nfpackageid=self.csar_id): - JobUtil.add_job_status(self.job_id, 100, "Delete pending CSAR(%s) successfully." % self.csar_id) - return - - csar_info = query_csar_from_catalog(self.csar_id) - - process_state = ignore_case_get(csar_info, "processState") - if process_state == P_STATUS_DELETING: - JobUtil.add_job_status(self.job_id, 100, "CSAR(%s) is deleting now." % self.csar_id) - return - - deletion_pending = ignore_case_get(csar_info, "deletionPending") - if deletion_pending.lower() == "false": - JobUtil.add_job_status(self.job_id, 100, "CSAR(%s) need not to be deleted." % self.csar_id) - return - - if NfInstModel.objects.filter(package_id=self.csar_id): - JobUtil.add_job_status(self.job_id, 100, "CSAR(%s) is in using, cannot be deleted." % self.csar_id) - return - - NfPackage().delete_csar(self.csar_id, self.job_id) - - -#################################################################################################################### -class NfPackage(object): - """ - Actions for nf package. - """ - - def __init__(self): - pass - - def get_csars(self): - ret = {"csars": []} - nf_pkgs = NfPackageModel.objects.filter() - for nf_pkg in nf_pkgs: - ret["csars"].append({ - "csarId": nf_pkg.nfpackageid, - "vnfdId": nf_pkg.vnfdid - }) - return ret - - def get_csar(self, csar_id): - pkg_info = {} - nf_pkg = NfPackageModel.objects.filter(nfpackageid=csar_id) - if nf_pkg: - pkg_info["vnfdId"] = nf_pkg[0].vnfdid - pkg_info["vnfdProvider"] = nf_pkg[0].vendor - pkg_info["vnfdVersion"] = nf_pkg[0].vnfdversion - pkg_info["vnfVersion"] = nf_pkg[0].vnfversion - - casrinfo = query_csar_from_catalog(csar_id) - props_of_catalog = [ - "name", "provider", "version", "operationalState", "usageState", - "onBoardState", "processState", "deletionPending", "downloadUri", - "createTime", "modifyTime", "format", "size"] - for prop in props_of_catalog: - pkg_info[prop] = ignore_case_get(casrinfo, prop) - - nf_pkg_files = VnfPackageFileModel.objects.filter(vnfpid=csar_id) - img_info = [{ - "index": str(i), - "fileName": nf_pkg_files[i].filename, - "imageId": nf_pkg_files[i].imageid, - "vimId": nf_pkg_files[i].vimid, - "vimUser": nf_pkg_files[i].vimuser, - "tenant": nf_pkg_files[i].tenant, - "status": nf_pkg_files[i].status} - for i in range(len(nf_pkg_files))] - - vnf_insts = NfInstModel.objects.filter(package_id=csar_id) - vnf_inst_info = [{"vnfInstanceId": vnf_inst.nfinstid, - "vnfInstanceName": vnf_inst.nf_name} for vnf_inst in vnf_insts] - - return [0, {"csarId": csar_id, - "packageInfo": pkg_info, - "imageInfo": img_info, - "vnfInstanceInfo": vnf_inst_info}] - - def delete_csar(self, csar_id, job_id): - JobUtil.add_job_status(job_id, 10, "Set processState of CSAR(%s)." % csar_id) - set_csar_state(csar_id, "processState", P_STATUS_DELETING) - - JobUtil.add_job_status(job_id, 20, "Get package files of CSAR(%s)." % csar_id) - all_nf_pkg_files = VnfPackageFileModel.objects.all() - nf_pkg_files = VnfPackageFileModel.objects.filter(vnfpid=csar_id) - vims = get_vims() - - for pkg_file in nf_pkg_files: - if IGNORE_DEL_IMG_WEHN_DEL_CSAR: - logger.warn("ignore delete image(%s)" % pkg_file.filename) - continue - JobUtil.add_job_status(job_id, 50, "Delete image(%s) of CSAR(%s)." % - (pkg_file.filename, csar_id)) - if self.is_image_refed_by_other_nf_pkg(all_nf_pkg_files, pkg_file.imageid, csar_id, pkg_file.vimid): - logger.warn("Image(%s) is refered by CSAR(%s).", pkg_file.filename, csar_id) - continue - sel_vim = [vim for vim in vims if vim["vimId"] == pkg_file.vimid] - if not sel_vim: - logger.warn("Vim(%s) does not exist.", pkg_file.vimid) - continue - vim_api = VimAdaptor({ - "vimid": pkg_file.vimid, - "vimtype": sel_vim[0]["type"], - "url": sel_vim[0]["url"], - "user": sel_vim[0]["userName"], - "passwd": sel_vim[0]["password"], - "tenant": sel_vim[0]["tenant"]}) - ret = vim_api.delete_image(pkg_file.imageid) - if ret[0] != 0: - logger.error("Failed to delete image(%s) from vim(%s)", pkg_file.filename, pkg_file.vimid) - - JobUtil.add_job_status(job_id, 70, "Delete CSAR(%s) from catalog." % csar_id) - ret = delete_csar_from_catalog(csar_id) - if ret[0] != 0: - raise NSLCMException(ret[1]) - - JobUtil.add_job_status(job_id, 90, "Delete CSAR(%s) from database." % csar_id) - VnfPackageFileModel.objects.filter(vnfpid=csar_id).delete() - NfPackageModel.objects.filter(nfpackageid=csar_id).delete() - - JobUtil.add_job_status(job_id, 100, "Delete CSAR(%s) successfully." % csar_id) - - def is_image_refed_by_other_nf_pkg(self, nf_pkg_files, imageid, csar_id, vim_id): - for f in nf_pkg_files: - if f.imageid == imageid and f.vimid == vim_id and f.vnfpid != csar_id: - return True - return False diff --git a/lcm/packages/ns_package.py b/lcm/packages/ns_package.py deleted file mode 100644 index 777256fb..00000000 --- a/lcm/packages/ns_package.py +++ /dev/null @@ -1,108 +0,0 @@ -# Copyright 2016 ZTE Corporation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging - -import traceback -import sys - -from lcm.pub.database.models import NSDModel, NSInstModel -from lcm.pub.utils.values import ignore_case_get -from lcm.pub.msapi.catalog import query_csar_from_catalog, set_csar_state -from lcm.pub.msapi.catalog import delete_csar_from_catalog -from lcm.pub.exceptions import NSLCMException - -logger = logging.getLogger(__name__) - -STATUS_SUCCESS, STATUS_FAILED = "success", "failed" - - -def fmt_ns_pkg_rsp(status, desc, error_code="500"): - return [0, {"status": status, "statusDescription": desc, "errorCode": error_code}] - - -def ns_common_call(fun, csar_id, operation=""): - ret = None - try: - if operation == "": - ret = fun(csar_id) - else: - ret = fun(csar_id, operation) - - if ret[0] != 0: - return fmt_ns_pkg_rsp(STATUS_FAILED, ret[1]) - except NSLCMException as e: - return fmt_ns_pkg_rsp(STATUS_FAILED, e.message) - except: - logger.error(traceback.format_exc()) - return fmt_ns_pkg_rsp(STATUS_FAILED, str(sys.exc_info())) - return fmt_ns_pkg_rsp(STATUS_SUCCESS, ret[1], "") - - -def ns_delete_pending_csar(csar_id): - return ns_common_call(NsPackage().delete_pending_csar, csar_id) - - -def ns_set_state_csar(csar_id, operation): - return ns_common_call(NsPackage().set_state_csar, csar_id, operation) - - -############################################################################################################### - - -class NsPackage(object): - """ - Actions for ns package. - """ - - def __init__(self): - pass - - def delete_csar(self, csar_id): - if not NSDModel.objects.filter(id=csar_id): - return delete_csar_from_catalog(csar_id) - - if NSInstModel.objects.filter(nspackage_id=csar_id): - return set_csar_state(csar_id, "deletionPending", True) - - ret = delete_csar_from_catalog(csar_id) - if ret[0] == 0: - NSDModel.objects.filter(id=csar_id).delete() - return ret - - def delete_pending_csar(self, csar_id): - if not NSDModel.objects.filter(id=csar_id): - return [0, "Delete pending CSAR(%s) successfully." % csar_id] - - pending = query_csar_from_catalog(csar_id, "deletionPending") - - if pending.lower() == "false": - return [1, "CSAR(%s) need not to be deleted." % csar_id] - - if NSInstModel.objects.filter(nspackage_id=csar_id): - return [1, "CSAR(%s) is in using, cannot be deleted." % csar_id] - - ret = delete_csar_from_catalog(csar_id) - if ret[0] == 0: - NSDModel.objects.filter(id=csar_id).delete() - return ret - - def set_state_csar(self, csar_id, operation): - if not NSDModel.objects.filter(id=csar_id): - raise NSLCMException("CSAR(%s) does not exist." % csar_id) - - csar = query_csar_from_catalog(csar_id) - if ignore_case_get(csar, "operationalState") == operation.capitalize(): - raise NSLCMException("CSAR(%s) already %s." % (csar_id, operation)) - return set_csar_state(csar_id, 'operationState', operation.capitalize()) diff --git a/lcm/packages/sdc_nf_package.py b/lcm/packages/sdc_nf_package.py deleted file mode 100644 index 0eeea4fc..00000000 --- a/lcm/packages/sdc_nf_package.py +++ /dev/null @@ -1,226 +0,0 @@ -# Copyright 2017 ZTE Corporation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import json -import logging -import os -import sys -import threading -import traceback - -from lcm.pub.config.config import CATALOG_ROOT_PATH -from lcm.pub.database.models import NfPackageModel, NfInstModel -from lcm.pub.exceptions import NSLCMException -from lcm.pub.msapi import sdc, sdc_run_catalog -from lcm.pub.utils import fileutil -from lcm.pub.utils import toscaparser -from lcm.pub.utils.jobutil import JobUtil - -logger = logging.getLogger(__name__) - -JOB_ERROR = 255 - - -def nf_get_csars(): - ret = None - try: - ret = SdcNfPackage().get_csars() - except NSLCMException as e: - return [1, e.message] - except: - logger.error(traceback.format_exc()) - return [1, str(sys.exc_info())] - return ret - - -def nf_get_csar(csar_id): - ret = None - try: - ret = SdcNfPackage().get_csar(csar_id) - except NSLCMException as e: - return [1, e.message] - except: - logger.error(traceback.format_exc()) - return [1, str(sys.exc_info())] - return ret - - -##################################################################################### -class SdcNfDistributeThread(threading.Thread): - """ - Sdc NF Package Distribute - """ - - def __init__(self, csar_id, vim_ids, lab_vim_id, job_id): - threading.Thread.__init__(self) - self.csar_id = csar_id - self.vim_ids = vim_ids - self.lab_vim_id = lab_vim_id - self.job_id = job_id - - self.csar_save_path = os.path.join(CATALOG_ROOT_PATH, csar_id) - - def run(self): - try: - self.on_distribute() - except NSLCMException as e: - self.rollback_distribute() - JobUtil.add_job_status(self.job_id, JOB_ERROR, e.message) - except: - logger.error(traceback.format_exc()) - logger.error(str(sys.exc_info())) - self.rollback_distribute() - JobUtil.add_job_status(self.job_id, JOB_ERROR, "Failed to distribute CSAR(%s)" % self.csar_id) - - def on_distribute(self): - JobUtil.create_job( - inst_type='nf', - jobaction='on_distribute', - inst_id=self.csar_id, - job_id=self.job_id) - JobUtil.add_job_status(self.job_id, 5, "Start CSAR(%s) distribute." % self.csar_id) - - if NfPackageModel.objects.filter(nfpackageid=self.csar_id): - raise NSLCMException("NF CSAR(%s) already exists." % self.csar_id) - - artifact = sdc.get_artifact(sdc.ASSETTYPE_RESOURCES, self.csar_id) - local_path = os.path.join(CATALOG_ROOT_PATH, self.csar_id) - local_file_name = sdc.download_artifacts(artifact["toscaModelURL"], - local_path, - "%s.csar" % artifact.get("name", self.csar_id)) - - vnfd_json = toscaparser.parse_vnfd(local_file_name) - vnfd = json.JSONDecoder().decode(vnfd_json) - - nfd_id = vnfd["metadata"]["id"] - if NfPackageModel.objects.filter(vnfdid=nfd_id): - raise NSLCMException("NFD(%s) already exists." % nfd_id) - - JobUtil.add_job_status(self.job_id, 30, "Save CSAR(%s) to database." % self.csar_id) - - vnfd_ver = vnfd["metadata"].get("vnfd_version") - if not vnfd_ver: - vnfd_ver = vnfd["metadata"].get("vnfdVersion", "undefined") - NfPackageModel( - uuid=self.csar_id, - nfpackageid=self.csar_id, - vnfdid=nfd_id, - vendor=vnfd["metadata"].get("vendor", "undefined"), - vnfdversion=vnfd_ver, - vnfversion=vnfd["metadata"].get("version", "undefined"), - vnfdmodel=vnfd_json, - vnfd_path=local_file_name).save() - - JobUtil.add_job_status(self.job_id, 100, "CSAR(%s) distribute successfully." % self.csar_id) - - def rollback_distribute(self): - try: - NfPackageModel.objects.filter(nfpackageid=self.csar_id).delete() - fileutil.delete_dirs(self.csar_save_path) - except: - logger.error(traceback.format_exc()) - logger.error(str(sys.exc_info())) - - -###################################################################################################################### - - -class SdcNfPkgDeleteThread(threading.Thread): - """ - Sdc NF Package Deleting - """ - - def __init__(self, csar_id, job_id, force_delete): - threading.Thread.__init__(self) - self.csar_id = csar_id - self.job_id = job_id - self.force_delete = force_delete - - def run(self): - try: - self.delete_csar() - except NSLCMException as e: - JobUtil.add_job_status(self.job_id, JOB_ERROR, e.message) - except: - logger.error(traceback.format_exc()) - logger.error(str(sys.exc_info())) - JobUtil.add_job_status(self.job_id, JOB_ERROR, "Failed to delete CSAR(%s)" % self.csar_id) - - def delete_csar(self): - JobUtil.create_job( - inst_type='nf', - jobaction='delete', - inst_id=self.csar_id, - job_id=self.job_id) - JobUtil.add_job_status(self.job_id, 5, "Start to delete CSAR(%s)." % self.csar_id) - - if self.force_delete: - NfInstModel.objects.filter(package_id=self.csar_id).delete() - else: - if NfInstModel.objects.filter(package_id=self.csar_id): - raise NSLCMException("NfInst by csar(%s) exists, cannot delete." % self.csar_id) - - JobUtil.add_job_status(self.job_id, 50, "Delete CSAR(%s) from Database." % self.csar_id) - - NfPackageModel.objects.filter(nfpackageid=self.csar_id).delete() - - JobUtil.add_job_status(self.job_id, 80, "Delete local CSAR(%s) file." % self.csar_id) - - csar_save_path = os.path.join(CATALOG_ROOT_PATH, self.csar_id) - fileutil.delete_dirs(csar_save_path) - - JobUtil.add_job_status(self.job_id, 100, "Delete CSAR(%s) successfully." % self.csar_id) - - -###################################################################################################################### - -class SdcNfPackage(object): - """ - Actions for sdc nf package. - """ - - def __init__(self): - pass - - def get_csars(self): - csars = {"csars": []} - nf_pkgs = NfPackageModel.objects.filter() - for nf_pkg in nf_pkgs: - csars["csars"].append({ - "csarId": nf_pkg.nfpackageid, - "vnfdId": nf_pkg.vnfdid - }) - return [0, csars] - - def get_csar(self, csar_id): - """ - pkg_info = {} - nf_pkg = NfPackageModel.objects.filter(nfpackageid=csar_id) - if nf_pkg: - pkg_info["vnfdId"] = nf_pkg[0].vnfdid - pkg_info["vnfdProvider"] = nf_pkg[0].vendor - pkg_info["vnfdVersion"] = nf_pkg[0].vnfdversion - pkg_info["vnfVersion"] = nf_pkg[0].vnfversion - """ - nf_pkg = sdc_run_catalog.query_vnfpackage_by_id(csar_id) - pkg_info = nf_pkg["packageInfo"] - - vnf_insts = NfInstModel.objects.filter(package_id=csar_id) - vnf_inst_info = [{"vnfInstanceId": vnf_inst.nfinstid, - "vnfInstanceName": vnf_inst.nf_name} for vnf_inst in vnf_insts] - - return [0, {"csarId": csar_id, - "packageInfo": pkg_info, - "imageInfo": [], - "vnfInstanceInfo": vnf_inst_info}] diff --git a/lcm/packages/tests/__init__.py b/lcm/packages/tests/__init__.py deleted file mode 100644 index 5580cc3d..00000000 --- a/lcm/packages/tests/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2016 ZTE Corporation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. diff --git a/lcm/packages/tests/test_nf.py b/lcm/packages/tests/test_nf.py deleted file mode 100644 index 6ebc98b5..00000000 --- a/lcm/packages/tests/test_nf.py +++ /dev/null @@ -1,770 +0,0 @@ -# Copyright 2016-2017 ZTE Corporation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import json - -import mock -from django.test import Client -from django.test import TestCase -from rest_framework import status - -from lcm.packages.nf_package import NfOnBoardingThread, NfPkgDeletePendingThread -from lcm.packages.nf_package import NfPkgDeleteThread -from lcm.pub.database.models import JobStatusModel, JobModel -from lcm.pub.database.models import NfPackageModel, VnfPackageFileModel, NfInstModel -from lcm.pub.nfvi.vim.vimadaptor import VimAdaptor -from lcm.pub.utils import fileutil -from lcm.pub.utils import restcall - - -class TestNfPackage(TestCase): - def setUp(self): - self.client = Client() - NfPackageModel.objects.filter().delete() - VnfPackageFileModel.objects.filter().delete() - NfInstModel.objects.filter().delete() - JobModel.objects.filter().delete() - JobStatusModel.objects.filter().delete() - self.vnfd_raw_data = { - "rawData": { - "instance": { - "metadata": { - "is_shared": False, - "plugin_info": "vbrasplugin_1.0", - "vendor": "zte", - "request_reclassification": False, - "name": "vbras", - "version": 1, - "vnf_type": "vbras", - "cross_dc": False, - "vnfd_version": "1.0.0", - "id": "zte_vbras_1.0", - "nsh_aware": True - }, - "nodes": [ - { - "id": "aaa_dnet_cp_0xu2j5sbigxc8h1ega3if0ld1", - "type_name": "tosca.nodes.nfv.ext.zte.CP", - "template_name": "aaa_dnet_cp", - "properties": { - "bandwidth": { - "type_name": "integer", - "value": 0 - }, - "direction": { - "type_name": "string", - "value": "bidirectional" - }, - "vnic_type": { - "type_name": "string", - "value": "normal" - }, - "sfc_encapsulation": { - "type_name": "string", - "value": "mac" - }, - "order": { - "type_name": "integer", - "value": 2 - } - }, - "relationships": [ - { - "name": "guest_os", - "source_requirement_index": 0, - "target_node_id": "AAA_image_d8aseebr120nbm7bo1ohkj194", - "target_capability_name": "feature" - } - ] - }, - { - "id": "LB_Image_oj5l2ay8l2g6vcq6fsswzduha", - "type_name": "tosca.nodes.nfv.ext.ImageFile", - "template_name": "LB_Image", - "properties": { - "disk_format": { - "type_name": "string", - "value": "qcow2" - }, - "file_url": { - "type_name": "string", - "value": "/SoftwareImages/image-lb" - }, - "name": { - "type_name": "string", - "value": "image-lb" - } - } - } - ] - }, - "model": { - "metadata": { - "is_shared": False, - "plugin_info": "vbrasplugin_1.0", - "vendor": "zte", - "request_reclassification": False, - "name": "vbras", - "version": 1, - "vnf_type": "vbras", - "cross_dc": False, - "vnfd_version": "1.0.0", - "id": "zte_vbras_1.0", - "nsh_aware": True - }, - "node_templates": [ - { - "name": "aaa_dnet_cp", - "type_name": "tosca.nodes.nfv.ext.zte.CP", - "default_instances": 1, - "min_instances": 0, - "properties": { - "bandwidth": { - "type_name": "integer", - "value": 0 - } - }, - "requirement_templates": [ - { - "name": "virtualbinding", - "target_node_template_name": "AAA", - "target_capability_name": "virtualbinding" - } - ] - } - ] - } - } - } - - def tearDown(self): - pass - - def assert_job_result(self, job_id, job_progress, job_detail): - jobs = JobStatusModel.objects.filter( - jobid=job_id, - progress=job_progress, - descp=job_detail) - self.assertEqual(1, len(jobs)) - - @mock.patch.object(NfOnBoardingThread, 'run') - def test_nf_pkg_on_boarding_normal(self, mock_run): - resp = self.client.post("/api/nslcm/v0/vnfpackage", { - "csarId": "1", - "vimIds": ["1"] - }, format='json') - self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED) - - @mock.patch.object(restcall, 'call_req') - def test_nf_pkg_on_boarding_when_on_boarded(self, mock_call_req): - mock_call_req.return_value = [0, json.JSONEncoder().encode({"onBoardState": "onBoarded"}), '200'] - NfOnBoardingThread(csar_id="1", - vim_ids=["1"], - lab_vim_id="", - job_id="2").run() - self.assert_job_result("2", 255, "CSAR(1) already onBoarded.") - - @mock.patch.object(restcall, 'call_req') - def test_nf_pkg_on_boarding_when_on_boarding(self, mock_call_req): - mock_call_req.return_value = [0, json.JSONEncoder().encode({ - "onBoardState": "non-onBoarded", - "processState": "onBoarding" - }), '200'] - NfOnBoardingThread(csar_id="2", - vim_ids=["1"], - lab_vim_id="", - job_id="3").run() - self.assert_job_result("3", 255, "CSAR(2) is onBoarding now.") - - @mock.patch.object(restcall, 'call_req') - def test_nf_on_boarding_when_nfd_already_exists(self, mock_call_req): - mock_vals = { - "/api/catalog/v1/csars/2": - [0, json.JSONEncoder().encode({ - "onBoardState": "onBoardFailed", "processState": "deleteFailed"}), '200'], - "/api/catalog/v1/servicetemplates/queryingrawdata": - [0, json.JSONEncoder().encode(self.vnfd_raw_data), '200']} - - def side_effect(*args): - return mock_vals[args[4]] - - mock_call_req.side_effect = side_effect - NfPackageModel(uuid="1", nfpackageid="2", vnfdid="zte_vbras_1.0").save() - NfOnBoardingThread(csar_id="2", vim_ids=["1"], lab_vim_id="", job_id="4").run() - self.assert_job_result("4", 255, "NFD(zte_vbras_1.0) already exists.") - - @mock.patch.object(restcall, 'call_req') - @mock.patch.object(fileutil, 'download_file_from_http') - @mock.patch.object(VimAdaptor, '__init__') - @mock.patch.object(VimAdaptor, 'create_image') - @mock.patch.object(VimAdaptor, 'get_image') - def test_nf_on_boarding_when_successfully(self, mock_get_image, mock_create_image, - mock__init__, mock_download_file_from_http, mock_call_req): - mock_download_file_from_http.return_value = True, "/root/package" - mock_vals = { - "/api/catalog/v1/csars/2": - [0, json.JSONEncoder().encode({ - "onBoardState": "onBoardFailed", "processState": "deleteFailed"}), '200'], - "/api/catalog/v1/servicetemplates/queryingrawdata": - [0, json.JSONEncoder().encode(self.vnfd_raw_data), '200'], - "/api/catalog/v1/csars/2/files?relativePath=/SoftwareImages/image-lb": - [0, json.JSONEncoder().encode({ - "csar_file_info": [{"downloadUri": "8"}, {"localPath": "9"}]}), '200'], - "/cloud-infrastructure/cloud-regions?depth=all": - [0, json.JSONEncoder().encode(vims_info), '200'], - "/api/catalog/v1/csars/2?onBoardState=onBoarded": [0, '{}', 200], - "/api/catalog/v1/csars/2?operationalState=Enabled": [0, '{}', 200], - "/api/catalog/v1/csars/2?processState=normal": [0, '{}', 200]} - mock_create_image.return_value = [0, {"id": "30", "name": "jerry", "res_type": 0}] - mock__init__.return_value = None - mock_get_image.return_value = [0, {"id": "30", "name": "jerry", "size": "60", "status": "active"}] - - def side_effect(*args): - return mock_vals[args[4]] - mock_call_req.side_effect = side_effect - - NfOnBoardingThread(csar_id="2", vim_ids=["1"], lab_vim_id="", job_id="4").run() - self.assert_job_result("4", 100, "CSAR(2) onBoarding successfully.") - - # @mock.patch.object(restcall, 'call_req') - # @mock.patch.object(fileutil, 'download_file_from_http') - # @mock.patch.object(VimAdaptor, '__init__') - # @mock.patch.object(VimAdaptor, 'create_image') - # @mock.patch.object(VimAdaptor, 'get_image') - # def test_nf_on_boarding_when_timeout(self, mock_get_image, mock_create_image, - # mock__init__, mock_download_file_from_http, mock_call_req): - # nf_package.MAX_RETRY_TIMES = 2 - # nf_package.SLEEP_INTERVAL_SECONDS = 1 - # mock_download_file_from_http.return_value = True, "/root/package" - # mock_vals = { - # "/api/catalog/v1/csars/3": - # [0, json.JSONEncoder().encode({"onBoardState": "onBoardFailed", - # "processState": "deleteFailed"}), '200'], - # "/api/catalog/v1/servicetemplates/queryingrawdata": - # [0, json.JSONEncoder().encode(self.vnfd_raw_data), '200'], - # "/api/catalog/v1/csars/3/files?relativePath=/SoftwareImages/image-lb": - # [0, json.JSONEncoder().encode({ - # "csar_file_info": [{"downloadUri": "8"}, {"localPath": "9"}]}), '200'], - # "/api/catalog/v1/csars/3?processState=onBoardFailed": [0, '{}', 200], - # "/cloud-infrastructure/cloud-regions?depth=all": - # [0, json.JSONEncoder().encode(vims_info), 200]} - # mock_create_image.return_value = [0, {"id": "30", "name": "jerry", "res_type": 0}] - # mock__init__.return_value = None - # mock_get_image.return_value = [0, {"id": "30", "name": "jerry", "size": "60", "status": "0"}] - # - # def side_effect(*args): - # return mock_vals[args[4]] - # - # mock_call_req.side_effect = side_effect - # NfOnBoardingThread(csar_id="3", vim_ids=["1"], lab_vim_id="", job_id="6").run() - # self.assert_job_result("6", 255, "Failed to create image:timeout(2 seconds.)") - - # @mock.patch.object(restcall, 'call_req') - # @mock.patch.object(fileutil, 'download_file_from_http') - # @mock.patch.object(VimAdaptor, '__init__') - # @mock.patch.object(VimAdaptor, 'create_image') - # def test_nf_on_boarding_when_failed_to_create_image(self, mock_create_image, - # mock__init__, mock_download_file_from_http, mock_call_req): - # mock_download_file_from_http.return_value = True, "/root/package" - # mock_vals = { - # "/api/catalog/v1/csars/5": - # [0, json.JSONEncoder().encode({ - # "onBoardState": "onBoardFailed", "processState": "deleteFailed"}), '200'], - # "/api/catalog/v1/servicetemplates/queryingrawdata": - # [0, json.JSONEncoder().encode(self.vnfd_raw_data), '200'], - # "/api/catalog/v1/csars/5/files?relativePath=/SoftwareImages/image-lb": - # [0, json.JSONEncoder().encode({ - # "csar_file_info": [{"downloadUri": "8"}, {"localPath": "9"}]}), '200'], - # "/api/catalog/v1/csars/5?processState=onBoardFailed": [0, '{}', 200], - # "/cloud-infrastructure/cloud-regions?depth=all": - # [0, json.JSONEncoder().encode(vims_info), '200']} - # mock_create_image.return_value = [1, 'Unsupported image format.'] - # mock__init__.return_value = None - # - # def side_effect(*args): - # return mock_vals[args[4]] - # mock_call_req.side_effect = side_effect - # NfOnBoardingThread(csar_id="5", vim_ids=["1"], lab_vim_id="", job_id="8").run() - # self.assert_job_result("8", 255, "Failed to create image:Unsupported image format.") - - ######################################################################### - @mock.patch.object(restcall, 'call_req') - def test_get_csar_successfully(self, mock_call_req): - mock_call_req.return_value = [0, json.JSONEncoder().encode({ - "name": "1", "provider": "2", "version": "3", "operationalState": "4", - "usageState": "5", "onBoardState": "6", "processState": "7", - "deletionPending": "8", "downloadUri": "9", "createTime": "10", - "modifyTime": "11", "format": "12", "size": "13" - }), '200'] - NfPackageModel(uuid="1", vnfdid="001", vendor="vendor", - vnfdversion="1.2.0", vnfversion="1.1.0", nfpackageid="13").save() - VnfPackageFileModel(id="1", filename="filename", imageid="00001", - vimid="1", vimuser="001", tenant="12", status="1", vnfpid="13").save() - NfInstModel(nfinstid="1", mnfinstid="001", nf_name="name", package_id="13").save() - resp = self.client.get("/api/nslcm/v0/vnfpackage/13") - self.assertEqual(resp.status_code, status.HTTP_200_OK) - expect_data = { - "csarId": '13', - "packageInfo": { - "vnfdId": "001", - "vnfdProvider": "vendor", - "vnfdVersion": "1.2.0", - "vnfVersion": "1.1.0", - "name": "1", - "provider": "2", - "version": "3", - "operationalState": "4", - "usageState": "5", - "onBoardState": "6", - "processState": "7", - "deletionPending": "8", - "downloadUri": "9", - "createTime": "10", - "modifyTime": "11", - "format": "12", - "size": "13"}, - "imageInfo": [{ - "index": "0", - "fileName": "filename", - "imageId": "00001", - "vimId": "1", - "vimUser": "001", - "tenant": "12", - "status": "1"}], - "vnfInstanceInfo": [{ - "vnfInstanceId": "1", - "vnfInstanceName": "name"}]} - self.assertEqual(expect_data, resp.data) - - ######################################################################### - @mock.patch.object(restcall, 'call_req') - def test_delete_pending_csar_when_successfully(self, mock_call_req): - mock_call_req.return_value = [0, json.JSONEncoder().encode({ - "processState": "deleting"}), "200"] - NfPkgDeletePendingThread(csar_id="1", job_id='2').run() - self.assert_job_result("2", 100, "Delete pending CSAR(1) successfully.") - - @mock.patch.object(restcall, 'call_req') - def test_delete_pending_csar_when_deleting(self, mock_call_req): - NfPackageModel(uuid="01", nfpackageid="1").save() - mock_call_req.return_value = [0, json.JSONEncoder().encode({ - "processState": "deleting"}), "200"] - NfPkgDeletePendingThread(csar_id="1", job_id='2').run() - self.assert_job_result("2", 100, "CSAR(1) is deleting now.") - - @mock.patch.object(restcall, 'call_req') - def test_delete_pending_csar_when_not_deletion_pending(self, mock_call_req): - NfPackageModel(uuid="01", nfpackageid="1").save() - mock_call_req.return_value = [0, json.JSONEncoder().encode({ - "deletionPending": "false"}), "200"] - NfPkgDeletePendingThread(csar_id="1", job_id='2').run() - self.assert_job_result("2", 100, "CSAR(1) need not to be deleted.") - - @mock.patch.object(restcall, 'call_req') - def test_delete_pending_csar_when_in_using(self, mock_call_req): - mock_call_req.return_value = [0, json.JSONEncoder().encode({ - "processState": "normal"}), "200"] - NfPackageModel(uuid="01", nfpackageid="1").save() - NfInstModel(nfinstid="01", package_id="1").save() - NfPkgDeletePendingThread(csar_id="1", job_id='2').run() - self.assert_job_result("2", 100, "CSAR(1) is in using, cannot be deleted.") - - @mock.patch.object(VimAdaptor, '__init__') - @mock.patch.object(VimAdaptor, 'delete_image') - @mock.patch.object(restcall, 'call_req') - def test_delete_csarr_when_exception(self, mock_call_req, mock_delete_image, mock_init_): - mock_vals = { - ("/api/catalog/v1/csars/1", "DELETE"): - [1, "{}", "400"], - ("/api/catalog/v1/csars/1?processState=deleting", "PUT"): - [0, "{}", "200"], - ("/api/catalog/v1/csars/1?processState=deleteFailed", "PUT"): - [0, "{}", "200"], - ("/api/catalog/v1/csars/1", "GET"): - [0, json.JSONEncoder().encode({"processState": "normal"}), "200"], - ("/cloud-infrastructure/cloud-regions?depth=all", "GET"): - [0, json.JSONEncoder().encode(vims_info), "200"]} - mock_delete_image.return_value = [0, "", '200'] - - def side_effect(*args): - return mock_vals[(args[4], args[5])] - - mock_call_req.side_effect = side_effect - mock_init_.return_value = None - VnfPackageFileModel(vnfpid="1", imageid="001", vimid="002").save() - NfPackageModel(uuid="01", nfpackageid="1").save() - NfPkgDeletePendingThread(csar_id="1", job_id='2').run() - self.assert_job_result("2", 255, "Failed to delete CSAR(1) from catalog.") - - @mock.patch.object(VimAdaptor, '__init__') - @mock.patch.object(VimAdaptor, 'delete_image') - @mock.patch.object(restcall, 'call_req') - def test_delete_csar_when_successfully(self, mock_call_req, mock_delete_image, mock_init_): - mock_vals = { - ("/api/catalog/v1/csars/1", "DELETE"): - [0, json.JSONEncoder().encode({"successfully": "successfully"}), "200"], - ("/api/catalog/v1/csars/1?processState=deleting", "PUT"): - [0, json.JSONEncoder().encode({"successfully": "successfully"}), "200"], - ("/api/catalog/v1/csars/1?processState=deleteFailed", "PUT"): - [0, json.JSONEncoder().encode({"successfully": "successfully"}), "200"], - ("/api/catalog/v1/csars/1", "GET"): - [0, json.JSONEncoder().encode({"notProcessState": "notProcessState"}), "200"], - ("/cloud-infrastructure/cloud-regions?depth=all", "GET"): - [0, json.JSONEncoder().encode(vims_info), "200"]} - mock_delete_image.return_value = [0, json.JSONEncoder().encode({"test": "test"}), '200'] - - def side_effect(*args): - return mock_vals[(args[4], args[5])] - - mock_call_req.side_effect = side_effect - mock_init_.return_value = None - VnfPackageFileModel(vnfpid="1", imageid="001", vimid="002").save() - NfPackageModel(uuid="01", nfpackageid="1").save() - NfPkgDeletePendingThread(csar_id="1", job_id='2').run() - self.assert_job_result("2", 100, "Delete CSAR(1) successfully.") - - ######################################################################### - @mock.patch.object(restcall, 'call_req') - def test_delete_nf_pkg_when_deleting(self, mock_call_req): - mock_call_req.return_value = [0, json.JSONEncoder().encode({"processState": "deleting"}), '200'] - NfPkgDeleteThread(csar_id="1", job_id="2").run() - self.assert_job_result("2", 100, "CSAR(1) is deleting now.") - - def test_get_nf_csars_normal(self): - NfPackageModel(uuid="01", nfpackageid="1", vnfdid="2").save() - resp = self.client.get("/api/nslcm/v0/vnfpackage") - self.assertEqual(resp.status_code, status.HTTP_200_OK) - self.assertEqual(1, len(resp.data["csars"])) - self.assertEqual("1", resp.data["csars"][0]["csarId"]) - self.assertEqual("2", resp.data["csars"][0]["vnfdId"]) - - -vims_info = { - "cloud-region": [ - { - "cloud-owner": "example-cloud-owner-val-60268", - "cloud-region-id": "example-cloud-region-id-val-77704", - "cloud-type": "example-cloud-type-val-20689", - "owner-defined-type": "example-owner-defined-type-val-24237", - "cloud-region-version": "example-cloud-region-version-val-95948", - "identity-url": "example-identity-url-val-98336", - "cloud-zone": "example-cloud-zone-val-67202", - "complex-name": "example-complex-name-val-86264", - "sriov-automation": True, - "cloud-extra-info": "example-cloud-extra-info-val-44735", - "cloud-epa-caps": "example-cloud-epa-caps-val-67134", - "resource-version": "example-resource-version-val-47608", - "volume-groups": { - "volume-group": [ - { - "volume-group-id": "example-volume-group-id-val-79555", - "volume-group-name": "example-volume-group-name-val-21888", - "heat-stack-id": "example-heat-stack-id-val-56926", - "vnf-type": "example-vnf-type-val-47890", - "orchestration-status": "example-orchestration-status-val-34971", - "model-customization-id": "example-model-customization-id-val-7851", - "vf-module-model-customization-id": "example-vf-module-model-customization-id-val-35365", - "resource-version": "example-resource-version-val-66022" - } - ] - }, - "tenants": { - "tenant": [ - { - "tenant-id": "example-tenant-id-val-30151", - "tenant-name": "example-tenant-name-val-12231", - "tenant-context": "example-tenant-context-val-80991", - "resource-version": "example-resource-version-val-5033", - "vservers": { - "vserver": [ - { - "vserver-id": "example-vserver-id-val-70581", - "vserver-name": "example-vserver-name-val-63390", - "vserver-name2": "example-vserver-name2-val-70924", - "prov-status": "example-prov-status-val-24088", - "vserver-selflink": "example-vserver-selflink-val-17737", - "in-maint": True, - "is-closed-loop-disabled": True, - "resource-version": "example-resource-version-val-46166", - "volumes": { - "volume": [ - { - "volume-id": "example-volume-id-val-9740", - "volume-selflink": "example-volume-selflink-val-8411", - "resource-version": "example-resource-version-val-41965" - } - ] - }, - "l-interfaces": { - "l-interface": [ - { - "interface-name": "example-interface-name-val-67663", - "interface-role": "example-interface-role-val-27132", - "v6-wan-link-ip": "example-v6-wan-link-ip-val-85445", - "selflink": "example-selflink-val-83317", - "interface-id": "example-interface-id-val-98716", - "macaddr": "example-macaddr-val-18235", - "network-name": "example-network-name-val-45040", - "management-option": "example-management-option-val-65761", - "interface-description": "example-interface-description-val-32615", - "is-port-mirrored": True, - "resource-version": "example-resource-version-val-10801", - "in-maint": True, - "prov-status": "example-prov-status-val-5726", - "is-ip-unnumbered": True, - "allowed-address-pairs": "example-allowed-address-pairs-val-52679", - "vlans": { - "vlan": [ - { - "vlan-interface": "example-vlan-interface-val-61591", - "vlan-id-inner": 53472228, - "vlan-id-outer": 93087267, - "resource-version": "example-resource-version-val-52900", - "speed-value": "example-speed-value-val-69335", - "speed-units": "example-speed-units-val-72089", - "vlan-description": "example-vlan-description-val-96604", - "backdoor-connection": "example-backdoor-connection-val-42299", - "vpn-key": "example-vpn-key-val-50517", - "orchestration-status": "example-orchestration-status-val-66570", - "in-maint": True, - "prov-status": "example-prov-status-val-46495", - "is-ip-unnumbered": True, - "l3-interface-ipv4-address-list": [ - { - "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-32173", - "l3-interface-ipv4-prefix-length": 29740951, - "vlan-id-inner": 93873764, - "vlan-id-outer": 82615508, - "is-floating": True, - "resource-version": "example-resource-version-val-75216", - "neutron-network-id": "example-neutron-network-id-val-77878", - "neutron-subnet-id": "example-neutron-subnet-id-val-79062" - } - ], - "l3-interface-ipv6-address-list": [ - { - "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-88548", - "l3-interface-ipv6-prefix-length": 89047373, - "vlan-id-inner": 95671681, - "vlan-id-outer": 88533796, - "is-floating": True, - "resource-version": "example-resource-version-val-40990", - "neutron-network-id": "example-neutron-network-id-val-81951", - "neutron-subnet-id": "example-neutron-subnet-id-val-4218" - } - ] - } - ] - }, - "sriov-vfs": { - "sriov-vf": [ - { - "pci-id": "example-pci-id-val-12933", - "vf-vlan-filter": "example-vf-vlan-filter-val-90275", - "vf-mac-filter": "example-vf-mac-filter-val-13509", - "vf-vlan-strip": True, - "vf-vlan-anti-spoof-check": True, - "vf-mac-anti-spoof-check": True, - "vf-mirrors": "example-vf-mirrors-val-59746", - "vf-broadcast-allow": True, - "vf-unknown-multicast-allow": True, - "vf-unknown-unicast-allow": True, - "vf-insert-stag": True, - "vf-link-status": "example-vf-link-status-val-37662", - "resource-version": "example-resource-version-val-86970", - "neutron-network-id": "example-neutron-network-id-val-71727" - } - ] - }, - "l-interfaces": { - "l-interface": [ - { - "interface-name": "example-interface-name-val-91632", - "interface-role": "example-interface-role-val-59119", - "v6-wan-link-ip": "example-v6-wan-link-ip-val-21039", - "selflink": "example-selflink-val-16277", - "interface-id": "example-interface-id-val-77457", - "macaddr": "example-macaddr-val-49026", - "network-name": "example-network-name-val-3483", - "management-option": "example-management-option-val-16429", - "interface-description": "example-interface-description-val-50889", - "is-port-mirrored": True, - "resource-version": "example-resource-version-val-30308", - "in-maint": True, - "prov-status": "example-prov-status-val-69406", - "is-ip-unnumbered": True, - "allowed-address-pairs": "example-allowed-address-pairs-val-49123" - } - ] - }, - "l3-interface-ipv4-address-list": [ - { - "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-63922", - "l3-interface-ipv4-prefix-length": 13823411, - "vlan-id-inner": 14316230, - "vlan-id-outer": 66559625, - "is-floating": True, - "resource-version": "example-resource-version-val-30766", - "neutron-network-id": "example-neutron-network-id-val-46636", - "neutron-subnet-id": "example-neutron-subnet-id-val-96658" - } - ], - "l3-interface-ipv6-address-list": [ - { - "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-21246", - "l3-interface-ipv6-prefix-length": 20226253, - "vlan-id-inner": 68200128, - "vlan-id-outer": 18442586, - "is-floating": True, - "resource-version": "example-resource-version-val-24602", - "neutron-network-id": "example-neutron-network-id-val-49811", - "neutron-subnet-id": "example-neutron-subnet-id-val-67505" - } - ] - } - ] - } - } - ] - } - } - ] - }, - "flavors": { - "flavor": [ - { - "flavor-id": "example-flavor-id-val-15058", - "flavor-name": "example-flavor-name-val-69485", - "flavor-vcpus": 92601, - "flavor-ram": 31468, - "flavor-disk": 58744, - "flavor-ephemeral": 84771, - "flavor-swap": "example-flavor-swap-val-66481", - "flavor-is-public": True, - "flavor-selflink": "example-flavor-selflink-val-48912", - "flavor-disabled": True, - "resource-version": "example-resource-version-val-55131" - } - ] - }, - "group-assignments": { - "group-assignment": [ - { - "group-id": "example-group-id-val-79234", - "group-type": "example-group-type-val-29164", - "group-name": "example-group-name-val-57605", - "group-description": "example-group-description-val-52975", - "resource-version": "example-resource-version-val-10280" - } - ] - }, - "snapshots": { - "snapshot": [ - { - "snapshot-id": "example-snapshot-id-val-60630", - "snapshot-name": "example-snapshot-name-val-90351", - "snapshot-architecture": "example-snapshot-architecture-val-3225", - "snapshot-os-distro": "example-snapshot-os-distro-val-31399", - "snapshot-os-version": "example-snapshot-os-version-val-16981", - "application": "example-application-val-34584", - "application-vendor": "example-application-vendor-val-97854", - "application-version": "example-application-version-val-20705", - "snapshot-selflink": "example-snapshot-selflink-val-84731", - "prev-snapshot-id": "example-prev-snapshot-id-val-77339", - "resource-version": "example-resource-version-val-19220" - } - ] - }, - "images": { - "image": [ - { - "image-id": "example-image-id-val-34721", - "image-name": "example-image-name-val-64106", - "image-architecture": "example-image-architecture-val-8247", - "image-os-distro": "example-image-os-distro-val-98534", - "image-os-version": "example-image-os-version-val-87444", - "application": "example-application-val-30758", - "application-vendor": "example-application-vendor-val-7048", - "application-version": "example-application-version-val-79678", - "image-selflink": "example-image-selflink-val-72836", - "resource-version": "example-resource-version-val-79432", - "metadata": { - "metadatum": [ - { - "metaname": "example-metaname-val-75188", - "metaval": "example-metaval-val-64947", - "resource-version": "example-resource-version-val-59427" - } - ] - } - } - ] - }, - "dvs-switches": { - "dvs-switch": [ - { - "switch-name": "example-switch-name-val-21335", - "vcenter-url": "example-vcenter-url-val-74348", - "resource-version": "example-resource-version-val-51253" - } - ] - }, - "oam-networks": { - "oam-network": [ - { - "network-uuid": "example-network-uuid-val-65686", - "network-name": "example-network-name-val-94383", - "cvlan-tag": 31041170, - "ipv4-oam-gateway-address": "example-ipv4-oam-gateway-address-val-15815", - "ipv4-oam-gateway-address-prefix-length": 65477, - "resource-version": "example-resource-version-val-21712" - } - ] - }, - "availability-zones": { - "availability-zone": [ - { - "availability-zone-name": "example-availability-zone-name-val-14569", - "hypervisor-type": "example-hypervisor-type-val-70481", - "operational-status": "example-operational-status-val-13589", - "resource-version": "example-resource-version-val-78031" - } - ] - }, - "esr-system-info-list": { - "esr-system-info": [ - { - "esr-system-info-id": "example-esr-system-info-id-val-58799", - "system-name": "example-system-name-val-78629", - "type": "example-type-val-4146", - "vendor": "example-vendor-val-11916", - "version": "example-version-val-60284", - "service-url": "example-service-url-val-85858", - "user-name": "example-user-name-val-23297", - "password": "example-password-val-33729", - "system-type": "example-system-type-val-54309", - "protocal": "example-protocal-val-86585", - "ssl-cacert": "example-ssl-cacert-val-95811", - "ssl-insecure": True, - "ip-address": "example-ip-address-val-62987", - "port": "example-port-val-83650", - "cloud-domain": "example-cloud-domain-val-9841", - "default-tenant": "example-default-tenant-val-52776", - "resource-version": "example-resource-version-val-61961" - } - ] - } - } - ] -} diff --git a/lcm/packages/tests/test_ns.py b/lcm/packages/tests/test_ns.py deleted file mode 100644 index 3a3c9caa..00000000 --- a/lcm/packages/tests/test_ns.py +++ /dev/null @@ -1,247 +0,0 @@ -# Copyright 2016 ZTE Corporation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -import json -import mock -from rest_framework import status -from django.test import TestCase -from django.test import Client - -from lcm.pub.utils import restcall -from lcm.pub.database.models import NSDModel, NSInstModel, NfPackageModel - - -class TestNsPackage(TestCase): - def setUp(self): - self.client = Client() - NSDModel.objects.filter().delete() - NSInstModel.objects.filter().delete() - NfPackageModel.objects.filter().delete() - self.nsd_raw_data = { - "rawData": { - "instance": { - "metadata": { - "vendor": "ZTE", - "name": "VBRAS_NS", - "csarVersion": 1, - "csarType": "NSAR", - "csarProvider": "ZTE", - "version": 1, - "invariant_id": "VBRAS_NS_NO_SFC", - "id": "VBRAS_NS_ZTE_1.0", - "description": "VBRAS_ZTE_NS" - }, - "nodes": [ - { - "id": "VBras_yfye7lsgi73p8j4p2a6vbguzd", - "type_name": "tosca.nodes.nfv.ext.zte.VNF.VBras", - "template_name": "VBras", - "properties": { - "vendor": { - "type_name": "string", - "value": "zte" - }, - "name": { - "type_name": "string", - "value": "vbras" - }, - "version": { - "type_name": "string", - "value": "1.0" - }, - "vnf_type": { - "type_name": "string", - "value": "vbras" - }, - "vnfd_version": { - "type_name": "string", - "value": "1.0.0" - }, - "id": { - "type_name": "string", - "value": "zte_vbras_1.0" - } - } - } - ] - }, - "model": { - "metadata": { - "vendor": "ZTE", - "name": "VBRAS_NS", - "csarVersion": 1, - "csarType": "NSAR", - "csarProvider": "ZTE", - "version": 1, - "invariant_id": "VBRAS_NS_NO_SFC", - "id": "VBRAS_NS_ZTE_1.0", - "description": "VBRAS_ZTE_NS" - }, - "node_templates": [ - { - "name": "VBras", - "type_name": "tosca.nodes.nfv.ext.zte.VNF.VBras", - "default_instances": 1, - "min_instances": 0, - "properties": { - "vendor": { - "type_name": "string", - "value": "zte" - }, - "name": { - "type_name": "string", - "value": "vbras" - }, - "version": { - "type_name": "string", - "value": "1.0" - }, - "vnf_type": { - "type_name": "string", - "value": "vbras" - }, - "vnfd_version": { - "type_name": "string", - "value": "1.0.0" - }, - "id": { - "type_name": "string", - "value": "zte_vbras_1.0" - } - }, - "requirement_templates": [ - { - "name": "lb_mnet_vl_cp", - "target_node_template_name": "ext_mnet_net", - "target_capability_name": "virtual_linkable" - } - ] - } - ] - } - } - } - - def tearDown(self): - pass - - def set_nsd_metadata(self, key, val): - self.nsd_raw_data["rawData"]["instance"]["metadata"][key] = val - - def set_nsd_vnf_id(self, val): - self.nsd_raw_data["rawData"]["instance"]["nodes"][0]["properties"]["id"]["value"] = val - - ############################################################################################################### - def test_delete_pending_csar_when_id_not_exist(self): - resp = self.client.delete("/api/nslcm/v0/nspackage/9/deletionpending") - self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED) - self.assertEqual("success", resp.data["status"]) - self.assertEqual("Delete pending CSAR(9) successfully.", resp.data["statusDescription"]) - - @mock.patch.object(restcall, 'call_req') - def test_delete_pending_csar_when_pending_is_false(self, mock_call_req): - mock_call_req.return_value = [0, '{"deletionPending": "false"}', '200'] - NSDModel(id="10", nsd_id="2").save() - resp = self.client.delete("/api/nslcm/v0/nspackage/10/deletionpending") - self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED) - self.assertEqual("failed", resp.data["status"]) - self.assertEqual("CSAR(10) need not to be deleted.", resp.data["statusDescription"]) - - @mock.patch.object(restcall, 'call_req') - def test_delete_pending_csar_when_refed_by_ns(self, mock_call_req): - mock_call_req.return_value = [0, '{"deletionPending": "true"}', '200'] - NSDModel(id="11", nsd_id="2").save() - NSInstModel(id="1", nspackage_id="11").save() - resp = self.client.delete("/api/nslcm/v0/nspackage/11/deletionpending") - self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED) - self.assertEqual("failed", resp.data["status"]) - self.assertEqual("CSAR(11) is in using, cannot be deleted.", resp.data["statusDescription"]) - - @mock.patch.object(restcall, 'call_req') - def test_delete_pending_csar_when_delete_success(self, mock_call_req): - mock_call_req.side_effect = [ - [0, '{"deletionPending": "true"}', '200'], - [0, "OK", '204']] - NSDModel(id="12", nsd_id="2").save() - resp = self.client.delete("/api/nslcm/v0/nspackage/12/deletionpending") - self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED) - self.assertEqual("success", resp.data["status"]) - self.assertEqual("Delete CSAR(12) successfully.", resp.data["statusDescription"]) - - ############################################################################################################### - def test_disable_csar_when_id_not_exist_table(self): - resp = self.client.put("/api/nslcm/v0/nspackage/14/disabled") - self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED) - self.assertEqual("failed", resp.data["status"]) - self.assertEqual("CSAR(14) does not exist.", resp.data["statusDescription"]) - - @mock.patch.object(restcall, 'call_req') - def test_disable_csar_when_csar_is_disabled(self, mock_call_req): - NSDModel(id="15", nsd_id="2").save() - mock_call_req.return_value = [0, json.JSONEncoder().encode({"operationalState": "Disabled"}), '200'] - resp = self.client.put("/api/nslcm/v0/nspackage/15/disabled") - self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED) - self.assertEqual("failed", resp.data["status"]) - self.assertEqual("CSAR(15) already disabled.", resp.data["statusDescription"]) - - @mock.patch.object(restcall, 'call_req') - def test_disable_csar_successfully(self, mock_call_req): - NSDModel(id="16", nsd_id="2").save() - mock_vals = { - "/api/catalog/v1/csars/16": - [0, json.JSONEncoder().encode({"operationalState": "Enabled"}), '200'], - "/api/catalog/v1/csars/16?operationState=Disabled": - [0, "OK", '200']} - - def side_effect(*args): - return mock_vals[args[4]] - mock_call_req.side_effect = side_effect - - resp = self.client.put("/api/nslcm/v0/nspackage/16/disabled") - self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED) - self.assertEqual("success", resp.data["status"]) - self.assertEqual("Set operationState to Disabled of CSAR(16) successfully.", resp.data["statusDescription"]) - - ############################################################################################################### - def test_enable_csar_when_id_not_exist_table(self): - resp = self.client.put("/api/nslcm/v0/nspackage/17/enabled") - self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED) - self.assertEqual("failed", resp.data["status"]) - self.assertEqual("CSAR(17) does not exist.", resp.data["statusDescription"]) - - @mock.patch.object(restcall, 'call_req') - def test_enable_csar_when_csar_is_enabled(self, mock_call_req): - NSDModel(id="18", nsd_id="2").save() - mock_call_req.return_value = [0, json.JSONEncoder().encode({"operationalState": "Enabled"}), '200'] - resp = self.client.put("/api/nslcm/v0/nspackage/18/enabled") - self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED) - self.assertEqual("failed", resp.data["status"]) - self.assertEqual("CSAR(18) already enabled.", resp.data["statusDescription"]) - - @mock.patch.object(restcall, 'call_req') - def test_enable_csar_successfully(self, mock_call_req): - NSDModel(id="19", nsd_id="2").save() - mock_vals = { - "/api/catalog/v1/csars/19": - [0, json.JSONEncoder().encode({"operationalState": "Disabled"}), '200'], - "/api/catalog/v1/csars/19?operationState=Enabled": - [0, "OK", '200']} - - def side_effect(*args): - return mock_vals[args[4]] - mock_call_req.side_effect = side_effect - - resp = self.client.put("/api/nslcm/v0/nspackage/19/enabled") - self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED) - self.assertEqual("success", resp.data["status"]) - self.assertEqual("Set operationState to Enabled of CSAR(19) successfully.", resp.data["statusDescription"]) diff --git a/lcm/packages/tests/test_sdc_nf.py b/lcm/packages/tests/test_sdc_nf.py deleted file mode 100644 index 6c95b850..00000000 --- a/lcm/packages/tests/test_sdc_nf.py +++ /dev/null @@ -1,347 +0,0 @@ -# Copyright 2017 ZTE Corporation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -import json - -import mock -from django.test import Client -from django.test import TestCase -from rest_framework import status - -from lcm.packages.sdc_nf_package import SdcNfDistributeThread, SdcNfPkgDeleteThread -from lcm.pub.database.models import JobStatusModel, JobModel -from lcm.pub.database.models import NfPackageModel, NfInstModel -from lcm.pub.msapi import sdc -from lcm.pub.utils import restcall, toscaparser - - -class TestNfPackage(TestCase): - def setUp(self): - self.client = Client() - NfPackageModel.objects.filter().delete() - NfInstModel.objects.filter().delete() - JobModel.objects.filter().delete() - JobStatusModel.objects.filter().delete() - self.vnfd_data = { - "volume_storages": [ - { - "properties": { - "size_of_storage": { - "factor": 10, - "value": 10000000000, - "unit": "GB", - "unit_size": 1000000000 - }, - "type_of_storage": "volume", - "rdma_enabled": False, - "size": "10 GB" - }, - "volume_storage_id": "vNAT_Storage_6wdgwzedlb6sq18uzrr41sof7", - "description": "" - } - ], - "inputs": {}, - "vdus": [ - { - "volume_storages": [ - "vNAT_Storage_6wdgwzedlb6sq18uzrr41sof7" - ], - "description": "", - "dependencies": [], - "vls": [], - "properties": { - "name": "vNat", - "configurable_properties": { - "test": { - "additional_vnfc_configurable_properties": { - "aaa": "1", - "bbb": "2", - "ccc": "3" - } - } - }, - "description": "the virtual machine of vNat", - "nfvi_constraints": [ - "test" - ], - "boot_order": [ - "vNAT_Storage" - ] - }, - "vdu_id": "vdu_vNat", - "artifacts": [ - { - "artifact_name": "vNatVNFImage", - "type": "tosca.artifacts.nfv.SwImage", - "properties": { - "operating_system": "linux", - "sw_image": "/swimages/vRouterVNF_ControlPlane.qcow2", - "name": "vNatVNFImage", - "container_format": "bare", - "min_ram": "1 GB", - "disk_format": "qcow2", - "supported_virtualisation_environments": [ - "test_0" - ], - "version": "1.0", - "checksum": "5000", - "min_disk": "10 GB", - "size": "10 GB" - }, - "file": "/swimages/vRouterVNF_ControlPlane.qcow2" - } - ], - "nfv_compute": { - "flavor_extra_specs": { - "hw:cpu_sockets": "2", - "sw:ovs_dpdk": "true", - "hw:cpu_threads": "2", - "hw:numa_mem.1": "3072", - "hw:numa_mem.0": "1024", - "hw:numa_nodes": "2", - "hw:numa_cpus.0": "0,1", - "hw:numa_cpus.1": "2,3,4,5", - "hw:cpu_cores": "2", - "hw:cpu_threads_policy": "isolate" - }, - "cpu_frequency": "2.4 GHz", - "num_cpus": 2, - "mem_size": "10 GB" - }, - "local_storages": [], - "image_file": "vNatVNFImage", - "cps": [] - } - ], - "image_files": [ - { - "properties": { - "operating_system": "linux", - "sw_image": "/swimages/vRouterVNF_ControlPlane.qcow2", - "name": "vNatVNFImage", - "container_format": "bare", - "min_ram": "1 GB", - "disk_format": "qcow2", - "supported_virtualisation_environments": [ - "test_0" - ], - "version": "1.0", - "checksum": "5000", - "min_disk": "10 GB", - "size": "10 GB" - }, - "image_file_id": "vNatVNFImage", - "description": "" - } - ], - "routers": [], - "local_storages": [], - "vnf_exposed": { - "external_cps": [ - { - "key_name": "sriov_plane", - "cp_id": "SRIOV_Port" - } - ], - "forward_cps": [] - }, - "vls": [ - { - "route_id": "", - "vl_id": "sriov_link", - "route_external": False, - "description": "", - "properties": { - "vl_flavours": { - "vl_id": "aaaa" - }, - "connectivity_type": { - "layer_protocol": "ipv4", - "flow_pattern": "flat" - }, - "description": "sriov_link", - "test_access": [ - "test" - ] - } - } - ], - "cps": [ - { - "vl_id": "sriov_link", - "vdu_id": "vdu_vNat", - "description": "", - "cp_id": "SRIOV_Port", - "properties": { - "address_data": [ - { - "address_type": "ip_address", - "l3_address_data": { - "ip_address_type": "ipv4", - "floating_ip_activated": False, - "number_of_ip_address": 1, - "ip_address_assignment": True - } - } - ], - "description": "sriov port", - "layer_protocol": "ipv4", - "virtual_network_interface_requirements": [ - { - "requirement": { - "SRIOV": "true" - }, - "support_mandatory": False, - "name": "sriov", - "description": "sriov" - }, - { - "requirement": { - "SRIOV": "False" - }, - "support_mandatory": False, - "name": "normal", - "description": "normal" - } - ], - "role": "root", - "bitrate_requirement": 10 - } - } - ], - "metadata": { - "vnfSoftwareVersion": "1.0.0", - "vnfProductName": "zte", - "localizationLanguage": [ - "english", - "chinese" - ], - "vnfProvider": "zte", - "vnfmInfo": "zte", - "defaultLocalizationLanguage": "english", - "vnfdId": "zte-hss-1.0", - "id": "zte-hss-1.0", - "vnfProductInfoDescription": "hss", - "vnfdVersion": "1.0.0", - "vnfProductInfoName": "hss" - } - } - - def tearDown(self): - pass - - def assert_job_result(self, job_id, job_progress, job_detail): - jobs = JobStatusModel.objects.filter( - jobid=job_id, - progress=job_progress, - descp=job_detail) - self.assertEqual(1, len(jobs)) - - @mock.patch.object(SdcNfDistributeThread, 'run') - def test_nf_pkg_distribute_normal(self, mock_run): - resp = self.client.post("/api/nslcm/v1/vnfpackage", {"csarId": "1", "vimIds": ["1"]}, format='json') - self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED) - - def test_nf_pkg_distribute_when_csar_already_exist(self): - NfPackageModel(uuid="1", nfpackageid="1", vnfdid="vcpe_vfw_zte_1_0").save() - SdcNfDistributeThread(csar_id="1", vim_ids=["1"], lab_vim_id="", job_id="2").run() - self.assert_job_result("2", 255, "NF CSAR(1) already exists.") - - @mock.patch.object(restcall, 'call_req') - @mock.patch.object(sdc, 'download_artifacts') - @mock.patch.object(toscaparser, 'parse_vnfd') - def test_nf_pkg_distribute_when_vnfd_already_exist(self, mock_parse_vnfd, mock_download_artifacts, - mock_call_req): - mock_parse_vnfd.return_value = json.JSONEncoder().encode(self.vnfd_data) - mock_download_artifacts.return_value = "/home/hss.csar" - mock_call_req.return_value = [0, json.JSONEncoder().encode([{ - "uuid": "1", - "toscaModelURL": "https://127.0.0.1:1234/sdc/v1/hss.csar" - }]), '200'] - NfPackageModel(uuid="2", nfpackageid="2", vnfdid="zte-hss-1.0").save() - SdcNfDistributeThread(csar_id="1", vim_ids=["1"], lab_vim_id="", job_id="2").run() - self.assert_job_result("2", 255, "NFD(zte-hss-1.0) already exists.") - - @mock.patch.object(restcall, 'call_req') - @mock.patch.object(sdc, 'download_artifacts') - @mock.patch.object(toscaparser, 'parse_vnfd') - def test_nf_pkg_distribute_successfully(self, mock_parse_vnfd, mock_download_artifacts, mock_call_req): - mock_parse_vnfd.return_value = json.JSONEncoder().encode(self.vnfd_data) - mock_download_artifacts.return_value = "/home/hss.csar" - mock_call_req.return_value = [0, json.JSONEncoder().encode([{ - "uuid": "1", - "toscaModelURL": "https://127.0.0.1:1234/sdc/v1/hss.csar" - }]), '200'] - SdcNfDistributeThread(csar_id="1", vim_ids=["1"], lab_vim_id="", job_id="4").run() - self.assert_job_result("4", 100, "CSAR(1) distribute successfully.") - - ############################################################################################################### - - @mock.patch.object(SdcNfPkgDeleteThread, 'run') - def test_nf_pkg_delete_normal(self, mock_run): - resp = self.client.delete("/api/nslcm/v1/vnfpackage/1") - self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED) - - def test_nf_pkg_normal_delete(self): - NfPackageModel(uuid="2", nfpackageid="2", vnfdid="vcpe_vfw_zte_1_0").save() - SdcNfPkgDeleteThread(csar_id="2", job_id="2", force_delete=False).run() - self.assert_job_result("2", 100, "Delete CSAR(2) successfully.") - - def test_nf_pkg_force_delete(self): - NfPackageModel(uuid="1", nfpackageid="1", vnfdid="vcpe_vfw_zte_1_0").save() - NfInstModel(nfinstid="1", package_id="1").save() - SdcNfPkgDeleteThread(csar_id="1", job_id="2", force_delete=True).run() - self.assert_job_result("2", 100, "Delete CSAR(1) successfully.") - - def test_nf_pkg_delete_when_pkg_in_using(self): - NfPackageModel(uuid="3", nfpackageid="3", vnfdid="vcpe_vfw_zte_1_0").save() - NfInstModel(nfinstid="3", package_id="3").save() - SdcNfPkgDeleteThread(csar_id="3", job_id="2", force_delete=False).run() - self.assert_job_result("2", 255, "NfInst by csar(3) exists, cannot delete.") - - def test_nf_pkg_get_all(self): - NfPackageModel(uuid="3", nfpackageid="3", vnfdid="4").save() - - resp = self.client.get("/api/nslcm/v1/vnfpackage") - self.assertEqual(resp.status_code, status.HTTP_200_OK) - self.assertEqual({"csars": [{"csarId": "3", "vnfdId": "4"}]}, resp.data) - - @mock.patch.object(restcall, 'call_req') - def test_nf_pkg_get_one(self, mock_call_req): - NfPackageModel(uuid="4", nfpackageid="4", vnfdid="5", vendor="6", vnfdversion="7", vnfversion="8").save() - NfInstModel(nfinstid="1", package_id="4", nf_name="3").save() - mock_call_req.return_value = [0, json.JSONEncoder().encode({ - "packageInfo": { - "vnfdId": "5", - "vnfdProvider": "6", - "vnfdVersion": "7", - "vnfVersion": "8" - } - }), '200'] - - resp = self.client.get("/api/nslcm/v1/vnfpackage/4") - self.assertEqual(resp.status_code, status.HTTP_200_OK) - expect_data = { - "csarId": "4", - "packageInfo": { - "vnfdId": "5", - "vnfdProvider": "6", - "vnfdVersion": "7", - "vnfVersion": "8" - }, - "imageInfo": [], - "vnfInstanceInfo": [{ - "vnfInstanceId": "1", "vnfInstanceName": "3" - }] - } - self.assertEqual(expect_data, resp.data) diff --git a/lcm/packages/urls.py b/lcm/packages/urls.py deleted file mode 100644 index cdde953f..00000000 --- a/lcm/packages/urls.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2016 ZTE Corporation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from django.conf.urls import url -from rest_framework.urlpatterns import format_suffix_patterns -from lcm.packages import views - -urlpatterns = [ - url(r'^api/nslcm/v1/vnfpackage$', views.nf_distribute_get, name='nf_distribute_get'), - url(r'^api/nslcm/v1/vnfpackage/(?P<csarId>[0-9a-zA-Z\-\_]+)$', views.nf_rd_csar, name='nf_rd_csar'), - ######################################################################################### - url(r'^api/nslcm/v0/nspackage/(?P<csarId>[0-9a-zA-Z\-\_]+)/deletionpending$', - views.ns_delete_pending_csar, name='ns_delete_pending_csar'), - url(r'^api/nslcm/v0/nspackage/(?P<csarId>[0-9a-zA-Z\-\_]+)/(?P<operation>(disabled|enabled))$', - views.ns_set_state_csar, name='ns_set_state_csar'), - url(r'^api/nslcm/v0/vnfpackage/(?P<csarId>[0-9a-zA-Z\-\_]+)$', views.nf_access_csar, name='nf_access_csar'), - url(r'^api/nslcm/v0/vnfpackage$', views.nf_on_boarding, name='nf_on_boarding'), - url(r'^api/nslcm/v0/vnfpackage/(?P<csarId>[0-9a-zA-Z\-\_]+)/deletionpending$', - views.nf_delete_pending_csar, name='nf_delete_pending_csar'), ] - -urlpatterns = format_suffix_patterns(urlpatterns) diff --git a/lcm/packages/views.py b/lcm/packages/views.py deleted file mode 100644 index 0b6af8bd..00000000 --- a/lcm/packages/views.py +++ /dev/null @@ -1,143 +0,0 @@ -# Copyright 2016-2017 ZTE Corporation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging -import uuid - -from rest_framework import status -from rest_framework.decorators import api_view -from rest_framework.response import Response - -from lcm.pub.utils.values import ignore_case_get -from lcm.pub.utils.syscomm import fun_name -from lcm.packages import ns_package, nf_package, sdc_nf_package - -logger = logging.getLogger(__name__) - - -#################################################################################################### -@api_view(http_method_names=['POST', 'GET']) -def nf_distribute_get(request, *args, **kwargs): - logger.debug("Enter %s%s, method is %s", fun_name(), request.data, request.method) - ret, normal_status = None, None - if request.method == 'GET': - ret = sdc_nf_package.nf_get_csars() - normal_status = status.HTTP_200_OK - else: - csar_id = ignore_case_get(request.data, "csarId") - vim_ids = ignore_case_get(request.data, "vimIds") - lab_vim_id = ignore_case_get(request.data, "labVimId") - job_id = str(uuid.uuid4()) - sdc_nf_package.SdcNfDistributeThread(csar_id, vim_ids, lab_vim_id, job_id).start() - ret = [0, {"jobId": job_id}] - normal_status = status.HTTP_202_ACCEPTED - logger.debug("Leave %s, Return value is %s", fun_name(), ret) - if ret[0] != 0: - return Response(data={'error': ret[1]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) - return Response(data=ret[1], status=normal_status) - - -@api_view(http_method_names=['GET', 'DELETE']) -def nf_rd_csar(request, *args, **kwargs): - csar_id = ignore_case_get(kwargs, "csarId") - logger.info("Enter %s, method is %s, csar_id is %s", fun_name(), request.method, csar_id) - ret, normal_status = None, None - if request.method == 'GET': - ret = sdc_nf_package.nf_get_csar(csar_id) - normal_status = status.HTTP_200_OK - else: - force_delete = csar_id.endswith("force") - if force_delete: - csar_id = csar_id[:-5] - job_id = str(uuid.uuid4()) - sdc_nf_package.SdcNfPkgDeleteThread(csar_id, job_id, force_delete).start() - ret = [0, {"jobId": job_id}] - normal_status = status.HTTP_202_ACCEPTED - logger.info("Leave %s, Return value is %s", fun_name(), str(ret)) - if ret[0] != 0: - return Response(data={'error': ret[1]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) - return Response(data=ret[1], status=normal_status) - - -#################################################################################################### - - -@api_view(http_method_names=['DELETE']) -def ns_delete_pending_csar(request, *args, **kwargs): - csar_id = ignore_case_get(kwargs, "csarId") - logger.info("Enter %s, method is %s, csar_id is %s", fun_name(), request.method, csar_id) - ret = ns_package.ns_delete_pending_csar(csar_id) - logger.info("Leave %s, Return value is %s", fun_name(), str(ret)) - if ret[0] != 0: - return Response(data={'error': ret[1]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) - return Response(data=ret[1], status=status.HTTP_202_ACCEPTED) - - -@api_view(http_method_names=['PUT']) -def ns_set_state_csar(request, *args, **kwargs): - csar_id = ignore_case_get(kwargs, "csarId") - operation = ignore_case_get(kwargs, "operation") - logger.info("Enter %s, method is %s, csar_id is %s, operation is %s", fun_name(), request.method, csar_id, operation) - ret = ns_package.ns_set_state_csar(csar_id, operation) - logger.info("Leave %s, Return value is %s", fun_name(), str(ret)) - if ret[0] != 0: - return Response(data={'error': ret[1]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) - return Response(data=ret[1], status=status.HTTP_202_ACCEPTED) - - -################################################################################################################# -@api_view(http_method_names=['POST', 'GET']) -def nf_on_boarding(request, *args, **kwargs): - logger.info("Enter %s%s, method is %s", fun_name(), request.data, request.method) - if request.method == 'GET': - ret = nf_package.NfPackage().get_csars() - logger.debug("csars=%s", str(ret)) - return Response(data=ret, status=status.HTTP_200_OK) - csar_id = ignore_case_get(request.data, "csarId") - vim_ids = ignore_case_get(request.data, "vimIds") - lab_vim_id = ignore_case_get(request.data, "labVimId") - job_id = str(uuid.uuid4()) - nf_package.NfOnBoardingThread(csar_id, vim_ids, lab_vim_id, job_id).start() - ret = {"jobId": job_id} - logger.info("Leave %s, Return value is %s", fun_name(), str(ret)) - return Response(data=ret, status=status.HTTP_202_ACCEPTED) - - -@api_view(http_method_names=['GET', 'DELETE']) -def nf_access_csar(request, *args, **kwargs): - logger.info("Enter %s%s, method is %s", fun_name(), args, request.method) - csar_id = ignore_case_get(kwargs, "csarId") - if request.method == 'GET': - ret = nf_package.NfPackage().get_csar(csar_id) - logger.info("Leave %s, Return value is %s", fun_name(), str(ret)) - if ret[0] != 0: - return Response(data={'error': ret[1]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) - return Response(data=ret[1], status=status.HTTP_200_OK) - # NF package deleting - job_id = str(uuid.uuid4()) - nf_package.NfPkgDeleteThread(csar_id, job_id).start() - ret = {"jobId": job_id} - logger.info("Leave %s, Return value is %s", fun_name(), str(ret)) - return Response(data=ret, status=status.HTTP_202_ACCEPTED) - - -@api_view(http_method_names=['DELETE']) -def nf_delete_pending_csar(request, *args, **kwargs): - logger.info("Enter %s%s, method is %s", fun_name(), args, request.method) - csar_id = ignore_case_get(kwargs, "csarId") - job_id = str(uuid.uuid4()) - nf_package.NfPkgDeletePendingThread(csar_id, job_id).start() - ret = {"jobId": job_id} - logger.info("Leave %s, Return value is %s", fun_name(), str(ret)) - return Response(data=ret, status=status.HTTP_202_ACCEPTED) diff --git a/lcm/urls.py b/lcm/urls.py index af5e7f69..729057f0 100644 --- a/lcm/urls.py +++ b/lcm/urls.py @@ -20,7 +20,6 @@ from lcm.pub.config.config import REG_TO_MSB_WHEN_START, REG_TO_MSB_REG_URL, REG urlpatterns = [ url(r'^', include('lcm.samples.urls')), - url(r'^', include('lcm.packages.urls')), url(r'^', include('lcm.ns.vnfs.urls')), url(r'^', include('lcm.ns.vls.urls')), url(r'^', include('lcm.ns.sfcs.urls')), |