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
33 class NewProject(object):
34 """Ease creating new projects/users"""
35 # pylint: disable=too-many-instance-attributes
37 __logger = logging.getLogger(__name__)
39 def __init__(self, cloud, case_name, guid):
41 self.orig_cloud = cloud
42 self.case_name = case_name
50 """Create projects/users"""
51 assert self.orig_cloud
53 self.password = str(uuid.uuid4())
54 self.domain = self.orig_cloud.get_domain(
55 name_or_id=self.orig_cloud.auth.get(
56 "project_domain_name", "Default"))
57 self.project = self.orig_cloud.create_project(
58 name='{}-project_{}'.format(self.case_name, self.guid),
59 description="Created by OPNFV Functest: {}".format(
61 domain_id=self.domain.id)
62 self.__logger.debug("project: %s", self.project)
63 self.user = self.orig_cloud.create_user(
64 name='{}-user_{}'.format(self.case_name, self.guid),
65 password=self.password,
66 domain_id=self.domain.id)
67 self.__logger.debug("user: %s", self.user)
68 self.orig_cloud.grant_role(
69 "Member", user=self.user.id, project=self.project.id,
70 domain=self.domain.id)
71 osconfig = os_client_config.config.OpenStackConfig()
72 osconfig.cloud_config[
73 'clouds']['envvars']['project_name'] = self.project.name
74 osconfig.cloud_config['clouds']['envvars']['username'] = self.user.name
75 osconfig.cloud_config['clouds']['envvars']['password'] = self.password
76 self.__logger.debug("cloud_config %s", osconfig.cloud_config)
77 self.cloud = shade.OpenStackCloud(
78 cloud_config=osconfig.get_one_cloud())
79 self.__logger.debug("new cloud %s", self.cloud.auth)
82 """Remove projects/users"""
84 assert self.orig_cloud
86 assert self.project.id
87 self.orig_cloud.delete_user(self.user.id)
88 self.orig_cloud.delete_project(self.project.id)
89 except Exception: # pylint: disable=broad-except
90 self.__logger.exception("Cannot clean all ressources")
93 class TenantNetwork1(testcase.TestCase):
94 # pylint: disable=too-many-instance-attributes
95 """Create a tenant network (scenario1)
97 It creates and configures all tenant network ressources required by
98 advanced testcases (subnet, network and router).
100 It ensures that all testcases inheriting from TenantNetwork1 could work
101 without network specific configurations (or at least read the same config
105 __logger = logging.getLogger(__name__)
106 cidr = '192.168.0.0/24'
107 shared_network = False
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 = self.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())
132 def get_external_network(cloud):
134 Returns the configured external network name or
135 the first retrieved external network name
138 if env.get("EXTERNAL_NETWORK"):
139 network = cloud.get_network(
140 env.get("EXTERNAL_NETWORK"), {"router:external": True})
143 networks = cloud.list_networks({"router:external": True})
148 def _create_network_ressources(self):
152 if hasattr(config.CONF, '{}_network_type'.format(self.case_name)):
153 provider["network_type"] = getattr(
154 config.CONF, '{}_network_type'.format(self.case_name))
155 if hasattr(config.CONF, '{}_physical_network'.format(self.case_name)):
156 provider["physical_network"] = getattr(
157 config.CONF, '{}_physical_network'.format(self.case_name))
158 if hasattr(config.CONF, '{}_segmentation_id'.format(self.case_name)):
159 provider["segmentation_id"] = getattr(
160 config.CONF, '{}_segmentation_id'.format(self.case_name))
161 self.network = self.cloud.create_network(
162 '{}-net_{}'.format(self.case_name, self.guid),
164 shared=self.shared_network)
165 self.__logger.debug("network: %s", self.network)
167 self.subnet = self.cloud.create_subnet(
169 subnet_name='{}-subnet_{}'.format(self.case_name, self.guid),
171 config.CONF, '{}_private_subnet_cidr'.format(self.case_name),
174 dns_nameservers=[env.get('NAMESERVER')])
175 self.__logger.debug("subnet: %s", self.subnet)
177 self.router = self.cloud.create_router(
178 name='{}-router_{}'.format(self.case_name, self.guid),
179 ext_gateway_net_id=self.ext_net.id)
180 self.__logger.debug("router: %s", self.router)
181 self.cloud.add_router_interface(self.router, subnet_id=self.subnet.id)
183 def run(self, **kwargs):
184 status = testcase.TestCase.EX_RUN_ERROR
187 self.start_time = time.time()
188 self._create_network_ressources()
190 status = testcase.TestCase.EX_OK
191 except Exception: # pylint: disable=broad-except
192 self.__logger.exception('Cannot run %s', self.case_name)
194 self.stop_time = time.time()
200 self.cloud.remove_router_interface(self.router, self.subnet.id)
201 self.cloud.delete_router(self.router.id)
202 self.cloud.delete_subnet(self.subnet.id)
203 self.cloud.delete_network(self.network.id)
204 except Exception: # pylint: disable=broad-except
205 self.__logger.exception("cannot clean all ressources")
208 class TenantNetwork2(TenantNetwork1):
209 """Create a tenant network (scenario2)
211 It creates new user/project before creating and configuring all tenant
212 network ressources required by a testcase (subnet, network and router).
214 It ensures that all testcases inheriting from TenantNetwork2 could work
215 without network specific configurations (or at least read the same config
219 __logger = logging.getLogger(__name__)
221 def __init__(self, **kwargs):
222 if "case_name" not in kwargs:
223 kwargs["case_name"] = 'tenantnetwork2'
224 super(TenantNetwork2, self).__init__(**kwargs)
227 self.project = NewProject(
228 self.cloud, self.case_name, self.guid)
229 self.project.create()
230 self.cloud = self.project.cloud
231 except Exception: # pylint: disable=broad-except
232 self.__logger.exception("Cannot create user or project")
238 super(TenantNetwork2, self).clean()
241 except Exception: # pylint: disable=broad-except
242 self.__logger.exception("Cannot clean all ressources")