diff options
author | George Paraskevopoulos <geopar@intracom-telecom.com> | 2017-02-15 11:53:45 +0200 |
---|---|---|
committer | George Paraskevopoulos <geopar@intracom-telecom.com> | 2017-02-16 14:03:54 +0200 |
commit | caf8ae14070fb46386e87fae2df96339b9fdf350 (patch) | |
tree | dbc41fdc1c7401cccf7971e2829ec4feee14ccc0 | |
parent | 306daf5219a2ba7975c2cc22096e41fd39f91918 (diff) |
Add topology_shuffler
JIRA: SFC-63
This module will be used to configure the assignment of endpoints and
VNFs to compute hosts dynamically
Change-Id: Ie778b52796c76d829ccb3d49e1c9bc7f5e7c7b47
Signed-off-by: George Paraskevopoulos <geopar@intracom-telecom.com>
-rw-r--r-- | sfc/lib/topology_shuffler.py | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/sfc/lib/topology_shuffler.py b/sfc/lib/topology_shuffler.py new file mode 100644 index 00000000..ccabe427 --- /dev/null +++ b/sfc/lib/topology_shuffler.py @@ -0,0 +1,151 @@ +import datetime +import random +import functest.utils.openstack_utils as os_utils +import functest.utils.functest_logger as ft_logger + + +logger = ft_logger.Logger(__name__).getLogger() + +# The possible topologies we are testing +TOPOLOGIES = [ + { + 'id': 'CLIENT_VNF_SAME_HOST', + 'description': ''' + Client instance and vnfs are are on the same + compute host. Server instance is on a different host + ''' + }, + { + 'id': 'CLIENT_SERVER_SAME_HOST', + 'description': ''' + Client instance and server instance are on the same + compute host. All VNFs are on a different host. + ''' + }, + { + 'id': 'SERVER_VNF_SAME_HOST', + 'description': ''' + Server instance and vnfs are are on the same + compute host. Server instance is on a different host + ''' + }, + { + 'id': 'CLIENT_SERVER_SAME_HOST_SPLIT_VNF', + 'description': ''' + Client and server are on the same host. + The VNFs are split between hosts Round Robin. + ''' + }, + { + 'id': 'CLIENT_SERVER_DIFFERENT_HOST_SPLIT_VNF', + 'description': ''' + Client and server are on different hosts. + The VNFs are split between hosts Round Robin. + ''' + } +] + +DEFAULT_TOPO = { + 'id': 'DEFAULT', + 'description': ''' + The default topology created by nova scheduler + ''' +} + + +def _get_seed(): + ''' + Get a seed based on the day of the week to choose which topology to test + + NOTE: There's sure a smarter way to do this + Probably with the Jenkins job id + ''' + cutoff = len(TOPOLOGIES - 1) + seed = datetime.datetime.today().weekday() + if seed > cutoff: + seed = random.randrange(cutoff) + return seed + + +def _split_host_aggregates(): + ''' + Gets all the compute hosts and creates an aggregate for each. + Aggregates are named based on the convention compute1, compute2, ... + ''' + nova_client = os_utils.get_nova_client() + hosts = os_utils.get_hypervisors(nova_client) + aggregates = [] + for idx, host in enumerate(hosts): + az_name = 'compute{0}'.format(idx) + # aggregate name is the same as availability zone name + os_utils.create_aggregate_with_host( + nova_client, az_name, az_name, host) + aggregates.append(az_name) + # aggregates and av zones abstractions are tightly coupled in nova + return aggregates + + +def clean_host_aggregates(aggregates): + ''' + Clean all the created host aggregates + ''' + nova_client = os_utils.get_nova_client() + for aggregate in aggregates: + if not os_utils.delete_aggregate(nova_client, aggregate): + logger.error('Could not delete aggregate {0}' + .format(aggregate)) + + +def topology(vnf_names, host_aggregates=None, seed=None): + ''' + Get the topology for client, server and vnfs. + The topology is returned as a dict in the form + { + 'client': <availability_zone>, + 'server': <availability_zone>, + 'vnf1': <availability_zone>, + 'vnf2': <availability_zone> + ... + } + Use seed=-1 to get the default topology created by nova-scheduler + ''' + + if host_aggregates is None: + host_aggregates = _split_host_aggregates() + if len(host_aggregates) < 2 or seed is None: + return None + + topology = TOPOLOGIES[seed] + topology_assigment = {} + if topology['id'] == 'CLIENT_VNF_SAME_HOST': + topology_assigment['client'] = host_aggregates[0] + topology_assigment['server'] = host_aggregates[1] + for vnf in vnf_names: + topology_assigment[vnf] = host_aggregates[0] + elif topology['id'] == 'CLIENT_SERVER_SAME_HOST': + topology_assigment['client'] = host_aggregates[0] + topology_assigment['server'] = host_aggregates[0] + for vnf in vnf_names: + topology_assigment[vnf] = host_aggregates[1] + elif topology['id'] == 'SERVER_VNF_SAME_HOST': + topology_assigment['client'] = host_aggregates[1] + topology_assigment['server'] = host_aggregates[0] + for vnf in vnf_names: + topology_assigment[vnf] = host_aggregates[0] + elif topology['id'] == 'CLIENT_SERVER_SAME_HOST_SPLIT_VNF': + topology_assigment['client'] = host_aggregates[0] + topology_assigment['server'] = host_aggregates[0] + idx = 0 + for vnf in vnf_names: + topology_assigment[vnf] = host_aggregates[idx % 2] + idx += 1 + elif topology['id'] == 'CLIENT_SERVER_DIFFERENT_HOST_SPLIT_VNF': + topology_assigment['client'] = host_aggregates[0] + topology_assigment['server'] = host_aggregates[1] + idx = 0 + for vnf in vnf_names: + topology_assigment[vnf] = host_aggregates[idx % 2] + idx += 1 + logger.info("Creating enpoint and VNF topology on the compute hosts") + logger.info(topology['description']) + return topology_assigment |