Add input parameters of zte vnf
[vfc/nfvo/driver/vnfm/svnfm.git] / zte / vmanager / driver / interfaces / views.py
1 # Copyright 2016-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 traceback
19 import os
20
21 from rest_framework.decorators import api_view
22 from rest_framework.response import Response
23
24 from driver.pub.utils import restcall
25 from driver.pub.utils.restcall import req_by_msb, call_aai
26
27 logger = logging.getLogger(__name__)
28
29
30 def load_json_file(file_name):
31     json_file = os.path.join(os.path.dirname(__file__), "data/" + file_name)
32     f = open(json_file)
33     json_data = json.JSONDecoder().decode(f.read())
34     f.close()
35     return json_data
36
37
38 def fun_name():
39     return "=================%s==================" % inspect.stack()[1][3]
40
41
42 def ignorcase_get(args, key):
43     if not key:
44         return ""
45     if not args:
46         return ""
47     if key in args:
48         return args[key]
49     for old_key in args:
50         if old_key.upper() == key.upper():
51             return args[old_key]
52     return ""
53
54
55 def mapping_conv(keyword_map, rest_return):
56     resp_data = {}
57     for param in keyword_map:
58         if keyword_map[param]:
59             resp_data[keyword_map[param]] = ignorcase_get(rest_return, param)
60     return resp_data
61
62
63 query_vnfd_url = "api/nslcm/v1/vnfpackage/%s"
64 query_vnfm_url = "api/extsys/v1/vnfms/%s"
65 query_package_url = "api/nslcm/v1/vnfpackage/%s"
66
67
68 # Query vnfm_info from nslcm
69 def get_vnfminfo_from_nslcm(vnfmid):
70     ret = req_by_msb("api/nslcm/v1/vnfms/%s" % vnfmid, "GET")
71     return ret
72
73
74 # Query vnfm_info from esr
75 def vnfm_get(vnfmid):
76     ret = call_aai("api/aai-esr-server/v1/vnfms/%s" % vnfmid, "GET")
77     return ret
78
79
80 # Query vnfd_info from nslcm
81 def vnfd_get(vnfpackageid):
82     ret = req_by_msb("api/nslcm/v1/vnfpackage/%s" % vnfpackageid, "GET")
83     return ret
84
85
86 # Query vnfpackage_info from nslcm
87 def vnfpackage_get(csarid):
88     ret = req_by_msb("api/nslcm/v1/vnfpackage/%s" % csarid, "GET")
89     return ret
90
91
92 # ==================================================
93 create_vnf_url = "v1/vnfs"
94 create_vnf_param_mapping = {
95     "packageUrl": "",
96     "instantiateUrl": "",
97     "instantiationLevel": "",
98     "vnfInstanceName": "",
99     "vnfPackageId": "",
100     "vnfDescriptorId": "",
101     "flavorId": "",
102     "vnfInstanceDescription": "",
103     "extVirtualLink": "",
104     "additionalParam": ""}
105 create_vnf_resp_mapping = {
106     "VNFInstanceID": "vnfInstanceId",
107     "JobId": "jobid"
108 }
109
110
111 @api_view(http_method_names=['POST'])
112 def instantiate_vnf(request, *args, **kwargs):
113     try:
114         logger.debug("[%s] request.data=%s", fun_name(), request.data)
115         vnfm_id = ignorcase_get(kwargs, "vnfmid")
116         ret = get_vnfminfo_from_nslcm(vnfm_id)
117         if ret[0] != 0:
118             return Response(data={'error': ret[1]}, status=ret[2])
119         vnfm_info = json.JSONDecoder().decode(ret[1])
120         logger.debug("[%s] vnfm_info=%s", fun_name(), vnfm_info)
121         vnf_package_id = ignorcase_get(request.data, "vnfPackageId")
122         ret = vnfd_get(vnf_package_id)
123         if ret[0] != 0:
124             return Response(data={'error': ret[1]}, status=ret[2])
125         vnfd_info = json.JSONDecoder().decode(ret[1])
126         logger.debug("[%s] vnfd_info=%s", fun_name(), vnfd_info)
127         csar_id = ignorcase_get(vnfd_info, "csarId")
128         ret = vnfpackage_get(csar_id)
129         if ret[0] != 0:
130             return Response(data={'error': ret[1]}, status=ret[2])
131         vnf_package_info = json.JSONDecoder().decode(ret[1])
132         packageInfo = ignorcase_get(vnf_package_info, "packageInfo")
133         logger.debug("[%s] packageInfo=%s", fun_name(), packageInfo)
134         data = {}
135         data["NFVOID"] = 1
136         data["VNFMID"] = vnfm_id
137         # vnfdId = ignorcase_get(packageInfo, "vnfdId")
138         vnfdModel = json.loads(ignorcase_get(packageInfo, "vnfdModel"))
139         metadata = ignorcase_get(vnfdModel, "metadata")
140         vnfd_name = ignorcase_get(metadata, "name")
141         # TODO  convert sdc vnf package to vnf vender package
142         from urlparse import urlparse
143         vnfm_ip = urlparse(ignorcase_get(vnfm_info, "url")).netloc.split(':')[0]
144
145         inputs = []
146         if "SPGW" in vnfd_name.upper():
147             data["VNFD"] = "ftp://VMVNFM:Vnfm_1g3T@" + vnfm_ip + ":21/" + "SPGW"
148             data["VNFURL"] = "ftp://VMVNFM:Vnfm_1g3T@" + vnfm_ip + ":21/" + "SPGW"
149             inputs = load_json_file("SPGW" + "_inputs.json")
150         elif "MME" in vnfd_name.upper():
151             data["VNFD"] = "ftp://VMVNFM:Vnfm_1g3T@" + vnfm_ip + ":21/" + "MME"
152             data["VNFURL"] = "ftp://VMVNFM:Vnfm_1g3T@" + vnfm_ip + ":21/" + "MME"
153             inputs = load_json_file("MME" + "_inputs.json")
154         else:
155             data["VNFD"] = ignorcase_get(packageInfo, "downloadUri")
156             data["VNFURL"] = ignorcase_get(packageInfo, "downloadUri")
157
158         data["extension"] = {}
159         for name, value in ignorcase_get(ignorcase_get(request.data, "additionalParam"), "inputs").items():
160             inputs.append({"name": name, "value": value})
161
162         logger.info(
163             "ignorcase_get(request.data, \"additionalParam\") = %s" % ignorcase_get(request.data, "additionalParam"))
164         data["extension"]["inputs"] = json.dumps(inputs)
165         data["extension"]["extVirtualLinks"] = ignorcase_get(
166             ignorcase_get(request.data, "additionalParam"), "extVirtualLinks")
167         data["extension"]["vnfinstancename"] = ignorcase_get(request.data, "vnfInstanceName")
168         data["extension"]["vnfid"] = data["VNFD"]
169         data["extension"]["multivim"] = 0
170         logger.debug("[%s] call_req data=%s", fun_name(), data)
171
172         ret = restcall.call_req(
173             base_url=ignorcase_get(vnfm_info, "url"),
174             user=ignorcase_get(vnfm_info, "userName"),
175             passwd=ignorcase_get(vnfm_info, "password"),
176             auth_type=restcall.rest_no_auth,
177             resource=create_vnf_url,
178             method='post',
179             content=json.JSONEncoder().encode(data))
180
181         logger.debug("[%s] call_req ret=%s", fun_name(), ret)
182         if ret[0] != 0:
183             return Response(data={'error': ret[1]}, status=ret[2])
184         resp = json.JSONDecoder().decode(ret[1])
185         resp_data = mapping_conv(create_vnf_resp_mapping, resp)
186         logger.info("[%s]resp_data=%s", fun_name(), resp_data)
187     except Exception as e:
188         logger.error("Error occurred when instantiating VNF")
189         raise e
190     return Response(data=resp_data, status=ret[2])
191
192
193 # ==================================================
194 vnf_delete_url = "v1/vnfs/%s"
195 vnf_delete_param_mapping = {
196     "terminationType": "terminationType",
197     "gracefulTerminationTimeout": "gracefulTerminationTimeout"}
198 vnf_delete_resp_mapping = {
199     "vnfInstanceId": "vnfInstanceId",
200     "JobId": "jobid"}
201
202
203 @api_view(http_method_names=['POST'])
204 def terminate_vnf(request, *args, **kwargs):
205     try:
206         logger.debug("[%s] request.data=%s", fun_name(), request.data)
207         vnfm_id = ignorcase_get(kwargs, "vnfmid")
208         ret = get_vnfminfo_from_nslcm(vnfm_id)
209         if ret[0] != 0:
210             return Response(data={'error': ret[1]}, status=ret[2])
211         vnfm_info = json.JSONDecoder().decode(ret[1])
212         logger.debug("[%s] vnfm_info=%s", fun_name(), vnfm_info)
213         data = {}
214         logger.debug("[%s]req_data=%s", fun_name(), data)
215         ret = restcall.call_req(
216             base_url=ignorcase_get(vnfm_info, "url"),
217             user=ignorcase_get(vnfm_info, "userName"),
218             passwd=ignorcase_get(vnfm_info, "password"),
219             auth_type=restcall.rest_no_auth,
220             resource=vnf_delete_url % (ignorcase_get(kwargs, "vnfInstanceID")),
221             method='delete',
222             content=json.JSONEncoder().encode(data))
223         if ret[0] != 0:
224             return Response(data={'error': ret[1]}, status=ret[2])
225         resp = json.JSONDecoder().decode(ret[1])
226         resp_data = mapping_conv(vnf_delete_resp_mapping, resp)
227         logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
228     except Exception as e:
229         logger.error("Error occurred when terminating VNF")
230         raise e
231     return Response(data=resp_data, status=ret[2])
232
233
234 # ==================================================
235
236
237 vnf_detail_url = "v1/vnfs/%s"
238 vnf_detail_resp_mapping = {
239     "VNFInstanseStatus": "status"
240 }
241
242
243 @api_view(http_method_names=['GET'])
244 def query_vnf(request, *args, **kwargs):
245     try:
246         logger.debug("[%s] request.data=%s", fun_name(), request.data)
247         vnfm_id = ignorcase_get(kwargs, "vnfmid")
248         ret = get_vnfminfo_from_nslcm(vnfm_id)
249         if ret[0] != 0:
250             return Response(data={'error': ret[1]}, status=ret[2])
251         vnfm_info = json.JSONDecoder().decode(ret[1])
252         logger.debug("[%s] vnfm_info=%s", fun_name(), vnfm_info)
253         data = {}
254         ret = restcall.call_req(
255             base_url=ignorcase_get(vnfm_info, "url"),
256             user=ignorcase_get(vnfm_info, "userName"),
257             passwd=ignorcase_get(vnfm_info, "password"),
258             auth_type=restcall.rest_no_auth,
259             resource=vnf_detail_url % (ignorcase_get(kwargs, "vnfInstanceID")),
260             method='get',
261             content=json.JSONEncoder().encode(data))
262         if ret[0] != 0:
263             return Response(data={'error': ret[1]}, status=ret[2])
264         resp = json.JSONDecoder().decode(ret[1])
265         vnf_status = ignorcase_get(resp, "vnfinstancestatus")
266         resp_data = {"vnfInfo": {"vnfStatus": vnf_status}}
267         logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
268     except Exception as e:
269         logger.error("Error occurred when querying VNF information.")
270         raise e
271     return Response(data=resp_data, status=ret[2])
272
273
274 # Get Operation Status
275 operation_status_url = '/v1/jobs/{jobId}?NFVOID={nfvoId}&VNFMID={vnfmId}&ResponseID={responseId}'
276 operation_status_resp_map = {
277     "JobId": "jobId",
278     "Status": "status",
279     "Progress": "progress",
280     "StatusDescription": "currentStep",
281     "ErrorCode": "errorCode",
282     "ResponseId": "responseId",
283     "ResponseHistoryList": "responseHistoryList",
284     "ResponseDescriptor": "responseDescriptor"
285 }
286
287
288 @api_view(http_method_names=['GET'])
289 def operation_status(request, *args, **kwargs):
290     data = {}
291     try:
292         logger.debug("[%s] request.data=%s", fun_name(), request.data)
293         vnfm_id = ignorcase_get(kwargs, "vnfmid")
294         ret = get_vnfminfo_from_nslcm(vnfm_id)
295         if ret[0] != 0:
296             return Response(data={'error': ret[1]}, status=ret[2])
297         vnfm_info = json.JSONDecoder().decode(ret[1])
298         logger.debug("[%s] vnfm_info=%s", fun_name(), vnfm_info)
299         ret = restcall.call_req(
300             base_url=ignorcase_get(vnfm_info, 'url'),
301             user=ignorcase_get(vnfm_info, 'userName'),
302             passwd=ignorcase_get(vnfm_info, 'password'),
303             auth_type=restcall.rest_no_auth,
304             resource=operation_status_url.format(jobId=ignorcase_get(kwargs, 'jobid'), nfvoId=1,
305                                                  vnfmId=ignorcase_get(kwargs, 'vnfmid'),
306                                                  responseId=ignorcase_get(request.GET, 'responseId')),
307             method='get',
308             content=json.JSONEncoder().encode(data))
309
310         if ret[0] != 0:
311             return Response(data={'error': ret[1]}, status=ret[2])
312         resp_data = json.JSONDecoder().decode(ret[1])
313         logger.info("[%s]resp_data=%s", fun_name(), resp_data)
314     except Exception as e:
315         logger.error("Error occurred when getting operation status information.")
316         raise e
317     return Response(data=resp_data, status=ret[2])
318
319
320 # Grant VNF Lifecycle Operation
321 grant_vnf_url = 'api/nslcm/v1/ns/grantvnf'
322 grant_vnf_param_map = {
323     "VNFMID": "",
324     "NFVOID": "",
325     "VIMID": "",
326     "ExVIMIDList": "",
327     "ExVIMID": "",
328     "Tenant": "",
329     "VNFInstanceID": "vnfInstanceId",
330     "OperationRight": "",
331     "VMList": "",
332     "VMFlavor": "",
333     "VMNumber": ""}
334
335
336 @api_view(http_method_names=['PUT'])
337 def grantvnf(request, *args, **kwargs):
338     logger.info("=====grantvnf=====")
339     try:
340         resp_data = {}
341         logger.info("req_data = %s", request.data)
342         data = mapping_conv(grant_vnf_param_map, request.data)
343         logger.info("grant_vnf_url = %s", grant_vnf_url)
344         data["vnfDescriptorId"] = ""
345         if ignorcase_get(request.data, "operationright") == 0:
346             data["lifecycleOperation"] = "Instantiate"
347             data["addresource"] = []
348             for vm in ignorcase_get(request.data, "vmlist"):
349                 for i in range(int(ignorcase_get(vm, "vmnumber"))):
350                     data["addresource"].append(
351                         {"type": "vdu",
352                          "resourceDefinitionId": i,
353                          "vdu": ignorcase_get(vm, "vmflavor"),
354                          "vimid": ignorcase_get(vm, "vimid"),
355                          "tenant": ignorcase_get(vm, "tenant")
356                          })
357
358         data["additionalparam"] = {}
359         data["additionalparam"]["vnfmid"] = ignorcase_get(request.data, "vnfmid")
360         data["additionalparam"]["vimid"] = ignorcase_get(request.data, "vimid")
361         data["additionalparam"]["tenant"] = ignorcase_get(request.data, "tenant")
362
363         logger.info("data = %s", data)
364         ret = req_by_msb(grant_vnf_url, "POST", content=json.JSONEncoder().encode(data))
365         logger.info("ret = %s", ret)
366         if ret[0] != 0:
367             return Response(data={'error': ret[1]}, status=ret[2])
368         resp = json.JSONDecoder().decode(ret[1])
369
370         resp_data['vimid'] = ignorcase_get(resp['vim'], 'vimid')
371         resp_data['tenant'] = ignorcase_get(ignorcase_get(resp['vim'], 'accessinfo'), 'tenant')
372
373         logger.info("[%s]resp_data=%s", fun_name(), resp_data)
374     except Exception as e:
375         logger.error("Error occurred in Grant VNF.")
376         raise e
377     return Response(data=resp_data, status=ret[2])
378
379
380 # Notify LCM Events
381 notify_url = 'api/nslcm/v1/ns/{vnfmid}/vnfs/{vnfInstanceId}/Notify'
382 notify_param_map = {
383     "NFVOID": "",
384     "VNFMID": "VNFMID",
385     "VIMID": "vimid",
386     "VNFInstanceID": "vnfInstanceId",
387     "TimeStamp": "",
388     "EventType": "operation",
389     "VMList": "",
390     "VMFlavor": "",
391     "VMNumber": "",
392     "VMIDlist": "",
393     "VMUUID": ""
394 }
395
396
397 @api_view(http_method_names=['POST'])
398 def notify(request, *args, **kwargs):
399     try:
400         logger.info("[%s]req_data = %s", fun_name(), request.data)
401         data = mapping_conv(notify_param_map, request.data)
402         logger.info("[%s]data = %s", fun_name(), data)
403
404         data["status"] = "result"
405         data["jobId"] = "notMust"
406         data["affectedVnfc"] = []
407         data["affectedVl"] = []
408         data["affectedVirtualStorage"] = []
409         data["affectedCp"] = []
410
411         affectedvnfcs = ignorcase_get(ignorcase_get(request.data, "extension"), "affectedvnfc")
412         affectedvls = ignorcase_get(ignorcase_get(request.data, "extension"), "affectedvl")
413         affectedcps = ignorcase_get(ignorcase_get(request.data, "extension"), "affectedcp")
414         vnfdmodule = ignorcase_get(ignorcase_get(request.data, "extension"), "vnfdmodule")
415
416         data["vnfdmodule"] = vnfdmodule
417
418         for affectedvnfc in affectedvnfcs:
419             data["affectedVnfc"].append({
420                 "vnfcInstanceId": ignorcase_get(affectedvnfc, "vnfcinstanceid"),
421                 "vduId": ignorcase_get(affectedvnfc, "vduId"),
422                 "changeType": ignorcase_get(affectedvnfc, "changeType"),
423                 "vimid": ignorcase_get(ignorcase_get(affectedvnfc, "computeresource"), "vimid"),
424                 "vmId": ignorcase_get(ignorcase_get(affectedvnfc, "computeresource"), "resourceid"),
425                 "vmName": ignorcase_get(ignorcase_get(affectedvnfc, "computeresource"), "resourcename")
426             })
427
428         for affectedvl in affectedvls:
429             data["affectedVl"].append({
430                 "vlInstanceId": ignorcase_get(affectedvl, "virtuallinkinstanceid"),
431                 "vimid": ignorcase_get(ignorcase_get(affectedvl, "networkresource"), "vimid"),
432                 "vldid": ignorcase_get(affectedvl, "virtuallinkdescid"),
433                 "vllid": ignorcase_get(ignorcase_get(affectedvl, "networkresource"), "resourceid"),
434                 "vlName": ignorcase_get(ignorcase_get(affectedvl, "networkresource"), "resourcename")
435             })
436
437         for affectedcp in affectedcps:
438             data["affectedCp"].append(affectedcp)
439             #     {
440             #     "virtualLinkInstanceId": ignorcase_get(affectedcp, "virtuallinkinstanceid"),
441             #     "ownerId": ignorcase_get(affectedcp, "ownerId"),
442             #     "ownerType": ignorcase_get(affectedcp, "ownerType")
443             # }
444         ret = req_by_msb(notify_url.format(vnfmid=ignorcase_get(data, 'VNFMID'),
445                                            vnfInstanceId=ignorcase_get(data, 'vnfinstanceid')),
446                          "POST", content=json.JSONEncoder().encode(data))
447
448         logger.info("[%s]data = %s", fun_name(), ret)
449         if ret[0] != 0:
450             return Response(data={'error': ret[1]}, status=ret[2])
451     except Exception as e:
452         logger.error("Error occurred in LCM notification.")
453         raise e
454     return Response(data=None, status=ret[2])
455
456
457 nf_scaling_url = '/v1/vnfs/{vnfInstanceID}/scale'
458
459
460 @api_view(http_method_names=['POST'])
461 def scale(request, *args, **kwargs):
462     logger.info("====scale_vnf===")
463     try:
464         logger.info("request.data = %s", request.data)
465         logger.info("requested_url = %s", request.get_full_path())
466         vnfm_id = ignorcase_get(kwargs, "vnfmid")
467         nf_instance_id = ignorcase_get(kwargs, "vnfInstanceId")
468         ret = get_vnfminfo_from_nslcm(vnfm_id)
469         if ret[0] != 0:
470             return Response(data={'error': ret[1]}, status=ret[2])
471         vnfm_info = json.JSONDecoder().decode(ret[1])
472         scale_type = ignorcase_get(request.data, "type")
473         aspect_id = ignorcase_get(request.data, "aspectId")
474         number_of_steps = ignorcase_get(request.data, "numberOfSteps")
475         # extension = ignorcase_get(request.data, "additionalParam")
476         # vnfd_model = ignorcase_get(extension, "vnfdModel")
477         data = {
478             'vnfmid': vnfm_id,
479             'nfvoid': 1,
480             'scaletype': '0' if scale_type == 'SCALE_OUT' else '1',
481             'vmlist': [{'VMNumber': number_of_steps, 'VMFlavor': aspect_id}],
482             'extension': ''
483         }
484         '''
485         for vdu_id in get_vdus(vnfd_model, aspect_id):
486             data['vmlist'].append({
487                 "VMFlavor": vdu_id,
488                 "VMNumber": number_of_steps
489             })
490         '''
491         logger.info("data = %s", data)
492         ret = restcall.call_req(
493             base_url=ignorcase_get(vnfm_info, "url"),
494             user=ignorcase_get(vnfm_info, "userName"),
495             passwd=ignorcase_get(vnfm_info, "password"),
496             auth_type=restcall.rest_no_auth,
497             resource=nf_scaling_url.format(vnfInstanceID=nf_instance_id),
498             method='put',  # POST
499             content=json.JSONEncoder().encode(data))
500         logger.info("ret=%s", ret)
501         if ret[0] != 0:
502             return Response(data={'error': 'scale error'}, status=ret[2])
503         resp_data = json.JSONDecoder().decode(ret[1])
504         # jobId = resp_data["jobid"]
505         logger.info("resp_data=%s", resp_data)
506     except Exception as e:
507         logger.error("Error occurred when scaling VNF,error:%s", e.message)
508         logger.error(traceback.format_exc())
509         return Response(data={'error': 'scale expection'}, status='500')
510     return Response(data=resp_data, status=ret[2])
511
512
513 nf_healing_url = '/api/v1/nf_m_i/nfs/{vnfInstanceID}/vms/operation'
514
515
516 @api_view(http_method_names=['POST'])
517 def heal(request, *args, **kwargs):
518     logger.info("====heal_vnf===")
519     try:
520         logger.info("request.data = %s", request.data)
521         logger.info("requested_url = %s", request.get_full_path())
522         vnfm_id = ignorcase_get(kwargs, "vnfmid")
523         nf_instance_id = ignorcase_get(kwargs, "vnfInstanceId")
524         ret = get_vnfminfo_from_nslcm(vnfm_id)
525         if ret[0] != 0:
526             return Response(data={'error': ret[1]}, status=ret[2])
527         vnfm_info = json.JSONDecoder().decode(ret[1])
528         data = request.data
529         data['lifecycleoperation'] = 'operate'
530         data['isgrace'] = 'force'
531
532         logger.info("data = %s", data)
533         ret = restcall.call_req(
534             base_url=ignorcase_get(vnfm_info, "url"),
535             user=ignorcase_get(vnfm_info, "userName"),
536             passwd=ignorcase_get(vnfm_info, "password"),
537             auth_type=restcall.rest_no_auth,
538             resource=nf_healing_url.format(vnfInstanceID=nf_instance_id),
539             method='put',  # POST
540             content=json.JSONEncoder().encode(data))
541         logger.info("ret=%s", ret)
542         if ret[0] != 0:
543             return Response(data={'error': 'heal error'}, status=ret[2])
544         resp_data = json.JSONDecoder().decode(ret[1])
545         # jobId = resp_data["jobid"]
546         logger.info("resp_data=%s", resp_data)
547     except Exception as e:
548         logger.error("Error occurred when healing VNF,error:%s", e.message)
549         logger.error(traceback.format_exc())
550         return Response(data={'error': 'heal expection'}, status='500')
551     return Response(data=resp_data, status=ret[2])
552
553
554 def get_vdus(nf_model, aspect_id):
555     associated_group = ''
556     members = []
557     vnf_flavours = nf_model['vnf_flavours']
558     for vnf_flaour in vnf_flavours:
559         scaling_aspects = vnf_flaour['scaling_aspects']
560         for aspect in scaling_aspects:
561             if aspect_id == aspect['id']:
562                 associated_group = aspect['associated_group']
563                 break
564     if not associated_group:
565         logger.error('Cannot find the corresponding element group')
566         raise Exception('Cannot find the corresponding element group')
567     for element_group in nf_model['element_groups']:
568         if element_group['group_id'] == associated_group:
569             members = element_group['members']
570     if not members:
571         logger.error('Cannot find the corresponding members')
572         raise Exception('Cannot find the corresponding members')
573     return members
574
575
576 @api_view(http_method_names=['GET'])
577 def samples(request, *args, **kwargs):
578     return Response(data={"status": "ok"})