1 # Copyright 2017 ZTE Corporation.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
23 from catalog.packages.biz.vnf_package import VnfPackage
24 from catalog.packages.const import PKG_STATUS
25 from catalog.pub.config.config import CATALOG_ROOT_PATH, CATALOG_URL_PATH
26 from catalog.pub.config.config import REG_TO_MSB_REG_PARAM
27 from catalog.pub.database.models import VnfPackageModel
28 from catalog.pub.exceptions import CatalogException, PackageHasExistsException
29 from catalog.pub.msapi import sdc
30 from catalog.pub.utils import fileutil
31 from catalog.pub.utils import toscaparser
32 from catalog.pub.utils.jobutil import JobUtil, JOB_ERROR_CODE
34 logger = logging.getLogger(__name__)
42 ret = NfPackage().get_csars()
43 except CatalogException as e:
45 except Exception as e:
46 logger.error(e.args[0])
47 logger.error(traceback.format_exc())
48 return [1, str(sys.exc_info())]
52 def nf_get_csar(csar_id):
55 ret = NfPackage().get_csar(csar_id)
56 except CatalogException as e:
58 except Exception as e:
59 logger.error(e.args[0])
60 logger.error(traceback.format_exc())
61 return [1, str(sys.exc_info())]
65 def parse_vnfd(csar_id, inputs):
68 nf_pkg = VnfPackageModel.objects.filter(vnfPackageId=csar_id)
70 raise CatalogException("VNF CSAR(%s) does not exist." % csar_id)
71 csar_path = nf_pkg[0].localFilePath
72 ret = {"model": toscaparser.parse_vnfd(csar_path, inputs)}
73 except CatalogException as e:
75 except Exception as e:
76 logger.error(e.args[0])
77 logger.error(traceback.format_exc())
78 return [1, str(sys.exc_info())]
82 class NfDistributeThread(threading.Thread):
84 Sdc NF Package Distribute
87 def __init__(self, csar_id, vim_ids, lab_vim_id, job_id):
88 threading.Thread.__init__(self)
89 self.csar_id = csar_id
90 self.vim_ids = vim_ids
91 self.lab_vim_id = lab_vim_id
94 self.csar_save_path = os.path.join(CATALOG_ROOT_PATH, csar_id)
99 except PackageHasExistsException as e:
100 self.rollback_distribute()
101 JobUtil.add_job_status(self.job_id, JOB_ERROR, e.args[0], error_code=JOB_ERROR_CODE.PACKAGE_EXIST)
102 except CatalogException as e:
103 self.rollback_distribute()
104 JobUtil.add_job_status(self.job_id, JOB_ERROR, e.args[0], error_code=JOB_ERROR_CODE.CATALOG_EXCEPTION)
105 except Exception as e:
106 logger.error(e.args[0])
107 logger.error(traceback.format_exc())
108 logger.error(str(sys.exc_info()))
109 self.rollback_distribute()
110 JobUtil.add_job_status(self.job_id, JOB_ERROR, "Failed to distribute CSAR(%s)" % self.csar_id,
111 error_code=JOB_ERROR_CODE.SYSTEM_ERROR)
113 def on_distribute(self):
116 jobaction='on_distribute',
117 inst_id=self.csar_id,
119 JobUtil.add_job_status(self.job_id, 5, "Start CSAR(%s) distribute." % self.csar_id)
121 if VnfPackageModel.objects.filter(vnfPackageId=self.csar_id):
122 err_msg = "NF CSAR(%s) already exists." % self.csar_id
123 JobUtil.add_job_status(self.job_id, JOB_ERROR, err_msg, error_code=JOB_ERROR_CODE.PACKAGE_EXIST)
126 artifact = sdc.get_artifact(sdc.ASSETTYPE_RESOURCES, self.csar_id)
127 local_path = os.path.join(CATALOG_ROOT_PATH, self.csar_id)
128 csar_name = "%s.csar" % artifact.get("name", self.csar_id)
129 local_file_name = sdc.download_artifacts(artifact["toscaModelURL"], local_path, csar_name)
130 if local_file_name.endswith(".csar") or local_file_name.endswith(".zip"):
131 fileutil.unzip_csar(local_file_name, local_path)
133 # find original vendor ETSI package under the ONBOARDING_PACKAGE directory
134 onboarding_package_dir = os.path.join(local_path, "Artifacts/Deployment/ONBOARDED_PACKAGE")
135 if os.path.exists(onboarding_package_dir):
136 files = os.listdir(onboarding_package_dir)
137 for file_name in files:
138 a_file = os.path.join(onboarding_package_dir, file_name)
139 if os.path.isfile(a_file) & file_name.endswith(".csar"):
140 vendor_vnf_file = a_file
143 # find original vendor ETSI package under Artifacts/Deployment/OTHER directory
144 if vendor_vnf_file.strip() == '':
145 vendor_vnf_file = os.path.join(local_path, "Artifacts/Deployment/OTHER/vnf.csar")
146 if os.path.exists(vendor_vnf_file):
147 local_file_name = vendor_vnf_file
149 local_file_name = vendor_vnf_file
151 # create VNFD zip file
152 self.create_vnfd_zip(self.csar_id, vendor_vnf_file)
154 vnfd_json = toscaparser.parse_vnfd(local_file_name)
155 vnfd = json.JSONDecoder().decode(vnfd_json)
157 if not vnfd.get("vnf"):
158 raise CatalogException("VNF properties and metadata in VNF Package(id=%s) are empty." % self.csar_id)
160 vnfd_id = vnfd["vnf"]["properties"].get("descriptor_id", "")
161 if VnfPackageModel.objects.filter(vnfdId=vnfd_id):
162 logger.error("VNF package(%s) already exists.", vnfd_id)
163 raise PackageHasExistsException("VNF package(%s) already exists." % vnfd_id)
164 JobUtil.add_job_status(self.job_id, 30, "Save CSAR(%s) to database." % self.csar_id)
165 vnfd_ver = vnfd["vnf"]["properties"].get("descriptor_version", "")
166 vnf_provider = vnfd["vnf"]["properties"].get("provider", "")
167 vnf_software_version = vnfd["vnf"]["properties"].get("software_version", "")
168 vnfd_product_name = vnfd["vnf"]["properties"].get("product_name", "")
170 vnfPackageId=self.csar_id,
172 vnfVendor=vnf_provider,
173 vnfdProductName=vnfd_product_name,
174 vnfdVersion=vnfd_ver,
175 vnfSoftwareVersion=vnf_software_version,
177 localFilePath=local_file_name,
178 vnfPackageUri=csar_name,
179 onboardingState=PKG_STATUS.ONBOARDED,
180 operationalState=PKG_STATUS.ENABLED,
181 usageState=PKG_STATUS.NOT_IN_USE
183 JobUtil.add_job_status(self.job_id, 100, "CSAR(%s) distribute successfully." % self.csar_id)
185 def create_vnfd_zip(self, csar_id, vendor_vnf_file):
187 Create VNFD zip file.
188 :param csar_id: CSAR Id
189 :param vendor_vnf_file: the vendor original package(csar)
192 if os.path.exists(vendor_vnf_file):
193 # create VNFD from vendor original package
194 VnfPackage().creat_vnfd(csar_id, vendor_vnf_file)
197 vnf_package_path = os.path.join(CATALOG_ROOT_PATH, self.csar_id)
198 vnfd_zip_file = os.path.join(vnf_package_path, 'VNFD.zip')
199 with zipfile.ZipFile(vnfd_zip_file, 'w', zipfile.ZIP_DEFLATED) as vnfd_zip:
200 def_path = os.path.join(vnf_package_path, "Definitions")
201 if os.path.exists(def_path):
202 def_files = os.listdir(def_path)
203 for def_file in def_files:
204 full_path = os.path.join(def_path, def_file)
205 vnfd_zip.write(full_path, def_file)
206 except Exception as e:
208 if os.path.exists(vnfd_zip_file):
209 os.remove(vnfd_zip_file)
211 def rollback_distribute(self):
213 VnfPackageModel.objects.filter(vnfPackageId=self.csar_id).delete()
214 fileutil.delete_dirs(self.csar_save_path)
215 except Exception as e:
216 logger.error(e.args[0])
217 logger.error(traceback.format_exc())
218 logger.error(str(sys.exc_info()))
221 class NfPkgDeleteThread(threading.Thread):
223 Sdc NF Package Deleting
226 def __init__(self, csar_id, job_id):
227 threading.Thread.__init__(self)
228 self.csar_id = csar_id
234 except CatalogException as e:
235 JobUtil.add_job_status(self.job_id, JOB_ERROR, e.args[0])
236 except Exception as e:
237 logger.error(e.args[0])
238 logger.error(traceback.format_exc())
239 logger.error(str(sys.exc_info()))
240 JobUtil.add_job_status(self.job_id, JOB_ERROR, "Failed to delete CSAR(%s)" % self.csar_id)
242 def delete_csar(self):
246 inst_id=self.csar_id,
248 JobUtil.add_job_status(self.job_id, 5, "Start to delete CSAR(%s)." % self.csar_id)
250 VnfPackageModel.objects.filter(vnfPackageId=self.csar_id).delete()
252 JobUtil.add_job_status(self.job_id, 50, "Delete local CSAR(%s) file." % self.csar_id)
254 csar_save_path = os.path.join(CATALOG_ROOT_PATH, self.csar_id)
255 fileutil.delete_dirs(csar_save_path)
257 JobUtil.add_job_status(self.job_id, 100, "Delete CSAR(%s) successfully." % self.csar_id)
260 class NfPackage(object):
262 Actions for sdc nf package.
270 nf_pkgs = VnfPackageModel.objects.filter()
271 for nf_pkg in nf_pkgs:
272 ret = self.get_csar(nf_pkg.vnfPackageId)
276 def get_csar(self, csar_id):
278 nf_pkg = VnfPackageModel.objects.filter(vnfPackageId=csar_id)
280 nf_pkg = VnfPackageModel.objects.filter(vnfdId=csar_id)
283 db_csar_id = nf_pkg[0].vnfPackageId
284 pkg_info["vnfdId"] = nf_pkg[0].vnfdId
285 pkg_info["vnfPackageId"] = nf_pkg[0].vnfPackageId
286 pkg_info["vnfdProvider"] = nf_pkg[0].vnfVendor
287 pkg_info["vnfdVersion"] = nf_pkg[0].vnfdVersion
288 pkg_info["vnfVersion"] = nf_pkg[0].vnfSoftwareVersion
289 pkg_info["csarName"] = nf_pkg[0].vnfPackageUri
290 pkg_info["vnfdModel"] = nf_pkg[0].vnfdModel
291 pkg_info["downloadUrl"] = "http://%s:%s/%s/%s/%s" % (
292 REG_TO_MSB_REG_PARAM[0]["nodes"][0]["ip"],
293 REG_TO_MSB_REG_PARAM[0]["nodes"][0]["port"],
296 nf_pkg[0].vnfPackageUri)
298 raise CatalogException("Vnf package[%s] not Found." % csar_id)
301 "csarId": db_csar_id,
302 "packageInfo": pkg_info,
305 return [0, csar_info]