X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=functest%2Fcore%2Ftenantnetwork.py;h=9f5913c7065f22f89f7c4b62bdaca9cff0f0ebc8;hb=fbb0d16e9ccec7f2b543906ff13801d802fecc3f;hp=e43971fbaf1ee7da0c54d1cb16de112c42934513;hpb=979161874ba837f55a53aba391966c52433123e6;p=functest.git diff --git a/functest/core/tenantnetwork.py b/functest/core/tenantnetwork.py index e43971fba..9f5913c70 100644 --- a/functest/core/tenantnetwork.py +++ b/functest/core/tenantnetwork.py @@ -9,10 +9,11 @@ """Ease deploying tenant networks -It offers a simple way to create all tenant network ressources required by a +It offers a simple way to create all tenant network resources 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 + - TenantNetwork2 creates a user and project to isolate the same resources This classes could be reused by more complexed scenarios (Single VM) """ @@ -28,14 +29,92 @@ from xtesting.core import testcase from functest.utils import config from functest.utils import env -from functest.utils import functest_utils + + +class NewProject(object): + """Ease creating new projects/users""" + # pylint: disable=too-many-instance-attributes + + __logger = logging.getLogger(__name__) + + def __init__(self, cloud, case_name, guid): + self.cloud = None + self.orig_cloud = cloud + self.case_name = case_name + self.guid = guid + self.project = None + self.user = None + self.password = None + self.domain = None + self.role = None + self.role_name = None + self.default_member = env.get('NEW_USER_ROLE') + + def create(self): + """Create projects/users""" + assert self.orig_cloud + assert self.case_name + self.password = str(uuid.uuid4()) + self.domain = self.orig_cloud.get_domain( + name_or_id=self.orig_cloud.auth.get( + "project_domain_name", "Default")) + self.project = self.orig_cloud.create_project( + name='{}-project_{}'.format(self.case_name[:18], 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.orig_cloud.create_user( + name='{}-user_{}'.format(self.case_name, self.guid), + password=self.password, + domain_id=self.domain.id) + self.__logger.debug("user: %s", self.user) + try: + if self.orig_cloud.get_role(self.default_member): + self.role_name = self.default_member + elif self.orig_cloud.get_role(self.default_member.lower()): + self.role_name = self.default_member.lower() + else: + raise Exception("Cannot detect {}".format(self.default_member)) + except Exception: # pylint: disable=broad-except + self.__logger.info("Creating default role %s", self.default_member) + self.role = self.orig_cloud.create_role(self.default_member) + self.role_name = self.role.name + self.__logger.debug("role: %s", self.role) + self.orig_cloud.grant_role( + self.role_name, user=self.user.id, project=self.project.id, + domain=self.domain.id) + osconfig = os_client_config.config.OpenStackConfig() + osconfig.cloud_config[ + 'clouds']['envvars']['project_name'] = self.project.name + osconfig.cloud_config[ + 'clouds']['envvars']['project_id'] = self.project.id + osconfig.cloud_config['clouds']['envvars']['username'] = self.user.name + osconfig.cloud_config['clouds']['envvars']['password'] = self.password + self.__logger.debug("cloud_config %s", osconfig.cloud_config) + self.cloud = shade.OpenStackCloud( + cloud_config=osconfig.get_one_cloud()) + self.__logger.debug("new cloud %s", self.cloud.auth) + + def clean(self): + """Remove projects/users""" + try: + assert self.orig_cloud + if self.user: + self.orig_cloud.delete_user(self.user.id) + if self.project: + self.orig_cloud.delete_project(self.project.id) + if self.role: + self.orig_cloud.delete_role(self.role.id) + except Exception: # pylint: disable=broad-except + self.__logger.exception("Cannot clean all resources") 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 + It creates and configures all tenant network resources required by advanced testcases (subnet, network and router). It ensures that all testcases inheriting from TenantNetwork1 could work @@ -44,7 +123,8 @@ class TenantNetwork1(testcase.TestCase): """ __logger = logging.getLogger(__name__) - cidr = '192.168.0.0/24' + cidr = '192.168.120.0/24' + shared_network = False def __init__(self, **kwargs): if "case_name" not in kwargs: @@ -54,13 +134,14 @@ class TenantNetwork1(testcase.TestCase): getattr(config.CONF, 'dir_results'), self.case_name) try: cloud_config = os_client_config.get_config() - self.cloud = shade.OpenStackCloud(cloud_config=cloud_config) + self.cloud = self.orig_cloud = shade.OpenStackCloud( + cloud_config=cloud_config) except Exception: # pylint: disable=broad-except - self.cloud = None + self.cloud = self.orig_cloud = None self.ext_net = None self.__logger.exception("Cannot connect to Cloud") try: - self.ext_net = functest_utils.get_external_network(self.cloud) + self.ext_net = self.get_external_network(self.cloud) except Exception: # pylint: disable=broad-except self.__logger.exception("Cannot get the external network") self.guid = str(uuid.uuid4()) @@ -68,7 +149,51 @@ class TenantNetwork1(testcase.TestCase): self.subnet = None self.router = None - def _create_network_ressources(self): + @staticmethod + def get_external_network(cloud): + """ + Return the configured external network name or + the first retrieved external network name + """ + assert cloud + if env.get("EXTERNAL_NETWORK"): + network = cloud.get_network( + env.get("EXTERNAL_NETWORK"), {"router:external": True}) + if network: + return network + networks = cloud.list_networks({"router:external": True}) + if networks: + return networks[0] + return None + + @staticmethod + def get_default_role(cloud, member="Member"): + """Get the default role + + It also tests the role in lowercase to avoid possible conflicts. + """ + role = cloud.get_role(member) + if not role: + role = cloud.get_role(member.lower()) + return role + + @staticmethod + def get_public_auth_url(cloud): + """Get Keystone public endpoint""" + keystone_id = cloud.search_services('keystone')[0].id + endpoint = cloud.search_endpoints( + filters={'interface': 'public', + 'service_id': keystone_id})[0].url + return endpoint + + def create_network_resources(self): + """Create all tenant network resources + + It creates a router which gateway is the external network detected. + The new subnet is attached to that router. + + Raises: expection on error + """ assert self.cloud assert self.ext_net provider = {} @@ -81,9 +206,16 @@ class TenantNetwork1(testcase.TestCase): 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( + domain = self.orig_cloud.get_domain( + name_or_id=self.orig_cloud.auth.get( + "project_domain_name", "Default")) + project = self.orig_cloud.get_project( + self.cloud.auth['project_name'], + domain_id=domain.id) + self.network = self.orig_cloud.create_network( '{}-net_{}'.format(self.case_name, self.guid), - provider=provider) + provider=provider, project_id=project.id, + shared=self.shared_network) self.__logger.debug("network: %s", self.network) self.subnet = self.cloud.create_subnet( @@ -107,7 +239,7 @@ class TenantNetwork1(testcase.TestCase): try: assert self.cloud self.start_time = time.time() - self._create_network_ressources() + self.create_network_resources() self.result = 100 status = testcase.TestCase.EX_OK except Exception: # pylint: disable=broad-except @@ -119,18 +251,24 @@ class TenantNetwork1(testcase.TestCase): 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) + if self.router: + if self.subnet: + self.cloud.remove_router_interface( + self.router, self.subnet.id) + self.cloud.delete_router(self.router.id) + if self.subnet: + self.cloud.delete_subnet(self.subnet.id) + if self.network: + self.cloud.delete_network(self.network.id) except Exception: # pylint: disable=broad-except - self.__logger.exception("cannot clean all ressources") + self.__logger.exception("cannot clean all resources") 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). + network resources 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 @@ -145,53 +283,19 @@ class TenantNetwork2(TenantNetwork1): 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"] + self.project = NewProject( + self.cloud, self.case_name, self.guid) + self.project.create() + self.cloud = self.project.cloud 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) + self.cloud = None + self.project = None 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) + assert self.project + self.project.clean() except Exception: # pylint: disable=broad-except - self.__logger.exception("cannot clean all ressources") + self.__logger.exception("Cannot clean all resources")