From 979161874ba837f55a53aba391966c52433123e6 Mon Sep 17 00:00:00 2001 From: Cédric Ollivier Date: Mon, 18 Jun 2018 13:52:42 +0200 Subject: Publish tenantnetwork scenarios MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They ease creating all tenant network ressources. These scenarios should be reused by other more complex ones. Change-Id: I4ce1872065bde92408d34f2ca8823ce98275d8d5 Signed-off-by: Cédric Ollivier --- docker/healthcheck/testcases.yaml | 32 ++++ functest/ci/testcases.yaml | 32 ++++ functest/core/tenantnetwork.py | 197 ++++++++++++++++++++++ functest/opnfv_tests/openstack/tempest/tempest.py | 8 +- 4 files changed, 266 insertions(+), 3 deletions(-) create mode 100644 functest/core/tenantnetwork.py diff --git a/docker/healthcheck/testcases.yaml b/docker/healthcheck/testcases.yaml index 33bc8d1b7..14d353dc1 100644 --- a/docker/healthcheck/testcases.yaml +++ b/docker/healthcheck/testcases.yaml @@ -61,3 +61,35 @@ tiers: run: module: 'functest.opnfv_tests.openstack.snaps.health_check' class: 'HealthCheck' + + - + case_name: tenantnetwork1 + project_name: functest + criteria: 100 + blocking: false + description: >- + It creates and configures all tenant network ressources + required by advanced testcases (subnet, network and + router). + dependencies: + installer: '' + scenario: '' + run: + module: 'functest.core.tenantnetwork' + class: 'TenantNetwork1' + + - + case_name: tenantnetwork2 + project_name: functest + criteria: 100 + blocking: false + description: >- + It creates new user/project before creating and configuring + all tenant network ressources required by a testcase + (subnet, network and router). + dependencies: + installer: '' + scenario: '' + run: + module: 'functest.core.tenantnetwork' + class: 'TenantNetwork2' diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml index b3e05f082..55d9994a6 100644 --- a/functest/ci/testcases.yaml +++ b/functest/ci/testcases.yaml @@ -62,6 +62,38 @@ tiers: module: 'functest.opnfv_tests.openstack.snaps.health_check' class: 'HealthCheck' + - + case_name: tenantnetwork1 + project_name: functest + criteria: 100 + blocking: false + description: >- + It creates and configures all tenant network ressources + required by advanced testcases (subnet, network and + router). + dependencies: + installer: '' + scenario: '' + run: + module: 'functest.core.tenantnetwork' + class: 'TenantNetwork1' + + - + case_name: tenantnetwork2 + project_name: functest + criteria: 100 + blocking: false + description: >- + It creates new user/project before creating and configuring + all tenant network ressources required by a testcase + (subnet, network and router). + dependencies: + installer: '' + scenario: '' + run: + module: 'functest.core.tenantnetwork' + class: 'TenantNetwork2' + - name: smoke order: 1 diff --git a/functest/core/tenantnetwork.py b/functest/core/tenantnetwork.py new file mode 100644 index 000000000..e43971fba --- /dev/null +++ b/functest/core/tenantnetwork.py @@ -0,0 +1,197 @@ +#!/usr/bin/env python + +# Copyright (c) 2018 Orange and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 + +"""Ease deploying tenant networks + +It offers a simple way to create all tenant network ressources required by a +testcase (including all Functest ones): + - TenantNetwork1 selects the user and the project set as env vars + - TenantNetwork2 creates a user and project to isolate the same ressources + +This classes could be reused by more complexed scenarios (Single VM) +""" + +import logging +import os +import time +import uuid + +import os_client_config +import shade +from xtesting.core import testcase + +from functest.utils import config +from functest.utils import env +from functest.utils import functest_utils + + +class TenantNetwork1(testcase.TestCase): + # pylint: disable=too-many-instance-attributes + """Create a tenant network (scenario1) + + It creates and configures all tenant network ressources required by + advanced testcases (subnet, network and router). + + It ensures that all testcases inheriting from TenantNetwork1 could work + without network specific configurations (or at least read the same config + data). + """ + + __logger = logging.getLogger(__name__) + cidr = '192.168.0.0/24' + + def __init__(self, **kwargs): + if "case_name" not in kwargs: + kwargs["case_name"] = 'tenantnetwork1' + super(TenantNetwork1, self).__init__(**kwargs) + self.res_dir = os.path.join( + getattr(config.CONF, 'dir_results'), self.case_name) + try: + cloud_config = os_client_config.get_config() + self.cloud = shade.OpenStackCloud(cloud_config=cloud_config) + except Exception: # pylint: disable=broad-except + self.cloud = None + self.ext_net = None + self.__logger.exception("Cannot connect to Cloud") + try: + self.ext_net = functest_utils.get_external_network(self.cloud) + except Exception: # pylint: disable=broad-except + self.__logger.exception("Cannot get the external network") + self.guid = str(uuid.uuid4()) + self.network = None + self.subnet = None + self.router = None + + def _create_network_ressources(self): + assert self.cloud + assert self.ext_net + provider = {} + if hasattr(config.CONF, '{}_network_type'.format(self.case_name)): + provider["network_type"] = getattr( + config.CONF, '{}_network_type'.format(self.case_name)) + if hasattr(config.CONF, '{}_physical_network'.format(self.case_name)): + provider["physical_network"] = getattr( + config.CONF, '{}_physical_network'.format(self.case_name)) + if hasattr(config.CONF, '{}_segmentation_id'.format(self.case_name)): + provider["segmentation_id"] = getattr( + config.CONF, '{}_segmentation_id'.format(self.case_name)) + self.network = self.cloud.create_network( + '{}-net_{}'.format(self.case_name, self.guid), + provider=provider) + self.__logger.debug("network: %s", self.network) + + self.subnet = self.cloud.create_subnet( + self.network.id, + subnet_name='{}-subnet_{}'.format(self.case_name, self.guid), + cidr=getattr( + config.CONF, '{}_private_subnet_cidr'.format(self.case_name), + self.cidr), + enable_dhcp=True, + dns_nameservers=[env.get('NAMESERVER')]) + self.__logger.debug("subnet: %s", self.subnet) + + self.router = self.cloud.create_router( + name='{}-router_{}'.format(self.case_name, self.guid), + ext_gateway_net_id=self.ext_net.id) + self.__logger.debug("router: %s", self.router) + self.cloud.add_router_interface(self.router, subnet_id=self.subnet.id) + + def run(self, **kwargs): + status = testcase.TestCase.EX_RUN_ERROR + try: + assert self.cloud + self.start_time = time.time() + self._create_network_ressources() + self.result = 100 + status = testcase.TestCase.EX_OK + except Exception: # pylint: disable=broad-except + self.__logger.exception('Cannot run %s', self.case_name) + finally: + self.stop_time = time.time() + return status + + def clean(self): + try: + assert self.cloud + self.cloud.remove_router_interface(self.router, self.subnet.id) + self.cloud.delete_router(self.router.id) + self.cloud.delete_network(self.network.id) + except Exception: # pylint: disable=broad-except + self.__logger.exception("cannot clean all ressources") + + +class TenantNetwork2(TenantNetwork1): + """Create a tenant network (scenario2) + + It creates new user/project before creating and configuring all tenant + network ressources required by a testcase (subnet, network and router). + + It ensures that all testcases inheriting from TenantNetwork2 could work + without network specific configurations (or at least read the same config + data). + """ + + __logger = logging.getLogger(__name__) + + def __init__(self, **kwargs): + if "case_name" not in kwargs: + kwargs["case_name"] = 'tenantnetwork2' + super(TenantNetwork2, self).__init__(**kwargs) + try: + assert self.cloud + self.domain = self.cloud.get_domain( + name_or_id=self.cloud.auth.get( + "project_domain_name", "Default")) + except Exception: # pylint: disable=broad-except + self.domain = None + self.__logger.exception("Cannot connect to Cloud") + self.project = None + self.user = None + self.orig_cloud = None + self.password = str(uuid.uuid4()) + + def run(self, **kwargs): + assert self.cloud + assert self.domain + try: + self.project = self.cloud.create_project( + name='{}-project_{}'.format(self.case_name, self.guid), + description="Created by OPNFV Functest: {}".format( + self.case_name), + domain_id=self.domain.id) + self.__logger.debug("project: %s", self.project) + self.user = self.cloud.create_user( + name='{}-user_{}'.format(self.case_name, self.guid), + password=self.password, + default_project=self.project.id, + domain_id=self.domain.id) + self.__logger.debug("user: %s", self.user) + self.orig_cloud = self.cloud + os.environ["OS_USERNAME"] = self.user.name + os.environ["OS_PROJECT_NAME"] = self.user.default_project_id + cloud_config = os_client_config.get_config() + self.cloud = shade.OpenStackCloud(cloud_config=cloud_config) + os.environ["OS_USERNAME"] = self.orig_cloud.auth["username"] + os.environ["OS_PROJECT_NAME"] = self.orig_cloud.auth[ + "project_name"] + except Exception: # pylint: disable=broad-except + self.__logger.exception("Cannot create user or project") + return testcase.TestCase.EX_RUN_ERROR + return super(TenantNetwork2, self).run(**kwargs) + + def clean(self): + try: + assert self.cloud + super(TenantNetwork2, self).clean() + assert self.user.id + assert self.project.id + self.orig_cloud.delete_user(self.user.id) + self.orig_cloud.delete_project(self.project.id) + except Exception: # pylint: disable=broad-except + self.__logger.exception("cannot clean all ressources") diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py index 7fb24f239..d51337a1e 100644 --- a/functest/opnfv_tests/openstack/tempest/tempest.py +++ b/functest/opnfv_tests/openstack/tempest/tempest.py @@ -366,7 +366,9 @@ class TempestResourcesManager(object): self.guid = '-' + str(uuid.uuid4()) self.cloud = os_client_config.make_shade() LOGGER.debug("cloud: %s", self.cloud) - self.domain = self.cloud.auth.get("project_domain_name", "Default") + self.domain = self.cloud.get_domain( + name_or_id=self.cloud.auth.get( + "project_domain_name", "Default")) LOGGER.debug("domain: %s", self.domain) self.project = None self.user = None @@ -383,7 +385,7 @@ class TempestResourcesManager(object): getattr(config.CONF, 'tempest_identity_tenant_name') + self.guid, description=getattr( config.CONF, 'tempest_identity_tenant_description'), - domain_id=self.domain) + domain_id=self.domain.id) LOGGER.debug("project: %s", self.project) def _create_user(self): @@ -394,7 +396,7 @@ class TempestResourcesManager(object): password=getattr(config.CONF, 'tempest_identity_user_password'), default_project=getattr( config.CONF, 'tempest_identity_tenant_name') + self.guid, - domain_id=self.domain) + domain_id=self.domain.id) LOGGER.debug("user: %s", self.user) def _create_network(self): -- cgit 1.2.3-korg