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.decorators import api_view
22 from rest_framework.response import Response
23 from driver.pub.utils import restcall
24 from driver.pub.utils.restcall import req_by_msb
25 from rest_framework import status
27 # ==================================================
28 vnf_create_url = "openoapi/vnflcm/v1/vnf_instances"
29 vnf_inst_url = "openoapi/vnflcm/v1/vnf_instances/%s/instantiate"
30 vnf_delete_url = "openoapi/vnflcm/v1/vnf_instances/%s"
31 vnf_terminate_url = "openoapi/vnflcm/v1/vnf_instances/%s/terminate"
32 operation_status_url = "openoapi/vnflcm/v1/vnf_lc_ops/%s?responseId=%s"
33 vnf_detail_url = "openoapi/vnflcm/v1/vnf_instances/%s"
34 EXTSYS_GET_VNFM = "openoapi/extsys/v1/vnfms/%s"
35 vnf_query_url = "openoapi/vnflcm/v1/vnf_instances/%s"
36 notify_url = 'openoapi/nslcm/v1/vnfs/{vnfInstanceId}/Notify'
38 query_vnf_resp_mapping = {
40 "vnfInstanceName": "",
41 "vnfInstanceDescription": "",
51 logger = logging.getLogger(__name__)
54 def mapping_conv(keyword_map, rest_return):
56 for param in keyword_map:
57 if keyword_map[param]:
58 if isinstance(keyword_map[param], dict):
59 resp_data[param] = mapping_conv(keyword_map[param], ignorcase_get(rest_return, param))
61 resp_data[param] = ignorcase_get(rest_return, param)
65 return "=================%s==================" % inspect.stack()[1][3]
67 def ignorcase_get(args, key):
75 if old_key.upper() == key.upper():
79 def set_createvnf_params(data):
81 input_data["vnfdId"] = ignorcase_get(data,"vnfDescriptorId")
82 input_data["vnfInstanceName"] = ignorcase_get(data, "vnfInstanceName")
83 input_data["vnfInstanceDescription"] = ignorcase_get(data, "vnfInstanceDescription")
87 def set_instantvnf_params(data):
89 input_data["flavourId"] = ignorcase_get(data, "flavourId")
90 input_data["extVirtualLinks"] = ignorcase_get(data, "extVirtualLink")
91 input_data["additionalParams"] = ignorcase_get(data,"additionalParams")
92 input_data["flavourId"] = ignorcase_get(data,"flavourId")
96 def set_terminatevnf_params(data):
98 input_data["terminationType"] = ignorcase_get(data,"terminationType")
99 input_data["gracefulTerminationTimeout"] = ignorcase_get(data,"gracefulTerminationTimeout")
103 def set_deletevnf_params(data):
107 def get_inst_levelId(vnfdId):
112 def get_vnfm_info(vnfm_id):
113 ret = req_by_msb((EXTSYS_GET_VNFM) % vnfm_id, "GET")
115 return 255, Response(data={'error': ret[1]}, status=ret[2])
116 vnfm_info = json.JSONDecoder().decode(ret[1])
117 logger.debug("[%s] vnfm_info=%s", fun_name(), vnfm_info)
120 def call_vnfm_rest(vnfm_info, input_data, res_url, call_method = "post"):
121 ret = restcall.call_req(
122 base_url=ignorcase_get(vnfm_info, "url"),
123 user=ignorcase_get(vnfm_info, "userName"),
124 passwd=ignorcase_get(vnfm_info, "password"),
125 auth_type=restcall.rest_no_auth,
128 content=json.JSONEncoder().encode(input_data))
132 def call_vnfm_createvnf(vnfm_info, input_data):
133 return call_vnfm_rest(vnfm_info, input_data, vnf_create_url)
135 def call_vnfm_instvnf(vnfm_info, input_data, vnfInstanceId):
136 return call_vnfm_rest(vnfm_info, input_data, vnf_inst_url % vnfInstanceId, "post")
138 def call_vnfm_terminatevnf(vnfm_info, input_data, vnfInstanceId):
139 return call_vnfm_rest(vnfm_info, input_data, vnf_terminate_url % vnfInstanceId, "post")
141 def call_vnfm_deletevnf(vnfm_info, vnfInstanceId):
142 return call_vnfm_rest(vnfm_info, None, vnf_delete_url % vnfInstanceId, "delete")
144 def call_vnfm_queryvnf(vnfm_info,vnfInstanceId):
145 return call_vnfm_rest(vnfm_info, None, vnf_query_url % vnfInstanceId, "get")
147 def call_vnfm_operation_status(vnfm_info, jobId, responseId = None):
148 return call_vnfm_rest(vnfm_info, None, operation_status_url % (jobId, responseId), "get")
150 def wait4job(vnfm_id,jobId,gracefulTerminationTimeout):
152 begin_time = time.time()
154 ret, vnfm_info = get_vnfm_info(vnfm_id)
156 return 255, Response(data={"error":"Fail to get VNFM!"}, status=status.HTTP_412_PRECONDITION_FAILED)
160 cur_time = time.time()
161 if gracefulTerminationTimeout and (cur_time - begin_time > gracefulTerminationTimeout):
162 return 255, Response(data={"error":"Fail to terminate VNF!"}, status=status.HTTP_408_REQUEST_TIMEOUT)
164 ret = call_vnfm_operation_status(vnfm_info,jobId,responseId)
166 return 255, Response(data={"error":"Fail to get job status!"}, status=status.HTTP_412_PRECONDITION_FAILED)
167 if json.JSONDecoder().decode(ret[2]) != 200:
168 return 255, Response(data={"error":"Fail to get job status!"}, status=status.HTTP_412_PRECONDITION_FAILED)
169 job_info = json.JSONDecoder().decode(ret[1])
170 responseId = ignorcase_get(ignorcase_get(job_info, "VnfLcOpResponseDescriptor"), "responseId")
171 progress = ignorcase_get(ignorcase_get(job_info, "VnfLcOpResponseDescriptor"), "progress")
172 if progress == "100":
173 return 0, Response(data={"success":"success"}, status=status.HTTP_204_NO_CONTENT)
174 except Exception as e:
175 logger.error("Error occurred when do_createvnf")
176 return 255, Response(data={"error":"Exception caught! Fail to get job status!"}, status=status.HTTP_412_PRECONDITION_FAILED)
179 def do_createvnf(request, data, vnfm_id):
180 logger.debug("[%s] request.data=%s", fun_name(), request.data)
183 ret, vnfm_info = get_vnfm_info(vnfm_id)
185 return ret, vnfm_info
187 ret = call_vnfm_createvnf(vnfm_info, data)
188 logger.debug("[%s] call_req ret=%s", fun_name(), ret)
190 return 255, Response(data={'error': ret[1]}, status=ret[2])
191 resp = json.JSONDecoder().decode(ret[1])
192 except Exception as e:
193 logger.error("Error occurred when do_createvnf")
198 def do_instvnf(vnfInstanceId, request, data, vnfm_id):
199 logger.debug("[%s] request.data=%s", fun_name(), request.data)
202 ret, vnfm_info = get_vnfm_info(vnfm_id)
204 return ret, vnfm_info
206 ret = call_vnfm_instvnf(vnfm_info,data, vnfInstanceId)
207 logger.debug("[%s] call_req ret=%s", fun_name(), ret)
209 return 255, Response(data={'error': ret[1]}, status=ret[2])
210 resp = json.JSONDecoder().decode(ret[1])
211 except Exception as e:
212 logger.error("Error occurred when do_instvnf")
217 def do_terminatevnf(request, data, vnfm_id, vnfInstanceId):
218 logger.debug("[%s] request.data=%s", fun_name(), request.data)
220 ret, vnfm_info = get_vnfm_info(vnfm_id)
224 ret = call_vnfm_terminatevnf(vnfm_info, data, vnfInstanceId)
226 return 255, Response(data={'error': ret[1]}, status=ret[2])
227 resp_data = json.JSONDecoder().decode(ret[1])
228 logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
229 except Exception as e:
230 logger.error("Error occurred when do_terminatevnf")
235 def do_deletevnf(request, vnfm_id, vnfInstanceId):
236 logger.debug("[%s] request.data=%s", fun_name(), request.data)
237 input_data = set_deletevnf_params(request.data)
239 ret, vnfm_info = get_vnfm_info(vnfm_id)
241 return ret, vnfm_info
243 ret = call_vnfm_deletevnf(vnfm_info, vnfInstanceId)
246 return 255, Response(data={'error': ret[1]}, status=ret[2])
247 resp_data = json.JSONDecoder().decode(ret[1])
248 logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
249 except Exception as e:
250 logger.error("Error occurred when do_deletevnf")
254 def do_queryvnf(request, vnfm_id, vnfInstanceId):
255 logger.debug("[%s] request.data=%s", fun_name(), request.data)
257 ret, vnfm_info = get_vnfm_info(vnfm_id)
259 return ret, vnfm_info
261 ret = call_vnfm_queryvnf(vnfm_info, vnfInstanceId)
264 return 255, Response(data={'error': ret[1]}, status=ret[2])
265 resp_data = json.JSONDecoder().decode(ret[1])
266 logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
267 except Exception as e:
268 logger.error("Error occurred when do_query vnf")
272 @api_view(http_method_names=['POST'])
273 def instantiate_vnf(request, *args, **kwargs):
275 input_data = set_createvnf_params(request.data)
276 vnfm_id = ignorcase_get(kwargs, "vnfmid")
277 ret, resp = do_createvnf(request, input_data, vnfm_id)
281 logger.info("[%s]resp_data=%s", fun_name(), resp)
282 vnfInstanceId = resp["vnfInstanceId"]
283 logger.info("[%s]vnfInstanceId=%s", fun_name(), vnfInstanceId)
285 input_data = set_instantvnf_params(request.data)
286 ret, resp = do_instvnf(vnfInstanceId, request, input_data, vnfm_id)
290 resp_data = {"jobId":"", "vnfInstanceId":""}
291 resp_data["vnfInstanceId"] = vnfInstanceId
292 resp_data["jobId"] = resp["vnfLcOpId"]
293 except Exception as e:
294 logger.error("Error occurred when instantiating VNF")
297 return Response(data=resp_data, status=status.HTTP_201_CREATED)
300 @api_view(http_method_names=['POST'])
301 def terminate_vnf(request, *args, **kwargs):
302 vnfm_id = ignorcase_get(kwargs, "vnfmid")
303 vnfInstanceId = ignorcase_get(kwargs, "vnfInstanceId")
305 input_data = set_terminatevnf_params(request.data)
306 ret, resp = do_terminatevnf(request, input_data, vnfm_id, vnfInstanceId)
310 jobId = ignorcase_get(resp, "vnfLcOpId")
311 gracefulTerminationTimeout = ignorcase_get(request.data, "gracefulTerminationTimeout")
312 ret, response = wait4job(vnfm_id,jobId,gracefulTerminationTimeout)
316 ret, resp = do_deletevnf(request, vnfm_id, vnfInstanceId)
320 except Exception as e:
321 logger.error("Error occurred when terminating VNF")
324 return Response(data=resp, status=status.HTTP_204_NO_CONTENT)
326 @api_view(http_method_names=['GET'])
327 def query_vnf(request, *args, **kwargs):
328 vnfm_id = ignorcase_get(kwargs, "vnfmid")
329 vnfInstanceId = ignorcase_get(kwargs, "vnfInstanceId")
331 logger.debug("[%s] request.data=%s", fun_name(), request.data)
332 ret, resp = do_queryvnf(request, vnfm_id, vnfInstanceId)
336 resp_response_data = mapping_conv(query_vnf_resp_mapping, ignorcase_get(resp, "ResponseInfo"))
338 "vnfInfo":resp_response_data
340 #Handle vnfSoftwareVersion and vnfStatus specially
341 resp_data["vnfInfo"]["version"] = ignorcase_get(ignorcase_get(resp, "ResponseInfo"), "vnfSoftwareVersion")
342 if ignorcase_get(ignorcase_get(resp, "ResponseInfo"), "instantiationState"):
343 if ignorcase_get(ignorcase_get(resp, "ResponseInfo"), "instantiationState") == "INSTANTIATED":
344 resp_data["vnfInfo"]["vnfStatus"] = "ACTIVE"
345 if ignorcase_get(ignorcase_get(resp, "ResponseInfo"), "vnfInstanceId"):
346 resp_data["vnfInfo"]["vnfInstanceId"] = ignorcase_get(ignorcase_get(resp, "ResponseInfo"), "vnfInstanceId")
347 logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
348 except Exception as e:
349 logger.error("Error occurred when querying VNF information.")
351 return Response(data=resp_data, status=status.HTTP_200_OK)
353 # ==================================================
356 @api_view(http_method_names=['GET'])
357 def operation_status(request, *args, **kwargs):
360 logger.debug("[%s] request.data=%s", fun_name(), request.data)
361 vnfm_id = ignorcase_get(kwargs, "vnfmid")
362 jobId = ignorcase_get(kwargs, "jobId")
363 responseId = ignorcase_get(kwargs, "responseId")
365 ret, vnfm_info = get_vnfm_info(vnfm_id)
367 return Response(data={'error': ret[1]}, status=ret[2])
368 logger.debug("[%s] vnfm_info=%s", fun_name(), vnfm_info)
370 ret = call_vnfm_operation_status(vnfm_info, jobId, responseId)
373 return Response(data={'error': ret[1]}, status=ret[2])
374 resp_data = json.JSONDecoder().decode(ret[1])
375 logger.info("[%s]resp_data=%s", fun_name(), resp_data)
376 ResponseInfo = ignorcase_get(resp_data, "ResponseInfo")
378 operation_data["jobId"] = ignorcase_get(ResponseInfo, "vnfLcOpId")
379 operation_data["responseDescriptor"] = {}
380 operation_data["responseDescriptor"]["status"] = ignorcase_get(ignorcase_get(ResponseInfo, "responseDescriptor"),"lcmOperationStatus")
381 operation_data["responseDescriptor"]["progress"] = ignorcase_get(ignorcase_get(ResponseInfo, "responseDescriptor"),"progress")
382 operation_data["responseDescriptor"]["statusDescription"] = ignorcase_get(ignorcase_get(ResponseInfo, "responseDescriptor"),"statusDescription")
383 operation_data["responseDescriptor"]["errorCode"] = ignorcase_get(ignorcase_get(ResponseInfo, "responseDescriptor"),"errorCode")
384 operation_data["responseDescriptor"]["responseId"] = ignorcase_get(ignorcase_get(ResponseInfo, "responseDescriptor"),"responseId")
385 operation_data["responseDescriptor"]["responseHistoryList"] = ignorcase_get(ignorcase_get(ResponseInfo, "responseDescriptor"),"responseHistoryList")
387 except Exception as e:
388 logger.error("Error occurred when getting operation status information.")
390 return Response(data=operation_data, status=status.HTTP_200_OK)
393 # ==================================================
394 grant_vnf_url = 'openoapi/nslcm/v1/grantvnf'
396 @api_view(http_method_names=['PUT'])
397 def grantvnf(request, *args, **kwargs):
398 logger.info("=====grantvnf=====")
401 logger.info("req_data = %s", request.data)
402 ret = req_by_msb(grant_vnf_url, "POST", content=json.JSONEncoder().encode(request.data))
403 logger.info("ret = %s", ret)
405 return Response(data={'error': ret[1]}, status=ret[2])
406 resp = json.JSONDecoder().decode(ret[1])
407 resp_data['vimid'] = ignorcase_get(resp['vim'], 'vimid')
408 resp_data['tenant'] = ignorcase_get(ignorcase_get(resp['vim'], 'accessinfo'), 'tenant')
409 logger.info("[%s]resp_data=%s", fun_name(), resp_data)
410 except Exception as e:
411 logger.error("Error occurred in Grant VNF.")
413 return Response(data=resp_data, status=ret[2])
416 # ==================================================
419 @api_view(http_method_names=['POST'])
420 def notify(request, *args, **kwargs):
422 logger.info("[%s]req_data = %s", fun_name(), request.data)
423 ret = req_by_msb(notify_url.format(vnfmid=ignorcase_get(request.data, 'VNFMID'),
424 vnfInstanceId=ignorcase_get(request.data, 'vnfinstanceid')),
425 "POST", content=json.JSONEncoder().encode(request.data))
426 logger.info("[%s]data = %s", fun_name(), ret)
428 return Response(data={'error': ret[1]}, status=ret[2])
429 except Exception as e:
430 logger.error("Error occurred in LCM notification.")
432 return Response(data=None, status=ret[2])
434 @api_view(http_method_names=['GET'])
435 def get_vnfpkgs(request, *args, **kwargs):
436 logger.info("Enter %s", fun_name())
437 ret = req_by_msb("openoapi/nslcm/v1/vnfpackage", "GET")
439 return Response(data={'error': ret[1]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
440 resp = json.JSONDecoder().decode(ret[1])
441 return Response(data=resp, status=status.HTTP_200_OK)