3e62b068c0c00a904c6eaf380548de49db39cf31
[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 os
19 import traceback
20
21 from drf_yasg import openapi
22 from drf_yasg.utils import swagger_auto_schema
23 from rest_framework import status
24 from rest_framework.response import Response
25 from rest_framework.views import APIView
26 from django.http import StreamingHttpResponse
27
28 from driver.interfaces.serializers import HealReqSerializer, InstScaleHealRespSerializer, ScaleReqSerializer, \
29     NotifyReqSerializer, GrantRespSerializer, GrantReqSerializer, JobQueryRespSerializer, TerminateVnfRequestSerializer, \
30     InstantiateVnfRequestSerializer, QueryVnfResponseSerializer, SubscribesRespSerializer, \
31     SubscribeReqSerializer, SubscribeRespSerializer, VnfPkgsSerializer, NfvoInfoReqSerializer
32 from driver.pub.config.config import VNF_FTP
33 from driver.pub.utils import restcall
34 from driver.pub.utils.restcall import req_by_msb
35
36 CHUNK_SIZE = 1024 * 8
37
38 logger = logging.getLogger(__name__)
39
40
41 def load_json_file(file_name):
42     json_file = os.path.join(os.path.dirname(__file__), "data/" + file_name)
43     f = open(json_file)
44     json_data = json.JSONDecoder().decode(f.read())
45     f.close()
46     return json_data
47
48
49 def read(file_path, start, end):
50     fp = open(file_path, 'rb')
51     fp.seek(start)
52     pos = start
53     while pos + CHUNK_SIZE < end:
54         yield fp.read(CHUNK_SIZE)
55         pos = fp.tell()
56     yield fp.read(end - pos)
57
58
59 def parse_file_range(file_path, file_range):
60     start, end = 0, os.path.getsize(file_path)
61     if file_range:
62         [start, end] = file_range.split('-')
63         start, end = start.strip(), end.strip()
64         start, end = int(start), int(end)
65     return start, end
66
67
68 def fun_name():
69     return "=================%s==================" % inspect.stack()[1][3]
70
71
72 def ignorcase_get(args, key):
73     if not key:
74         return ""
75     if not args:
76         return ""
77     if key in args:
78         return args[key]
79     for old_key in args:
80         if old_key.upper() == key.upper():
81             return args[old_key]
82     return ""
83
84
85 # Query vnfm_info from nslcm
86 def get_vnfminfo_from_nslcm(vnfmid):
87     ret = req_by_msb("api/nslcm/v1/vnfms/%s" % vnfmid, "GET")
88     return ret
89
90
91 # Query vnfd_info from nslcm
92 def vnfd_get(vnfpackageid):
93     ret = req_by_msb("api/nslcm/v1/vnfpackage/%s" % vnfpackageid, "GET")
94     return ret
95
96
97 # Query vnfpackage_info from nslcm
98 def vnfpackage_get(csarid):
99     ret = req_by_msb("api/nslcm/v1/vnfpackage/%s" % csarid, "GET")
100     return ret
101
102
103 class InstantiateVnf(APIView):
104     @swagger_auto_schema(
105         request_body=InstantiateVnfRequestSerializer(),
106         responses={
107             status.HTTP_200_OK: InstScaleHealRespSerializer(),
108             status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
109         }
110     )
111     def post(self, request, vnfmid):
112         try:
113             logger.debug("[%s] request.data=%s", fun_name(), request.data)
114             instantiateVnfRequestSerializer = InstantiateVnfRequestSerializer(data=request.data)
115             if not instantiateVnfRequestSerializer.is_valid():
116                 raise Exception(instantiateVnfRequestSerializer.errors)
117
118             ret = get_vnfminfo_from_nslcm(vnfmid)
119             if ret[0] != 0:
120                 raise Exception(ret[1])
121
122             vnfm_info = json.JSONDecoder().decode(ret[1])
123             logger.debug("[%s] vnfm_info=%s", fun_name(), vnfm_info)
124             vnf_package_id = ignorcase_get(instantiateVnfRequestSerializer.data, "vnfPackageId")
125             ret = vnfd_get(vnf_package_id)
126             if ret[0] != 0:
127                 raise Exception(ret[1])
128
129             vnfd_info = json.JSONDecoder().decode(ret[1])
130             logger.debug("[%s] vnfd_info=%s", fun_name(), vnfd_info)
131             csar_id = ignorcase_get(vnfd_info, "csarId")
132             ret = vnfpackage_get(csar_id)
133             if ret[0] != 0:
134                 raise Exception(ret[1])
135
136             vnf_package_info = json.JSONDecoder().decode(ret[1])
137             packageInfo = ignorcase_get(vnf_package_info, "packageInfo")
138             logger.debug("[%s] packageInfo=%s", fun_name(), packageInfo)
139             logger.debug("VNF_FTP=%s", VNF_FTP)
140             data = {
141                 "vnfinstancename": "default",
142                 "NFVOID": 1,
143                 "VNFMID": vnfmid,
144                 "vnfd_id": packageInfo.get("vnfdId"),
145                 "deployflavorid": "default",
146                 "extension": {},
147                 "inputs": []
148             }
149
150             additionalParam = ignorcase_get(instantiateVnfRequestSerializer.data, "additionalParam")
151             for name, value in ignorcase_get(additionalParam, "inputs").items():
152                 data["inputs"].append({"key_name": name, "value": value, "type": "TODO"})
153
154             inputs_json = load_json_file("inputs.json")
155             [data["inputs"].append(item) for item in inputs_json["inputs"]]
156
157             logger.debug("[%s] call_req data=%s", fun_name(), data)
158
159             ret = restcall.call_req(
160                 base_url=ignorcase_get(vnfm_info, "url"),
161                 user=ignorcase_get(vnfm_info, "userName"),
162                 passwd=ignorcase_get(vnfm_info, "password"),
163                 auth_type=restcall.rest_no_auth,
164                 resource="v1/vnfs",
165                 method='post',
166                 content=json.JSONEncoder().encode(data))
167
168             logger.debug("[%s] call_req ret=%s", fun_name(), ret)
169             if ret[0] != 0:
170                 raise Exception(ret[1])
171
172             resp = json.JSONDecoder().decode(ret[1])
173             resp_data = {
174                 "vnfInstanceId": ignorcase_get(resp, "VNFInstanceID"),
175                 "jobId": ignorcase_get(resp, "JobId")
176             }
177             logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
178             instRespSerializer = InstScaleHealRespSerializer(data=resp_data)
179             if not instRespSerializer.is_valid():
180                 raise Exception(instRespSerializer.errors)
181
182             logger.debug("[%s] instRespSerializer.data=%s", fun_name(), instRespSerializer.data)
183             return Response(data=instRespSerializer.data, status=status.HTTP_200_OK)
184         except Exception as e:
185             logger.error("Error occurred when instantiating VNF,error:%s", e.message)
186             logger.error(traceback.format_exc())
187             return Response(data={'error': 'InstantiateVnf expection'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
188
189
190 class TerminateVnf(APIView):
191     @swagger_auto_schema(
192         request_body=TerminateVnfRequestSerializer(),
193         responses={
194             status.HTTP_200_OK: InstScaleHealRespSerializer(),
195             status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
196         }
197     )
198     def post(self, request, vnfmid, vnfInstanceId):
199         try:
200             logger.debug("[%s] request.data=%s", fun_name(), request.data)
201             logger.debug("vnfmid=%s, vnfInstanceId=%s", vnfmid, vnfInstanceId)
202             terminate_vnf_request_serializer = TerminateVnfRequestSerializer(data=request.data)
203             if not terminate_vnf_request_serializer.is_valid():
204                 raise Exception(terminate_vnf_request_serializer.errors)
205
206             ret = get_vnfminfo_from_nslcm(vnfmid)
207             if ret[0] != 0:
208                 raise Exception(ret[1])
209
210             vnfm_info = json.JSONDecoder().decode(ret[1])
211             logger.debug("[%s] vnfm_info=%s", fun_name(), vnfm_info)
212             ret = restcall.call_req(
213                 base_url=ignorcase_get(vnfm_info, "url"),
214                 user=ignorcase_get(vnfm_info, "userName"),
215                 passwd=ignorcase_get(vnfm_info, "password"),
216                 auth_type=restcall.rest_no_auth,
217                 resource="v1/vnfs/%s?NFVOID=1&VNFMID=%s" % (vnfInstanceId, vnfmid),
218                 method='delete',
219                 content='{}')
220             if ret[0] != 0:
221                 raise Exception(ret[1])
222
223             resp = json.JSONDecoder().decode(ret[1])
224             resp_data = {
225                 "vnfInstanceId": vnfInstanceId,
226                 "jobId": ignorcase_get(resp, "JobId")
227             }
228             logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
229             terminateRespSerializer = InstScaleHealRespSerializer(data=resp_data)
230             if not terminateRespSerializer.is_valid():
231                 raise Exception(terminateRespSerializer.errors)
232             return Response(data=terminateRespSerializer.data, status=status.HTTP_200_OK)
233         except Exception as e:
234             logger.error("Error occurred when terminating VNF,error: %s", e.message)
235             logger.error(traceback.format_exc())
236             return Response(data={'error': 'TerminateVnf expection'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
237
238
239 class QueryVnf(APIView):
240     @swagger_auto_schema(
241         responses={
242             status.HTTP_200_OK: QueryVnfResponseSerializer(),
243             status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
244         }
245     )
246     def get(self, request, vnfmid, vnfInstanceId):
247         try:
248             logger.debug("[%s] request.data=%s", fun_name(), request.data)
249             ret = get_vnfminfo_from_nslcm(vnfmid)
250             if ret[0] != 0:
251                 raise Exception(ret[1])
252
253             vnfm_info = json.JSONDecoder().decode(ret[1])
254             logger.debug("[%s] vnfm_info=%s", fun_name(), vnfm_info)
255             ret = restcall.call_req(
256                 base_url=ignorcase_get(vnfm_info, "url"),
257                 user=ignorcase_get(vnfm_info, "userName"),
258                 passwd=ignorcase_get(vnfm_info, "password"),
259                 auth_type=restcall.rest_no_auth,
260                 resource="v1/vnfs/%s" % vnfInstanceId,
261                 method='get',
262                 content=json.JSONEncoder().encode({}))
263             if ret[0] != 0:
264                 raise Exception(ret[1])
265
266             resp = json.JSONDecoder().decode(ret[1])
267             vnf_status = ignorcase_get(resp, "vnfinstancestatus")
268             resp_data = {"vnfInfo": {"vnfStatus": vnf_status}}
269             logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
270             queryVnfResponseSerializer = QueryVnfResponseSerializer(data=resp_data)
271             if not queryVnfResponseSerializer.is_valid():
272                 raise Exception(queryVnfResponseSerializer.errors)
273             return Response(data=queryVnfResponseSerializer.data, status=status.HTTP_200_OK)
274         except Exception as e:
275             logger.error("Error occurred when querying VNF information,error:%s", e.message)
276             logger.error(traceback.format_exc())
277             return Response(data={'error': 'QueryVnf expection'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
278
279
280 class JobView(APIView):
281     @swagger_auto_schema(
282         manual_parameters=[
283             openapi.Parameter('responseId',
284                               openapi.IN_QUERY,
285                               "responseId",
286                               type=openapi.TYPE_INTEGER
287                               ),
288         ],
289         responses={
290             status.HTTP_200_OK: JobQueryRespSerializer(),
291             status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
292         }
293     )
294     def get(self, request, vnfmid, jobid):
295         try:
296             logger.debug("[%s] request.data=%s", fun_name(), request.data)
297             ret = get_vnfminfo_from_nslcm(vnfmid)
298             if ret[0] != 0:
299                 raise Exception(ret[1])
300
301             vnfm_info = json.JSONDecoder().decode(ret[1])
302             logger.debug("[%s] vnfm_info=%s", fun_name(), vnfm_info)
303             operation_status_url = '/v1/jobs/{jobId}?NFVOID={nfvoId}&VNFMID={vnfmId}&ResponseID={responseId}'
304             responseId = ignorcase_get(request.GET, 'responseId')
305             query_url = operation_status_url.format(jobId=jobid, nfvoId=1, vnfmId=vnfmid, responseId=responseId)
306             ret = restcall.call_req(
307                 base_url=ignorcase_get(vnfm_info, 'url'),
308                 user=ignorcase_get(vnfm_info, 'userName'),
309                 passwd=ignorcase_get(vnfm_info, 'password'),
310                 auth_type=restcall.rest_no_auth,
311                 resource=query_url,
312                 method='get',
313                 content={})
314
315             if ret[0] != 0:
316                 raise Exception(ret[1])
317
318             resp_data = json.JSONDecoder().decode(ret[1])
319             logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
320             jobQueryRespSerializer = JobQueryRespSerializer(data=resp_data)
321             if not jobQueryRespSerializer.is_valid():
322                 raise Exception(jobQueryRespSerializer.errors)
323
324             return Response(data=jobQueryRespSerializer.data, status=status.HTTP_200_OK)
325         except Exception as e:
326             logger.error("Error occurred when getting operation status information,error:%s", e.message)
327             logger.error(traceback.format_exc())
328             return Response(data={'error': 'QueryJob expection'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
329
330
331 class GrantVnf(APIView):
332     @swagger_auto_schema(
333         request_body=GrantReqSerializer(),
334         responses={
335             status.HTTP_201_CREATED: GrantRespSerializer(),
336             status.HTTP_500_INTERNAL_SERVER_ERROR: 'Internal error'
337         }
338     )
339     def put(self, request):
340         logger.debug("=====GrantVnf=====")
341         try:
342             logger.debug("request.data = %s", request.data)
343             grantReqSerializer = GrantReqSerializer(data=request.data)
344             if not grantReqSerializer.is_valid():
345                 raise Exception(grantReqSerializer.errors)
346
347             logger.debug("grantReqSerializer.data = %s", grantReqSerializer.data)
348             req_data = {
349                 "vnfInstanceId": ignorcase_get(grantReqSerializer.data, "vnfistanceid"),
350                 "vnfDescriptorId": "",
351                 "addresource": [],
352                 "additionalparam": {
353                     "vnfmid": ignorcase_get(grantReqSerializer.data, "vnfmid"),
354                     "vimid": ignorcase_get(grantReqSerializer.data, "vimid"),
355                     "tenant": ignorcase_get(grantReqSerializer.data, "tenant")
356                 }
357             }
358             if ignorcase_get(grantReqSerializer.data, "operationright") == 0:
359                 req_data["lifecycleOperation"] = "Instantiate"
360                 for vm in ignorcase_get(grantReqSerializer.data, "vmlist"):
361                     for i in range(int(ignorcase_get(vm, "VMNumber"))):
362                         req_data["addresource"].append(
363                             {
364                                 "type": "vdu",
365                                 "resourceDefinitionId": i,
366                                 "vdu": ignorcase_get(vm, "VMFlavor"),
367                                 "vimid": ignorcase_get(vm, "vimid"),
368                                 "tenant": ignorcase_get(vm, "tenant")})
369
370             logger.debug("req_data=%s", req_data)
371             ret = req_by_msb('api/nslcm/v1/ns/grantvnf', "POST", content=json.JSONEncoder().encode(req_data))
372             logger.info("ret = %s", ret)
373             if ret[0] != 0:
374                 raise Exception(ret[1])
375
376             resp = json.JSONDecoder().decode(ret[1])
377             resp_data = {
378                 'vimid': ignorcase_get(resp['vim'], 'vimid'),
379                 'tenant': ignorcase_get(ignorcase_get(resp['vim'], 'accessinfo'), 'tenant')
380             }
381             logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
382             grantRespSerializer = GrantRespSerializer(data=resp_data)
383             if not grantRespSerializer.is_valid():
384                 raise Exception(grantRespSerializer.errors)
385
386             logger.debug("grantRespSerializer.data=%s", grantRespSerializer.data)
387             return Response(data=grantRespSerializer.data, status=status.HTTP_201_CREATED)
388         except Exception as e:
389             logger.error("Error occurred in Grant VNF, error: %s", e.message)
390             logger.error(traceback.format_exc())
391             return Response(data={'error': 'Grant expection'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
392
393
394 class Notify(APIView):
395     @swagger_auto_schema(
396         request_body=NotifyReqSerializer(),
397         responses={
398             status.HTTP_200_OK: 'Successfully',
399             status.HTTP_500_INTERNAL_SERVER_ERROR: 'Internal error'
400         }
401     )
402     def post(self, request):
403         try:
404             logger.debug("[%s]request.data = %s", fun_name(), request.data)
405             notifyReqSerializer = NotifyReqSerializer(data=request.data)
406             if not notifyReqSerializer.is_valid():
407                 raise Exception(notifyReqSerializer.errors)
408
409             logger.debug("[%s]notifyReqSerializer.data = %s", fun_name(), notifyReqSerializer.data)
410             req_data = {
411                 "status": "result",
412                 "vnfInstanceId": ignorcase_get(notifyReqSerializer.data, "vnfinstanceid"),
413                 "vnfmId": ignorcase_get(notifyReqSerializer.data, "vnfmid"),
414                 "vimId": ignorcase_get(notifyReqSerializer.data, "vimid"),
415                 "operation": ignorcase_get(notifyReqSerializer.data, "EventType"),
416                 "jobId": "notMust",
417                 "affectedVl": [],
418                 "affectedCp": [],
419                 "affectedVirtualStorage": [],
420                 "affectedVnfc": [],
421             }
422
423             extension = ignorcase_get(notifyReqSerializer.data, "extension")
424             openo_notification = ignorcase_get(extension, "openo_notification")
425             if openo_notification:
426                 affectedvnfcs = ignorcase_get(openo_notification, "affectedVnfc")
427                 affectedvls = ignorcase_get(openo_notification, "affectedvirtuallink")
428                 affectedcps = ignorcase_get(openo_notification, "affectedCp")
429                 vnfdmodule = ignorcase_get(openo_notification, "vnfdmodule")
430             else:
431                 affectedvnfcs = ignorcase_get(ignorcase_get(notifyReqSerializer.data, "extension"), "affectedvnfc")
432                 affectedvls = ignorcase_get(ignorcase_get(notifyReqSerializer.data, "extension"), "affectedvl")
433                 affectedcps = ignorcase_get(ignorcase_get(notifyReqSerializer.data, "extension"), "affectedcp")
434                 vnfdmodule = ignorcase_get(ignorcase_get(notifyReqSerializer.data, "extension"), "vnfdmodule")
435
436             req_data["vnfdmodule"] = vnfdmodule
437
438             for affectedvnfc in affectedvnfcs:
439                 req_data["affectedVnfc"].append({
440                     "vnfcInstanceId": ignorcase_get(affectedvnfc, "vnfcInstanceId"),
441                     "vduId": ignorcase_get(affectedvnfc, "vduId"),
442                     "changeType": ignorcase_get(affectedvnfc, "changeType"),
443                     "vimId": ignorcase_get(ignorcase_get(affectedvnfc, "computeResource"), "vimId"),
444                     "vmId": ignorcase_get(ignorcase_get(affectedvnfc, "computeResource"), "resourceId"),
445                     "vmName": ignorcase_get(ignorcase_get(affectedvnfc, "computeResource"), "resourceName")
446                 })
447
448             for affectedvl in affectedvls:
449                 req_data["affectedVl"].append({
450                     "vlInstanceId": ignorcase_get(affectedvl, "virtualLinkInstanceId"),
451                     "changeType": ignorcase_get(affectedvl, "changeType"),
452                     "vimId": ignorcase_get(ignorcase_get(affectedvl, "networkResource"), "vimId"),
453                     "vldId": ignorcase_get(affectedvl, "virtuallinkdescid"),
454                     "networkResource": {
455                         "resourceType": "network",
456                         "resourceId": ignorcase_get(ignorcase_get(affectedvl, "networkresource"), "resourceid"),
457                         "resourceName": ignorcase_get(ignorcase_get(affectedvl, "networkresource"), "resourcename")
458                     }
459                 })
460
461             for affectedcp in affectedcps:
462                 req_data["affectedCp"].append(affectedcp)
463
464             vnfmid = ignorcase_get(req_data, 'vnfmId')
465             vnfInstanceId = ignorcase_get(req_data, 'vnfinstanceid')
466             notify_url = 'api/nslcm/v1/ns/%s/vnfs/%s/Notify' % (vnfmid, vnfInstanceId)
467             logger.debug("notify_url = %s", notify_url)
468             logger.debug("req_data = %s", req_data)
469             ret = req_by_msb(notify_url, "POST", content=json.JSONEncoder().encode(req_data))
470
471             logger.debug("[%s]data = %s", fun_name(), ret)
472             if ret[0] != 0:
473                 raise Exception(ret[1])
474
475             return Response(data=None, status=status.HTTP_200_OK)
476         except Exception as e:
477             logger.error("Error occurred in LCM notification,error: %s", e.message)
478             logger.error(traceback.format_exc())
479             return Response(data={'error': 'Notify expection'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
480
481
482 class Scale(APIView):
483     @swagger_auto_schema(
484         request_body=ScaleReqSerializer(),
485         responses={
486             status.HTTP_202_ACCEPTED: InstScaleHealRespSerializer(),
487             status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
488         }
489     )
490     def post(self, request, vnfmid, vnfInstanceId):
491         logger.debug("====scale_vnf===")
492         try:
493             logger.debug("request.data = %s", request.data)
494             logger.debug("requested_url = %s", request.get_full_path())
495             scaleReqSerializer = ScaleReqSerializer(data=request.data)
496             if not scaleReqSerializer.is_valid():
497                 raise Exception(scaleReqSerializer.errors)
498
499             ret = get_vnfminfo_from_nslcm(vnfmid)
500             if ret[0] != 0:
501                 raise Exception(ret[1])
502
503             vnfm_info = json.JSONDecoder().decode(ret[1])
504             scale_type = ignorcase_get(scaleReqSerializer.data, "type")
505             aspect_id = ignorcase_get(scaleReqSerializer.data, "aspectId")
506             number_of_steps = ignorcase_get(scaleReqSerializer.data, "numberOfSteps")
507             data = {
508                 'vnfmid': vnfmid,
509                 'nfvoid': 1,
510                 'scaletype': '0' if scale_type == 'SCALE_OUT' else '1',
511                 'vmlist': [{
512                     'VMNumber': number_of_steps,
513                     'VMFlavor': aspect_id
514                 }],
515                 'extension': ''
516             }
517
518             logger.debug("data = %s", data)
519             ret = restcall.call_req(
520                 base_url=ignorcase_get(vnfm_info, "url"),
521                 user=ignorcase_get(vnfm_info, "userName"),
522                 passwd=ignorcase_get(vnfm_info, "password"),
523                 auth_type=restcall.rest_no_auth,
524                 resource='/v1/vnfs/{vnfInstanceID}/scale'.format(vnfInstanceID=vnfInstanceId),
525                 method='put',  # POST
526                 content=json.JSONEncoder().encode(data))
527             logger.debug("ret=%s", ret)
528             if ret[0] != 0:
529                 raise Exception('scale error')
530
531             scaleRespSerializer = InstScaleHealRespSerializer(data=json.JSONDecoder().decode(ret[1]))
532             if not scaleRespSerializer.is_valid():
533                 raise Exception(scaleRespSerializer.errors)
534
535             logger.debug("scaleRespSerializer.data=%s", scaleRespSerializer.data)
536             return Response(data=scaleRespSerializer.data, status=status.HTTP_202_ACCEPTED)
537         except Exception as e:
538             logger.error("Error occurred when scaling VNF,error:%s", e.message)
539             logger.error(traceback.format_exc())
540             return Response(data={'error': 'Scale expection'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
541
542
543 class Heal(APIView):
544     @swagger_auto_schema(
545         request_body=HealReqSerializer(),
546         responses={
547             status.HTTP_202_ACCEPTED: InstScaleHealRespSerializer(),
548             status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
549         }
550     )
551     def post(self, request, vnfmid, vnfInstanceId):
552         logger.debug("====heal_vnf===")
553         try:
554             logger.debug("request.data = %s", request.data)
555             logger.debug("requested_url = %s", request.get_full_path())
556             healReqSerializer = HealReqSerializer(data=request.data)
557             if not healReqSerializer.is_valid():
558                 raise Exception(healReqSerializer.errors)
559
560             logger.debug("healReqSerializer.data = %s", healReqSerializer.data)
561             logger.debug("vnfmid = %s", vnfmid)
562             ret = get_vnfminfo_from_nslcm(vnfmid)
563             if ret[0] != 0:
564                 raise Exception(ret[1])
565
566             vnfm_info = json.JSONDecoder().decode(ret[1])
567             req_data = {
568                 "action": ignorcase_get(healReqSerializer.data, 'action'),
569                 "lifecycleoperation": "operate",
570                 "isgrace": "force",
571                 "affectedvm": [],
572             }
573             affectedvm = ignorcase_get(healReqSerializer.data, 'affectedvm')
574             if isinstance(affectedvm, list):
575                 req_data['affectedvm'] = affectedvm
576             else:
577                 req_data['affectedvm'].append(affectedvm)
578
579             logger.debug("req_data = %s", req_data)
580             ret = restcall.call_req(
581                 base_url=ignorcase_get(vnfm_info, "url"),
582                 user=ignorcase_get(vnfm_info, "userName"),
583                 passwd=ignorcase_get(vnfm_info, "password"),
584                 auth_type=restcall.rest_no_auth,
585                 resource='/api/v1/nf_m_i/nfs/{vnfInstanceID}/vms/operation'.format(vnfInstanceID=vnfInstanceId),
586                 method='post',
587                 content=json.JSONEncoder().encode(req_data))
588             logger.debug("ret=%s", ret)
589             if ret[0] != 0:
590                 raise Exception('heal error')
591
592             healRespSerializer = InstScaleHealRespSerializer(data=json.JSONDecoder().decode(ret[1]))
593             if not healRespSerializer.is_valid():
594                 raise Exception(healRespSerializer.errors)
595
596             logger.debug("healRespSerializer.data=%s", healRespSerializer.data)
597             return Response(data=healRespSerializer.data, status=status.HTTP_202_ACCEPTED)
598         except Exception as e:
599             logger.error("Error occurred when healing VNF,error:%s", e.message)
600             logger.error(traceback.format_exc())
601             return Response(data={'error': 'Heal expection'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
602
603
604 def get_vdus(nf_model, aspect_id):
605     associated_group = ''
606     members = []
607     vnf_flavours = nf_model['vnf_flavours']
608     for vnf_flaour in vnf_flavours:
609         scaling_aspects = vnf_flaour['scaling_aspects']
610         for aspect in scaling_aspects:
611             if aspect_id == aspect['id']:
612                 associated_group = aspect['associated_group']
613                 break
614     if not associated_group:
615         logger.error('Cannot find the corresponding element group')
616         raise Exception('Cannot find the corresponding element group')
617     for element_group in nf_model['element_groups']:
618         if element_group['group_id'] == associated_group:
619             members = element_group['members']
620     if not members:
621         logger.error('Cannot find the corresponding members')
622         raise Exception('Cannot find the corresponding members')
623     return members
624
625
626 class SampleList(APIView):
627     @swagger_auto_schema(
628         responses={
629             status.HTTP_200_OK: 'Successfully'})
630     def get(self, request):
631         logger.debug("get")
632         return Response({"status": "active"})
633
634
635 class Subscribe(APIView):
636     @swagger_auto_schema(
637         responses={
638             status.HTTP_200_OK: SubscribesRespSerializer(),
639             status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
640         }
641     )
642     def get(self, request):
643         logger.debug("====Subscribe get====")
644         resp_data = {
645             "subscriptions": [{
646                 "subscribeid": "cdbddb00-452c-11e9-91e8-acc860114657",
647                 "filter": [{
648                     "vendor": "ZTE",
649                     "type": "vCPE",
650                 }],
651                 "notificationuri": " https://127.0.0.1:80/v2/vnfm/vnfds/notification",
652             }]
653         }
654         return Response(data=resp_data, status=status.HTTP_200_OK)
655
656     @swagger_auto_schema(
657         request_body=SubscribeReqSerializer(),
658         responses={
659             status.HTTP_201_CREATED: SubscribeRespSerializer(),
660             status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
661         }
662     )
663     def post(self, request):
664         logger.debug("====Subscribe post====")
665         resp_data = {"subscribeid": "cdbddb00-452c-11e9-91e8-acc860114657"}
666         return Response(data=resp_data, status=status.HTTP_201_CREATED)
667
668
669 class SubscribeDetail(APIView):
670     @swagger_auto_schema(
671         responses={
672             status.HTTP_204_NO_CONTENT: "None",
673             status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
674         }
675     )
676     def delete(self, request, subscribeId):
677         logger.debug("====SubscribeDetail delete %s====", subscribeId)
678         return Response(status=status.HTTP_204_NO_CONTENT)
679
680
681 class VnfPkgs(APIView):
682     @swagger_auto_schema(
683         responses={
684             status.HTTP_200_OK: VnfPkgsSerializer(),
685             status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
686         }
687     )
688     def get(self, request):
689         logger.debug("====VnfPkgs get====")
690         resp_data = {
691             "data": [{
692                 "packageid": "924fc980-4530-11e9-ae68-acc860114657",
693                 "vendor": "ZTE",
694                 "type": "vCPE",
695                 "vnfdfile": "MRP6600_FS_SRIOV_4NIC_200W.zip",
696                 "imagefiles": ["MRP6600_FS_SRIOV_MRPISU_IMGV500R008C20SPC030T.tar"],
697                 "swfiles": ["MRP6600_SRV_V500R008C20SPC030T.tar"],
698                 "description": "This is a service for vCPE.",
699             }]
700         }
701         return Response(data=resp_data, status=status.HTTP_200_OK)
702
703
704 class VnfPkg(APIView):
705     @swagger_auto_schema(
706         responses={
707             status.HTTP_200_OK: "File stream for vnf pkg file",
708             status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
709         }
710     )
711     def get(self, request, packageId, fileName):
712         logger.debug("====VnfPkg get====%s, %s", packageId, fileName)
713         file_range = request.META.get('RANGE')
714         logger.debug('file_range: %s' % file_range)
715         # TODO: get filepath
716         local_file_path = fileName
717         start, end = parse_file_range(local_file_path, file_range)
718         file_iterator = read(local_file_path, start, end)
719         return StreamingHttpResponse(file_iterator, status=status.HTTP_200_OK)
720
721
722 class NfvoInfo(APIView):
723     @swagger_auto_schema(
724         request_body=NfvoInfoReqSerializer(),
725         responses={
726             status.HTTP_200_OK: "Update successfully",
727             status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
728         }
729     )
730     def put(self, request, vnfmid):
731         logger.debug("====NfvoInfo put====%s", vnfmid)
732         req_data = {
733             "nfvoid": request.data.get("nfvoid", "1"),
734             "vnfmid": vnfmid,
735             "nfvourl": request.data.get("nfvourl", "http://127.0.0.1:80")
736         }
737         ret = get_vnfminfo_from_nslcm(vnfmid)
738         if ret[0] != 0:
739             return Response(data={'error': ret[1]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
740
741         vnfm_info = json.JSONDecoder().decode(ret[1])
742         logger.debug("[%s] vnfm_info=%s", fun_name(), vnfm_info)
743         ret = restcall.call_req(
744             base_url=ignorcase_get(vnfm_info, "url"),
745             user=ignorcase_get(vnfm_info, "userName"),
746             passwd=ignorcase_get(vnfm_info, "password"),
747             auth_type=restcall.rest_no_auth,
748             resource="v1/nfvo/info",
749             method='put',
750             content=json.dumps(req_data))
751         if ret[0] != 0:
752             return Response(data={'error': ret[1]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
753         logger.debug("update nfvo info successfully.")
754         return Response(data={}, status=status.HTTP_200_OK)
755
756
757 class HealthCheckView(APIView):
758     @swagger_auto_schema(
759         responses={
760             status.HTTP_200_OK: 'Active'})
761     def get(self, request, format=None):
762         logger.debug("HealthCheck")
763         return Response({"status": "active"})