diff options
-rw-r--r-- | zte/vmanager/driver/interfaces/serializers.py | 135 | ||||
-rw-r--r-- | zte/vmanager/driver/interfaces/tests.py | 9 | ||||
-rw-r--r-- | zte/vmanager/driver/interfaces/urls.py | 4 | ||||
-rw-r--r-- | zte/vmanager/driver/interfaces/views.py | 274 | ||||
-rw-r--r-- | zte/vmanager/driver/swagger/swagger.json | 4 |
5 files changed, 281 insertions, 145 deletions
diff --git a/zte/vmanager/driver/interfaces/serializers.py b/zte/vmanager/driver/interfaces/serializers.py index 2e601185..ed6658fe 100644 --- a/zte/vmanager/driver/interfaces/serializers.py +++ b/zte/vmanager/driver/interfaces/serializers.py @@ -15,30 +15,143 @@ from rest_framework import serializers +class VMIDlistSerializer(serializers.Serializer): + VMID = serializers.CharField( + help_text="VMID", + max_length=255, + required=False, + allow_null=True) + VMName = serializers.CharField( + help_text="VMName", + max_length=255, + required=False, + allow_null=True) + vimid = serializers.CharField( + help_text="vimid", + max_length=255, + required=False, + allow_null=True) + tenant = serializers.CharField( + help_text="tenant", + max_length=255, + required=False, + allow_null=True) + + +class VmlistSerializer(serializers.Serializer): + VMNumber = serializers.CharField( + help_text="VMNumber", + max_length=255, + required=False, + allow_null=True) + vdutype = serializers.CharField( + help_text="vdutype", + max_length=255, + required=False, + allow_null=True) + VMFlavor = serializers.CharField( + help_text="VMFlavor", + max_length=255, + required=False, + allow_null=True) + VMIDlist = VMIDlistSerializer(help_text='VMIDlist', required=False, many=True) + + +class NotifyReqSerializer(serializers.Serializer): + nfvoid = serializers.CharField( + help_text="nfvoid", + max_length=255, + required=True, + allow_null=True) + vnfmid = serializers.CharField( + help_text="vnfmid", + max_length=255, + required=True, + allow_null=True) + vimid = serializers.CharField( + help_text="vimid", + max_length=255, + required=True, + allow_null=True) + timestamp = serializers.CharField( + help_text="timestamp", + max_length=255, + required=False, + allow_blank=True) + vnfinstanceid = serializers.CharField( + help_text="vnfinstanceid", + max_length=255, + required=False, + allow_null=True) + eventtype = serializers.CharField( + help_text="eventtype", + max_length=255, + required=False, + allow_null=True) + vmlist = VmlistSerializer(help_text='vmlist', required=False, many=True) + extension = serializers.DictField( + help_text="extension", + child=serializers.DictField(allow_null=True), + required=False, + allow_null=True) + affectedcp = serializers.ListSerializer( + help_text='affectedcp', + child=serializers.DictField(allow_null=True), + required=False) + affectedvirtuallink = serializers.ListSerializer( + help_text='affectedvirtuallink', + child=serializers.DictField(allow_null=True), + required=False) + + +class ScaleReqSerializer(serializers.Serializer): + type = serializers.CharField( + help_text="type", + max_length=255, + required=True, + allow_null=True) + aspectId = serializers.CharField( + help_text="aspectId", + max_length=255, + required=True, + allow_null=True) + numberOfSteps = serializers.CharField( + help_text="numberOfSteps", + max_length=255, + required=True, + allow_null=True) + additionalParam = serializers.DictField( + help_text="additionalParam", + child=serializers.DictField(allow_null=True), + required=False, + allow_null=True) + + class AffectedvmSerializer(serializers.Serializer): extention = serializers.CharField( help_text="extention", max_length=255, - required=True, allow_blank=True) + required=True, + allow_blank=True) vmid = serializers.CharField( help_text="vmid", max_length=255, required=True, - allow_null=False) + allow_null=True) changtype = serializers.CharField( help_text="changtype", max_length=255, - required=False, + required=True, allow_null=True) vduid = serializers.CharField( help_text="vduid", max_length=255, required=True, - allow_null=False) + allow_null=True) vmname = serializers.CharField( help_text="vmname", max_length=255, - required=False, + required=True, allow_null=True) flavour = serializers.DictField( help_text="flavour", @@ -52,7 +165,7 @@ class HealReqSerializer(serializers.Serializer): help_text="action", max_length=255, required=True, - allow_null=True) + allow_null=False) lifecycleoperation = serializers.CharField( help_text="lifecycleoperation", max_length=255, @@ -63,17 +176,17 @@ class HealReqSerializer(serializers.Serializer): max_length=255, required=False, allow_null=True) - affectedvm = AffectedvmSerializer(help_text='affectedvm', many=True) + affectedvm = AffectedvmSerializer(help_text='affectedvm', required=True, many=True) -class HealRespSerializer(serializers.Serializer): - jobid = serializers.CharField( +class InstScaleHealRespSerializer(serializers.Serializer): + jobId = serializers.CharField( help_text="jobid", max_length=255, required=True, allow_null=True) - nfInstanceId = serializers.CharField( + vnfInstanceId = serializers.CharField( help_text="nfInstanceId", max_length=255, required=True, - allow_null=False) + allow_null=True) diff --git a/zte/vmanager/driver/interfaces/tests.py b/zte/vmanager/driver/interfaces/tests.py index 24c7fbdf..fb0f7679 100644 --- a/zte/vmanager/driver/interfaces/tests.py +++ b/zte/vmanager/driver/interfaces/tests.py @@ -351,7 +351,10 @@ class InterfacesTest(TestCase): @mock.patch.object(restcall, 'call_req') def test_scale(self, mock_call_req): - job_info = {"jobid": "801", "nfInstanceId": "101"} + job_info = { + "jobId": "801", + "vnfInstanceId": "101" + } vnfm_info = { "userName": "admin", "vendor": "ZTE", @@ -435,8 +438,8 @@ class InterfacesTest(TestCase): @mock.patch.object(restcall, 'call_req') def test_heal(self, mock_call_req): job_info = { - "jobid": "12234455", - "nfInstanceId": "10144445666" + "jobId": "12234455", + "vnfInstanceId": "10144445666" } vnfm_info = { "userName": "admin", diff --git a/zte/vmanager/driver/interfaces/urls.py b/zte/vmanager/driver/interfaces/urls.py index 07df352b..0167cfaa 100644 --- a/zte/vmanager/driver/interfaces/urls.py +++ b/zte/vmanager/driver/interfaces/urls.py @@ -25,9 +25,9 @@ urlpatterns = [ url(r'^api/ztevnfmdriver/v1/(?P<vnfmid>[0-9a-zA-Z\-\_]+)/jobs/(?P<jobid>[0-9a-zA-Z\-\_]+)$', views.operation_status, name='operation_status'), url(r'^api/ztevnfmdriver/v1/resource/grant$', views.grantvnf, name='grantvnf'), - url(r'^api/ztevnfmdriver/v1/vnfs/lifecyclechangesnotification$', views.notify, name='notify'), + url(r'^api/ztevnfmdriver/v1/vnfs/lifecyclechangesnotification$', views.Notify.as_view(), name='notify'), url(r'^api/ztevnfmdriver/v1/(?P<vnfmid>[0-9a-zA-Z\-\_]+)/vnfs/(?P<vnfInstanceId>[0-9a-zA-Z\-\_]+)/scale$', - views.scale, name='scale'), + views.Scale.as_view(), name='scale'), url(r'^api/ztevnfmdriver/v1/(?P<vnfmid>[0-9a-zA-Z\-\_]+)/vnfs/(?P<vnfInstanceId>[0-9a-zA-Z\-\_]+)/heal$', views.Heal.as_view(), name='heal'), url(r'^samples/$', views.samples, name='samples') diff --git a/zte/vmanager/driver/interfaces/views.py b/zte/vmanager/driver/interfaces/views.py index 485657e2..76b010f1 100644 --- a/zte/vmanager/driver/interfaces/views.py +++ b/zte/vmanager/driver/interfaces/views.py @@ -15,8 +15,8 @@ import inspect import json import logging -import traceback import os +import traceback from drf_yasg.utils import swagger_auto_schema from rest_framework import status @@ -24,10 +24,11 @@ from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework.views import APIView -from driver.interfaces.serializers import HealReqSerializer, HealRespSerializer +from driver.interfaces.serializers import HealReqSerializer, InstScaleHealRespSerializer, ScaleReqSerializer, \ + NotifyReqSerializer +from driver.pub.config.config import VNF_FTP from driver.pub.utils import restcall from driver.pub.utils.restcall import req_by_msb -from driver.pub.config.config import VNF_FTP logger = logging.getLogger(__name__) @@ -310,138 +311,156 @@ def grantvnf(request, *args, **kwargs): return Response(data=resp_data, status=ret[2]) -@api_view(http_method_names=['POST']) -def notify(request, *args, **kwargs): - try: - logger.info("[%s]req_data = %s", fun_name(), request.data) - notify_param_map = { - "NFVOID": "", - "VNFMID": "VNFMID", - "VIMID": "vimid", - "VNFInstanceID": "vnfInstanceId", - "TimeStamp": "", - "EventType": "operation", - "VMList": "", - "VMFlavor": "", - "VMNumber": "", - "VMIDlist": "", - "VMUUID": "" - } - data = mapping_conv(notify_param_map, request.data) - logger.info("[%s]data = %s", fun_name(), data) - - data["status"] = "result" - data["jobId"] = "notMust" - data["affectedVnfc"] = [] - data["affectedVl"] = [] - data["affectedVirtualStorage"] = [] - data["affectedCp"] = [] - - extension = ignorcase_get(request.data, "extension") - openo_notification = ignorcase_get(extension, "openo_notification") - if openo_notification: - affectedvnfcs = ignorcase_get(openo_notification, "affectedVnfc") - affectedvls = ignorcase_get(openo_notification, "affectedvirtuallink") - affectedcps = ignorcase_get(openo_notification, "affectedCp") - vnfdmodule = ignorcase_get(openo_notification, "vnfdmodule") - else: - affectedvnfcs = ignorcase_get(ignorcase_get(request.data, "extension"), "affectedvnfc") - affectedvls = ignorcase_get(ignorcase_get(request.data, "extension"), "affectedvl") - affectedcps = ignorcase_get(ignorcase_get(request.data, "extension"), "affectedcp") - vnfdmodule = ignorcase_get(ignorcase_get(request.data, "extension"), "vnfdmodule") - - data["vnfdmodule"] = vnfdmodule - - for affectedvnfc in affectedvnfcs: - data["affectedVnfc"].append({ - "vnfcInstanceId": ignorcase_get(affectedvnfc, "vnfcInstanceId"), - "vduId": ignorcase_get(affectedvnfc, "vduId"), - "changeType": ignorcase_get(affectedvnfc, "changeType"), - "vimId": ignorcase_get(ignorcase_get(affectedvnfc, "computeResource"), "vimId"), - "vmId": ignorcase_get(ignorcase_get(affectedvnfc, "computeResource"), "resourceId"), - "vmName": ignorcase_get(ignorcase_get(affectedvnfc, "computeResource"), "resourceName") - }) - - for affectedvl in affectedvls: - data["affectedVl"].append({ - "vlInstanceId": ignorcase_get(affectedvl, "virtualLinkInstanceId"), - "changeType": ignorcase_get(affectedvl, "changeType"), - "vimId": ignorcase_get(ignorcase_get(affectedvl, "networkResource"), "vimId"), - "vldId": ignorcase_get(affectedvl, "virtuallinkdescid"), - "networkResource": { - "resourceType": "network", - "resourceId": ignorcase_get(ignorcase_get(affectedvl, "networkresource"), "resourceid"), - "resourceName": ignorcase_get(ignorcase_get(affectedvl, "networkresource"), "resourcename") - } - }) - - for affectedcp in affectedcps: - data["affectedCp"].append(affectedcp) - - notify_url = 'api/nslcm/v1/ns/{vnfmid}/vnfs/{vnfInstanceId}/Notify' - ret = req_by_msb(notify_url.format(vnfmid=ignorcase_get(data, 'VNFMID'), - vnfInstanceId=ignorcase_get(data, 'vnfinstanceid')), - "POST", content=json.JSONEncoder().encode(data)) - - logger.info("[%s]data = %s", fun_name(), ret) - if ret[0] != 0: - return Response(data={'error': ret[1]}, status=ret[2]) - except Exception as e: - logger.error("Error occurred in LCM notification.") - logger.error(traceback.format_exc()) - raise e - return Response(data=None, status=ret[2]) +class Notify(APIView): + @swagger_auto_schema( + request_body=NotifyReqSerializer() + ) + def post(self, request): + try: + logger.info("[%s]req_data = %s", fun_name(), request.data) + notify_param_map = { + "NFVOID": "", + "VNFMID": "VNFMID", + "VIMID": "vimid", + "VNFInstanceID": "vnfInstanceId", + "TimeStamp": "", + "EventType": "operation", + "VMList": "", + "VMFlavor": "", + "VMNumber": "", + "VMIDlist": "", + "VMUUID": "" + } + data = mapping_conv(notify_param_map, request.data) + logger.info("[%s]data = %s", fun_name(), data) + + data["status"] = "result" + data["jobId"] = "notMust" + data["affectedVnfc"] = [] + data["affectedVl"] = [] + data["affectedVirtualStorage"] = [] + data["affectedCp"] = [] + + extension = ignorcase_get(request.data, "extension") + openo_notification = ignorcase_get(extension, "openo_notification") + if openo_notification: + affectedvnfcs = ignorcase_get(openo_notification, "affectedVnfc") + affectedvls = ignorcase_get(openo_notification, "affectedvirtuallink") + affectedcps = ignorcase_get(openo_notification, "affectedCp") + vnfdmodule = ignorcase_get(openo_notification, "vnfdmodule") + else: + affectedvnfcs = ignorcase_get(ignorcase_get(request.data, "extension"), "affectedvnfc") + affectedvls = ignorcase_get(ignorcase_get(request.data, "extension"), "affectedvl") + affectedcps = ignorcase_get(ignorcase_get(request.data, "extension"), "affectedcp") + vnfdmodule = ignorcase_get(ignorcase_get(request.data, "extension"), "vnfdmodule") + + data["vnfdmodule"] = vnfdmodule + + for affectedvnfc in affectedvnfcs: + data["affectedVnfc"].append({ + "vnfcInstanceId": ignorcase_get(affectedvnfc, "vnfcInstanceId"), + "vduId": ignorcase_get(affectedvnfc, "vduId"), + "changeType": ignorcase_get(affectedvnfc, "changeType"), + "vimId": ignorcase_get(ignorcase_get(affectedvnfc, "computeResource"), "vimId"), + "vmId": ignorcase_get(ignorcase_get(affectedvnfc, "computeResource"), "resourceId"), + "vmName": ignorcase_get(ignorcase_get(affectedvnfc, "computeResource"), "resourceName") + }) + + for affectedvl in affectedvls: + data["affectedVl"].append({ + "vlInstanceId": ignorcase_get(affectedvl, "virtualLinkInstanceId"), + "changeType": ignorcase_get(affectedvl, "changeType"), + "vimId": ignorcase_get(ignorcase_get(affectedvl, "networkResource"), "vimId"), + "vldId": ignorcase_get(affectedvl, "virtuallinkdescid"), + "networkResource": { + "resourceType": "network", + "resourceId": ignorcase_get(ignorcase_get(affectedvl, "networkresource"), "resourceid"), + "resourceName": ignorcase_get(ignorcase_get(affectedvl, "networkresource"), "resourcename") + } + }) + + for affectedcp in affectedcps: + data["affectedCp"].append(affectedcp) + + notify_url = 'api/nslcm/v1/ns/{vnfmid}/vnfs/{vnfInstanceId}/Notify' + ret = req_by_msb(notify_url.format(vnfmid=ignorcase_get(data, 'VNFMID'), + vnfInstanceId=ignorcase_get(data, 'vnfinstanceid')), + "POST", content=json.JSONEncoder().encode(data)) + + logger.info("[%s]data = %s", fun_name(), ret) + if ret[0] != 0: + return Response(data={'error': ret[1]}, status=ret[2]) + return Response(data=None, status=ret[2]) + except Exception as e: + logger.error("Error occurred in LCM notification.") + logger.error(traceback.format_exc()) + raise e -@api_view(http_method_names=['POST']) -def scale(request, *args, **kwargs): - logger.info("====scale_vnf===") - try: - logger.info("request.data = %s", request.data) - logger.info("requested_url = %s", request.get_full_path()) - vnfm_id = ignorcase_get(kwargs, "vnfmid") - nf_instance_id = ignorcase_get(kwargs, "vnfInstanceId") - ret = get_vnfminfo_from_nslcm(vnfm_id) - if ret[0] != 0: - return Response(data={'error': ret[1]}, status=ret[2]) - vnfm_info = json.JSONDecoder().decode(ret[1]) - scale_type = ignorcase_get(request.data, "type") - aspect_id = ignorcase_get(request.data, "aspectId") - number_of_steps = ignorcase_get(request.data, "numberOfSteps") - data = { - 'vnfmid': vnfm_id, - 'nfvoid': 1, - 'scaletype': '0' if scale_type == 'SCALE_OUT' else '1', - 'vmlist': [{'VMNumber': number_of_steps, 'VMFlavor': aspect_id}], - 'extension': '' +class Scale(APIView): + @swagger_auto_schema( + request_body=ScaleReqSerializer(), + responses={ + status.HTTP_202_ACCEPTED: InstScaleHealRespSerializer(), + status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error" } + ) + def post(self, request, vnfmid, vnfInstanceId): + logger.info("====scale_vnf===") + try: + logger.info("request.data = %s", request.data) + logger.info("requested_url = %s", request.get_full_path()) + scaleReqSerializer = ScaleReqSerializer(data=request.data) + if not scaleReqSerializer.is_valid(): + raise Exception(scaleReqSerializer.errors) - logger.info("data = %s", data) - ret = restcall.call_req( - base_url=ignorcase_get(vnfm_info, "url"), - user=ignorcase_get(vnfm_info, "userName"), - passwd=ignorcase_get(vnfm_info, "password"), - auth_type=restcall.rest_no_auth, - resource='/v1/vnfs/{vnfInstanceID}/scale'.format(vnfInstanceID=nf_instance_id), - method='put', # POST - content=json.JSONEncoder().encode(data)) - logger.info("ret=%s", ret) - if ret[0] != 0: - return Response(data={'error': 'scale error'}, status=ret[2]) - resp_data = json.JSONDecoder().decode(ret[1]) - logger.info("resp_data=%s", resp_data) - except Exception as e: - logger.error("Error occurred when scaling VNF,error:%s", e.message) - logger.error(traceback.format_exc()) - return Response(data={'error': 'scale expection'}, status='500') - return Response(data=resp_data, status=ret[2]) + ret = get_vnfminfo_from_nslcm(vnfmid) + if ret[0] != 0: + raise Exception(ret[1]) + + vnfm_info = json.JSONDecoder().decode(ret[1]) + scale_type = ignorcase_get(scaleReqSerializer.data, "type") + aspect_id = ignorcase_get(scaleReqSerializer.data, "aspectId") + number_of_steps = ignorcase_get(scaleReqSerializer.data, "numberOfSteps") + data = { + 'vnfmid': vnfmid, + 'nfvoid': 1, + 'scaletype': '0' if scale_type == 'SCALE_OUT' else '1', + 'vmlist': [{'VMNumber': number_of_steps, 'VMFlavor': aspect_id}], + 'extension': '' + } + + logger.info("data = %s", data) + ret = restcall.call_req( + base_url=ignorcase_get(vnfm_info, "url"), + user=ignorcase_get(vnfm_info, "userName"), + passwd=ignorcase_get(vnfm_info, "password"), + auth_type=restcall.rest_no_auth, + resource='/v1/vnfs/{vnfInstanceID}/scale'.format(vnfInstanceID=vnfInstanceId), + method='put', # POST + content=json.JSONEncoder().encode(data)) + logger.info("ret=%s", ret) + if ret[0] != 0: + raise Exception('scale error') + + resp_data = json.JSONDecoder().decode(ret[1]) + logger.info("resp_data=%s", resp_data) + scaleRespSerializer = InstScaleHealRespSerializer(data=resp_data) + if not scaleRespSerializer.is_valid(): + raise Exception(scaleRespSerializer.errors) + + return Response(data=scaleRespSerializer.data, status=status.HTTP_202_ACCEPTED) + except Exception as e: + logger.error("Error occurred when scaling VNF,error:%s", e.message) + logger.error(traceback.format_exc()) + return Response(data={'error': 'scale expection'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) class Heal(APIView): @swagger_auto_schema( request_body=HealReqSerializer(), responses={ - status.HTTP_202_ACCEPTED: HealRespSerializer(), + status.HTTP_202_ACCEPTED: InstScaleHealRespSerializer(), status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error" } ) @@ -456,7 +475,8 @@ class Heal(APIView): ret = get_vnfminfo_from_nslcm(vnfmid) if ret[0] != 0: - return Response(data={'error': ret[1]}, status=ret[2]) + raise Exception(ret[1]) + vnfm_info = json.JSONDecoder().decode(ret[1]) data = {} data['action'] = ignorcase_get(healReqSerializer.data, 'action') @@ -483,7 +503,7 @@ class Heal(APIView): raise Exception('heal error') resp_data = json.JSONDecoder().decode(ret[1]) logger.info("resp_data=%s", resp_data) - healRespSerializer = HealRespSerializer(data=resp_data) + healRespSerializer = InstScaleHealRespSerializer(data=resp_data) if not healRespSerializer.is_valid(): raise Exception(healRespSerializer.errors) diff --git a/zte/vmanager/driver/swagger/swagger.json b/zte/vmanager/driver/swagger/swagger.json index 0378e6ec..dfe53df9 100644 --- a/zte/vmanager/driver/swagger/swagger.json +++ b/zte/vmanager/driver/swagger/swagger.json @@ -4,7 +4,7 @@ "version": "1.0.0", "title": "ZTE VNFM Driver Service rest API" }, - "basePath": "/api/{vnfmtype}/v1", + "basePath": "/api/ztevnfmdriver/v1", "tags": [ { "name": "ztevnfmdriver" @@ -395,7 +395,7 @@ "vnfInstanceId": { "type": "string" }, - "jobid": { + "jobId": { "type": "string" } } |