Heal api in Gvnfm Driver 29/65229/5
authorShobana Jothi <shobana.jothi@verizon.com>
Fri, 7 Sep 2018 14:26:37 +0000 (19:56 +0530)
committerShobana Jothi <shobana.jothi@verizon.com>
Mon, 17 Sep 2018 07:27:09 +0000 (12:57 +0530)
Change-Id: I674cc0231c172f9fb0985bd6b1182138182c07dc
Issue-ID: VFC-1050
Signed-off-by: Shobana Jothi<shobana.jothi@verizon.com>
gvnfmadapter/driver/interfaces/serializers/heal_request.py [new file with mode: 0644]
gvnfmadapter/driver/interfaces/tests.py
gvnfmadapter/driver/interfaces/urls.py
gvnfmadapter/driver/interfaces/views.py

diff --git a/gvnfmadapter/driver/interfaces/serializers/heal_request.py b/gvnfmadapter/driver/interfaces/serializers/heal_request.py
new file mode 100644 (file)
index 0000000..c212769
--- /dev/null
@@ -0,0 +1,34 @@
+# Copyright (C) 2018 Verizon. All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from rest_framework import serializers
+
+
+class AffectedVm(serializers.Serializer):
+    vmid = serializers.CharField(help_text="Vm id", required=True)
+    vduid = serializers.CharField(help_text="Vdu id", required=True)
+    vmname = serializers.CharField(help_text="Vm name", required=True)
+
+class VnfHealRequestSerializer(serializers.Serializer):
+    action = serializers.CharField(help_text="Action for NS heal", required=True, allow_null=True)
+    affectedvm = AffectedVm(help_text="Get the vm information to be healed", required=True)
+
+class HealVnfRequestSerializerToVnfm(serializers.Serializer):
+    cause = serializers.CharField(help_text="Cause of NS heal", required=False, allow_null=True)
+    additionalParams = serializers.DictField(
+        help_text="Additional input parameters for the healing process, \
+        specific to the VNF being healed, \
+        as declared in the VNFD as part of HealVnfOpConfig.",
+        required=False,
+        allow_null=True)
index 7196f3a..c062c7c 100644 (file)
@@ -818,3 +818,103 @@ class InterfacesTest(TestCase):
         self.assertEqual(status.HTTP_202_ACCEPTED, response.status_code)
         self.assertEqual(None, response.data)
         self.assertEqual("/vnf_lc_ops/NF-OPERATE-12-2a3be946-b01d-11e8-9302-08002705b121", response['Location'])
+
+# Heal API
+    @mock.patch.object(restcall, 'call_req')
+    def test_heal_vnf_404_NotFound(self, mock_call_req):
+        vnfm_info = {
+            "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
+            "name": "g_vnfm",
+            "type": "gvnfmdriver",
+            "vimId": "",
+            "vendor": "vendor1",
+            "version": "v1.0",
+            "description": "vnfm",
+            "certificateUrl": "",
+            "url": "http://10.74.44.11",
+            "userName": "admin",
+            "password": "admin",
+            "createTime": "2016-07-06 15:33:18"
+        }
+        req_data = {
+            "action": "vmReset",
+            "affectedvm": {
+                "vmid": "1",
+                "vduid": "vdu1Id",
+                "vmname": "vduinstname"
+            }
+        }
+        probDetail = {"status": 404, "detail": "VNF Instance not found"}
+        r1 = [0, json.JSONEncoder().encode(vnfm_info), "200", ""]
+        r2 = [1, json.JSONEncoder().encode(probDetail), "404", ""]
+        mock_call_req.side_effect = [r1, r2]
+        response = self.client.post("/api/gvnfmdriver/v1/vnfmid/vnfs/2/heal",
+                                    data=json.dumps(req_data), content_type="application/json")
+        self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code)
+        self.assertEqual(probDetail, response.data)
+
+    @mock.patch.object(restcall, 'call_req')
+    def test_heal_vnf_409_Conflict(self, mock_call_req):
+        vnfm_info = {
+            "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
+            "name": "g_vnfm",
+            "type": "gvnfmdriver",
+            "vimId": "",
+            "vendor": "vendor1",
+            "version": "v1.0",
+            "description": "vnfm",
+            "certificateUrl": "",
+            "url": "http://10.74.44.11",
+            "userName": "admin",
+            "password": "admin",
+            "createTime": "2016-07-06 15:33:18"
+        }
+        req_data = {
+            "action": "vmReset",
+            "affectedvm": {
+                "vmid": "1",
+                "vduid": "vdu1Id",
+                "vmname": "vduinstname"
+            }
+        }
+        probDetail = {"status": 409, "detail": "VNF Instance not in Instantiated State"}
+        r1 = [0, json.JSONEncoder().encode(vnfm_info), "200", ""]
+        r2 = [1, json.JSONEncoder().encode(probDetail), "409", ""]
+        mock_call_req.side_effect = [r1, r2]
+        response = self.client.post("/api/gvnfmdriver/v1/vnfmid/vnfs/2/heal",
+                                    data=json.dumps(req_data), content_type="application/json")
+        self.assertEqual(status.HTTP_409_CONFLICT, response.status_code)
+        self.assertEqual(probDetail, response.data)
+
+    @mock.patch.object(restcall, 'call_req')
+    def test_heal_vnf_success(self, mock_call_req):
+        vnfm_info = {
+            "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
+            "name": "g_vnfm",
+            "type": "gvnfmdriver",
+            "vimId": "",
+            "vendor": "vendor1",
+            "version": "v1.0",
+            "description": "vnfm",
+            "certificateUrl": "",
+            "url": "http://10.74.44.11",
+            "userName": "admin",
+            "password": "admin",
+            "createTime": "2016-07-06 15:33:18"
+        }
+        req_data = {
+            "action": "vmReset",
+            "affectedvm": {
+                "vmid": "1",
+                "vduid": "vdu1Id",
+                "vmname": "vduinstname"
+            }
+        }
+        r1 = [0, json.JSONEncoder().encode(vnfm_info), "200"]
+        r2 = [0, json.JSONEncoder().encode(''), "202", "/vnf_lc_ops/NF-HEAL-12-2a3be946-b01d-11e8-9302-08002705b121"]
+        mock_call_req.side_effect = [r1, r2]
+        response = self.client.post("/api/gvnfmdriver/v1/vnfmid/vnfs/2/heal",
+                                    data=json.dumps(req_data), content_type="application/json")
+        self.assertEqual(status.HTTP_202_ACCEPTED, response.status_code)
+        self.assertEqual(None, response.data)
+        self.assertEqual("/vnf_lc_ops/NF-HEAL-12-2a3be946-b01d-11e8-9302-08002705b121", response['Location'])
index b615d9b..9a36463 100644 (file)
@@ -15,7 +15,7 @@
 from django.conf.urls import url
 from driver.interfaces.views import VnfInstInfo, VnfTermInfo, VnfQueryInfo, VnfOperInfo
 from driver.interfaces.views import Subscription
