Add unit test for ns instantiate
[vfc/nfvo/lcm.git] / lcm / ns / 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 import json
15 import logging
16 import traceback
17
18 from rest_framework import status
19 from rest_framework.response import Response
20 from rest_framework.views import APIView
21 from drf_yasg.utils import swagger_auto_schema
22
23 from lcm.ns.ns_create import CreateNSService
24 from lcm.ns.ns_delete import DeleteNsService
25 from lcm.ns.ns_get import GetNSInfoService
26 from lcm.ns.ns_heal import NSHealService
27 from lcm.ns.ns_instant import InstantNSService
28 from lcm.ns.ns_manual_scale import NSManualScaleService
29 from lcm.ns.ns_terminate import TerminateNsService
30 from lcm.pub.database.models import NSInstModel, ServiceBaseInfoModel
31 from lcm.pub.utils.jobutil import JobUtil, JOB_TYPE
32 from lcm.pub.utils.restcall import req_by_msb
33 from lcm.pub.utils.values import ignore_case_get
34 from lcm.ns.serializers import CreateNsReqSerializer, CreateNsRespSerializer
35 from lcm.ns.serializers import QueryNsRespSerializer
36 from lcm.ns.serializers import NsOperateJobSerializer
37 from lcm.ns.serializers import InstantNsReqSerializer
38 from lcm.ns.serializers import TerminateNsReqSerializer
39 from lcm.ns.serializers import HealNsReqSerializer
40 from lcm.ns.serializers import InstNsPostDealReqSerializer
41 from lcm.ns.serializers import ManualScaleNsReqSerializer
42 from lcm.pub.exceptions import NSLCMException
43
44 logger = logging.getLogger(__name__)
45
46
47 class CreateNSView(APIView):
48     @swagger_auto_schema(
49         request_body=None,
50         responses={
51             status.HTTP_200_OK: QueryNsRespSerializer(help_text="NS instances", many=True),
52             status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error"
53         }
54     )
55     def get(self, request):
56         try:
57             logger.debug("CreateNSView::get")
58             filter = None
59             csarId = ignore_case_get(request.META, 'csarId')
60             if csarId:
61                 filter = {"csarId": csarId}
62
63             ret = GetNSInfoService(filter).get_ns_info()
64             logger.debug("CreateNSView::get::ret=%s", ret)
65             resp_serializer = QueryNsRespSerializer(data=ret, many=True)
66             if not resp_serializer.is_valid():
67                 raise NSLCMException(resp_serializer.errors)
68             return Response(data=resp_serializer.data, status=status.HTTP_200_OK)
69         except Exception as e:
70             logger.error(traceback.format_exc())
71             logger.error("Exception in GetNS: %s", e.message)
72             return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
73
74     @swagger_auto_schema(
75         request_body=CreateNsReqSerializer(),
76         responses={
77             status.HTTP_201_CREATED: CreateNsRespSerializer(),
78             status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error"
79         }
80     )
81     def post(self, request):
82         logger.debug("Enter CreateNS: %s", request.data)
83         try:
84             req_serializer = CreateNsReqSerializer(data=request.data)
85             if not req_serializer.is_valid():
86                 raise NSLCMException(req_serializer.errors)
87
88             if ignore_case_get(request.data, 'test') == "test":
89                 return Response(data={'nsInstanceId': "test"}, status=status.HTTP_201_CREATED)
90             csar_id = ignore_case_get(request.data, 'csarId')
91             ns_name = ignore_case_get(request.data, 'nsName')
92             description = ignore_case_get(request.data, 'description')
93             context = ignore_case_get(request.data, 'context')
94             ns_inst_id = CreateNSService(csar_id, ns_name, description, context).do_biz()
95
96             logger.debug("CreateNSView::post::ret={'nsInstanceId':%s}", ns_inst_id)
97             resp_serializer = CreateNsRespSerializer(data={'nsInstanceId': ns_inst_id})
98             if not resp_serializer.is_valid():
99                 raise NSLCMException(resp_serializer.errors)
100             return Response(data=resp_serializer.data, status=status.HTTP_201_CREATED)
101         except Exception as e:
102             logger.error(traceback.format_exc())
103             logger.error("Exception in CreateNS: %s", e.message)
104             return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
105
106
107 class NSInstView(APIView):
108     @swagger_auto_schema(
109         request_body=InstantNsReqSerializer(),
110         responses={
111             status.HTTP_200_OK: NsOperateJobSerializer(),
112             status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error"
113         }
114     )
115     def post(self, request, ns_instance_id):
116         logger.debug("Enter NSInstView::post::ns_instance_id=%s", ns_instance_id)
117         logger.debug("request.data=%s", request.data)
118         req_serializer = InstantNsReqSerializer(data=request.data)
119         if not req_serializer.is_valid():
120             return Response({'error': req_serializer.errors},
121                             status=status.HTTP_500_INTERNAL_SERVER_ERROR)
122         ack = InstantNSService(ns_instance_id, request.data).do_biz()
123         resp_serializer = NsOperateJobSerializer(data=ack['data'])
124         if not resp_serializer.is_valid():
125             return Response({'error': resp_serializer.errors},
126                             status=status.HTTP_500_INTERNAL_SERVER_ERROR)
127         logger.debug("Leave NSInstView::post::ack=%s", ack)
128         return Response(data=resp_serializer.data, status=ack['status'])
129
130
131 class TerminateNSView(APIView):
132     @swagger_auto_schema(
133         request_body=TerminateNsReqSerializer(),
134         responses={
135             status.HTTP_202_ACCEPTED: NsOperateJobSerializer(),
136             status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error"
137         }
138     )
139     def post(self, request, ns_instance_id):
140         try:
141             logger.debug("Enter TerminateNSView::post %s", request.data)
142             req_serializer = TerminateNsReqSerializer(data=request.data)
143             if not req_serializer.is_valid():
144                 raise NSLCMException(req_serializer.errors)
145
146             termination_type = ignore_case_get(request.data, 'terminationType')
147             graceful_termination_timeout = ignore_case_get(request.data, 'gracefulTerminationTimeout')
148             job_id = JobUtil.create_job("VNF", JOB_TYPE.TERMINATE_VNF, ns_instance_id)
149             TerminateNsService(ns_instance_id, termination_type, graceful_termination_timeout, job_id).start()
150
151             resp_serializer = NsOperateJobSerializer(data={'jobId': job_id})
152             if not resp_serializer.is_valid():
153                 raise NSLCMException(resp_serializer.errors)
154             logger.debug("Leave TerminateNSView::post ret=%s", resp_serializer.data)
155             return Response(data=resp_serializer.data, status=status.HTTP_202_ACCEPTED)
156         except Exception as e:
157             logger.error("Exception in CreateNS: %s", e.message)
158             return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
159
160
161 class NSHealView(APIView):
162     @swagger_auto_schema(
163         request_body=HealNsReqSerializer(),
164         responses={
165             status.HTTP_202_ACCEPTED: NsOperateJobSerializer(),
166             status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error"
167         }
168     )
169     def post(self, request, ns_instance_id):
170         try:
171             logger.debug("Enter HealNSView::post %s", request.data)
172             logger.debug("Enter HealNSView:: %s", ns_instance_id)
173             req_serializer = HealNsReqSerializer(data=request.data)
174             if not req_serializer.is_valid():
175                 raise NSLCMException(req_serializer.errors)
176
177             job_id = JobUtil.create_job("VNF", JOB_TYPE.HEAL_VNF, ns_instance_id)
178             NSHealService(ns_instance_id, request.data, job_id).start()
179
180             resp_serializer = NsOperateJobSerializer(data={'jobId': job_id})
181             if not resp_serializer.is_valid():
182                 raise NSLCMException(resp_serializer.errors)
183
184             logger.debug("Leave HealNSView::post ret=%s", resp_serializer.data)
185             return Response(data=resp_serializer.data, status=status.HTTP_202_ACCEPTED)
186         except Exception as e:
187             logger.error("Exception in HealNSView: %s", e.message)
188             return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
189
190
191 class NSDetailView(APIView):
192     @swagger_auto_schema(
193         request_body=None,
194         responses={
195             status.HTTP_200_OK: QueryNsRespSerializer(help_text="NS instance", many=True),
196             status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error",
197             status.HTTP_404_NOT_FOUND: "Ns instance does not exist"
198         }
199     )
200     def get(self, request, ns_instance_id):
201         try:
202             logger.debug("Enter NSDetailView::get ns(%s)", ns_instance_id)
203             ns_filter = {"ns_inst_id": ns_instance_id}
204             ret = GetNSInfoService(ns_filter).get_ns_info()
205             if not ret:
206                 return Response(status=status.HTTP_404_NOT_FOUND)
207             logger.debug("Leave NSDetailView::get::ret=%s", ret)
208             resp_serializer = QueryNsRespSerializer(data=ret, many=True)
209             if not resp_serializer.is_valid():
210                 raise NSLCMException(resp_serializer.errors)
211             return Response(data=resp_serializer.data, status=status.HTTP_200_OK)
212         except Exception as e:
213             logger.error(traceback.format_exc())
214             logger.error("Exception in GetNSDetail: %s", e.message)
215             return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
216
217     @swagger_auto_schema(
218         request_body=None,
219         responses={
220             status.HTTP_204_NO_CONTENT: 'successful',
221             status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error"
222         }
223     )
224     def delete(self, request, ns_instance_id):
225         try:
226             logger.debug("Enter NSDetailView::delete ns(%s)", ns_instance_id)
227             DeleteNsService(ns_instance_id).do_biz()
228             return Response(data={}, status=status.HTTP_204_NO_CONTENT)
229         except Exception as e:
230             logger.error(traceback.format_exc())
231             logger.error("Exception in delete NS: %s", e.message)
232             return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
233
234
235 class NSInstPostDealView(APIView):
236     @swagger_auto_schema(
237         request_body=InstNsPostDealReqSerializer(help_text="NS instant post deal"),
238         responses={
239             status.HTTP_202_ACCEPTED: "NS instant post deal success",
240             status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error"
241         }
242     )
243     def post(self, request, ns_instance_id):
244         logger.debug("Enter NSInstPostDealView::post %s, %s", request.data, ns_instance_id)
245         ns_post_status = ignore_case_get(request.data, 'status')
246         ns_status = 'ACTIVE' if ns_post_status == 'true' else 'FAILED'
247         ns_opr_status = 'success' if ns_post_status == 'true' else 'failed'
248         try:
249             req_serializer = InstNsPostDealReqSerializer(data=request.data)
250             if not req_serializer.is_valid():
251                 raise NSLCMException(req_serializer.errors)
252             NSInstModel.objects.filter(id=ns_instance_id).update(status=ns_status)
253             ServiceBaseInfoModel.objects.filter(service_id=ns_instance_id).update(
254                 active_status=ns_status, status=ns_opr_status)
255             nsd_info = NSInstModel.objects.filter(id=ns_instance_id)
256             nsd_id = nsd_info[0].nsd_id
257             nsd_model = json.loads(nsd_info[0].nsd_model)
258             if "policies" in nsd_model and nsd_model["policies"]:
259                 policy = nsd_model["policies"][0]
260                 if "properties" in policy and policy["properties"]:
261                     file_url = ignore_case_get(policy["properties"][0], "drl_file_url")
262                 else:
263                     file_url = ""
264                 self.send_policy_request(ns_instance_id, nsd_id, file_url)
265         except:
266             logger.error(traceback.format_exc())
267             return Response(data={'error': 'Failed to update status of NS(%s)' % ns_instance_id},
268                             status=status.HTTP_500_INTERNAL_SERVER_ERROR)
269         logger.debug("*****NS INST %s, %s******", ns_status, ns_opr_status)
270         return Response(data={'success': 'Update status of NS(%s) to %s' % (ns_instance_id, ns_status)},
271                         status=status.HTTP_202_ACCEPTED)
272
273     def send_policy_request(self, ns_instance_id, nsd_id, file_url):
274         input_data = {
275             "nsid": ns_instance_id,
276             "nsdid": nsd_id,
277             "fileUri": file_url
278         }
279         req_param = json.JSONEncoder().encode(input_data)
280         policy_engine_url = 'api/polengine/v1/policyinfo'
281         ret = req_by_msb(policy_engine_url, "POST", req_param)
282         if ret[0] != 0:
283             logger.error("Failed to send ns policy req")
284
285
286 class NSManualScaleView(APIView):
287     @swagger_auto_schema(
288         request_body=ManualScaleNsReqSerializer(help_text="NS manual scale"),
289         responses={
290             status.HTTP_202_ACCEPTED: NsOperateJobSerializer(),
291             status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error"
292         }
293     )
294     def post(self, request, ns_instance_id):
295         logger.debug("Enter NSManualScaleView::post %s, %s", request.data, ns_instance_id)
296         job_id = JobUtil.create_job("NS", JOB_TYPE.MANUAL_SCALE_VNF, ns_instance_id)
297         try:
298             req_serializer = ManualScaleNsReqSerializer(data=request.data)
299             if not req_serializer.is_valid():
300                 raise NSLCMException(req_serializer.errors)
301
302             NSManualScaleService(ns_instance_id, request.data, job_id).start()
303
304             resp_serializer = NsOperateJobSerializer(data={'jobId': job_id})
305             if not resp_serializer.is_valid():
306                 raise NSLCMException(resp_serializer.errors)
307
308             return Response(data=resp_serializer.data, status=status.HTTP_202_ACCEPTED)
309         except Exception as e:
310             logger.error(traceback.format_exc())
311             JobUtil.add_job_status(job_id, 255, 'NS scale failed: %s' % e.message)
312             return Response(data={'error': 'NS scale failed: %s' % ns_instance_id},
313                             status=status.HTTP_500_INTERNAL_SERVER_ERROR)