From 1f55bd9564c95d4eabd3addfe6d2542e9db853b5 Mon Sep 17 00:00:00 2001 From: YuanHong Deng Date: Thu, 14 May 2020 14:59:33 +0800 Subject: [PATCH] Update VNF interface and IP information in A&AI Change-Id: Ic33df46dd08f4a23986f1117e3ba759cbcb08a67 Issue-ID: VFC-1673 Signed-off-by: YuanHong Deng --- lcm/ns_vnfs/biz/handle_notification.py | 71 ++++++++++++++++++++++++++++- lcm/ns_vnfs/tests/tests.py | 82 +++++++++++++++++++++++++++++++++- 2 files changed, 150 insertions(+), 3 deletions(-) diff --git a/lcm/ns_vnfs/biz/handle_notification.py b/lcm/ns_vnfs/biz/handle_notification.py index 647878c9..56717cd1 100644 --- a/lcm/ns_vnfs/biz/handle_notification.py +++ b/lcm/ns_vnfs/biz/handle_notification.py @@ -27,7 +27,9 @@ from lcm.pub.database.models import (CPInstModel, NfInstModel, PortInstModel, from lcm.pub.exceptions import NSLCMException, RequestException from lcm.pub.msapi.aai import (create_network_aai, create_vserver_aai, delete_network_aai, delete_vserver_aai, - query_network_aai, query_vserver_aai) + query_network_aai, query_vserver_aai, create_l_interface_aai, + create_l3_interface_ipv4_address_list_aai, query_l_interface_aai, + delete_l_interface_aai) from lcm.pub.msapi.extsys import get_vim_by_id, split_vim_to_owner_region from lcm.pub.utils.values import ignore_case_get @@ -54,6 +56,7 @@ class HandleVnfLcmOocNotification(object): self.update_Storage() if REPORT_TO_AAI: self.update_network_in_aai() + self.update_ip_addr_in_aai() logger.debug("notify lcm end") except NSLCMException as e: exception(e.args[0]) @@ -157,6 +160,72 @@ class HandleVnfLcmOocNotification(object): def update_Storage(self): pass + def del_l_interface_from_aai(self, vnf_id, l_interface_name): + logger.debug("Delete l_interface::delete_l_interface_in_aai[%s] in aai.", l_interface_name) + try: + l_interface_info = query_l_interface_aai(vnf_id, l_interface_name) + resource_version = l_interface_info.get("resource-version", '') + resp_data, resp_status = delete_l_interface_aai(vnf_id, l_interface_name, resource_version) + logger.debug("Delete l_interface[%s] from aai successfully, status: %s", l_interface_name, + resp_status) + except RequestException: + logger.debug("l_interface delete exception in AAI") + except NSLCMException as e: + logger.debug("Fail to delete l_interface[%s] from aai: %s", l_interface_name, e.args[0]) + except Exception as e: + logger.error("Exception occurs when delete l_interface[%s] from aai: %s", l_interface_name, + e.args[0]) + logger.error(traceback.format_exc()) + + def create_l_interface_aai(self, vnf_instid, l_interfaces_name): + logger.debug("Createl_interface::createl_interface_aai::report l_interface[%s] to aai." % l_interfaces_name) + try: + + resp_data, resp_status = create_l_interface_aai(vnf_instid, l_interfaces_name) + logger.debug("Success to create l_interface[%s] to aai: [%s].", l_interfaces_name, resp_status) + except NSLCMException as e: + logger.debug( + "Fail to create l_interfaces_name[%s] to aai, detail message: %s" % (l_interfaces_name, e.args[0])) + except: + logger.error(traceback.format_exc()) + + def create_l3_interface_ipv4_address_list_aai(self, vnf_instid, l_interfaces_name, ip): + logger.debug( + "Create l3_interface_ipv4_address_list::create_l3_interface_ipv4_address_list_aai::report " + "l_interface[%s]::ip_list[%s] to aai." % (l_interfaces_name, ip)) + try: + resp_data, resp_status = create_l3_interface_ipv4_address_list_aai(vnf_instid, l_interfaces_name, ip) + logger.debug("Success to create l_interface_ip_list[%s] to aai: [%s].", ip, resp_status) + except NSLCMException as e: + logger.debug( + "Fail to create ip_list[%s] to aai, detail message: %s" % (l_interfaces_name, e.args[0])) + except: + logger.error(traceback.format_exc()) + + def update_ip_addr_in_aai(self): + logger.debug("update ip addr in aai::begin to report ip to aai.") + try: + for ext in self.affectedCps: + extLinkPorts = ignore_case_get(ext, 'extLinkPorts') + changeType = ignore_case_get(ext, 'changeType') + for res in extLinkPorts: + resourceHandle = ignore_case_get(res, 'resourceHandle') + l_interfaces_name = ignore_case_get(resourceHandle, 'resourceProviderId') + print(l_interfaces_name) + ip = ignore_case_get(resourceHandle, 'ipAddress') + if changeType in ['ADDED', 'MODIFIED']: + self.create_l_interface_aai(self.vnf_instid, l_interfaces_name) + self.create_l3_interface_ipv4_address_list_aai(self.vnf_instid, l_interfaces_name, ip) + elif changeType == 'REMOVED': + self.del_l_interface_from_aai(self.vnf_instid, l_interfaces_name) + else: + logger.error('update ip addr struct error: changeType not in' + ' {ADDED, REMOVED, MODIFIED, TEMPORARY}') + except Exception as e: + logger.debug("Fail to update ip addr to aai, detail message: %s" % e.args[0]) + except: + logger.error(traceback.format_exc()) + def update_network_in_aai(self): logger.debug("update_network_in_aai::begin to report network to aai.") try: diff --git a/lcm/ns_vnfs/tests/tests.py b/lcm/ns_vnfs/tests/tests.py index 5614c57e..e67c0d5e 100644 --- a/lcm/ns_vnfs/tests/tests.py +++ b/lcm/ns_vnfs/tests/tests.py @@ -32,8 +32,8 @@ from lcm.ns_vnfs.biz.heal_vnfs import NFHealService from lcm.ns_vnfs.biz.scale_vnfs import NFManualScaleService from lcm.ns_vnfs.biz.subscribe import SubscriptionDeletion from lcm.ns_vnfs.biz.terminate_nfs import TerminateVnfs -from lcm.ns_vnfs.enum import VNF_STATUS, LIFE_CYCLE_OPERATION, RESOURCE_CHANGE_TYPE, VNFC_CHANGE_TYPE, INST_TYPE, \ - NETWORK_RESOURCE_TYPE +from lcm.ns_vnfs.enum import VNF_STATUS, LIFE_CYCLE_OPERATION, RESOURCE_CHANGE_TYPE, VNFC_CHANGE_TYPE, \ + INST_TYPE, NETWORK_RESOURCE_TYPE from lcm.ns_vnfs.biz.place_vnfs import PlaceVnfs from lcm.pub.msapi import resmgr from lcm.ns_vnfs.tests.test_data import vnfm_info, vim_info, vnf_place_request @@ -2484,3 +2484,81 @@ class TestVnfNotifyView(TestCase): self.assertEqual(1, 0) except Exception: self.assertEqual(1, 1) + + @mock.patch.object(restcall, "call_req") + def test_handle_vnf_identifier_notification_when_save_ip_aai(self, mock_call_req): + l_interface_info_aai = { + "interface-name": "resourceProviderId", + "is-port-mirrored": False, + "resource-version": "1589506153510", + "in-maint": False, + "is-ip-unnumbered": False + } + l3_interface_ipv4_address_list = { + "l3-interface-ipv4-address": "ipAddress", + "resource-version": "1589527363970" + } + mock_vals = { + "/network/generic-vnfs/generic-vnf/%s/l-interfaces/l-interface/%s" + % ("test_vnf_notify", "resourceProviderId"): + [0, json.JSONEncoder().encode(l_interface_info_aai), "200"], + "/network/generic-vnfs/generic-vnf/%s/l-interfaces/l-interface/%s/l3-interface-ipv4-address-list/%s" + % ("test_vnf_notify", "resourceProviderId", "ipAddress"): + [0, json.JSONEncoder().encode(l3_interface_ipv4_address_list), "200"], + "/network/l3-networks/l3-network/%s" % "vl_instance_id": + [0, json.JSONEncoder().encode({}), "200"], + + } + + def side_effect(*args): + return mock_vals[args[4]] + + mock_call_req.side_effect = side_effect + + data = { + "id": "1111", + "notificationType": "VnfLcmOperationOccurrenceNotification", + "subscriptionId": "1111", + "timeStamp": "1111", + "notificationStatus": "START", + "operationState": "STARTING", + "vnfInstanceId": self.nf_inst_id, + "operation": "INSTANTIATE", + "isAutomaticInvocation": "1111", + "vnfLcmOpOccId": "1111", + "affectedVnfcs": [{"id": "vnfc_instance_id", + "vduId": "vdu_id", + "changeType": VNFC_CHANGE_TYPE.MODIFIED, + "computeResource": { + "vimConnectionId": "vim_connection_id", + "resourceId": "resource_id" + }}], + "affectedVirtualLinks": [{"id": "vl_instance_id", + "virtualLinkDescId": "virtual_link_desc_id", + "changeType": VNFC_CHANGE_TYPE.MODIFIED, + "networkResource": { + "vimLevelResourceType": "network", + "resourceId": "resource_id" + }}], + "changedExtConnectivity": [{"id": "virtual_link_instance_id", + "extLinkPorts": [{"cpInstanceId": "cp_instance_id", + "id": "cpd_id", + "resourceHandle": { + "vimConnectionId": "vim_connection_id", + "resourceId": "resource_id", + "resourceProviderId": "resourceProviderId", + "tenant": "tenant", + "ipAddress": "ipAddress", + "macAddress": "macAddress", + "instId": "instId", + "networkId": "networkId", + "subnetId": "subnetId" + } + }], + "changeType": VNFC_CHANGE_TYPE.MODIFIED + }] + } + HandleVnfLcmOocNotification(self.vnfm_inst_id, self.m_nf_inst_id, data).do_biz() + url = '/api/nslcm/v2/ns/%s/vnfs/%s/Notify' % (self.vnfm_inst_id, self.m_nf_inst_id) + response = self.client.post(url, data) + self.assertEqual(status.HTTP_204_NO_CONTENT, response.status_code, response.content) -- 2.16.6