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