From e2c09f3117bc608a26f2172a0f07a0df41922730 Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Fri, 30 Nov 2018 09:55:29 +0000 Subject: [PATCH] Find WIM before creating local networks The usage of the wim_account information for create networks inside the VIMs/datacenters should be developed in future commits Change-Id: I545455f23cbde9071b2bdc91ae032b7a76e0eefe Signed-off-by: Anderson Bravalheri --- osm_ro/nfvo.py | 18 +++++++++++++++- osm_ro/wim/engine.py | 38 +++++++++++++++++++++++++++------ osm_ro/wim/persistence.py | 4 ++-- osm_ro/wim/tests/test_engine.py | 3 +-- 4 files changed, 51 insertions(+), 12 deletions(-) diff --git a/osm_ro/nfvo.py b/osm_ro/nfvo.py index 7b8a820b..b1c86f9c 100644 --- a/osm_ro/nfvo.py +++ b/osm_ro/nfvo.py @@ -61,6 +61,7 @@ from .http_tools import errors as httperrors from .wim.engine import WimEngine from .wim.persistence import WimPersistence from copy import deepcopy +from pprint import pformat # global global_config @@ -3034,6 +3035,8 @@ def create_instance(mydb, tenant_id, instance_dict): # Auxiliary dictionaries from x to y sce_net2instance = {} net2task_id = {'scenario': {}} + # Mapping between local networks and WIMs + wim_usage = {} def ip_profile_IM2RO(ip_profile_im): # translate from input format to database format @@ -3177,6 +3180,18 @@ def create_instance(mydb, tenant_id, instance_dict): if not involved_datacenters: involved_datacenters.append(default_datacenter_id) + # --> WIM + # TODO: use this information during network creation + wim_account_id = None + if len(involved_datacenters) > 1 and 'uuid' in sce_net: + # OBS: sce_net without uuid are used internally to VNFs + # and the assumption is that VNFs will not be split among + # different datacenters + wim_account_id = wim_engine.find_suitable_wim_account( + involved_datacenters, tenant_id) + wim_usage[sce_net['uuid']] = wim_account_id + # <-- WIM + descriptor_net = {} if instance_dict.get("networks") and instance_dict["networks"].get(sce_net["name"]): descriptor_net = instance_dict["networks"][sce_net["name"]] @@ -3499,7 +3514,8 @@ def create_instance(mydb, tenant_id, instance_dict): db_instance_action["number_tasks"] = task_index # --> WIM - wan_links = wim_engine.derive_wan_links(db_instance_nets, tenant_id) + logger.debug('wim_usage:\n%s\n\n', pformat(wim_usage)) + wan_links = wim_engine.derive_wan_links(wim_usage, db_instance_nets, tenant_id) wim_actions = wim_engine.create_actions(wan_links) wim_actions, db_instance_action = ( wim_engine.incorporate_actions(wim_actions, db_instance_action)) diff --git a/osm_ro/wim/engine.py b/osm_ro/wim/engine.py index dde5dee4..fcb3477f 100644 --- a/osm_ro/wim/engine.py +++ b/osm_ro/wim/engine.py @@ -247,7 +247,7 @@ class WimEngine(object): """Find a single WIM that is able to connect all the datacenters listed - Raises + Raises: NoWimConnectedToDatacenters: if no WIM connected to all datacenters at once is found """ @@ -261,14 +261,35 @@ class WimEngine(object): # used here) return suitable_wim_ids[0] + def find_suitable_wim_account(self, datacenter_ids, tenant): + """Find a WIM account that is able to connect all the datacenters + listed + + Arguments: + datacenter_ids (list): List of UUIDs of all the datacenters (vims), + that need to be connected. + tenant (str): UUID of the OSM tenant + + Returns: + str: UUID of the WIM account that is able to connect all the + datacenters. + """ + wim_id = self.find_common_wim(datacenter_ids, tenant) + return self.persist.get_wim_account_by(wim_id, tenant)['uuid'] + def derive_wan_link(self, + wim_usage, instance_scenario_id, sce_net_id, networks, tenant): """Create a instance_wim_nets record for the given information""" - datacenters = [n['datacenter_id'] for n in networks] - wim_id = self.find_common_wim(datacenters, tenant) - - account = self.persist.get_wim_account_by(wim_id, tenant) + if sce_net_id in wim_usage: + account_id = wim_usage[sce_net_id] + account = self.persist.get_wim_account_by(uuid=account_id) + wim_id = account['wim_id'] + else: + datacenters = [n['datacenter_id'] for n in networks] + wim_id = self.find_common_wim(datacenters, tenant) + account = self.persist.get_wim_account_by(wim_id, tenant) return { 'uuid': str(uuid4()), @@ -278,15 +299,17 @@ class WimEngine(object): 'wim_account_id': account['uuid'] } - def derive_wan_links(self, networks, tenant=None): + def derive_wan_links(self, wim_usage, networks, tenant=None): """Discover and return what are the wan_links that have to be created considering a set of networks (VLDs) required for a scenario instance (NSR). Arguments: + wim_usage(dict): Mapping between sce_net_id and wim_id networks(list): Dicts containing the information about the networks that will be instantiated to materialize a Network Service (scenario) instance. + Corresponding to the ``instance_net`` record. Returns: list: list of WAN links to be written to the database @@ -302,7 +325,8 @@ class WimEngine(object): if counter > 1] return [ - self.derive_wan_link(key[0], key[1], grouped_networks[key], tenant) + self.derive_wan_link(wim_usage, + key[0], key[1], grouped_networks[key], tenant) for key in wan_groups ] diff --git a/osm_ro/wim/persistence.py b/osm_ro/wim/persistence.py index 8a74d491..8f95d563 100644 --- a/osm_ro/wim/persistence.py +++ b/osm_ro/wim/persistence.py @@ -363,10 +363,10 @@ class WimPersistence(object): kwargs.setdefault('WHERE', {'wim_account.uuid': uuid}) return self.query(FROM=_WIM_ACCOUNT_JOIN, **kwargs) - def get_wim_account_by(self, wim=None, tenant=None, **kwargs): + def get_wim_account_by(self, wim=None, tenant=None, uuid=None, **kwargs): """Similar to ``get_wim_accounts_by``, but ensuring just one result""" kwargs.setdefault('error_if_multiple', True) - return self.get_wim_accounts_by(wim, tenant, **kwargs)[0] + return self.get_wim_accounts_by(wim, tenant, uuid, **kwargs)[0] def get_wim_accounts(self, **kwargs): """Retrieve all the accounts from the database""" diff --git a/osm_ro/wim/tests/test_engine.py b/osm_ro/wim/tests/test_engine.py index 6fb2d8cb..9bb7bca0 100644 --- a/osm_ro/wim/tests/test_engine.py +++ b/osm_ro/wim/tests/test_engine.py @@ -163,8 +163,7 @@ class TestWimEngine(unittest.TestCase): # When we receive a list of 4 instance nets, representing # 2 VLDs connecting 2 datacenters each instance_nets = eg.instance_nets(2, 2) - wan_links = engine.derive_wan_links( - instance_nets, uuid('tenant0')) + wan_links = engine.derive_wan_links({}, instance_nets, uuid('tenant0')) # Then we should derive 2 wan_links with the same instance_scenario_id # and different scenario_network_id -- 2.17.1