Get original vendor package under the ONBOARDING_PACKAGE directory from SDC resource...
[modeling/etsicatalog.git] / catalog / packages / biz / sdc_vnf_package.py
1 # Copyright 2017 ZTE Corporation.
2 #
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
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
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.
14
15 import json
16 import logging
17 import os
18 import sys
19 import threading
20 import traceback
21
22 from catalog.packages.const import PKG_STATUS
23 from catalog.pub.config.config import CATALOG_ROOT_PATH, CATALOG_URL_PATH
24 from catalog.pub.config.config import REG_TO_MSB_REG_PARAM
25 from catalog.pub.database.models import VnfPackageModel
26 from catalog.pub.exceptions import CatalogException
27 from catalog.pub.msapi import sdc
28 from catalog.pub.utils import fileutil
29 from catalog.pub.utils import toscaparser
30 from catalog.pub.utils.jobutil import JobUtil
31
32 logger = logging.getLogger(__name__)
33
34 JOB_ERROR = 255
35
36
37 def nf_get_csars():
38     ret = None
39     try:
40         ret = NfPackage().get_csars()
41     except CatalogException as e:
42         return [1, e.args[0]]
43     except Exception as e:
44         logger.error(e.args[0])
45         logger.error(traceback.format_exc())
46         return [1, str(sys.exc_info())]
47     return ret
48
49
50 def nf_get_csar(csar_id):
51     ret = None
52     try:
53         ret = NfPackage().get_csar(csar_id)
54     except CatalogException as e:
55         return [1, e.args[0]]
56     except Exception as e:
57         logger.error(e.args[0])
58         logger.error(traceback.format_exc())
59         return [1, str(sys.exc_info())]
60     return ret
61
62
63 def parse_vnfd(csar_id, inputs):
64     ret = None
65     try:
66         nf_pkg = VnfPackageModel.objects.filter(vnfPackageId=csar_id)
67         if not nf_pkg:
68             raise CatalogException("VNF CSAR(%s) does not exist." % csar_id)
69         csar_path = nf_pkg[0].localFilePath
70         ret = {"model": toscaparser.parse_vnfd(csar_path, inputs)}
71     except CatalogException as e:
72         return [1, e.args[0]]
73     except Exception as e:
74         logger.error(e.args[0])
75         logger.error(traceback.format_exc())
76         return [1, str(sys.exc_info())]
77     return [0, ret]
78
79
80 class NfDistributeThread(threading.Thread):
81     """
82     Sdc NF Package Distribute
83     """
84
85     def __init__(self, csar_id, vim_ids, lab_vim_id, job_id):
86         threading.Thread.__init__(self)
87         self.csar_id = csar_id
88         self.vim_ids = vim_ids
89         self.lab_vim_id = lab_vim_id
90         self.job_id = job_id
91
92         self.csar_save_path = os.path.join(CATALOG_ROOT_PATH, csar_id)
93
94     def run(self):
95         try:
96             self.on_distribute()
97         except CatalogException as e:
98             self.rollback_distribute()
99             JobUtil.add_job_status(self.job_id, JOB_ERROR, e.args[0])
100         except Exception as e:
101             logger.error(e.args[0])
102             logger.error(traceback.format_exc())
103             logger.error(str(sys.exc_info()))
104             self.rollback_distribute()
105             JobUtil.add_job_status(self.job_id, JOB_ERROR, "Failed to distribute CSAR(%s)" % self.csar_id)
106
107     def on_distribute(self):
108         JobUtil.create_job(
109             inst_type='nf',
110             jobaction='on_distribute',
111             inst_id=self.csar_id,
112             job_id=self.job_id)
113         JobUtil.add_job_status(self.job_id, 5, "Start CSAR(%s) distribute." % self.csar_id)
114
115         if VnfPackageModel.objects.filter(vnfPackageId=self.csar_id):
116             err_msg = "NF CSAR(%s) already exists." % self.csar_id
117             JobUtil.add_job_status(self.job_id, JOB_ERROR, err_msg)
118             return
119
120         artifact = sdc.get_artifact(sdc.ASSETTYPE_RESOURCES, self.csar_id)
121         local_path = os.path.join(CATALOG_ROOT_PATH, self.csar_id)
122         csar_name = "%s.csar" % artifact.get("name", self.csar_id)
123         local_file_name = sdc.download_artifacts(artifact["toscaModelURL"], local_path, csar_name)
124         if local_file_name.endswith(".csar") or local_file_name.endswith(".zip"):
125             fileutil.unzip_csar(local_file_name, local_path)
126             vendor_vnf_file = ""
127             # find original vendor ETSI package under the ONBOARDING_PACKAGE directory
128             onboarding_package_dir = os.path.join(local_path, "Artifacts/Deployment/ONBOARDED_PACKAGE")
129             if os.path.exists(onboarding_package_dir):
130                 files = os.listdir(onboarding_package_dir)
131                 for file_name in files:
132                     a_file = os.path.join(onboarding_package_dir, file_name)
133                     if os.path.isfile(a_file) & file_name.endswith(".csar"):
134                         vendor_vnf_file = a_file
135                         break
136
137             # find original vendor ETSI package under Artifacts/Deployment/OTHER directory
138             if vendor_vnf_file.isspace():
139                 vendor_vnf_file = os.path.join(local_path, "Artifacts/Deployment/OTHER/vnf.csar")
140                 if os.path.exists(vendor_vnf_file):
141                     local_file_name = vendor_vnf_file
142             else:
143                 local_file_name = vendor_vnf_file
144
145         vnfd_json = toscaparser.parse_vnfd(local_file_name)
146         vnfd = json.JSONDecoder().decode(vnfd_json)
147
148         if not vnfd.get("vnf"):
149             raise CatalogException("VNF properties and metadata in VNF Package(id=%s) are empty." % self.csar_id)
150
151         vnfd_id = vnfd["vnf"]["properties"].get("descriptor_id", "")
152         if VnfPackageModel.objects.filter(vnfdId=vnfd_id):
153             logger.error("VNF package(%s) already exists.", vnfd_id)
154             raise CatalogException("VNF package(%s) already exists." % vnfd_id)
155         JobUtil.add_job_status(self.job_id, 30, "Save CSAR(%s) to database." % self.csar_id)
156         vnfd_ver = vnfd["vnf"]["properties"].get("descriptor_version", "")
157         vnf_provider = vnfd["vnf"]["properties"].get("provider", "")
158         vnf_software_version = vnfd["vnf"]["properties"].get("software_version", "")
159         vnfd_product_name = vnfd["vnf"]["properties"].get("product_name", "")
160         VnfPackageModel(
161             vnfPackageId=self.csar_id,
162             vnfdId=vnfd_id,
163             vnfVendor=vnf_provider,
164             vnfdProductName=vnfd_product_name,
165             vnfdVersion=vnfd_ver,
166             vnfSoftwareVersion=vnf_software_version,
167             vnfdModel=vnfd_json,
168             localFilePath=local_file_name,
169             vnfPackageUri=csar_name,
170             onboardingState=PKG_STATUS.ONBOARDED,
171             operationalState=PKG_STATUS.ENABLED,
172             usageState=PKG_STATUS.NOT_IN_USE
173         ).save()
174         JobUtil.add_job_status(self.job_id, 100, "CSAR(%s) distribute successfully." % self.csar_id)
175
176     def rollback_distribute(self):
177         try:
178             VnfPackageModel.objects.filter(vnfPackageId=self.csar_id).delete()
179             fileutil.delete_dirs(self.csar_save_path)
180         except Exception as e:
181             logger.error(e.args[0])
182             logger.error(traceback.format_exc())
183             logger.error(str(sys.exc_info()))
184
185
186 class NfPkgDeleteThread(threading.Thread):
187     """
188     Sdc NF Package Deleting
189     """
190
191     def __init__(self, csar_id, job_id):
192         threading.Thread.__init__(self)
193         self.csar_id = csar_id
194         self.job_id = job_id
195
196     def run(self):
197         try:
198             self.delete_csar()
199         except CatalogException as e:
200             JobUtil.add_job_status(self.job_id, JOB_ERROR, e.args[0])
201         except Exception as e:
202             logger.error(e.args[0])
203             logger.error(traceback.format_exc())
204             logger.error(str(sys.exc_info()))
205             JobUtil.add_job_status(self.job_id, JOB_ERROR, "Failed to delete CSAR(%s)" % self.csar_id)
206
207     def delete_csar(self):
208         JobUtil.create_job(
209             inst_type='nf',
210             jobaction='delete',
211             inst_id=self.csar_id,
212             job_id=self.job_id)
213         JobUtil.add_job_status(self.job_id, 5, "Start to delete CSAR(%s)." % self.csar_id)
214
215         VnfPackageModel.objects.filter(vnfPackageId=self.csar_id).delete()
216
217         JobUtil.add_job_status(self.job_id, 50, "Delete local CSAR(%s) file." % self.csar_id)
218
219         csar_save_path = os.path.join(CATALOG_ROOT_PATH, self.csar_id)
220         fileutil.delete_dirs(csar_save_path)
221
222         JobUtil.add_job_status(self.job_id, 100, "Delete CSAR(%s) successfully." % self.csar_id)
223
224
225 class NfPackage(object):
226     """
227     Actions for sdc nf package.
228     """
229
230     def __init__(self):
231         pass
232
233     def get_csars(self):
234         csars = []
235         nf_pkgs = VnfPackageModel.objects.filter()
236         for nf_pkg in nf_pkgs:
237             ret = self.get_csar(nf_pkg.vnfPackageId)
238             csars.append(ret[1])
239         return [0, csars]
240
241     def get_csar(self, csar_id):
242         pkg_info = {}
243         nf_pkg = VnfPackageModel.objects.filter(vnfPackageId=csar_id)
244         if not nf_pkg:
245             nf_pkg = VnfPackageModel.objects.filter(vnfdId=csar_id)
246
247         if nf_pkg:
248             db_csar_id = nf_pkg[0].vnfPackageId
249             pkg_info["vnfdId"] = nf_pkg[0].vnfdId
250             pkg_info["vnfPackageId"] = nf_pkg[0].vnfPackageId
251             pkg_info["vnfdProvider"] = nf_pkg[0].vnfVendor
252             pkg_info["vnfdVersion"] = nf_pkg[0].vnfdVersion
253             pkg_info["vnfVersion"] = nf_pkg[0].vnfSoftwareVersion
254             pkg_info["csarName"] = nf_pkg[0].vnfPackageUri
255             pkg_info["vnfdModel"] = nf_pkg[0].vnfdModel
256             pkg_info["downloadUrl"] = "http://%s:%s/%s/%s/%s" % (
257                 REG_TO_MSB_REG_PARAM[0]["nodes"][0]["ip"],
258                 REG_TO_MSB_REG_PARAM[0]["nodes"][0]["port"],
259                 CATALOG_URL_PATH,
260                 db_csar_id,
261                 nf_pkg[0].vnfPackageUri)
262         else:
263             raise CatalogException("Vnf package[%s] not Found." % csar_id)
264
265         csar_info = {
266             "csarId": db_csar_id,
267             "packageInfo": pkg_info,
268             "imageInfo": []
269         }
270         return [0, csar_info]