Add UT cases for port chain
[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         req_serializer = InstantNsReqSerializer(data=request.data)
118         if not req_serializer.is_valid():
119             return Response({'error': req_serializer.errors},
120                             status=status.HTTP_500_INTERNAL_SERVER_ERROR)
121         ack = InstantNSService(ns_instance_id, request.data).do_biz()
122         resp_serializer = NsOperateJobSerializer(data=ack['data'])
123         if not resp_serializer.is_valid():
124             return Response({'error': resp_serializer.errors},
125                             status=status.HTTP_500_INTERNAL_SERVER_ERROR)
126         logger.debug("Leave NSInstView::post::ack=%s", ack)
127         return Response(data=resp_serializer.data, status=ack['status'])
128
129
130 class TerminateNSView(APIView):
131     @swagger_auto_schema(
132         request_body=TerminateNsReqSerializer(),
133         responses={
134             status.HTTP_202_ACCEPTED: NsOperateJobSerializer(),
135             status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error"
136         }
137     )
138     def post(self, request, ns_instance_id):
139         try:
140             logger.debug("Enter TerminateNSView::post %s", request.data)
141             req_serializer = TerminateNsReqSerializer(data=request.data)
142             if not req_serializer.is_valid():
143                 raise NSLCMException(req_serializer.errors)
144
145             termination_type = ignore_case_get(request.data, 'terminationType')
146             graceful_termination_timeout = ignore_case_get(request.data, 'gracefulTerminationTimeout')
147             job_id = JobUtil.create_job("VNF", JOB_TYPE.TERMINATE_VNF, ns_instance_id)
148             TerminateNsService(ns_instance_id, termination_type, graceful_termination_timeout, job_id).start()
149
150             resp_serializer = NsOperateJobSerializer(data={'jobId': job_id})
151             if not resp_serializer.is_valid():
152                 raise NSLCMException(resp_serializer.errors)
153             logger.debug("Leave TerminateNSView::post ret=%s", resp_serializer.data)
154             return Response(data=resp_serializer.data, status=status.HTTP_202_ACCEPTED)
155         except Exception as e:
156             logger.error("Exception in CreateNS: %s", e.message)
157             return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
158
159
160 class NSHealView(APIView):
161     @swagger_auto_schema(
162         request_body=HealNsReqSerializer(),
163         responses={
164             status.HTTP_202_ACCEPTED: NsOperateJobSerializer(),
165             status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error"
166         }
167     )
168     def post(self, request, ns_instance_id):
169         try:
170             logger.debug("Enter HealNSView::post %s", request.data)
171             logger.debug("Enter HealNSView:: %s", ns_instance_id)
172             req_serializer = HealNsReqSerializer(data=request.data)
173             if not req_serializer.is_valid():
174                 raise NSLCMException(req_serializer.errors)
175
176             job_id = JobUtil.create_job("VNF", JOB_TYPE.HEAL_VNF, ns_instance_id)
177             NSHealService(ns_instance_id, request.data, job_id).start()
178
179             resp_serializer = NsOperateJobSerializer(data={'jobId': job_id})
180             if not resp_serializer.is_valid():
181                 raise NSLCMException(resp_serializer.errors)
182
183             logger.debug("Leave HealNSView::post ret=%s", resp_serializer.data)
184             return Response(data=resp_serializer.data, status=status.HTTP_202_ACCEPTED)
185         except Exception as e:
186             logger.error("Exception in HealNSView: %s", e.message)
187             return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
188
189
190 class NSDetailView(APIView):
191     @swagger_auto_schema(
192         request_body=None,
193         responses={
194             status.HTTP_200_OK: QueryNsRespSerializer(help_text="NS instance", many=True),
195             status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error",
196             status.HTTP_404_NOT_FOUND: "Ns instance does not exist"
197         }
198     )
199     def get(self, request, ns_instance_id):
200         try:
201             logger.debug("Enter NSDetailView::get ns(%s)", ns_instance_id)
202             ns_filter = {"ns_inst_id": ns_instance_id}
203             ret = GetNSInfoService(ns_filter).get_ns_info()
204             if not ret:
205                 return Response(status=status.HTTP_404_NOT_FOUND)
206             logger.debug("Leave NSDetailView::get::ret=%s", ret)
207             resp_serializer = QueryNsRespSerializer(data=ret, many=True)
208             if not resp_serializer.is_valid():
209                 raise NSLCMException(resp_serializer.errors)
210             return Response(data=resp_serializer.data, status=status.HTTP_200_OK)
211         except Exception as e:
212             logger.error(traceback.format_exc())
213             logger.error("Exception in GetNSDetail: %s", e.message)
214             return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
215
216     @swagger_auto_schema(
217         request_body=None,
218         responses={
219             status.HTTP_204_NO_CONTENT: None,
220             status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error"
221         }
222     )
223     def delete(self, request, ns_instance_id):
224         try:
225             logger.debug("Enter NSDetailView::delete ns(%s)", ns_instance_id)
226             DeleteNsService(ns_instance_id).do_biz()
227             return Response(data={}, status=status.HTTP_204_NO_CONTENT)
228         except Exception as e:
229             logger.error(traceback.format_exc())
230             logger.error("Exception in delete NS: %s", e.message)
231             return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
232
233
234 class NSInstPostDealView(APIView):
235     @swagger_auto_schema(
236         request_body=InstNsPostDealReqSerializer(help_text="NS instant post deal"),
237         responses={
238             status.HTTP_202_ACCEPTED: "NS instant post deal success",
239             status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error"
240         }
241     )
242     def post(self, request, ns_instance_id):
243         logger.debug("Enter NSInstPostDealView::post %s, %s", request.data, ns_instance_id)
244         ns_post_status = ignore_case_get(request.data, 'status')
245         ns_status = 'ACTIVE' if ns_post_status == 'true' else 'FAILED'
246         ns_opr_status = 'success' if ns_post_status == 'true' else 'failed'
247         try:
248             req_serializer = InstNsPostDealReqSerializer(data=request.data)
249             if not req_serializer.is_valid():
250                 raise NSLCMException(req_serializer.errors)
251             NSInstModel.objects.filter(id=ns_instance_id).update(status=ns_status)
252             ServiceBaseInfoModel.objects.filter(service_id=ns_instance_id).update(
253                 active_status=ns_status, status=ns_opr_status)
254             nsd_info = NSInstModel.objects.filter(id=ns_instance_id)
255             nsd_id = nsd_info[0].nsd_id
256             nsd_model = json.loads(nsd_info[0].nsd_model)
257             if "policies" in nsd_model and nsd_model["policies"]:
258                 policy = nsd_model["policies"][0]
259                 if "properties" in policy and policy["properties"]:
260                     file_url = ignore_case_get(policy["properties"][0], "drl_file_url")
261                 else:
262                     file_url = ""
263                 self.send_policy_request(ns_instance_id, nsd_id, file_url)
264         except:
265             logger.error(traceback.format_exc())
266             return Response(data={'error': 'Failed to update status of NS(%s)' % ns_instance_id},
267                             status=status.HTTP_500_INTERNAL_SERVER_ERROR)
268         logger.debug("*****NS INST %s, %s******", ns_status, ns_opr_status)
269         return Response(data={'success': 'Update status of NS(%s) to %s' % (ns_instance_id, ns_status)},
270                         status=status.HTTP_202_ACCEPTED)
271
272     def send_policy_request(self, ns_instance_id, nsd_id, file_url):
273         input_data = {
274             "nsid": ns_instance_id,
275             "nsdid": nsd_id,
276             "fileUri": file_url
277         }
278         req_param = json.JSONEncoder().encode(input_data)
279         policy_engine_url = 'api/polengine/v1/policyinfo'
280         ret = req_by_msb(policy_engine_url, "POST", req_param)
281         if ret[0] != 0:
282             logger.error("Failed to send ns policy req")
283
284
285 class NSManualScaleView(APIView):
286     @swagger_auto_schema(
287         request_body=ManualScaleNsReqSerializer(help_text="NS manual scale"),
288         responses={
289             status.HTTP_202_ACCEPTED: NsOperateJobSerializer(),
290             status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error"
291         }
292     )
293     def post(self, request, ns_instance_id):
294         logger.debug("Enter NSManualScaleView::post %s, %s", request.data, ns_instance_id)
295         job_id = JobUtil.create_job("NS", JOB_TYPE.MANUAL_SCALE_VNF, ns_instance_id)
296         try:
297             req_serializer = ManualScaleNsReqSerializer(data=request.data)
298             if not req_serializer.is_valid():
299                 raise NSLCMException(req_serializer.errors)
300
301             NSManualScaleService(ns_instance_id, request.data, job_id).start()
302
303             resp_serializer = NsOperateJobSerializer(data={'jobId': job_id})
304             if not resp_serializer.is_valid():
305                 raise NSLCMException(resp_serializer.errors)
306
307             return Response(data=resp_serializer.data, status=status.HTTP_202_ACCEPTED)
308         except Exception as e:
309             logger.error(traceback.format_exc())
310             JobUtil.add_job_status(job_id, 255, 'NS scale failed: %s' % e.message)
311             return Response(data={'error': 'NS scale failed: %s' % ns_instance_id},
312                             status=status.HTTP_500_INTERNAL_SERVER_ERROR)