blob: eadb0c2e72ef8e7e5d574a7cc2542ac2b8481256 [file] [log] [blame]
Matthew Treinishb86cda92013-07-29 11:22:23 -04001# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2013 IBM Corp.
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License. You may obtain
7# a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations
15# under the License.
16
Miguel Lavalleb8fabc52013-08-23 11:19:57 -050017import netaddr
18
19import keystoneclient.v2_0.client as keystoneclient
20import neutronclient.v2_0.client as neutronclient
Matthew Treinishb86cda92013-07-29 11:22:23 -040021
22from tempest import clients
23from tempest.common.utils.data_utils import rand_name
24from tempest import config
25from tempest import exceptions
26from tempest.openstack.common import log as logging
27
28LOG = logging.getLogger(__name__)
29
30
31class IsolatedCreds(object):
32
33 def __init__(self, name, tempest_client=True, interface='json',
34 password='pass'):
35 self.isolated_creds = {}
Miguel Lavalleb8fabc52013-08-23 11:19:57 -050036 self.isolated_net_resources = {}
37 self.ports = []
Matthew Treinishb86cda92013-07-29 11:22:23 -040038 self.name = name
39 self.config = config.TempestConfig()
40 self.tempest_client = tempest_client
41 self.interface = interface
42 self.password = password
Miguel Lavalleb8fabc52013-08-23 11:19:57 -050043 self.identity_admin_client, self.network_admin_client = (
44 self._get_admin_clients())
Matthew Treinishb86cda92013-07-29 11:22:23 -040045
Miguel Lavalleb8fabc52013-08-23 11:19:57 -050046 def _get_official_admin_clients(self):
Matthew Treinishb86cda92013-07-29 11:22:23 -040047 username = self.config.identity.admin_username
48 password = self.config.identity.admin_password
49 tenant_name = self.config.identity.admin_tenant_name
50 auth_url = self.config.identity.uri
51 dscv = self.config.identity.disable_ssl_certificate_validation
Miguel Lavalleb8fabc52013-08-23 11:19:57 -050052 identity_client = keystoneclient.Client(username=username,
53 password=password,
54 tenant_name=tenant_name,
55 auth_url=auth_url,
56 insecure=dscv)
57 network_client = neutronclient.Client(username=username,
58 password=password,
59 tenant_name=tenant_name,
60 auth_url=auth_url,
61 insecure=dscv)
62 return identity_client, network_client
Matthew Treinishb86cda92013-07-29 11:22:23 -040063
Miguel Lavalleb8fabc52013-08-23 11:19:57 -050064 def _get_admin_clients(self):
Matthew Treinishb86cda92013-07-29 11:22:23 -040065 """
Miguel Lavalleb8fabc52013-08-23 11:19:57 -050066 Returns a tuple with instances of the following admin clients (in this
67 order):
68 identity
69 network
Matthew Treinishb86cda92013-07-29 11:22:23 -040070 """
71 if self.tempest_client:
72 os = clients.AdminManager(interface=self.interface)
Miguel Lavalleb8fabc52013-08-23 11:19:57 -050073 admin_clients = (os.identity_client,
74 os.network_client,)
Matthew Treinishb86cda92013-07-29 11:22:23 -040075 else:
Miguel Lavalleb8fabc52013-08-23 11:19:57 -050076 admin_clients = self._get_official_admin_clients()
77 return admin_clients
Matthew Treinishb86cda92013-07-29 11:22:23 -040078
79 def _create_tenant(self, name, description):
80 if self.tempest_client:
Miguel Lavalleb8fabc52013-08-23 11:19:57 -050081 resp, tenant = self.identity_admin_client.create_tenant(
Matthew Treinishb86cda92013-07-29 11:22:23 -040082 name=name, description=description)
83 else:
Miguel Lavalleb8fabc52013-08-23 11:19:57 -050084 tenant = self.identity_admin_client.tenants.create(
85 name,
86 description=description)
Matthew Treinishb86cda92013-07-29 11:22:23 -040087 return tenant
88
89 def _get_tenant_by_name(self, name):
90 if self.tempest_client:
Miguel Lavalleb8fabc52013-08-23 11:19:57 -050091 resp, tenant = self.identity_admin_client.get_tenant_by_name(name)
Matthew Treinishb86cda92013-07-29 11:22:23 -040092 else:
Miguel Lavalleb8fabc52013-08-23 11:19:57 -050093 tenants = self.identity_admin_client.tenants.list()
Matthew Treinishb86cda92013-07-29 11:22:23 -040094 for ten in tenants:
95 if ten['name'] == name:
96 tenant = ten
DennyZhang1eb40462013-09-26 14:18:30 -050097 break
98 else:
99 raise exceptions.NotFound('No such tenant')
Matthew Treinishb86cda92013-07-29 11:22:23 -0400100 return tenant
101
102 def _create_user(self, username, password, tenant, email):
103 if self.tempest_client:
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500104 resp, user = self.identity_admin_client.create_user(username,
105 password,
106 tenant['id'],
107 email)
Matthew Treinishb86cda92013-07-29 11:22:23 -0400108 else:
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500109 user = self.identity_admin_client.users.create(username, password,
110 email,
111 tenant_id=tenant.id)
Matthew Treinishb86cda92013-07-29 11:22:23 -0400112 return user
113
114 def _get_user(self, tenant, username):
115 if self.tempest_client:
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500116 resp, user = self.identity_admin_client.get_user_by_username(
117 tenant['id'],
118 username)
Matthew Treinishb86cda92013-07-29 11:22:23 -0400119 else:
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500120 user = self.identity_admin_client.users.get(username)
Matthew Treinishb86cda92013-07-29 11:22:23 -0400121 return user
122
123 def _list_roles(self):
124 if self.tempest_client:
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500125 resp, roles = self.identity_admin_client.list_roles()
Matthew Treinishb86cda92013-07-29 11:22:23 -0400126 else:
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500127 roles = self.identity_admin_client.roles.list()
Matthew Treinishb86cda92013-07-29 11:22:23 -0400128 return roles
129
130 def _assign_user_role(self, tenant, user, role):
131 if self.tempest_client:
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500132 self.identity_admin_client.assign_user_role(tenant, user, role)
Matthew Treinishb86cda92013-07-29 11:22:23 -0400133 else:
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500134 self.identity_admin_client.roles.add_user_role(user,
135 role, tenant=tenant)
Matthew Treinishb86cda92013-07-29 11:22:23 -0400136
137 def _delete_user(self, user):
138 if self.tempest_client:
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500139 self.identity_admin_client.delete_user(user)
Matthew Treinishb86cda92013-07-29 11:22:23 -0400140 else:
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500141 self.identity_admin_client.users.delete(user)
Matthew Treinishb86cda92013-07-29 11:22:23 -0400142
143 def _delete_tenant(self, tenant):
144 if self.tempest_client:
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500145 self.identity_admin_client.delete_tenant(tenant)
Matthew Treinishb86cda92013-07-29 11:22:23 -0400146 else:
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500147 self.identity_admin_client.tenants.delete(tenant)
Matthew Treinishb86cda92013-07-29 11:22:23 -0400148
149 def _create_creds(self, suffix=None, admin=False):
150 rand_name_root = rand_name(self.name)
151 if suffix:
152 rand_name_root += suffix
153 tenant_name = rand_name_root + "-tenant"
154 tenant_desc = tenant_name + "-desc"
155 rand_name_root = rand_name(self.name)
156 tenant = self._create_tenant(name=tenant_name,
157 description=tenant_desc)
158 if suffix:
159 rand_name_root += suffix
160 username = rand_name_root + "-user"
161 email = rand_name_root + "@example.com"
162 user = self._create_user(username, self.password,
163 tenant, email)
164 if admin:
165 role = None
166 try:
167 roles = self._list_roles()
Russell Sim7f894a52013-09-13 10:35:21 +1000168 admin_role = self.config.identity.admin_role
Matthew Treinishb86cda92013-07-29 11:22:23 -0400169 if self.tempest_client:
Russell Sim7f894a52013-09-13 10:35:21 +1000170 role = next(r for r in roles if r['name'] == admin_role)
Matthew Treinishb86cda92013-07-29 11:22:23 -0400171 else:
Russell Sim7f894a52013-09-13 10:35:21 +1000172 role = next(r for r in roles if r.name == admin_role)
Matthew Treinishb86cda92013-07-29 11:22:23 -0400173 except StopIteration:
174 msg = "No admin role found"
175 raise exceptions.NotFound(msg)
176 if self.tempest_client:
177 self._assign_user_role(tenant['id'], user['id'], role['id'])
178 else:
179 self._assign_user_role(tenant.id, user.id, role.id)
180 return user, tenant
181
182 def _get_cred_names(self, user, tenant):
183 if self.tempest_client:
184 username = user.get('name')
185 tenant_name = tenant.get('name')
186 else:
187 username = user.name
188 tenant_name = tenant.name
189 return username, tenant_name
190
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500191 def _get_tenant_id(self, tenant):
192 if self.tempest_client:
193 return tenant.get('id')
194 else:
195 return tenant.id
196
197 def _create_network_resources(self, tenant_id):
198 network = None
199 subnet = None
200 router = None
201 rand_name_root = rand_name(self.name)
202 network_name = rand_name_root + "-network"
203 network = self._create_network(network_name, tenant_id)
204 try:
205 subnet_name = rand_name_root + "-subnet"
206 subnet = self._create_subnet(subnet_name, tenant_id, network['id'])
207 router_name = rand_name_root + "-router"
208 router = self._create_router(router_name, tenant_id)
209 self._add_router_interface(router['id'], subnet['id'])
210 except Exception:
211 if router:
212 self._clear_isolated_router(router['id'], router['name'])
213 if subnet:
214 self._clear_isolated_subnet(subnet['id'], subnet['name'])
215 if network:
216 self._clear_isolated_network(network['id'], network['name'])
217 raise
218 return network, subnet, router
219
220 def _create_network(self, name, tenant_id):
221 if self.tempest_client:
222 resp, resp_body = self.network_admin_client.create_network(
223 name, tenant_id=tenant_id)
224 else:
225 body = {'network': {'tenant_id': tenant_id, 'name': name}}
226 resp_body = self.network_admin_client.create_network(body)
227 return resp_body['network']
228
229 def _create_subnet(self, subnet_name, tenant_id, network_id):
230 if not self.tempest_client:
231 body = {'subnet': {'name': subnet_name, 'tenant_id': tenant_id,
232 'network_id': network_id, 'ip_version': 4}}
233 base_cidr = netaddr.IPNetwork(self.config.network.tenant_network_cidr)
234 mask_bits = self.config.network.tenant_network_mask_bits
235 for subnet_cidr in base_cidr.subnet(mask_bits):
236 try:
237 if self.tempest_client:
238 resp, resp_body = self.network_admin_client.create_subnet(
239 network_id, str(subnet_cidr), name=subnet_name,
240 tenant_id=tenant_id)
241 else:
242 body['subnet']['cidr'] = str(subnet_cidr)
243 resp_body = self.network_admin_client.create_subnet(body)
244 break
245 except exceptions.BadRequest as e:
246 if 'overlaps with another subnet' not in str(e):
247 raise
248 else:
249 e = exceptions.BuildErrorException()
250 e.message = 'Available CIDR for subnet creation could not be found'
251 raise e
252 return resp_body['subnet']
253
254 def _create_router(self, router_name, tenant_id):
255 external_net_id = dict(
256 network_id=self.config.network.public_network_id)
257 if self.tempest_client:
258 resp, resp_body = self.network_admin_client.create_router(
259 router_name,
260 external_gateway_info=external_net_id,
261 tenant_id=tenant_id)
262 else:
263 body = {'router': {'name': router_name, 'tenant_id': tenant_id,
264 'external_gateway_info': external_net_id,
265 'admin_state_up': True}}
266 resp_body = self.network_admin_client.create_router(body)
267 return resp_body['router']
268
269 def _add_router_interface(self, router_id, subnet_id):
270 if self.tempest_client:
271 self.network_admin_client.add_router_interface_with_subnet_id(
272 router_id, subnet_id)
273 else:
274 body = {'subnet_id': subnet_id}
275 self.network_admin_client.add_interface_router(router_id, body)
276
Matthew Treinishb86cda92013-07-29 11:22:23 -0400277 def get_primary_tenant(self):
278 return self.isolated_creds.get('primary')[1]
279
280 def get_primary_user(self):
281 return self.isolated_creds.get('primary')[0]
282
283 def get_alt_tenant(self):
284 return self.isolated_creds.get('alt')[1]
285
286 def get_alt_user(self):
287 return self.isolated_creds.get('alt')[0]
288
289 def get_admin_tenant(self):
290 return self.isolated_creds.get('admin')[1]
291
292 def get_admin_user(self):
293 return self.isolated_creds.get('admin')[0]
294
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500295 def get_primary_network(self):
296 return self.isolated_net_resources.get('primary')[0]
297
298 def get_primary_subnet(self):
299 return self.isolated_net_resources.get('primary')[1]
300
301 def get_primary_router(self):
302 return self.isolated_net_resources.get('primary')[2]
303
304 def get_admin_network(self):
305 return self.isolated_net_resources.get('admin')[0]
306
307 def get_admin_subnet(self):
308 return self.isolated_net_resources.get('admin')[1]
309
310 def get_admin_router(self):
311 return self.isolated_net_resources.get('admin')[2]
312
313 def get_alt_network(self):
314 return self.isolated_net_resources.get('alt')[0]
315
316 def get_alt_subnet(self):
317 return self.isolated_net_resources.get('alt')[1]
318
319 def get_alt_router(self):
320 return self.isolated_net_resources.get('alt')[2]
321
Matthew Treinishb86cda92013-07-29 11:22:23 -0400322 def get_primary_creds(self):
323 if self.isolated_creds.get('primary'):
324 user, tenant = self.isolated_creds['primary']
325 username, tenant_name = self._get_cred_names(user, tenant)
326 else:
327 user, tenant = self._create_creds()
328 username, tenant_name = self._get_cred_names(user, tenant)
329 self.isolated_creds['primary'] = (user, tenant)
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500330 LOG.info("Acquired isolated creds:\n user: %s, tenant: %s"
Matthew Treinishb86cda92013-07-29 11:22:23 -0400331 % (username, tenant_name))
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500332 if self.config.service_available.neutron:
333 network, subnet, router = self._create_network_resources(
334 self._get_tenant_id(tenant))
335 self.isolated_net_resources['primary'] = (
336 network, subnet, router,)
337 LOG.info("Created isolated network resources for : \n"
338 + " user: %s, tenant: %s" % (username, tenant_name))
Matthew Treinishb86cda92013-07-29 11:22:23 -0400339 return username, tenant_name, self.password
340
341 def get_admin_creds(self):
342 if self.isolated_creds.get('admin'):
343 user, tenant = self.isolated_creds['admin']
344 username, tenant_name = self._get_cred_names(user, tenant)
345 else:
346 user, tenant = self._create_creds(admin=True)
347 username, tenant_name = self._get_cred_names(user, tenant)
348 self.isolated_creds['admin'] = (user, tenant)
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500349 LOG.info("Acquired admin isolated creds:\n user: %s, tenant: %s"
Matthew Treinishb86cda92013-07-29 11:22:23 -0400350 % (username, tenant_name))
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500351 if self.config.service_available.neutron:
352 network, subnet, router = self._create_network_resources(
353 self._get_tenant_id(tenant))
354 self.isolated_net_resources['admin'] = (
355 network, subnet, router,)
356 LOG.info("Created isolated network resources for : \n"
357 + " user: %s, tenant: %s" % (username, tenant_name))
358 return username, tenant_name, self.password
Matthew Treinishb86cda92013-07-29 11:22:23 -0400359
360 def get_alt_creds(self):
361 if self.isolated_creds.get('alt'):
362 user, tenant = self.isolated_creds['alt']
363 username, tenant_name = self._get_cred_names(user, tenant)
364 else:
365 user, tenant = self._create_creds()
366 username, tenant_name = self._get_cred_names(user, tenant)
367 self.isolated_creds['alt'] = (user, tenant)
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500368 LOG.info("Acquired alt isolated creds:\n user: %s, tenant: %s"
Matthew Treinishb86cda92013-07-29 11:22:23 -0400369 % (username, tenant_name))
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500370 if self.config.service_available.neutron:
371 network, subnet, router = self._create_network_resources(
372 self._get_tenant_id(tenant))
373 self.isolated_net_resources['alt'] = (
374 network, subnet, router,)
375 LOG.info("Created isolated network resources for : \n"
376 + " user: %s, tenant: %s" % (username, tenant_name))
Matthew Treinishb86cda92013-07-29 11:22:23 -0400377 return username, tenant_name, self.password
378
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500379 def _clear_isolated_router(self, router_id, router_name):
380 net_client = self.network_admin_client
381 try:
382 net_client.delete_router(router_id)
383 except exceptions.NotFound:
384 LOG.warn('router with name: %s not found for delete' %
385 router_name)
386 pass
387
388 def _clear_isolated_subnet(self, subnet_id, subnet_name):
389 net_client = self.network_admin_client
390 try:
391 net_client.delete_subnet(subnet_id)
392 except exceptions.NotFound:
393 LOG.warn('subnet with name: %s not found for delete' %
394 subnet_name)
395 pass
396
397 def _clear_isolated_network(self, network_id, network_name):
398 net_client = self.network_admin_client
399 try:
400 net_client.delete_network(network_id)
401 except exceptions.NotFound:
402 LOG.warn('network with name: %s not found for delete' %
403 network_name)
404 pass
405
406 def _cleanup_ports(self, network_id):
407 # TODO(mlavalle) This method will be removed once patch
408 # https://review.openstack.org/#/c/46563/ merges in Neutron
409 if not self.ports:
410 if self.tempest_client:
411 resp, resp_body = self.network_admin_client.list_ports()
412 else:
413 resp_body = self.network_admin_client.list_ports()
414 self.ports = resp_body['ports']
415 ports_to_delete = [
416 port for port in self.ports if port['network_id'] == network_id]
417 for port in ports_to_delete:
418 try:
419 LOG.info('Cleaning up port id %s, name %s' %
420 (port['id'], port['name']))
421 self.network_admin_client.delete_port(port['id'])
422 except exceptions.NotFound:
423 LOG.warn('Port id: %s, name %s not found for clean-up' %
424 (port['id'], port['name']))
425
426 def _clear_isolated_net_resources(self):
427 net_client = self.network_admin_client
428 for cred in self.isolated_net_resources:
429 network, subnet, router = self.isolated_net_resources.get(cred)
430 try:
431 if self.tempest_client:
432 net_client.remove_router_interface_with_subnet_id(
433 router['id'], subnet['id'])
434 else:
435 body = {'subnet_id': subnet['id']}
436 net_client.remove_interface_router(router['id'], body)
437 except exceptions.NotFound:
438 LOG.warn('router with name: %s not found for delete' %
439 router['name'])
440 pass
441 self._clear_isolated_router(router['id'], router['name'])
442 # TODO(mlavalle) This method call will be removed once patch
443 # https://review.openstack.org/#/c/46563/ merges in Neutron
444 self._cleanup_ports(network['id'])
445 self._clear_isolated_subnet(subnet['id'], subnet['name'])
446 self._clear_isolated_network(network['id'], network['name'])
447 LOG.info("Cleared isolated network resources: \n"
448 + " network: %s, subnet: %s, router: %s"
449 % (network['name'], subnet['name'], router['name']))
450
Matthew Treinishb86cda92013-07-29 11:22:23 -0400451 def clear_isolated_creds(self):
452 if not self.isolated_creds:
453 return
Miguel Lavalleb8fabc52013-08-23 11:19:57 -0500454 self._clear_isolated_net_resources()
Matthew Treinishb86cda92013-07-29 11:22:23 -0400455 for cred in self.isolated_creds:
456 user, tenant = self.isolated_creds.get(cred)
457 try:
458 if self.tempest_client:
459 self._delete_user(user['id'])
460 else:
461 self._delete_user(user.id)
462 except exceptions.NotFound:
463 if self.tempest_client:
464 name = user['name']
465 else:
466 name = user.name
467 LOG.warn("user with name: %s not found for delete" % name)
468 pass
469 try:
470 if self.tempest_client:
471 self._delete_tenant(tenant['id'])
472 else:
473 self._delete_tenant(tenant.id)
474 except exceptions.NotFound:
475 if self.tempest_client:
476 name = tenant['name']
477 else:
478 name = tenant.name
479 LOG.warn("tenant with name: %s not found for delete" % name)
480 pass