Ns descriptor related stuffs.
[vfc/nfvo/catalog.git] / catalog / packages / biz / vnfpackage.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.pub.config.config import CATALOG_ROOT_PATH, CATALOG_URL_PATH, MSB_SERVICE_IP
23 from catalog.pub.config.config import REG_TO_MSB_REG_PARAM
24 from catalog.pub.database.models import VnfPackageModel
25 from catalog.pub.exceptions import CatalogException
26 from catalog.pub.msapi import sdc
27 from catalog.pub.utils import fileutil
28 from catalog.pub.utils import toscaparser
29 from catalog.pub.utils.jobutil import JobUtil
30
31 logger = logging.getLogger(__name__)
32
33 JOB_ERROR = 255
34
35
36 def nf_get_csars():
37     ret = None
38     try:
39         ret = NfPackage().get_csars()
40     except CatalogException as e:
41         return [1, e.message]
42     except Exception as e:
43         logger.error(e.message)
44         logger.error(traceback.format_exc())
45         return [1, str(sys.exc_info())]
46     return ret
47
48
49 def nf_get_csar(csar_id):
50     ret = None
51     try:
52         ret = NfPackage().get_csar(csar_id)
53     except CatalogException as e:
54         return [1, e.message]
55     except Exception as e:
56         logger.error(e.message)
57         logger.error(traceback.format_exc())
58         return [1, str(sys.exc_info())]
59     return ret
60
61
62 def parse_vnfd(csar_id, inputs):
63     ret = None
64     try:
65         nf_pkg = VnfPackageModel.objects.filter(vnfPackageId=csar_id)
66         if not nf_pkg:
67             raise CatalogException("VNF CSAR(%s) does not exist." % csar_id)
68         csar_path = nf_pkg[0].localFilePath
69         ret = {"model": toscaparser.parse_vnfd(csar_path, inputs)}
70     except CatalogException as e:
71         return [1, e.message]
72     except Exception as e:
73         logger.error(e.message)
74         logger.error(traceback.format_exc())
75         return [1, str(sys.exc_info())]
76     return [0, ret]
77
78
79 class NfDistributeThread(threading.Thread):
80     """
81     Sdc NF Package Distribute
82     """
83
84     def __init__(self, csar_id, vim_ids, lab_vim_id, job_id):
85         threading.Thread.__init__(self)
86         self.csar_id = csar_id
87         self.vim_ids = vim_ids
88         self.lab_vim_id = lab_vim_id
89         self.job_id = job_id
90
91         self.csar_save_path = os.path.join(CATALOG_ROOT_PATH, csar_id)
92
93     def run(self):
94         try:
95             self.on_distribute()
96         except CatalogException as e:
97             self.rollback_distribute()
98             JobUtil.add_job_status(self.job_id, JOB_ERROR, e.message)
99         except Exception as e:
100             logger.error(e.message)
101             logger.error(traceback.format_exc())
102             logger.error(str(sys.exc_info()))
103             self.rollback_distribute()
104             JobUtil.add_job_status(self.job_id, JOB_ERROR, "Failed to distribute CSAR(%s)" % self.csar_id)
105
106     def on_distribute(self):
107         JobUtil.create_job(
108             inst_type='nf',
109             jobaction='on_distribute',
110             inst_id=self.csar_id,
111             job_id=self.job_id)
112         JobUtil.add_job_status(self.job_id, 5, "Start CSAR(%s) distribute." % self.csar_id)
113
114         if VnfPackageModel.objects.filter(vnfPackageId=self.csar_id):
115             err_msg = "NF CSAR(%s) already exists." % self.csar_id
116             JobUtil.add_job_status(self.job_id, JOB_ERROR, err_msg)
117             return
118
119         artifact = sdc.get_artifact(sdc.ASSETTYPE_RESOURCES, self.csar_id)
120         local_path = os.path.join(CATALOG_ROOT_PATH, self.csar_id)
121         csar_name = "%s.csar" % artifact.get("name", self.csar_id)
122         local_file_name = sdc.download_artifacts(artifact["toscaModelURL"], local_path, csar_name)
123
124         vnfd_json = toscaparser.parse_vnfd(local_file_name)
125         vnfd = json.JSONDecoder().decode(vnfd_json)
126
127         nfd_id = vnfd["metadata"]["id"]
128         if VnfPackageModel.objects.filter(vnfdId=nfd_id):
129             raise CatalogException("NFD(%s) already exists." % nfd_id)
130
131         JobUtil.add_job_status(self.job_id, 30, "Save CSAR(%s) to database." % self.csar_id)
132
133         vnfd_ver = vnfd["metadata"].get("vnfd_version")
134         if not vnfd_ver:
135             vnfd_ver = vnfd["metadata"].get("vnfdVersion", "undefined")
136         VnfPackageModel(
137             vnfPackageId=self.csar_id,
138             vnfdId=nfd_id,
139             vnfVendor=vnfd["metadata"].get("vendor", "undefined"),
140             vnfdVersion=vnfd_ver,
141             vnfSoftwareVersion=vnfd["metadata"].get("version", "undefined"),
142             vnfdModel=vnfd_json,
143             localFilePath=local_file_name,
144             vnfPackageUri=csar_name
145         ).save()
146
147         JobUtil.add_job_status(self.job_id, 100, "CSAR(%s) distribute successfully." % self.csar_id)
148
149     def rollback_distribute(self):
150         try:
151             VnfPackageModel.objects.filter(vnfPackageId=self.csar_id).delete()
152             fileutil.delete_dirs(self.csar_save_path)
153         except Exception as e:
154             logger.error(e.message)
155             logger.error(traceback.format_exc())
156             logger.error(str(sys.exc_info()))
157
158
159 class NfPkgDeleteThread(threading.Thread):
160     """
161     Sdc NF Package Deleting
162     """
163
164     def __init__(self, csar_id, job_id):
165         threading.Thread.__init__(self)
166         self.csar_id = csar_id
167         self.job_id = job_id
168
169     def run(self):
170         try:
171             self.delete_csar()
172         except CatalogException as e:
173             JobUtil.add_job_status(self.job_id, JOB_ERROR, e.message)
174         except Exception as e:
175             logger.error(e.message)
176             logger.error(traceback.format_exc())
177             logger.error(str(sys.exc_info()))
178             JobUtil.add_job_status(self.job_id, JOB_ERROR, "Failed to delete CSAR(%s)" % self.csar_id)
179
180     def delete_csar(self):
181         JobUtil.create_job(
182             inst_type='nf',
183             jobaction='delete',
184             inst_id=self.csar_id,
185             job_id=self.job_id)
186         JobUtil.add_job_status(self.job_id, 5, "Start to delete CSAR(%s)." % self.csar_id)
187
188         VnfPackageModel.objects.filter(vnfPackageId=self.csar_id).delete()
189
190         JobUtil.add_job_status(self.job_id, 50, "Delete local CSAR(%s) file." % self.csar_id)
191
192         csar_save_path = os.path.join(CATALOG_ROOT_PATH, self.csar_id)
193         fileutil.delete_dirs(csar_save_path)
194
195         JobUtil.add_job_status(self.job_id, 100, "Delete CSAR(%s) successfully." % self.csar_id)
196
197
198 class NfPackage(object):
199     """
200     Actions for sdc nf package.
201     """
202
203     def __init__(self):
204         pass
205
206     def get_csars(self):
207         csars = []
208         nf_pkgs = VnfPackageModel.objects.filter()
209         for nf_pkg in nf_pkgs:
210             ret = self.get_csar(nf_pkg.vnfPackageId)
211             csars.append(ret[1])
212         return [0, csars]
213
214     def get_csar(self, csar_id):
215         pkg_info = {}
216         nf_pkg = VnfPackageModel.objects.filter(vnfPackageId=csar_id)
217         if not nf_pkg:
218             nf_pkg = VnfPackageModel.objects.filter(vnfdId=csar_id)
219
220         if nf_pkg:
221             pkg_info["vnfdId"] = nf_pkg[0].vnfdId
222             pkg_info["vnfPackageId"] = nf_pkg[0].vnfPackageId
223             pkg_info["vnfdProvider"] = nf_pkg[0].vnfVendor
224             pkg_info["vnfdVersion"] = nf_pkg[0].vnfdVersion
225             pkg_info["vnfVersion"] = nf_pkg[0].vnfSoftwareVersion
226             pkg_info["csarName"] = nf_pkg[0].vnfPackageUri
227             pkg_info["vnfdModel"] = nf_pkg[0].vnfdModel
228             pkg_info["downloadUrl"] = "http://%s:%s/%s/%s/%s" % (
229                 MSB_SERVICE_IP,
230                 REG_TO_MSB_REG_PARAM["nodes"][0]["port"],
231                 CATALOG_URL_PATH,
232                 csar_id,
233                 nf_pkg[0].vnfPackageUri)
234         else:
235             raise CatalogException("Vnf package[%s] not Found." % csar_id)
236
237         csar_info = {
238             "csarId": csar_id,
239             "packageInfo": pkg_info,
240             "imageInfo": []
241         }
242         return [0, csar_info]