From d9f88e4c4f8bdac8feecd4afbce217eaed8d01e4 Mon Sep 17 00:00:00 2001 From: Varun Prasad Date: Mon, 28 Nov 2016 02:25:42 -0500 Subject: [PATCH] Descriptor Unification Signed-off-by: Varun Prasad --- .../python/rift/openmano/rift2openmano.py | 22 ++++++-- models/plugins/yang/nsd.yang | 10 +++- .../rift/rwcal/openstack/openstack_drv.py | 1 + rwcal/plugins/yang/rwcal.yang | 7 +++ .../tasklets/rwnsmtasklet/openmano_nsm.py | 8 +-- .../tasklets/rwnsmtasklet/rwnsmtasklet.py | 1 + .../tasklets/rwresmgrtasklet/rwresmgr_core.py | 37 ++++++++++---- .../tasklets/rwvnfmtasklet/rwvnfmtasklet.py | 50 +++++++++++++++++-- 8 files changed, 115 insertions(+), 21 deletions(-) diff --git a/models/openmano/python/rift/openmano/rift2openmano.py b/models/openmano/python/rift/openmano/rift2openmano.py index 56522851..67cef7e4 100755 --- a/models/openmano/python/rift/openmano/rift2openmano.py +++ b/models/openmano/python/rift/openmano/rift2openmano.py @@ -333,7 +333,7 @@ def rift2openmano_nsd(rift_nsd, rift_vnfds,openmano_vnfd_ids): return openmano -def rift2openmano_vnfd(rift_vnfd): +def rift2openmano_vnfd(rift_vnfd, rift_nsd): openmano_vnf = {"vnf":{}} vnf = openmano_vnf["vnf"] @@ -358,7 +358,23 @@ def rift2openmano_vnfd(rift_vnfd): raise ValueError("Internal connection point reference %s not found" % cp_ref_id) - def rift2openmano_if_type(rift_type): + def rift2openmano_if_type(ext_if): + + cp_ref_name = ext_if.vnfd_connection_point_ref + for vld in rift_nsd.vlds: + + # if it is an explicit mgmt_network then check if the given + # cp_ref is a part of it + if not vld.mgmt_network: + continue + + for vld_cp in vld.vnfd_connection_point_ref: + if vld_cp.vnfd_connection_point_ref == cp_ref_name: + return "mgmt" + + + rift_type = ext_if.virtual_interface.type_yang + # Retaining it for backward compatibility! if rift_type == "OM_MGMT": return "mgmt" elif rift_type == "VIRTIO" or rift_type == "E1000": @@ -380,7 +396,7 @@ def rift2openmano_vnfd(rift_vnfd): vdu, ext_if = find_vdu_and_ext_if_by_cp_ref(cp.name) connection = { "name": cp.name, - "type": rift2openmano_if_type(ext_if.virtual_interface.type_yang), + "type": rift2openmano_if_type(ext_if), "VNFC": vdu.name, "local_iface_name": ext_if.name, "description": "%s iface on VDU %s" % (ext_if.name, vdu.name), diff --git a/models/plugins/yang/nsd.yang b/models/plugins/yang/nsd.yang index ac0987c9..31750cae 100644 --- a/models/plugins/yang/nsd.yang +++ b/models/plugins/yang/nsd.yang @@ -326,6 +326,12 @@ module nsd // replicate for pnfd container here uses manotypes:provider-network; + leaf mgmt-network { + description "Flag indicating whether this network is a VIM management network"; + type boolean; + default false; + } + choice init-params { description "Extra parameters for VLD instantiation"; @@ -337,12 +343,14 @@ module nsd type string; } } + case vim-network-profile { leaf ip-profile-ref { description "Named reference to IP-profile object"; type string; } - } + } + } } diff --git a/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/openstack_drv.py b/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/openstack_drv.py index 2505da3d..bd29c3cd 100644 --- a/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/openstack_drv.py +++ b/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/openstack_drv.py @@ -1645,6 +1645,7 @@ class OpenstackDriver(object): logger.error("Could not identity the version information for openstack service endpoints. Auth_URL should contain \"/v2\" or \"/v3\" string in it") raise NotImplementedError("Auth URL is wrong or invalid. Only Keystone v2 & v3 supported") + self._mgmt_network_id = None if mgmt_network != None: self._mgmt_network = mgmt_network diff --git a/rwcal/plugins/yang/rwcal.yang b/rwcal/plugins/yang/rwcal.yang index 09e4acc2..6f45e7c1 100644 --- a/rwcal/plugins/yang/rwcal.yang +++ b/rwcal/plugins/yang/rwcal.yang @@ -975,6 +975,13 @@ module rwcal uses connection-point-type; } + leaf mgmt-network { + description + "Explicit mgmt-network name, otherwise the mgmt-network from + Cloud account is used"; + type string; + } + leaf allocate-public-address { description "If this VDU needs public IP address"; type boolean; diff --git a/rwlaunchpad/plugins/rwnsm/rift/tasklets/rwnsmtasklet/openmano_nsm.py b/rwlaunchpad/plugins/rwnsm/rift/tasklets/rwnsmtasklet/openmano_nsm.py index ddc4c9ba..e4c5f93f 100644 --- a/rwlaunchpad/plugins/rwnsm/rift/tasklets/rwnsmtasklet/openmano_nsm.py +++ b/rwlaunchpad/plugins/rwnsm/rift/tasklets/rwnsmtasklet/openmano_nsm.py @@ -153,7 +153,7 @@ class VnfrConsoleOperdataDtsHandler(object): class OpenmanoVnfr(object): - def __init__(self, log, loop, cli_api, vnfr): + def __init__(self, log, loop, cli_api, vnfr, nsd): self._log = log self._loop = loop self._cli_api = cli_api @@ -164,6 +164,8 @@ class OpenmanoVnfr(object): self._created = False + self.nsd = nsd + @property def vnfd(self): return rift2openmano.RiftVNFD(self._vnfr.vnfd) @@ -183,7 +185,7 @@ class OpenmanoVnfr(object): @property def openmano_vnfd(self): self._log.debug("Converting vnfd %s from rift to openmano", self.vnfd.id) - openmano_vnfd = rift2openmano.rift2openmano_vnfd(self.vnfd) + openmano_vnfd = rift2openmano.rift2openmano_vnfd(self.vnfd, self.nsd) return openmano_vnfd @property @@ -430,7 +432,7 @@ class OpenmanoNsr(object): @asyncio.coroutine def add_vnfr(self, vnfr): - vnfr = OpenmanoVnfr(self._log, self._loop, self._cli_api, vnfr) + vnfr = OpenmanoVnfr(self._log, self._loop, self._cli_api, vnfr, nsd=self.nsd) yield from vnfr.create() self._vnfrs.append(vnfr) diff --git a/rwlaunchpad/plugins/rwnsm/rift/tasklets/rwnsmtasklet/rwnsmtasklet.py b/rwlaunchpad/plugins/rwnsm/rift/tasklets/rwnsmtasklet/rwnsmtasklet.py index cf038578..dd6e1939 100755 --- a/rwlaunchpad/plugins/rwnsm/rift/tasklets/rwnsmtasklet/rwnsmtasklet.py +++ b/rwlaunchpad/plugins/rwnsm/rift/tasklets/rwnsmtasklet/rwnsmtasklet.py @@ -1888,6 +1888,7 @@ class NetworkServiceRecord(object): """ This function creates VLs for every VLD in the NSD associated with this NSR""" for vld in self.nsd_msg.vld: + self._log.debug("Found vld %s in nsr id %s", vld, self.id) cloud_account_list = self._extract_cloud_accounts_for_vl(vld) for cloud_account,om_datacenter in cloud_account_list: diff --git a/rwlaunchpad/plugins/rwresmgr/rift/tasklets/rwresmgrtasklet/rwresmgr_core.py b/rwlaunchpad/plugins/rwresmgr/rift/tasklets/rwresmgrtasklet/rwresmgr_core.py index d2897f87..161d5a49 100644 --- a/rwlaunchpad/plugins/rwresmgr/rift/tasklets/rwresmgrtasklet/rwresmgr_core.py +++ b/rwlaunchpad/plugins/rwresmgr/rift/tasklets/rwresmgrtasklet/rwresmgr_core.py @@ -183,6 +183,7 @@ class ResourceMgrCALHandler(object): def create_virtual_compute(self, req_params): #rc, rsp = self._rwcal.get_vdu_list(self._account) self._log.debug("Calling get_vdu_list API") + rc, rsp = yield from self._loop.run_in_executor(self._executor, self._rwcal.get_vdu_list, self._account) @@ -350,9 +351,10 @@ class ResourceMgrCALHandler(object): class Resource(object): - def __init__(self, resource_id, resource_type): + def __init__(self, resource_id, resource_type, request): self._id = resource_id self._type = resource_type + self._request = request @property def resource_id(self): @@ -362,18 +364,20 @@ class Resource(object): def resource_type(self): return self._type + @property + def request(self): + return self._request + def cleanup(self): pass class ComputeResource(Resource): - def __init__(self, resource_id, resource_type): - super(ComputeResource, self).__init__(resource_id, resource_type) + pass class NetworkResource(Resource): - def __init__(self, resource_id, resource_type): - super(NetworkResource, self).__init__(resource_id, resource_type) + pass class ResourcePoolInfo(object): @@ -614,7 +618,7 @@ class NetworkPool(ResourcePool): if resource_id in self._all_resources: self._log.error("Resource with id %s name %s of type %s is already used", resource_id, request.name, resource_type) raise ResMgrNoResourcesAvailable("Resource with name %s of type network is already used" %(resource_id)) - resource = self._resource_class(resource_id, resource_type) + resource = self._resource_class(resource_id, resource_type, request) self._all_resources[resource_id] = resource self._allocated_resources[resource_id] = resource self._log.info("Successfully allocated virtual-network resource from CAL with resource-id: %s", resource_id) @@ -742,7 +746,7 @@ class ComputePool(ResourcePool): def allocate_dynamic_resource(self, request): #request.flavor_id = yield from self.select_resource_flavor(request) resource_id = yield from self._cal.create_virtual_compute(request) - resource = self._resource_class(resource_id, 'dynamic') + resource = self._resource_class(resource_id, 'dynamic', request) self._all_resources[resource_id] = resource self._allocated_resources[resource_id] = resource self._log.info("Successfully allocated virtual-compute resource from CAL with resource-id: %s", resource_id) @@ -763,6 +767,7 @@ class ComputePool(ResourcePool): @asyncio.coroutine def get_resource_info(self, resource): info = yield from self._cal.get_virtual_compute_info(resource.resource_id) + self._log.info("Successfully retrieved virtual-compute information from CAL with resource-id: %s. Info: %s", resource.resource_id, str(info)) response = RwResourceMgrYang.VDUEventData_ResourceInfo() @@ -779,6 +784,19 @@ class ComputePool(ResourcePool): return info def _get_resource_state(self, resource_info, requested_params): + + + def conn_pts_len_equal(): + # if explicit mgmt network is defined then the allocated ports might + # one more than the expected. + allocated_ports = len(resource_info.connection_points) + requested_ports = len(requested_params.connection_points) + + if not requested_params.mgmt_network: + allocated_ports -= 1 + + return allocated_ports == requested_ports + if resource_info.state == 'failed': self._log.error(" Reached failed state.", resource_info.name) @@ -800,8 +818,7 @@ class ComputePool(ResourcePool): resource_info.name, requested_params) return 'pending' - if(len(requested_params.connection_points) != - len(resource_info.connection_points)): + if not conn_pts_len_equal(): self._log.warning(" Waiting for requested number of ports to be assigned to virtual-compute, requested: %d, assigned: %d", resource_info.name, len(requested_params.connection_points), @@ -1440,7 +1457,7 @@ class ResourceMgrCore(object): return r_info self._resource_table[event_id] = (r_id, cloud_account_name, resource.pool_name) - new_resource = pool._resource_class(r_id, 'dynamic') + new_resource = pool._resource_class(r_id, 'dynamic', request) if resource_type == 'compute': requested_params = RwcalYang.VDUInitParams() requested_params.from_dict(request.as_dict()) diff --git a/rwlaunchpad/plugins/rwvnfm/rift/tasklets/rwvnfmtasklet/rwvnfmtasklet.py b/rwlaunchpad/plugins/rwvnfm/rift/tasklets/rwvnfmtasklet/rwvnfmtasklet.py index 2c6c1024..c0974c9a 100755 --- a/rwlaunchpad/plugins/rwvnfm/rift/tasklets/rwvnfmtasklet/rwvnfmtasklet.py +++ b/rwlaunchpad/plugins/rwvnfm/rift/tasklets/rwvnfmtasklet/rwvnfmtasklet.py @@ -49,6 +49,7 @@ from gi.repository import ( import rift.tasklets import rift.package.store import rift.package.cloud_init +import rift.mano.dts as mano_dts class VMResourceError(Exception): @@ -270,6 +271,7 @@ class VirtualDeploymentUnitRecord(object): vdud, vnfr, mgmt_intf, + mgmt_network, cloud_account_name, vnfd_package_store, vdur_id=None, @@ -282,6 +284,7 @@ class VirtualDeploymentUnitRecord(object): self._mgmt_intf = mgmt_intf self._cloud_account_name = cloud_account_name self._vnfd_package_store = vnfd_package_store + self._mgmt_network = mgmt_network self._vdur_id = vdur_id or str(uuid.uuid4()) self._int_intf = [] @@ -552,6 +555,9 @@ class VirtualDeploymentUnitRecord(object): if config is not None: vm_create_msg_dict['vdu_init'] = {'userdata': config} + if self._mgmt_network: + vm_create_msg_dict['mgmt_network'] = self._mgmt_network + cp_list = [] for intf, cp, vlr in self._ext_intf: cp_info = {"name": cp, @@ -1046,7 +1052,7 @@ class InternalVirtualLinkRecord(object): class VirtualNetworkFunctionRecord(object): """ Virtual Network Function Record """ - def __init__(self, dts, log, loop, cluster_name, vnfm, vcs_handler, vnfr_msg): + def __init__(self, dts, log, loop, cluster_name, vnfm, vcs_handler, vnfr_msg, mgmt_network=None): self._dts = dts self._log = log self._loop = loop @@ -1057,6 +1063,7 @@ class VirtualNetworkFunctionRecord(object): self._vnfm = vnfm self._vcs_handler = vcs_handler self._vnfr = vnfr_msg + self._mgmt_network = mgmt_network self._vnfd = None self._state = VirtualNetworkFunctionRecordState.INIT @@ -1439,6 +1446,7 @@ class VirtualNetworkFunctionRecord(object): vdud=vdu, vnfr=vnfr, mgmt_intf=self.has_mgmt_interface(vdu), + mgmt_network=self._mgmt_network, cloud_account_name=self.cloud_account_name, vnfd_package_store=self._vnfd_package_store, vdur_id=vdur_id, @@ -2458,13 +2466,15 @@ class VnfManager(object): self._vcs_handler = VcsComponentDtsHandler(dts, log, loop, self) self._vnfr_handler = VnfrDtsHandler(dts, log, loop, self) + self._vnfr_ref_handler = VnfdRefCountDtsHandler(dts, log, loop, self) + self._nsr_handler = mano_dts.NsInstanceConfigSubscriber(log, dts, loop, callback=self.handle_nsr) self._dts_handlers = [VnfdDtsHandler(dts, log, loop, self), - self._vnfr_handler, self._vcs_handler, - VnfdRefCountDtsHandler(dts, log, loop, self)] + self._nsr_handler] self._vnfrs = {} self._vnfds = {} + self._nsrs = {} @property def vnfr_handler(self): @@ -2488,6 +2498,35 @@ class VnfManager(object): self._log.debug("Run VNFManager - registering static DTS handlers""") yield from self.register() + def handle_nsr(self, nsr, action): + if action in [rwdts.QueryAction.CREATE]: + self._nsrs[nsr.id] = nsr + elif action == rwdts.QueryAction.DELETE: + if nsr.id in self._nsrs: + del self._nsrs[nsr.id] + + def get_linked_mgmt_network(self, vnfr): + """For the given VNFR get the related mgmt network from the NSD, if + available. + """ + vnfd_id = vnfr.vnfd_ref + nsr_id = vnfr.nsr_id_ref + + # for the given related VNFR, get the corresponding NSR-config + nsr_obj = None + try: + nsr_obj = self._nsrs[nsr_id] + except KeyError: + raise("Unable to find the NS with the ID: {}".format(nsr_id)) + + # for the related NSD check if a VLD exists such that it's a mgmt + # network + for vld in nsr_obj.nsd.vld: + if vld.mgmt_network: + return vld.name + + return None + def get_vnfr(self, vnfr_id): """ get VNFR by vnfr id """ @@ -2507,8 +2546,11 @@ class VnfManager(object): vnfr.id, vnfr.vnfd_ref) + mgmt_network = self.get_linked_mgmt_network(vnfr) + self._vnfrs[vnfr.id] = VirtualNetworkFunctionRecord( - self._dts, self._log, self._loop, self._cluster_name, self, self.vcs_handler, vnfr + self._dts, self._log, self._loop, self._cluster_name, self, self.vcs_handler, vnfr, + mgmt_network=mgmt_network ) return self._vnfrs[vnfr.id] -- 2.25.1