3 # Copyright (c) 2018 Orange and others.
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 """Ease deploying tenant networks
12 It offers a simple way to create all tenant network ressources required by a
13 testcase (including all Functest ones):
14 - TenantNetwork1 selects the user and the project set as env vars
15 - TenantNetwork2 creates a user and project to isolate the same ressources
17 This classes could be reused by more complexed scenarios (Single VM)
25 import os_client_config
27 from xtesting.core import testcase
29 from functest.utils import config
30 from functest.utils import env
31 from functest.utils import functest_utils
34 class NewProject(object):
35 """Ease creating new projects/users"""
36 # pylint: disable=too-many-instance-attributes
38 __logger = logging.getLogger(__name__)
40 def __init__(self, cloud, case_name, guid):
42 self.orig_cloud = cloud
43 self.case_name = case_name
51 """Create projects/users"""
52 assert self.orig_cloud
54 self.password = str(uuid.uuid4())
55 self.domain = self.orig_cloud.get_domain(
56 name_or_id=self.orig_cloud.auth.get(
57 "project_domain_name", "Default"))
58 self.project = self.orig_cloud.create_project(
59 name='{}-project_{}'.format(self.case_name, self.guid),
60 description="Created by OPNFV Functest: {}".format(
62 domain_id=self.domain.id)
63 self.__logger.debug("project: %s", self.project)
64 self.user = self.orig_cloud.create_user(
65 name='{}-user_{}'.format(self.case_name, self.guid),
66 password=self.password,
67 domain_id=self.domain.id)
68 self.__logger.debug("user: %s", self.user)
69 self.orig_cloud.grant_role(
70 "_member_", user=self.user.id, project=self.project.id,
71 domain=self.domain.id)
72 osconfig = os_client_config.config.OpenStackConfig()
73 osconfig.cloud_config[
74 'clouds']['envvars']['project_name'] = self.project.name
75 osconfig.cloud_config['clouds']['envvars']['username'] = self.user.name
76 osconfig.cloud_config['clouds']['envvars']['password'] = self.password
77 self.__logger.debug("cloud_config %s", osconfig.cloud_config)
78 self.cloud = shade.OpenStackCloud(
79 cloud_config=osconfig.get_one_cloud())
80 self.__logger.debug("new cloud %s", self.cloud.auth)
83 """Remove projects/users"""
85 assert self.orig_cloud
87 assert self.project.id
88 self.orig_cloud.delete_user(self.user.id)
89 self.orig_cloud.delete_project(self.project.id)
90 except Exception: # pylint: disable=broad-except
91 self.__logger.exception("Cannot clean all ressources")
94 class TenantNetwork1(testcase.TestCase):
95 # pylint: disable=too-many-instance-attributes
96 """Create a tenant network (scenario1)
98 It creates and configures all tenant network ressources required by
99 advanced testcases (subnet, network and router).
101 It ensures that all testcases inheriting from TenantNetwork1 could work
102 without network specific configurations (or at least read the same config
106 __logger = logging.getLogger(__name__)
107 cidr = '192.168.0.0/24'
109 def __init__(self, **kwargs):
110 if "case_name" not in kwargs:
111 kwargs["case_name"] = 'tenantnetwork1'
112 super(TenantNetwork1, self).__init__(**kwargs)
113 self.res_dir = os.path.join(
114 getattr(config.CONF, 'dir_results'), self.case_name)
116 cloud_config = os_client_config.get_config()
117 self.cloud = shade.OpenStackCloud(cloud_config=cloud_config)
118 except Exception: # pylint: disable=broad-except
121 self.__logger.exception("Cannot connect to Cloud")
123 self.ext_net = functest_utils.get_external_network(self.cloud)
124 except Exception: # pylint: disable=broad-except
125 self.__logger.exception("Cannot get the external network")
126 self.guid = str(uuid.uuid4())
131 def _create_network_ressources(self):
135 if hasattr(config.CONF, '{}_network_type'.format(self.case_name)):
136 provider["network_type"] = getattr(
137 config.CONF, '{}_network_type'.format(self.case_name))
138 if hasattr(config.CONF, '{}_physical_network'.format(self.case_name)):
139 provider["physical_network"] = getattr(
140 config.CONF, '{}_physical_network'.format(self.case_name))
141 if hasattr(config.CONF, '{}_segmentation_id'.format(self.case_name)):
142 provider["segmentation_id"] = getattr(
143 config.CONF, '{}_segmentation_id'.format(self.case_name))
144 self.network = self.cloud.create_network(
145 '{}-net_{}'.format(self.case_name, self.guid),
147 self.__logger.debug("network: %s", self.network)
149 self.subnet = self.cloud.create_subnet(
151 subnet_name='{}-subnet_{}'.format(self.case_name, self.guid),
153 config.CONF, '{}_private_subnet_cidr'.format(self.case_name),
156 dns_nameservers=[env.get('NAMESERVER')])
157 self.__logger.debug("subnet: %s", self.subnet)
159 self.router = self.cloud.create_router(
160 name='{}-router_{}'.format(self.case_name, self.guid),
161 ext_gateway_net_id=self.ext_net.id)
162 self.__logger.debug("router: %s", self.router)
163 self.cloud.add_router_interface(self.router, subnet_id=self.subnet.id)
165 def run(self, **kwargs):
166 status = testcase.TestCase.EX_RUN_ERROR
169 self.start_time = time.time()
170 self._create_network_ressources()
172 status = testcase.TestCase.EX_OK
173 except Exception: # pylint: disable=broad-except
174 self.__logger.exception('Cannot run %s', self.case_name)
176 self.stop_time = time.time()
182 self.cloud.remove_router_interface(self.router, self.subnet.id)
183 self.cloud.delete_router(self.router.id)
184 self.cloud.delete_subnet(self.subnet.id)
185 self.cloud.delete_network(self.network.id)
186 except Exception: # pylint: disable=broad-except
187 self.__logger.exception("cannot clean all ressources")
190 class TenantNetwork2(TenantNetwork1):
191 """Create a tenant network (scenario2)
193 It creates new user/project before creating and configuring all tenant
194 network ressources required by a testcase (subnet, network and router).
196 It ensures that all testcases inheriting from TenantNetwork2 could work
197 without network specific configurations (or at least read the same config
201 __logger = logging.getLogger(__name__)
203 def __init__(self, **kwargs):
204 if "case_name" not in kwargs:
205 kwargs["case_name"] = 'tenantnetwork2'
206 super(TenantNetwork2, self).__init__(**kwargs)
209 self.project = NewProject(
210 self.cloud, self.case_name, self.guid)
211 self.project.create()
212 self.cloud = self.project.cloud
213 except Exception: # pylint: disable=broad-except
214 self.__logger.exception("Cannot create user or project")
220 super(TenantNetwork2, self).clean()
223 except Exception: # pylint: disable=broad-except
224 self.__logger.exception("Cannot clean all ressources")