aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lcm/v2/grant_vnf.py101
-rw-r--r--lcm/v2/handle_vnflcmooc_notification.py22
-rw-r--r--lcm/v2/tests.py56
-rw-r--r--lcm/v2/views.py1
4 files changed, 154 insertions, 26 deletions
diff --git a/lcm/v2/grant_vnf.py b/lcm/v2/grant_vnf.py
index a3ba37f9..38b1fbc2 100644
--- a/lcm/v2/grant_vnf.py
+++ b/lcm/v2/grant_vnf.py
@@ -15,6 +15,11 @@
import json
import logging
import uuid
+from lcm.pub.database.models import NfInstModel
+from lcm.pub.exceptions import NSLCMException
+from lcm.pub.msapi.sdc_run_catalog import query_vnfpackage_by_id
+from lcm.pub.utils.values import ignore_case_get
+from lcm.pub.msapi import resmgr
logger = logging.getLogger(__name__)
@@ -24,12 +29,104 @@ class GrantVnf(object):
self.data = grant_data
def exec_grant(self):
+ logger.debug("grant data from vnfm:%s", self.data)
if isinstance(self.data, (unicode, str)):
self.data = json.JSONDecoder().decode(self.data)
+ has_res_tpl = False
+ grant_type = None
+ vimConnections = []
+ if ignore_case_get(self.data, "addResources"):
+ grant_type = "addResources"
+ elif ignore_case_get(self.data, "removeResources"):
+ grant_type = "removeResources"
+ else:
+ has_res_tpl = True
+
+ for res in ignore_case_get(self.data, grant_type):
+ if "resourceTemplate" in res:
+ has_res_tpl = True
+ break
+
+ if not has_res_tpl:
+ m_vnf_inst_id = ignore_case_get(self.data, "vnfInstanceId")
+ additional_param = ignore_case_get(self.data, "additionalparam")
+ vnfm_inst_id = ignore_case_get(additional_param, "vnfmid")
+ vim_id = ignore_case_get(additional_param, "vimid")
+
+ vnfinsts = NfInstModel.objects.filter(
+ mnfinstid=m_vnf_inst_id, vnfm_inst_id=vnfm_inst_id)
+ if not vnfinsts:
+ raise NSLCMException("Vnfinst(%s) is not found in vnfm(%s)" % (
+ m_vnf_inst_id, vnfm_inst_id))
+
+ vnf_pkg_id = vnfinsts[0].package_id
+ nfpackage_info = query_vnfpackage_by_id(vnf_pkg_id)
+ vnf_pkg = nfpackage_info["packageInfo"]
+ vnfd = json.JSONDecoder().decode(vnf_pkg["vnfdModel"])
+
+ req_param = {
+ "vnfInstanceId": m_vnf_inst_id,
+ "vimId": vim_id,
+ "additionalParam": additional_param,
+ grant_type: []
+ }
+ for res in ignore_case_get(self.data, grant_type):
+ vdu_name = ignore_case_get(res, "vdu")
+ grant_res = {
+ "resourceDefinitionId": ignore_case_get(res, "resourceDefinitionId"),
+ "type": ignore_case_get(res, "type"),
+ "vdu": vdu_name
+ }
+ for vdu in vnfd["vdus"]:
+ if vdu_name in (vdu["vdu_id"], vdu["properties"].get("name", "")):
+ grant_res["resourceTemplate"] = self.get_res_tpl(vdu, vnfd)
+ break
+ req_param[grant_type].append(grant_res)
+ self.data = req_param
+ vimConnections.append(resmgr.grant_vnf(self.data))
grant_resp = {
"id": str(uuid.uuid4()),
- "vnfInstanceId": self.data.get("vnfInstanceId"),
- "vnfLcmOpOccId": self.data.get("vnfLcmOpOccId")
+ "vnfInstanceId": ignore_case_get(self.data, 'vnfInstanceId'),
+ "vnfLcmOpOccId": ignore_case_get(self.data, "vnfLcmOpOccId"),
+ "vimConnections": vimConnections
}
logger.debug("grant_resp=%s", grant_resp)
return grant_resp
+
+ def get_res_tpl(self, vdu, vnfd):
+ storage_size = 0
+ for storage_id in vdu["local_storages"]:
+ storage_size = storage_size + self.get_storage_size(storage_id, vnfd)
+ resourceTemplate = {
+ "virtualComputeDescriptor": {
+ "virtualCpu": {
+ "numVirtualCpu": int(vdu["virtual_compute"]["virtual_cpu"]["num_virtual_cpu"])
+ },
+ "virtualMemory": {
+ "virtualMemSize": parse_unit(vdu["virtual_compute"]["virtual_memory"]["virtual_mem_size"], "MB")
+ }
+ },
+ "virtualStorageDescriptor": {
+ "typeOfStorage": "",
+ "sizeOfStorage": storage_size,
+ "swImageDescriptor": ""
+ }
+ }
+ return resourceTemplate
+
+ def get_storage_size(self, storage_id, vnfd):
+ for storage in vnfd["local_storages"]:
+ if storage_id == storage["local_storage_id"]:
+ return parse_unit(storage["properties"]["size"], "GB")
+ return 0
+
+
+def parse_unit(val, base_unit):
+ recognized_units = ["B", "kB", "KiB", "MB", "MiB", "GB", "GiB", "TB", "TiB"]
+ units_rate = [1, 1000, 1024, 1000000, 1048576, 1000000000, 1073741824, 1000000000000, 1099511627776]
+ unit_rate_map = {unit.upper(): rate for unit, rate in zip(recognized_units, units_rate)}
+ num_unit = val.strip().split(" ")
+ if len(num_unit) != 2:
+ return val.strip()
+ num, unit = num_unit[0], num_unit[1]
+ return int(num) * unit_rate_map[unit.upper()] / unit_rate_map[base_unit.upper()]
diff --git a/lcm/v2/handle_vnflcmooc_notification.py b/lcm/v2/handle_vnflcmooc_notification.py
index 3ab4debe..4b13a246 100644
--- a/lcm/v2/handle_vnflcmooc_notification.py
+++ b/lcm/v2/handle_vnflcmooc_notification.py
@@ -82,23 +82,23 @@ class HandleVnfLcmOocNotification(object):
vmId = ignore_case_get(computeResource, 'resourceId')
vmName = ignore_case_get(computeResource, 'resourceId') # replaced with resouceId temporarily
- if changeType == 'added':
+ if changeType == 'ADDED':
VNFCInstModel(vnfcinstanceid=vnfcInstanceId, vduid=vduId,
nfinstid=self.vnf_instid, vmid=vmId).save()
VmInstModel(vmid=vmId, vimid=vimId, resouceid=vmId, insttype=INST_TYPE.VNF,
instid=self.vnf_instid, vmname=vmName, hostid='1').save()
if REPORT_TO_AAI:
self.create_vserver_in_aai(vimId, vmId, vmName)
- elif changeType == 'removed':
+ elif changeType == 'REMOVED':
if REPORT_TO_AAI:
self.delete_vserver_in_aai(vimId, vmId, vmName)
VNFCInstModel.objects.filter(vnfcinstanceid=vnfcInstanceId).delete()
- elif changeType == 'modified':
+ elif changeType == 'MODIFIED':
VNFCInstModel.objects.filter(vnfcinstanceid=vnfcInstanceId).update(vduid=vduId,
nfinstid=self.vnf_instid,
vmid=vmId)
else:
- self.exception('affectedVnfc struct error: changeType not in {added,removed,modified}')
+ self.exception('affectedVnfc struct error: changeType not in {ADDED, REMOVED, MODIFIED, TEMPORARY}')
logger.debug("Success to update all vserver to aai.")
def update_Vl(self):
@@ -116,17 +116,17 @@ class HandleVnfLcmOocNotification(object):
ownerId = self.get_vnfinstid(self.m_vnfInstanceId, self.vnfmid)
- if changeType == 'added':
+ if changeType == 'ADDED':
VLInstModel(vlinstanceid=vlInstanceId, vldid=vldid, vlinstancename=resourceName, ownertype=0,
ownerid=ownerId, relatednetworkid=resourceId, vltype=0).save()
- elif changeType == 'removed':
+ elif changeType == 'REMOVED':
VLInstModel.objects.filter(vlinstanceid=vlInstanceId).delete()
- elif changeType == 'modified':
+ elif changeType == 'MODIFIED':
VLInstModel.objects.filter(vlinstanceid=vlInstanceId)\
.update(vldid=vldid, vlinstancename=resourceName, ownertype=0, ownerid=ownerId,
relatednetworkid=resourceId, vltype=0)
else:
- self.exception('affectedVl struct error: changeType not in {added,removed,modified}')
+ self.exception('affectedVl struct error: changeType not in {ADDED, REMOVED, MODIFIED, TEMPORARY}')
def update_Cp(self):
for cp in self.affectedCps:
@@ -182,12 +182,12 @@ class HandleVnfLcmOocNotification(object):
ownerId = self.get_vnfinstid(self.m_vnfInstanceId, self.vnfmid)
- if changeType in ['added', 'modified']:
+ if changeType in ['ADDED', 'MODIFIED']:
self.create_network_and_subnet_in_aai(vlInstanceId, ownerId)
- elif changeType == 'removed':
+ elif changeType == 'REMOVED':
self.delete_network_and_subnet_in_aai(vlInstanceId)
else:
- logger.error('affectedVl struct error: changeType not in {added,removed,modified}')
+ logger.error('affectedVl struct error: changeType not in {ADDED, REMOVED, MODIFIED, TEMPORARY}')
except NSLCMException as e:
logger.debug("Fail to create internal network to aai, detail message: %s" % e.message)
except:
diff --git a/lcm/v2/tests.py b/lcm/v2/tests.py
index 55fa2f1d..996852f1 100644
--- a/lcm/v2/tests.py
+++ b/lcm/v2/tests.py
@@ -14,18 +14,22 @@
import unittest
import json
-from django.test import Client
+import mock
+from rest_framework.test import APIClient
from rest_framework import status
+from lcm.pub.database.models import NfInstModel
+from lcm.pub.utils import restcall
class VnfGrantViewTest(unittest.TestCase):
def setUp(self):
- self.client = Client()
+ self.client = APIClient()
def tearDown(self):
pass
- def test_grant_vnf_normal(self):
+ @mock.patch.object(restcall, 'call_req')
+ def test_grant_vnf_normal(self, mock_call_req):
data = {
"vnfInstanceId": "1",
"vnfLcmOpOccId": "2",
@@ -40,7 +44,7 @@ class VnfGrantViewTest(unittest.TestCase):
"type": "COMPUTE",
"vduId": "2",
"resourceTemplateId": "3",
- "resource": {
+ "resourceTemplate": {
"vimConnectionId": "4",
"resourceProviderId": "5",
"resourceId": "6",
@@ -85,13 +89,24 @@ class VnfGrantViewTest(unittest.TestCase):
}
}
}
+ vimConnections = {
+ "id": "1",
+ "vimId": "1",
+ }
+ mock_call_req.return_value = [0, json.JSONEncoder().encode(vimConnections), '200']
response = self.client.post("/api/nslcm/v2/grants", data=data, format='json')
self.assertEqual(status.HTTP_201_CREATED, response.status_code, response.content)
resp_data = json.loads(response.content)
expect_resp_data = {
"id": resp_data.get("id"),
"vnfInstanceId": "1",
- "vnfLcmOpOccId": "2"
+ "vnfLcmOpOccId": "2",
+ "vimConnections": [
+ {
+ "id": "1",
+ "vimId": "1"
+ }
+ ]
}
self.assertEqual(expect_resp_data, resp_data)
@@ -114,11 +129,11 @@ class VnfGrantViewTest(unittest.TestCase):
"affectedVnfcs": [{
"id": "string",
"vduId": "string",
- "changeType": "added",
+ "changeType": "ADDED",
"computeResource": {
"vimConnectionId": "string",
"resourceProviderId": "string",
- "resouceId": "string",
+ "resourceId": "string",
"vimLevelResourceType": "string"
},
"metadata": {},
@@ -127,16 +142,28 @@ class VnfGrantViewTest(unittest.TestCase):
"removedStorageResourceIds": [],
}],
"affectedVirtualLinks": [{
- "vlInstanceId": "string",
- "vldId": "string",
- "changeType": "added",
+ "id": "string",
+ "virtualLinkDescId": "string",
+ "changeType": "ADDED",
"networkResource": {
- "resourceType": "network",
+ "vimConnectionId": "string",
+ "resourceProviderId": "string",
"resourceId": "string",
- "resourceName": "string"
+ "vimLevelResourceType": "network",
}
}],
- "affectedVirtualStorages": [{}],
+ "affectedVirtualStorages": [{
+ "id": "string",
+ "virtualStorageDescId": "string",
+ "changeType": "ADDED",
+ "storageResource": {
+ "vimConnectionId": "string",
+ "resourceProviderId": "string",
+ "resourceId": "string",
+ "vimLevelResourceType": "network",
+ },
+ "metadata": {}
+ }],
"changedInfo": {
"vnfInstanceName": "string",
"vnfInstanceDescription": "string",
@@ -220,5 +247,8 @@ class VnfGrantViewTest(unittest.TestCase):
}
}
}
+ NfInstModel.objects.create(nfinstid='22',
+ mnfinstid='2',
+ vnfm_inst_id='1')
response = self.client.post("/api/nslcm/v2/ns/1/vnfs/2/Notify", data=data, format='json')
self.assertEqual(status.HTTP_204_NO_CONTENT, response.status_code, response.content)
diff --git a/lcm/v2/views.py b/lcm/v2/views.py
index a3ce25a7..9c953c19 100644
--- a/lcm/v2/views.py
+++ b/lcm/v2/views.py
@@ -75,6 +75,7 @@ class VnfNotifyView(APIView):
vnfLcmOocNotificationSerializer = VnfLcmOperationOccurrenceNotificationSerializer(data=request.data)
if not vnfLcmOocNotificationSerializer.is_valid():
raise Exception(vnfLcmOocNotificationSerializer.errors)
+
HandleVnfLcmOocNotification(vnfmId, vnfInstanceId, vnfLcmOocNotificationSerializer.data).do_biz()
return Response(data={}, status=status.HTTP_204_NO_CONTENT)
except Exception as e: