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.cloud = shade.OpenStackCloud(
78 cloud_config=osconfig.get_one_cloud())
81 """Remove projects/users"""
83 assert self.orig_cloud
85 assert self.project.id
86 self.orig_cloud.delete_user(self.user.id)
87 self.orig_cloud.delete_project(self.project.id)
88 except Exception: # pylint: disable=broad-except
89 self.__logger.exception("Cannot clean all ressources")
92 class TenantNetwork1(testcase.TestCase):
93 # pylint: disable=too-many-instance-attributes
94 """Create a tenant network (scenario1)
96 It creates and configures all tenant network ressources required by
97 advanced testcases (subnet, network and router).
99 It ensures that all testcases inheriting from TenantNetwork1 could work
100 without network specific configurations (or at least read the same config
104 __logger = logging.getLogger(__name__)
105 cidr = '192.168.0.0/24'
107 def __init__(self, **kwargs):
108 if "case_name" not in kwargs:
109 kwargs["case_name"] = 'tenantnetwork1'
110 super(TenantNetwork1, self).__init__(**kwargs)
111 self.res_dir = os.path.join(
112 getattr(config.CONF, 'dir_results'), self.case_name)
114 cloud_config = os_client_config.get_config()
115 self.cloud = shade.OpenStackCloud(cloud_config=cloud_config)
116 except Exception: # pylint: disable=broad-except
119 self.__logger.exception("Cannot connect to Cloud")
121 self.ext_net = functest_utils.get_external_network(self.cloud)
122 except Exception: # pylint: disable=broad-except
123 self.__logger.exception("Cannot get the external network")
124 self.guid = str(uuid.uuid4())
129 def _create_network_ressources(self):
133 if hasattr(config.CONF, '{}_network_type'.format(self.case_name)):
134 provider["network_type"] = getattr(
135 config.CONF, '{}_network_type'.format(self.case_name))
136 if hasattr(config.CONF, '{}_physical_network'.format(self.case_name)):
137 provider["physical_network"] = getattr(
138 config.CONF, '{}_physical_network'.format(self.case_name))
139 if hasattr(config.CONF, '{}_segmentation_id'.format(self.case_name)):
140 provider["segmentation_id"] = getattr(
141 config.CONF, '{}_segmentation_id'.format(self.case_name))
142 self.network = self.cloud.create_network(
143 '{}-net_{}'.format(self.case_name, self.guid),
145 self.__logger.debug("network: %s", self.network)
147 self.subnet = self.cloud.create_subnet(
149 subnet_name='{}-subnet_{}'.format(self.case_name, self.guid),
151 config.CONF, '{}_private_subnet_cidr'.format(self.case_name),
154 dns_nameservers=[env.get('NAMESERVER')])
155 self.__logger.debug("subnet: %s", self.subnet)
157 self.router = self.cloud.create_router(
158 name='{}-router_{}'.format(self.case_name, self.guid),
159 ext_gateway_net_id=self.ext_net.id)
160 self.__logger.debug("router: %s", self.router)
161 self.cloud.add_router_interface(self.router, subnet_id=self.subnet.id)
163 def run(self, **kwargs):
164 status = testcase.TestCase.EX_RUN_ERROR
167 self.start_time = time.time()
168 self._create_network_ressources()
170 status = testcase.TestCase.EX_OK
171 except Exception: # pylint: disable=broad-except
172 self.__logger.exception('Cannot run %s', self.case_name)
174 self.stop_time = time.time()
180 self.cloud.remove_router_interface(self.router, self.subnet.id)
181 self.cloud.delete_router(self.router.id)
182 self.cloud.delete_subnet(self.subnet.id)
183 self.cloud.delete_network(self.network.id)
184 except Exception: # pylint: disable=broad-except
185 self.__logger.exception("cannot clean all ressources")
188 class TenantNetwork2(TenantNetwork1):
189 """Create a tenant network (scenario2)
191 It creates new user/project before creating and configuring all tenant
192 network ressources required by a testcase (subnet, network and router).
194 It ensures that all testcases inheriting from TenantNetwork2 could work
195 without network specific configurations (or at least read the same config
199 __logger = logging.getLogger(__name__)
201 def __init__(self, **kwargs):
202 if "case_name" not in kwargs:
203 kwargs["case_name"] = 'tenantnetwork2'
204 super(TenantNetwork2, self).__init__(**kwargs)
207 self.project = NewProject(
208 self.cloud, self.case_name, self.guid)
209 self.project.create()
210 self.cloud = self.project.cloud
211 except Exception: # pylint: disable=broad-except
212 self.__logger.exception("Cannot create user or project")
218 super(TenantNetwork2, self).clean()
221 except Exception: # pylint: disable=broad-except
222 self.__logger.exception("Cannot clean all ressources")