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.
21 from rest_framework import status
22 from rest_framework.decorators import api_view
23 from rest_framework.response import Response
25 from driver.pub.exceptions import GvnfmDriverException
26 from driver.pub.utils import restcall
27 from driver.pub.utils.restcall import req_by_msb
29 logger = logging.getLogger(__name__)
32 @api_view(http_method_names=['POST'])
33 def instantiate_vnf(request, *args, **kwargs):
35 logger.debug("instantiate_vnf--post::> %s" % request.data)
36 logger.debug("Create vnf begin!")
38 "vnfdId": ignorcase_get(request.data, "vnfDescriptorId"),
39 "vnfInstanceName": ignorcase_get(request.data, "vnfInstanceName"),
40 "vnfInstanceDescription": ignorcase_get(request.data, "vnfInstanceDescription")
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!")
48 logger.debug("Instantiate vnf start!")
49 vnfInstanceId = resp["vnfInstanceId"]
51 "flavourId": ignorcase_get(request.data, "flavourId"),
52 "extVirtualLinks": ignorcase_get(request.data, "extVirtualLink"),
53 "additionalParams": ignorcase_get(request.data, "additionalParam")
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)
60 "vnfInstanceId": vnfInstanceId,
61 "jobId": ignorcase_get(resp, "vnfLcOpId")
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)
69 logger.error(traceback.format_exc())
70 return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
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")
81 "terminationType": ignorcase_get(request.data, "terminationType"),
82 "gracefulTerminationTimeout": ignorcase_get(request.data, "gracefulTerminationTimeout")
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)
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)
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!")
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)
108 logger.error(traceback.format_exc())
109 return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
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")
118 logger.debug("[%s] request.data=%s", fun_name(), request.data)
119 resp = do_queryvnf(request, vnfm_id, vnfInstanceId)
120 query_vnf_resp_mapping = {
122 "vnfInstanceName": "",
123 "vnfInstanceDescription": "",
131 resp_response_data = mapping_conv(query_vnf_resp_mapping, ignorcase_get(resp, "ResponseInfo"))
133 "vnfInfo": resp_response_data
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)
146 logger.error(traceback.format_exc())
147 return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
150 @api_view(http_method_names=['GET'])
151 def operation_status(request, *args, **kwargs):
152 logger.debug("operation_status--post::> %s" % request.data)
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)
162 ret = call_vnfm("api/vnflcm/v1/vnf_lc_ops/%s?responseId=%s" % (jobId, responseId), "GET", vnfm_info)
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
174 "jobId": ignorcase_get(ResponseInfo, "vnfLcOpId"),
175 "responseDescriptor": responseDescriptor
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)
182 logger.error(traceback.format_exc())
183 return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
186 @api_view(http_method_names=['PUT'])
187 def grantvnf(request, *args, **kwargs):
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)
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')
199 'vimid': ignorcase_get(vim_info, 'vimid'),
200 'tenant': ignorcase_get(accessinfo, 'tenant')
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)
208 logger.error(traceback.format_exc())
209 return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
212 @api_view(http_method_names=['POST'])
213 def notify(request, *args, **kwargs):
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)
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)
227 logger.error(traceback.format_exc())
228 return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
231 @api_view(http_method_names=['GET'])
232 def get_vnfpkgs(request, *args, **kwargs):
234 logger.debug("Enter %s", fun_name())
235 ret = req_by_msb("api/nslcm/v1/vnfpackage", "GET")
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)
245 logger.error(traceback.format_exc())
246 return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
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,
257 content=json.JSONEncoder().encode(data))
261 def mapping_conv(keyword_map, rest_return):
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))
268 resp_data[param] = ignorcase_get(rest_return, param)
273 return "=========%s=========" % inspect.stack()[1][3]
276 def ignorcase_get(args, key):
284 if old_key.upper() == key.upper():
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)
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])
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)
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:
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)
312 logger.error("Failed to query job: %s:%s", ret[2], ret[1])
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)
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
327 logger.error("Job(%s) failed: %s", job_id, job_desc)
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"}
335 logger.error("Job(%s) timeout", job_id)
336 raise GvnfmDriverException("Fail to get job status!")
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)
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])
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)
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])
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)
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])
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)
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])
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)
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])