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 import const
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
33 from catalog.packages.biz.notificationsutil import PkgNotifications
35 logger = logging.getLogger(__name__)
43 ret = NfPackage().get_csars()
44 except CatalogException as e:
46 except Exception as e:
47 logger.error(e.args[0])
48 logger.error(traceback.format_exc())
49 return [1, str(sys.exc_info())]
53 def nf_get_csar(csar_id):
56 ret = NfPackage().get_csar(csar_id)
57 except CatalogException as e:
59 except Exception as e:
60 logger.error(e.args[0])
61 logger.error(traceback.format_exc())
62 return [1, str(sys.exc_info())]
66 def parse_vnfd(csar_id, inputs):
69 nf_pkg = VnfPackageModel.objects.filter(vnfPackageId=csar_id)
71 raise CatalogException("VNF CSAR(%s) does not exist." % csar_id)
72 csar_path = nf_pkg[0].localFilePath
73 ret = {"model": toscaparser.parse_vnfd(csar_path, inputs)}
74 except CatalogException as e:
76 except Exception as e:
77 logger.error(e.args[0])
78 logger.error(traceback.format_exc())
79 return [1, str(sys.exc_info())]
83 class NfDistributeThread(threading.Thread):
85 Sdc NF Package Distribute
88 def __init__(self, csar_id, vim_ids, lab_vim_id, job_id):
89 threading.Thread.__init__(self)
90 self.csar_id = csar_id
91 self.vim_ids = vim_ids
92 self.lab_vim_id = lab_vim_id
95 self.csar_save_path = os.path.join(CATALOG_ROOT_PATH, csar_id)
100 except PackageHasExistsException as e:
101 self.rollback_distribute()
102 JobUtil.add_job_status(self.job_id, JOB_ERROR, e.args[0], error_code=JOB_ERROR_CODE.PACKAGE_EXIST)
103 except CatalogException as e:
104 self.rollback_distribute()
105 JobUtil.add_job_status(self.job_id, JOB_ERROR, e.args[0], error_code=JOB_ERROR_CODE.CATALOG_EXCEPTION)
106 except Exception as e:
107 logger.error(e.args[0])
108 logger.error(traceback.format_exc())
109 logger.error(str(sys.exc_info()))
110 self.rollback_distribute()
111 JobUtil.add_job_status(self.job_id, JOB_ERROR, "Failed to distribute CSAR(%s)" % self.csar_id,
112 error_code=JOB_ERROR_CODE.SYSTEM_ERROR)
114 def on_distribute(self):
117 jobaction='on_distribute',
118 inst_id=self.csar_id,
120 JobUtil.add_job_status(self.job_id, 5, "Start CSAR(%s) distribute." % self.csar_id)
122 if VnfPackageModel.objects.filter(vnfPackageId=self.csar_id):
123 err_msg = "NF CSAR(%s) already exists." % self.csar_id
124 JobUtil.add_job_status(self.job_id, JOB_ERROR, err_msg, error_code=JOB_ERROR_CODE.PACKAGE_EXIST)
127 artifact = sdc.get_artifact(sdc.ASSETTYPE_RESOURCES, self.csar_id)
128 local_path = os.path.join(CATALOG_ROOT_PATH, self.csar_id)
129 csar_name = "%s.csar" % artifact.get("name", self.csar_id)
130 local_file_name = sdc.download_artifacts(artifact["toscaModelURL"], local_path, csar_name)
131 if local_file_name.endswith(".csar") or local_file_name.endswith(".zip"):
132 fileutil.unzip_csar(local_file_name, local_path)
134 # find original vendor ETSI package under the ONBOARDING_PACKAGE directory
135 onboarding_package_dir = os.path.join(local_path, "Artifacts/Deployment/ONBOARDED_PACKAGE")
136 if os.path.exists(onboarding_package_dir):
137 files = os.listdir(onboarding_package_dir)
138 for file_name in files:
139 a_file = os.path.join(onboarding_package_dir, file_name)
140 if os.path.isfile(a_file) & file_name.endswith(".csar"):
141 vendor_vnf_file = a_file
144 # find original vendor ETSI package under Artifacts/Deployment/OTHER directory
145 if vendor_vnf_file.strip() == '':
146 vendor_vnf_file = os.path.join(local_path, "Artifacts/Deployment/OTHER/vnf.csar")
147 if os.path.exists(vendor_vnf_file):
148 local_file_name = vendor_vnf_file
150 local_file_name = vendor_vnf_file
152 # create VNFD zip file
153 self.create_vnfd_zip(self.csar_id, vendor_vnf_file)
155 vnfd_json = toscaparser.parse_vnfd(local_file_name)
156 vnfd = json.JSONDecoder().decode(vnfd_json)
158 if not vnfd.get("vnf"):
159 raise CatalogException("VNF properties and metadata in VNF Package(id=%s) are empty." % self.csar_id)
161 vnfd_id = vnfd["vnf"]["properties"].get("descriptor_id", "")
162 if VnfPackageModel.objects.filter(vnfdId=vnfd_id):
163 logger.error("VNF package(%s) already exists.", vnfd_id)
164 raise PackageHasExistsException("VNF package(%s) already exists." % vnfd_id)
165 JobUtil.add_job_status(self.job_id, 30, "Save CSAR(%s) to database." % self.csar_id)
166 vnfd_ver = vnfd["vnf"]["properties"].get("descriptor_version", "")
167 vnf_provider = vnfd["vnf"]["properties"].get("provider", "")
168 vnf_software_version = vnfd["vnf"]["properties"].get("software_version", "")
169 vnfd_product_name = vnfd["vnf"]["properties"].get("product_name", "")
171 vnfPackageId=self.csar_id,
173 vnfVendor=vnf_provider,
174 vnfdProductName=vnfd_product_name,
175 vnfdVersion=vnfd_ver,
176 vnfSoftwareVersion=vnf_software_version,
178 localFilePath=local_file_name,
179 vnfPackageUri=csar_name,
180 onboardingState=const.PKG_STATUS.ONBOARDED,
181 operationalState=const.PKG_STATUS.ENABLED,
182 usageState=const.PKG_STATUS.NOT_IN_USE
184 JobUtil.add_job_status(self.job_id, 100, "CSAR(%s) distribute successfully." % self.csar_id)
185 send_notification(self.csar_id, const.PKG_NOTIFICATION_TYPE.ONBOARDING,
186 const.PKG_CHANGE_TYPE.OP_STATE_CHANGE)
188 def create_vnfd_zip(self, csar_id, vendor_vnf_file):
190 Create VNFD zip file.
191 :param csar_id: CSAR Id
192 :param vendor_vnf_file: the vendor original package(csar)
195 if os.path.exists(vendor_vnf_file):
196 # create VNFD from vendor original package
197 VnfPackage().creat_vnfd(csar_id, vendor_vnf_file)
200 vnf_package_path = os.path.join(CATALOG_ROOT_PATH, self.csar_id)
201 vnfd_zip_file = os.path.join(vnf_package_path, 'VNFD.zip')
202 with zipfile.ZipFile(vnfd_zip_file, 'w', zipfile.ZIP_DEFLATED) as vnfd_zip:
203 def_path = os.path.join(vnf_package_path, "Definitions")
204 if os.path.exists(def_path):
205 def_files = os.listdir(def_path)
206 for def_file in def_files:
207 full_path = os.path.join(def_path, def_file)
208 vnfd_zip.write(full_path, def_file)
209 except Exception as e:
211 if os.path.exists(vnfd_zip_file):
212 os.remove(vnfd_zip_file)
214 def rollback_distribute(self):
216 VnfPackageModel.objects.filter(vnfPackageId=self.csar_id).delete()
217 fileutil.delete_dirs(self.csar_save_path)
218 except Exception as e:
219 logger.error(e.args[0])
220 logger.error(traceback.format_exc())
221 logger.error(str(sys.exc_info()))
224 class NfPkgDeleteThread(threading.Thread):
226 Sdc NF Package Deleting
229 def __init__(self, csar_id, job_id):
230 threading.Thread.__init__(self)
231 self.csar_id = csar_id
237 except CatalogException as e:
238 JobUtil.add_job_status(self.job_id, JOB_ERROR, e.args[0])
239 except Exception as e:
240 logger.error(e.args[0])
241 logger.error(traceback.format_exc())
242 logger.error(str(sys.exc_info()))
243 JobUtil.add_job_status(self.job_id, JOB_ERROR, "Failed to delete CSAR(%s)" % self.csar_id)
245 def delete_csar(self):
249 inst_id=self.csar_id,
251 JobUtil.add_job_status(self.job_id, 5, "Start to delete CSAR(%s)." % self.csar_id)
252 send_notification(self.csar_id, const.PKG_NOTIFICATION_TYPE.CHANGE,
253 const.PKG_CHANGE_TYPE.PKG_DELETE)
254 VnfPackageModel.objects.filter(vnfPackageId=self.csar_id).delete()
256 JobUtil.add_job_status(self.job_id, 50, "Delete local CSAR(%s) file." % self.csar_id)
258 csar_save_path = os.path.join(CATALOG_ROOT_PATH, self.csar_id)
259 fileutil.delete_dirs(csar_save_path)
261 JobUtil.add_job_status(self.job_id, 100, "Delete CSAR(%s) successfully." % self.csar_id)
264 class NfPackage(object):
266 Actions for sdc nf package.
274 nf_pkgs = VnfPackageModel.objects.filter()
275 for nf_pkg in nf_pkgs:
276 ret = self.get_csar(nf_pkg.vnfPackageId)
280 def get_csar(self, csar_id):
282 nf_pkg = VnfPackageModel.objects.filter(vnfPackageId=csar_id)
284 nf_pkg = VnfPackageModel.objects.filter(vnfdId=csar_id)
287 db_csar_id = nf_pkg[0].vnfPackageId
288 pkg_info["vnfdId"] = nf_pkg[0].vnfdId
289 pkg_info["vnfPackageId"] = nf_pkg[0].vnfPackageId
290 pkg_info["vnfdProvider"] = nf_pkg[0].vnfVendor
291 pkg_info["vnfdVersion"] = nf_pkg[0].vnfdVersion
292 pkg_info["vnfVersion"] = nf_pkg[0].vnfSoftwareVersion
293 pkg_info["csarName"] = nf_pkg[0].vnfPackageUri
294 pkg_info["vnfdModel"] = nf_pkg[0].vnfdModel
295 pkg_info["downloadUrl"] = "http://%s:%s/%s/%s/%s" % (
296 REG_TO_MSB_REG_PARAM[0]["nodes"][0]["ip"],
297 REG_TO_MSB_REG_PARAM[0]["nodes"][0]["port"],
300 nf_pkg[0].vnfPackageUri)
302 raise CatalogException("Vnf package[%s] not Found." % csar_id)
305 "csarId": db_csar_id,
306 "packageInfo": pkg_info,
309 return [0, csar_info]
312 def send_notification(pkg_id, type, pkg_change_type, operational_state=None):
313 notify = PkgNotifications(type, pkg_id, change_type=pkg_change_type,
314 operational_state=operational_state)
315 notify.send_notification()