-from driver.interfaces.views import VnfPkgsInfo, VnfGrantInfo, VnfNotifyInfo, QuerySingleVnfLcmOpOcc, VnfOperateView
+from driver.interfaces.views import VnfPkgsInfo, VnfGrantInfo, VnfNotifyInfo, QuerySingleVnfLcmOpOcc, VnfOperateView, VnfHealView
 
 urlpatterns = [
     url(r'^api/(?P<vnfmtype>[0-9a-zA-Z\-\_]+)/v1/(?P<vnfmid>[0-9a-zA-Z\-\_]+)/vnfs$', VnfInstInfo.as_view()),
@@ -30,4 +30,6 @@ urlpatterns = [
     url(r'^api/(?P<vnfmtype>[0-9a-zA-Z\-\_]+)/v1/(?P<vnfmid>[0-9a-zA-Z\-\_]+)/vnf_lcm_op_occs/(?P<lcmopoccid>[0-9a-zA-Z_-]+)$', QuerySingleVnfLcmOpOcc.as_view()),
     url(r'^api/(?P<vnfmtype>[0-9a-zA-Z\-\_]+)/v1/(?P<vnfmid>[0-9a-zA-Z\-\_]+)/vnfs/(?P<vnfInstanceId>'
         r'[0-9a-zA-Z\-\_]+)/operate$', VnfOperateView.as_view()),
+    url(r'^api/(?P<vnfmtype>[0-9a-zA-Z\-\_]+)/v1/(?P<vnfmid>[0-9a-zA-Z\-\_]+)/vnfs/(?P<vnfInstanceId>'
+        r'[0-9a-zA-Z\-\_]+)/heal$', VnfHealView.as_view()),
 ]
index b32aa8c..3a62b24 100644 (file)
@@ -35,6 +35,7 @@ from driver.pub.exceptions import GvnfmDriverException
 from driver.pub.utils import restcall
 from driver.pub.utils.restcall import req_by_msb
 from driver.interfaces.serializers.operate_request import VnfOperateRequestSerializer
+from driver.interfaces.serializers.heal_request import HealVnfRequestSerializerToVnfm, VnfHealRequestSerializer
 from driver.interfaces.serializers.response import ProblemDetailsSerializer
 
 logger = logging.getLogger(__name__)
@@ -341,6 +342,56 @@ class VnfOperateView(APIView):
             return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
 
 
+class VnfHealView(APIView):
+    @swagger_auto_schema(
+        request_body=VnfHealRequestSerializer(),
+        responses={
+            status.HTTP_202_ACCEPTED: "Success",
+            status.HTTP_404_NOT_FOUND: ProblemDetailsSerializer(),
+            status.HTTP_409_CONFLICT: ProblemDetailsSerializer(),
+            status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
+        }
+    )
+    def post(self, request, vnfmtype, vnfmid, vnfInstanceId):
+        logger.debug("Heal_vnf--post::> %s" % request.data)
+        logger.debug("Heal vnf begin!")
+        try:
+            requestSerializer = VnfHealRequestSerializer(data=request.data)
+            request_isValid = requestSerializer.is_valid()
+            if not request_isValid:
+                raise Exception(requestSerializer.errors)
+            healdata = {
+                u"additionalParams": {
+                    u"action": ignorcase_get(request.data, "action"),
+                    u"affectedvm": ignorcase_get(request.data, "affectedvm")
+                }
+            }
+            input_data = HealVnfRequestSerializerToVnfm(data=healdata)
+            resp_isvalid = input_data.is_valid()
+            if not resp_isvalid:
+                raise GvnfmDriverException(input_data.errors)
+            logger.debug("Heal vnf start!")
+            logger.debug("do_heal: vnfmid=[%s],vnfInstanceId=[%s],request data=[%s]",
+                         vnfmid, vnfInstanceId, input_data)
+            statusCode, resp, location = do_lcmVnf(vnfmid, vnfInstanceId, input_data.data, "heal")
+            logger.debug("do_heal: response data=[%s]", resp)
+            logger.debug("Heal vnf end!")
+            ret = int(statusCode)
+            if ret == status.HTTP_404_NOT_FOUND:
+                return Response(data=resp, status=status.HTTP_404_NOT_FOUND)
+            elif ret == status.HTTP_409_CONFLICT:
+                return Response(data=resp, status=status.HTTP_409_CONFLICT)
+            response = Response(data=None, status=status.HTTP_202_ACCEPTED)
+            response["Location"] = location
+            return response
+        except GvnfmDriverException as e:
+            logger.error('Heal vnf failed, detail message: %s' % e.message)
+            return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+        except:
+            logger.error(traceback.format_exc())
+            return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+
+
 class VnfPkgsInfo(APIView):
     def get(request, *args, **kwargs):
         try: