Fix vfc-gvnfm-driver pep8 issues
[vfc/nfvo/driver/vnfm/gvnfm.git] / gvnfmadapter / driver / interfaces / views.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 inspect
16 import json
17 import logging
18 import time
19 import traceback
20
21 from rest_framework import status
22 from rest_framework.decorators import api_view
23 from rest_framework.response import Response
24
25 from driver.pub.exceptions import GvnfmDriverException
26 from driver.pub.utils import restcall
27 from driver.pub.utils.restcall import req_by_msb
28
29 logger = logging.getLogger(__name__)
30
31
32 @api_view(http_method_names=['POST'])
33 def instantiate_vnf(request, *args, **kwargs):
34     try:
35         logger.debug("instantiate_vnf--post::> %s" % request.data)
36         logger.debug("Create vnf begin!")
37         input_data = {
38             "vnfdId": ignorcase_get(request.data, "vnfDescriptorId"),
39             "vnfInstanceName": ignorcase_get(request.data, "vnfInstanceName"),
40             "vnfInstanceDescription": ignorcase_get(request.data, "vnfInstanceDescription")
41         }
42         vnfm_id = ignorcase_get(kwargs, "vnfmid")
43         logger.debug("do_createvnf: request data=[%s],input_data=[%s],vnfm_id=[%s]", request.data, input_data, vnfm_id)
44         resp = do_createvnf(vnfm_id, input_data)
45         logger.debug("do_createvnf: response data=[%s]", resp)
46         logger.debug("Create vnf end!")
47
48         logger.debug("Instantiate vnf start!")
49         vnfInstanceId = resp["vnfInstanceId"]
50         input_data = {
51             "flavourId": ignorcase_get(request.data, "flavourId"),
52             "extVirtualLinks": ignorcase_get(request.data, "extVirtualLink"),
53             "additionalParams": ignorcase_get(request.data, "additionalParam")
54         }
55         logger.debug("do_instvnf: vnfInstanceId=[%s],request data=[%s],input_data=[%s],vnfm_id=[%s]",
56                      vnfInstanceId, request.data, input_data, vnfm_id)
57         resp = do_instvnf(vnfInstanceId, vnfm_id, input_data)
58         logger.debug("do_instvnf: response data=[%s]", resp)
59         resp_data = {
60             "vnfInstanceId": vnfInstanceId,
61             "jobId": ignorcase_get(resp, "vnfLcOpId")
62         }
63         logger.debug("Instantiate vnf end!")
64         return Response(data=resp_data, status=status.HTTP_201_CREATED)
65     except GvnfmDriverException as e:
66         logger.error('instantiate vnf failed, detail message: %s' % e.message)
67         return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
68     except:
69         logger.error(traceback.format_exc())
70         return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
71
72
73 @api_view(http_method_names=['POST'])
74 def terminate_vnf(request, *args, **kwargs):
75     logger.debug("terminate_vnf--post::> %s" % request.data)
76     logger.debug("Terminate vnf begin!")
77     vnfm_id = ignorcase_get(kwargs, "vnfmid")
78     vnfInstanceId = ignorcase_get(kwargs, "vnfInstanceId")
79     try:
80         input_data = {
81             "terminationType": ignorcase_get(request.data, "terminationType"),
82             "gracefulTerminationTimeout": ignorcase_get(request.data, "gracefulTerminationTimeout")
83         }
84         logger.debug("do_terminatevnf: vnfm_id=[%s],vnfInstanceId=[%s],input_data=[%s]",
85                      vnfm_id, vnfInstanceId, input_data)
86         resp = do_terminatevnf(vnfm_id, vnfInstanceId, input_data)
87         logger.debug("terminate_vnf: response data=[%s]", resp)
88
89         jobId = ignorcase_get(resp, "vnfLcOpId")
90         gracefulTerminationTimeout = ignorcase_get(request.data, "gracefulTerminationTimeout")
91         logger.debug("wait4job: vnfm_id=[%s],jobId=[%s],gracefulTerminationTimeout=[%s]",
92                      vnfm_id, jobId, gracefulTerminationTimeout)
93         resp = wait4job(vnfm_id, jobId, gracefulTerminationTimeout)
94         logger.debug("[wait4job] response=[%s]", resp)
95
96         logger.debug("Delete vnf start!")
97         logger.debug("do_deletevnf: vnfm_id=[%s],vnfInstanceId=[%s],request data=[%s]",
98                      vnfm_id, vnfInstanceId, request.data)
99         resp = do_deletevnf(vnfm_id, vnfInstanceId, request.data)
100         logger.debug("do_deletevnf: response data=[%s]", resp)
101         logger.debug("Delete vnf end!")
102
103         return Response(data=resp, status=status.HTTP_204_NO_CONTENT)
104     except GvnfmDriverException as e:
105         logger.error('Terminate vnf failed, detail message: %s' % e.message)
106         return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
107     except:
108         logger.error(traceback.format_exc())
109         return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
110
111
112 @api_view(http_method_names=['GET'])
113 def query_vnf(request, *args, **kwargs):
114     logger.debug("query_vnf--post::> %s" % request.data)
115     vnfm_id = ignorcase_get(kwargs, "vnfmid")
116     vnfInstanceId = ignorcase_get(kwargs, "vnfInstanceId")
117     try:
118         logger.debug("[%s] request.data=%s", fun_name(), request.data)
119         resp = do_queryvnf(request, vnfm_id, vnfInstanceId)
120         query_vnf_resp_mapping = {
121             "vnfInstanceId": "",
122             "vnfInstanceName": "",
123             "vnfInstanceDescription": "",
124             "vnfdId": "",
125             "vnfPackageId": "",
126             "version": "",
127             "vnfProvider": "",
128             "vnfType": "",
129             "vnfStatus": ""
130         }
131         resp_response_data = mapping_conv(query_vnf_resp_mapping, ignorcase_get(resp, "ResponseInfo"))
132         resp_data = {
133             "vnfInfo": resp_response_data
134         }
135         ResponseInfo = ignorcase_get(resp, "ResponseInfo")
136         resp_data["vnfInfo"]["version"] = ignorcase_get(ResponseInfo, "vnfSoftwareVersion")
137         if ignorcase_get(ResponseInfo, "instantiationState") == "INSTANTIATED":
138             resp_data["vnfInfo"]["vnfStatus"] = "ACTIVE"
139         resp_data["vnfInfo"]["vnfInstanceId"] = ignorcase_get(ResponseInfo, "vnfInstanceId")
140         logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
141         return Response(data=resp_data, status=status.HTTP_200_OK)
142     except GvnfmDriverException as e:
143         logger.error('Query vnf failed, detail message: %s' % e.message)
144         return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
145     except:
146         logger.error(traceback.format_exc())
147         return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
148
149
150 @api_view(http_method_names=['GET'])
151 def operation_status(request, *args, **kwargs):
152     logger.debug("operation_status--post::> %s" % request.data)
153     try:
154         logger.debug("[%s] request.data=%s", fun_name(), request.data)
155         vnfm_id = ignorcase_get(kwargs, "vnfmid")
156         jobId = ignorcase_get(kwargs, "jobId")
157         responseId = ignorcase_get(kwargs, "responseId")
158         logger.debug("[operation_status] vnfm_id=%s", vnfm_id)
159         vnfm_info = get_vnfminfo_from_nslcm(vnfm_id)
160         logger.debug("[operation_status] vnfm_info=[%s]", vnfm_info)
161
162         ret = call_vnfm("api/vnflcm/v1/vnf_lc_ops/%s?responseId=%s" % (jobId, responseId), "GET", vnfm_info)
163         if ret[0] != 0:
164             logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
165             raise GvnfmDriverException('Failed to query vnf operation status.')
166         resp_data = json.JSONDecoder().decode(ret[1])
167         logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
168         ResponseInfo = ignorcase_get(resp_data, "ResponseInfo")
169         responseDescriptor = ignorcase_get(ResponseInfo, "responseDescriptor")
170         status_tmp = ignorcase_get(responseDescriptor, "lcmOperationStatus")
171         del responseDescriptor["lcmOperationStatus"]
172         responseDescriptor["status"] = status_tmp
173         operation_data = {
174             "jobId": ignorcase_get(ResponseInfo, "vnfLcOpId"),
175             "responseDescriptor": responseDescriptor
176         }
177         return Response(data=operation_data, status=status.HTTP_200_OK)
178     except GvnfmDriverException as e:
179         logger.error('Query vnf failed, detail message: %s' % e.message)
180         return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
181     except:
182         logger.error(traceback.format_exc())
183         return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
184
185
186 @api_view(http_method_names=['PUT'])
187 def grantvnf(request, *args, **kwargs):
188     try:
189         logger.debug("[grantvnf] req_data = %s", request.data)
190         ret = req_by_msb('api/nslcm/v1/grantvnf', "POST", content=json.JSONEncoder().encode(request.data))
191         logger.debug("ret = %s", ret)
192         if ret[0] != 0:
193             logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
194             raise GvnfmDriverException('Failed to grant vnf.')
195         resp = json.JSONDecoder().decode(ret[1])
196         vim_info = resp['vim']
197         accessinfo = ignorcase_get(resp['vim'], 'accessinfo')
198         resp_data = {
199             'vimid': ignorcase_get(vim_info, 'vimid'),
200             'tenant': ignorcase_get(accessinfo, 'tenant')
201         }
202         logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
203         return Response(data=resp_data, status=ret[2])
204     except GvnfmDriverException as e:
205         logger.error('Grant vnf failed, detail message: %s' % e.message)
206         return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
207     except:
208         logger.error(traceback.format_exc())
209         return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
210
211
212 @api_view(http_method_names=['POST'])
213 def notify(request, *args, **kwargs):
214     try:
215         logger.debug("[%s]req_data = %s", fun_name(), request.data)
216         vnfinstanceid = ignorcase_get(request.data, 'vnfinstanceid')
217         ret = req_by_msb("api/nslcm/v1/vnfs/%s/Notify" % vnfinstanceid, "POST", json.JSONEncoder().encode(request.data))
218         logger.debug("[%s]data = %s", fun_name(), ret)
219         if ret[0] != 0:
220             logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
221             raise GvnfmDriverException('Failed to notify vnf.')
222         return Response(data=None, status=ret[2])
223     except GvnfmDriverException as e:
224         logger.error('Grant vnf failed, detail message: %s' % e.message)
225         return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
226     except:
227         logger.error(traceback.format_exc())
228         return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
229
230
231 @api_view(http_method_names=['GET'])
232 def get_vnfpkgs(request, *args, **kwargs):
233     try:
234         logger.debug("Enter %s", fun_name())
235         ret = req_by_msb("api/nslcm/v1/vnfpackage", "GET")
236         if ret[0] != 0:
237             logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
238             raise GvnfmDriverException('Failed to get vnfpkgs.')
239         resp = json.JSONDecoder().decode(ret[1])
240         return Response(data=resp, status=status.HTTP_200_OK)
241     except GvnfmDriverException as e:
242         logger.error('Get vnfpkgs failed, detail message: %s' % e.message)
243         return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
244     except:
245         logger.error(traceback.format_exc())
246         return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
247
248
249 def call_vnfm(resource, method, vnfm_info, data=""):
250     ret = restcall.call_req(
251         base_url=ignorcase_get(vnfm_info, "url"),
252         user=ignorcase_get(vnfm_info, "userName"),
253         passwd=ignorcase_get(vnfm_info, "password"),
254         auth_type=restcall.rest_no_auth,
255         resource=resource,
256         method=method,
257         content=json.JSONEncoder().encode(data))
258     return ret
259
260
261 def mapping_conv(keyword_map, rest_return):
262     resp_data = {}
263     for param in keyword_map:
264         if keyword_map[param]:
265             if isinstance(keyword_map[param], dict):
266                 resp_data[param] = mapping_conv(keyword_map[param], ignorcase_get(rest_return, param))
267             else:
268                 resp_data[param] = ignorcase_get(rest_return, param)
269     return resp_data
270
271
272 def fun_name():
273     return "=========%s=========" % inspect.stack()[1][3]
274
275
276 def ignorcase_get(args, key):
277     if not key:
278         return ""
279     if not args:
280         return ""
281     if key in args:
282         return args[key]
283     for old_key in args:
284         if old_key.upper() == key.upper():
285             return args[old_key]
286     return ""
287
288
289 def get_vnfminfo_from_nslcm(vnfm_id):
290     logger.debug("[get_vnfminfo_from_nslcm] vnfm_id=[%s]", vnfm_id)
291     ret = req_by_msb("api/aai-esr-server/v1/vnfms/%s" % vnfm_id, "GET")
292     logger.debug("[get_vnfminfo_from_nslcm] response=%s", ret)
293     if ret[0] != 0:
294         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
295         raise GvnfmDriverException("Failed to query vnfm(%s) from nslcm." % vnfm_id)
296     return json.JSONDecoder().decode(ret[1])
297
298
299 def wait4job(vnfm_id, job_id, gracefulTerminationTimeout=1200, retry_count=60, interval_second=3):
300     logger.debug("[wait4job] vnfm_id=[%s],jobId=[%s],gracefulTerminationTimeout=[%s]",
301                  vnfm_id, job_id, gracefulTerminationTimeout)
302     count = 0
303     response_id, new_response_id = 0, 0
304     job_end_normal, job_timeout = False, True
305     vnfm_info = get_vnfminfo_from_nslcm(vnfm_id)
306     logger.debug("[do_terminatevnf] vnfm_info=[%s]", vnfm_info)
307     while count < retry_count:
308         count = count + 1
309         time.sleep(interval_second)
310         ret = call_vnfm("api/vnflcm/v1/vnf_lc_ops/%s?responseId=%s" % (job_id, response_id), "GET", vnfm_info)
311         if ret[0] != 0:
312             logger.error("Failed to query job: %s:%s", ret[2], ret[1])
313             continue
314         job_result = json.JSONDecoder().decode(ret[1])
315         if "responseDescriptor" not in job_result:
316             logger.error("Job(%s) does not exist.", job_id)
317             continue
318         progress = job_result["responseDescriptor"]["progress"]
319         new_response_id = job_result["responseDescriptor"]["responseId"]
320         job_desc = job_result["responseDescriptor"]["statusDescription"]
321         if new_response_id != response_id:
322             logger.debug("%s:%s:%s", progress, new_response_id, job_desc)
323             response_id = new_response_id
324             count = 0
325         if progress == 255:
326             job_timeout = False
327             logger.error("Job(%s) failed: %s", job_id, job_desc)
328             break
329         elif progress == 100:
330             job_end_normal, job_timeout = True, False
331             logger.debug("Job(%s) ended normally,job_end_normal=[%s],job_timeout=[%s]",
332                          job_id, job_end_normal, job_timeout)
333             return {"success": "success"}
334     if job_timeout:
335         logger.error("Job(%s) timeout", job_id)
336     raise GvnfmDriverException("Fail to get job status!")
337
338
339 def do_createvnf(vnfm_id, data):
340     logger.debug("[%s] request.data=%s", fun_name(), data)
341     vnfm_info = get_vnfminfo_from_nslcm(vnfm_id)
342     logger.debug("[do_createvnf] vnfm_info=[%s]", vnfm_info)
343     ret = call_vnfm("api/vnflcm/v1/vnf_instances", "POST", vnfm_info, data)
344     logger.debug("[%s] call_req ret=%s", fun_name(), ret)
345     if ret[0] != 0:
346         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
347         raise GvnfmDriverException('Failed to create vnf.')
348     return json.JSONDecoder().decode(ret[1])
349
350
351 def do_instvnf(vnfInstanceId, vnfm_id, data):
352     logger.debug("[%s] request.data=%s", fun_name(), data)
353     vnfm_info = get_vnfminfo_from_nslcm(vnfm_id)
354     logger.debug("[do_instvnf] vnfm_info=[%s]", vnfm_info)
355     ret = call_vnfm("api/vnflcm/v1/vnf_instances/%s/instantiate" % vnfInstanceId, "POST", vnfm_info, data)
356     logger.debug("[%s] call_req ret=%s", fun_name(), ret)
357     if ret[0] != 0:
358         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
359         raise GvnfmDriverException('Failed to inst vnf.')
360     return json.JSONDecoder().decode(ret[1])
361
362
363 def do_terminatevnf(vnfm_id, vnfInstanceId, data):
364     logger.debug("[%s] request.data=%s", fun_name(), data)
365     vnfm_info = get_vnfminfo_from_nslcm(vnfm_id)
366     logger.debug("[do_terminatevnf] vnfm_info=[%s]", vnfm_info)
367     ret = call_vnfm("api/vnflcm/v1/vnf_instances/%s/terminate" % vnfInstanceId, "POST", vnfm_info, data)
368     if ret[0] != 0:
369         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
370         raise GvnfmDriverException('Failed to terminate vnf.')
371     return json.JSONDecoder().decode(ret[1])
372
373
374 def do_deletevnf(vnfm_id, vnfInstanceId, data):
375     logger.debug("[%s] request.data=%s", fun_name(), data)
376     vnfm_info = get_vnfminfo_from_nslcm(vnfm_id)
377     logger.debug("[do_deletevnf] vnfm_info=[%s]", vnfm_info)
378     ret = call_vnfm("api/vnflcm/v1/vnf_instances/%s" % vnfInstanceId, "DELETE", vnfm_info)
379     if ret[0] != 0:
380         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
381         raise GvnfmDriverException('Failed to delete vnf.')
382     return json.JSONDecoder().decode(ret[1])
383
384
385 def do_queryvnf(data, vnfm_id, vnfInstanceId):
386     logger.debug("[%s] request.data=%s", fun_name(), data)
387     vnfm_info = get_vnfminfo_from_nslcm(vnfm_id)
388     logger.debug("[do_deletevnf] vnfm_info=[%s]", vnfm_info)
389     ret = call_vnfm("api/vnflcm/v1/vnf_instances/%s" % vnfInstanceId, "GET", vnfm_info)
390     if ret[0] != 0:
391         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
392         raise GvnfmDriverException('Failed to query vnf.')
393     return json.JSONDecoder().decode(ret[1])