Fix bugs of parse nsd/vnfd api
[vfc/nfvo/catalog.git] / catalog / packages / ns_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 traceback
20
21 from catalog.pub.config.config import CATALOG_ROOT_PATH
22 from catalog.pub.database.models import NSPackageModel, VnfPackageModel
23 from catalog.pub.exceptions import CatalogException
24 from catalog.pub.msapi import nfvolcm
25 from catalog.pub.msapi import sdc
26 from catalog.pub.utils import fileutil
27 from catalog.pub.utils import toscaparser
28 from rest_framework import status
29
30 logger = logging.getLogger(__name__)
31
32 STATUS_SUCCESS, STATUS_FAILED = "success", "failed"
33
34
35 def fmt_ns_pkg_rsp(status, desc, error_code="500"):
36     return [0, {"status": status, "statusDescription": desc, "errorCode": error_code}]
37
38
39 def ns_on_distribute(csar_id):
40     ret = None
41     try:
42         ret = NsPackage().on_distribute(csar_id)
43     except CatalogException as e:
44         NsPackage().delete_catalog(csar_id)
45         return fmt_ns_pkg_rsp(STATUS_FAILED, e.message)
46     except:
47         logger.error(traceback.format_exc())
48         NsPackage().delete_catalog(csar_id)
49         return fmt_ns_pkg_rsp(STATUS_FAILED, str(sys.exc_info()))
50     return fmt_ns_pkg_rsp(STATUS_SUCCESS, ret[1], "")
51
52
53 def ns_delete_csar(csar_id, force_delete):
54     ret = None
55     nsinstances = []
56     try:
57        if force_delete:
58            ret = NsPackage().delete_csar(csar_id)
59            return fmt_ns_pkg_rsp(STATUS_SUCCESS, ret[1], "")
60        nsinstances = nfvolcm.get_nsInstances(csar_id)
61        if nsinstances:
62           if len(nsinstances) > 0:
63               return fmt_ns_pkg_rsp(STATUS_FAILED, "NS instances using the CSAR exists!",status.HTTP_412_PRECONDITION_FAILED)
64        ret = NsPackage().delete_csar(csar_id)
65        return fmt_ns_pkg_rsp(STATUS_SUCCESS, ret[1], "")
66     except CatalogException as e:
67         return fmt_ns_pkg_rsp(STATUS_FAILED, e.message)
68     except:
69         logger.error(traceback.format_exc())
70         return fmt_ns_pkg_rsp(STATUS_FAILED, str(sys.exc_info()))
71
72
73 def ns_get_csars():
74     ret = None
75     try:
76         ret = NsPackage().get_csars()
77     except CatalogException as e:
78         return [1, e.message]
79     except:
80         logger.error(traceback.format_exc())
81         return [1, str(sys.exc_info())]
82     return ret
83
84 def ns_get_csar(csar_id):
85     ret = None
86     try:
87         ret = NsPackage().get_csar(csar_id)
88     except CatalogException as e:
89         return [1, e.message]
90     except:
91         logger.error(traceback.format_exc())
92         return [1, str(sys.exc_info())]
93     return ret
94
95 def parse_nsd(csar_id, inputs):
96     ret= None
97     try:
98         ns_pkg = NSPackageModel.objects.filter(nsPackageId=csar_id)
99         if ns_pkg:
100             csar_path = ns_pkg[0].localFilePath
101             ret = {"model": toscaparser.parse_nsd(csar_path, inputs)}
102     except CatalogException as e:
103         return [1, e.message]
104     except:
105         logger.error(traceback.format_exc())
106         return [1, str(sys.exc_info())]
107     return [0, ret]
108
109
110 class NsPackage(object):
111     """
112     Actions for sdc ns package.
113     """
114
115     def __init__(self):
116         pass
117
118     def on_distribute(self, csar_id):
119         if NSPackageModel.objects.filter(nsPackageId=csar_id):
120             raise CatalogException("NS CSAR(%s) already exists." % csar_id)
121
122         nsd,local_file_name,nsd_json = self.get_nsd(csar_id)
123
124         nsd_id = nsd["metadata"]["id"]
125         if NSPackageModel.objects.filter(nsdId=nsd_id):
126             raise CatalogException("NSD(%s) already exists." % nsd_id)
127
128         for vnf in nsd["vnfs"]:
129             vnfd_id = vnf["properties"]["id"]
130             pkg = VnfPackageModel.objects.filter(vnfdId = vnfd_id)
131             if not pkg:
132                 raise CatalogException("VNF package(%s) is not distributed." % vnfd_id)
133
134         NSPackageModel(
135             nsPackageId=csar_id,
136             nsdId=nsd_id,
137             nsdName=nsd["metadata"].get("name", nsd_id),
138             nsdDesginer=nsd["metadata"].get("vendor", "undefined"),
139             nsdDescription=nsd["metadata"].get("description", ""),
140             nsdVersion=nsd["metadata"].get("version", "undefined"),
141             nsPackageUri=local_file_name,
142             sdcCsarId=csar_id,
143             localFilePath=local_file_name,
144             nsdModel=nsd_json
145             ).save()
146
147         return [0, "CSAR(%s) distributed successfully." % csar_id]
148
149     def get_nsd(self, csar_id):
150         artifact = sdc.get_artifact(sdc.ASSETTYPE_SERVICES, csar_id)
151         local_path = os.path.join(CATALOG_ROOT_PATH, csar_id)
152         local_file_name = sdc.download_artifacts(artifact["toscaModelURL"], local_path)
153
154         nsd_json = toscaparser.parse_nsd(local_file_name)
155         nsd = json.JSONDecoder().decode(nsd_json)
156
157         return nsd,local_file_name,nsd_json
158
159     def delete_csar(self, csar_id):
160         '''
161         if force_delete:
162             NSInstModel.objects.filter(nspackage_id=csar_id).delete()
163         else:
164             if NSInstModel.objects.filter(nspackage_id=csar_id):
165                 raise CatalogException("CSAR(%s) is in using, cannot be deleted." % csar_id)
166         '''
167         #nfvolcm.delete_ns_inst_mock()
168         NSPackageModel.objects.filter(nsPackageId=csar_id).delete()
169         return [0, "Delete CSAR(%s) successfully." % csar_id]
170
171
172     def get_csars(self):
173         csars = []
174         nss = NSPackageModel.objects.filter()
175         for ns in nss:
176             csars.append({
177                 "csarId": ns.nsPackageId,
178                 "nsdId": ns.nsdId
179             })
180         return [0,csars]
181
182     def get_csar(self, csar_id):
183         package_info = {}
184         csars = NSPackageModel.objects.filter(nsPackageId=csar_id)
185         if csars:
186             package_info["nsdId"] = csars[0].nsdId
187             package_info["nsdProvider"] = csars[0].nsdDesginer
188             package_info["nsdVersion"] = csars[0].nsdVersion
189
190         #nss = NSInstModel.objects.filter(nspackage_id=csar_id)
191         nss = nfvolcm.get_nsInstances(csar_id)
192         ns_instance_info = [{
193             "nsInstanceId": ns["nsInstanceId"],
194             "nsInstanceName": ns["nsName"]} for ns in nss]
195
196         return [0, {"csarId": csar_id, 
197             "packageInfo": package_info, 
198             "nsInstanceInfo": ns_instance_info}]
199
200     def delete_catalog(self, csar_id):
201         local_path = os.path.join(CATALOG_ROOT_PATH, csar_id)
202         fileutil.delete_dirs(local_path)