blob: 4137ec378ebc253a10568e9f1d3a4130d7dd5fc0 [file] [log] [blame]
Jay Pipes051075a2012-04-28 17:39:37 -04001# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2012 OpenStack, LLC
4# All Rights Reserved.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17
18import logging
19
20# Default client libs
Brian Waldonc9b99a22012-09-10 09:24:35 -070021import glanceclient
Maru Newbydec13ec2012-08-30 11:19:17 -070022import keystoneclient.v2_0.client
23import novaclient.client
Dan Princebff52232012-10-10 11:40:55 -040024try:
25 import quantumclient.v2_0.client
26except ImportError:
27 pass
Jay Pipes051075a2012-04-28 17:39:37 -040028
29import tempest.config
30from tempest import exceptions
31# Tempest REST Fuzz testing client libs
Matthew Treinisha83a16e2012-12-07 13:44:02 -050032from tempest.services.compute.json import console_output_client
33from tempest.services.compute.json import extensions_client
34from tempest.services.compute.json import flavors_client
35from tempest.services.compute.json import floating_ips_client
36from tempest.services.compute.json import images_client
37from tempest.services.compute.json import keypairs_client
38from tempest.services.compute.json import limits_client
39from tempest.services.compute.json import quotas_client
40from tempest.services.compute.json import security_groups_client
41from tempest.services.compute.json import servers_client
42from tempest.services.compute.json import volumes_extensions_client
Jay Pipes051075a2012-04-28 17:39:37 -040043from tempest.services.network.json import network_client
Rohit Karajgidd47d7e2012-07-31 04:11:01 -070044from tempest.services.volume.json import volumes_client
Jay Pipes051075a2012-04-28 17:39:37 -040045
46NetworkClient = network_client.NetworkClient
Mauro S. M. Rodrigues6e373242012-08-27 18:59:19 -040047ImagesClient = images_client.ImagesClientJSON
Tiago Melloeda03b52012-08-22 23:47:29 -030048FlavorsClient = flavors_client.FlavorsClientJSON
Dan Smithcf8fab62012-08-14 08:03:48 -070049ServersClient = servers_client.ServersClientJSON
Matthew Treinish33634462012-08-16 16:51:23 -040050LimitsClient = limits_client.LimitsClientJSON
Tiago Mello89126c32012-08-27 11:14:03 -030051ExtensionsClient = extensions_client.ExtensionsClientJSON
Vincent Hou22f03c72012-08-24 17:55:13 +080052FloatingIPsClient = floating_ips_client.FloatingIPsClientJSON
Vincent Houead03dc2012-08-24 21:35:11 +080053SecurityGroupsClient = security_groups_client.SecurityGroupsClientJSON
Mauro S. M. Rodriguesa636f532012-08-21 11:07:53 -040054KeyPairsClient = keypairs_client.KeyPairsClientJSON
Matthew Treinish4e086902012-08-17 17:52:22 -040055VolumesExtensionsClient = volumes_extensions_client.VolumesExtensionsClientJSON
Matthew Treinish9854d5b2012-09-20 10:22:13 -040056VolumesClient = volumes_client.VolumesClientJSON
rajalakshmi-ganesand793d692012-12-25 12:54:50 +053057ConsoleOutputsClient = console_output_client.ConsoleOutputsClientJSON
Rohit Karajgi07599c52012-11-02 05:35:16 -070058QuotasClient = quotas_client.QuotasClient
Jay Pipes051075a2012-04-28 17:39:37 -040059
60LOG = logging.getLogger(__name__)
61
62
63class Manager(object):
64
65 """
66 Base manager class
67
68 Manager objects are responsible for providing a configuration object
69 and a client object for a test case to use in performing actions.
70 """
71
72 def __init__(self):
73 self.config = tempest.config.TempestConfig()
Maru Newbydec13ec2012-08-30 11:19:17 -070074 self.client_attr_names = []
Jay Pipes051075a2012-04-28 17:39:37 -040075
76
77class FuzzClientManager(Manager):
78
79 """
80 Manager class that indicates the client provided by the manager
81 is a fuzz-testing client that Tempest contains. These fuzz-testing
82 clients are used to be able to throw random or invalid data at
83 an endpoint and check for appropriate error messages returned
84 from the endpoint.
85 """
86 pass
87
88
Maru Newbydec13ec2012-08-30 11:19:17 -070089class DefaultClientManager(Manager):
Jay Pipes051075a2012-04-28 17:39:37 -040090
91 """
Maru Newbydec13ec2012-08-30 11:19:17 -070092 Manager that provides the default clients to access the various
93 OpenStack APIs.
Jay Pipes051075a2012-04-28 17:39:37 -040094 """
95
96 NOVACLIENT_VERSION = '2'
97
98 def __init__(self):
Maru Newbydec13ec2012-08-30 11:19:17 -070099 super(DefaultClientManager, self).__init__()
100 self.compute_client = self._get_compute_client()
101 self.image_client = self._get_image_client()
102 self.identity_client = self._get_identity_client()
103 self.network_client = self._get_network_client()
104 self.client_attr_names = [
105 'compute_client',
106 'image_client',
107 'identity_client',
108 'network_client',
Zhongyue Luo30a563f2012-09-30 23:43:50 +0900109 ]
Maru Newbydec13ec2012-08-30 11:19:17 -0700110
111 def _get_compute_client(self, username=None, password=None,
112 tenant_name=None):
113 # Novaclient will not execute operations for anyone but the
114 # identified user, so a new client needs to be created for
115 # each user that operations need to be performed for.
116 if not username:
Attila Fazekascadcb1f2013-01-21 23:10:53 +0100117 username = self.config.identity.username
Maru Newbydec13ec2012-08-30 11:19:17 -0700118 if not password:
Attila Fazekascadcb1f2013-01-21 23:10:53 +0100119 password = self.config.identity.password
Maru Newbydec13ec2012-08-30 11:19:17 -0700120 if not tenant_name:
Attila Fazekascadcb1f2013-01-21 23:10:53 +0100121 tenant_name = self.config.identity.tenant_name
Jay Pipes051075a2012-04-28 17:39:37 -0400122
123 if None in (username, password, tenant_name):
Maru Newbydec13ec2012-08-30 11:19:17 -0700124 msg = ("Missing required credentials for compute client. "
Jay Pipes051075a2012-04-28 17:39:37 -0400125 "username: %(username)s, password: %(password)s, "
126 "tenant_name: %(tenant_name)s") % locals()
127 raise exceptions.InvalidConfiguration(msg)
128
Jay Pipes7c88eb22013-01-16 21:32:43 -0500129 auth_url = self.config.identity.uri
Jay Pipescd8eaec2013-01-16 21:03:48 -0500130 dscv = self.config.identity.disable_ssl_certificate_validation
Jay Pipes051075a2012-04-28 17:39:37 -0400131
132 client_args = (username, password, tenant_name, auth_url)
133
134 # Create our default Nova client to use in testing
Jay Pipes444c3e62012-10-04 19:26:35 -0400135 service_type = self.config.compute.catalog_type
Maru Newbydec13ec2012-08-30 11:19:17 -0700136 return novaclient.client.Client(self.NOVACLIENT_VERSION,
Zhongyue Luo79d8d362012-09-25 13:49:27 +0800137 *client_args,
138 service_type=service_type,
Jay Pipescd8eaec2013-01-16 21:03:48 -0500139 no_cache=True,
140 insecure=dscv)
Jay Pipes051075a2012-04-28 17:39:37 -0400141
Maru Newbydec13ec2012-08-30 11:19:17 -0700142 def _get_image_client(self):
Brian Waldonc9b99a22012-09-10 09:24:35 -0700143 keystone = self._get_identity_client()
144 token = keystone.auth_token
145 endpoint = keystone.service_catalog.url_for(service_type='image',
146 endpoint_type='publicURL')
Jay Pipescd8eaec2013-01-16 21:03:48 -0500147 dscv = self.config.identity.disable_ssl_certificate_validation
148 return glanceclient.Client('1', endpoint=endpoint, token=token,
149 insecure=dscv)
Maru Newbydec13ec2012-08-30 11:19:17 -0700150
Maru Newby81f07a02012-09-05 20:21:19 -0700151 def _get_identity_client(self, username=None, password=None,
152 tenant_name=None):
Maru Newbydec13ec2012-08-30 11:19:17 -0700153 # This identity client is not intended to check the security
Maru Newby81f07a02012-09-05 20:21:19 -0700154 # of the identity service, so use admin credentials by default.
155 if not username:
Attila Fazekascadcb1f2013-01-21 23:10:53 +0100156 username = self.config.identity.admin_username
Maru Newby81f07a02012-09-05 20:21:19 -0700157 if not password:
Attila Fazekascadcb1f2013-01-21 23:10:53 +0100158 password = self.config.identity.admin_password
Maru Newby81f07a02012-09-05 20:21:19 -0700159 if not tenant_name:
Attila Fazekascadcb1f2013-01-21 23:10:53 +0100160 tenant_name = self.config.identity.admin_tenant_name
Maru Newbydec13ec2012-08-30 11:19:17 -0700161
162 if None in (username, password, tenant_name):
163 msg = ("Missing required credentials for identity client. "
164 "username: %(username)s, password: %(password)s, "
165 "tenant_name: %(tenant_name)s") % locals()
166 raise exceptions.InvalidConfiguration(msg)
167
Jay Pipes7c88eb22013-01-16 21:32:43 -0500168 auth_url = self.config.identity.uri
Jay Pipescd8eaec2013-01-16 21:03:48 -0500169 dscv = self.config.identity.disable_ssl_certificate_validation
Maru Newbydec13ec2012-08-30 11:19:17 -0700170
171 return keystoneclient.v2_0.client.Client(username=username,
172 password=password,
173 tenant_name=tenant_name,
Jay Pipescd8eaec2013-01-16 21:03:48 -0500174 auth_url=auth_url,
175 insecure=dscv)
Maru Newbydec13ec2012-08-30 11:19:17 -0700176
177 def _get_network_client(self):
Maru Newbyb72f37c2012-12-14 02:17:06 +0000178 # The intended configuration is for the network client to have
179 # admin privileges and indicate for whom resources are being
180 # created via a 'tenant_id' parameter. This will often be
181 # preferable to authenticating as a specific user because
182 # working with certain resources (public routers and networks)
183 # often requires admin privileges anyway.
Attila Fazekascadcb1f2013-01-21 23:10:53 +0100184 username = self.config.identity.admin_username
185 password = self.config.identity.admin_password
186 tenant_name = self.config.identity.admin_tenant_name
Maru Newbydec13ec2012-08-30 11:19:17 -0700187
188 if None in (username, password, tenant_name):
189 msg = ("Missing required credentials for network client. "
190 "username: %(username)s, password: %(password)s, "
191 "tenant_name: %(tenant_name)s") % locals()
192 raise exceptions.InvalidConfiguration(msg)
193
Jay Pipes7c88eb22013-01-16 21:32:43 -0500194 auth_url = self.config.identity.uri
Jay Pipescd8eaec2013-01-16 21:03:48 -0500195 dscv = self.config.identity.disable_ssl_certificate_validation
Maru Newbydec13ec2012-08-30 11:19:17 -0700196
197 return quantumclient.v2_0.client.Client(username=username,
198 password=password,
199 tenant_name=tenant_name,
Jay Pipescd8eaec2013-01-16 21:03:48 -0500200 auth_url=auth_url,
201 insecure=dscv)
Jay Pipes051075a2012-04-28 17:39:37 -0400202
203
204class ComputeFuzzClientManager(FuzzClientManager):
205
206 """
207 Manager that uses the Tempest REST client that can send
208 random or invalid data at the OpenStack Compute API
209 """
210
211 def __init__(self, username=None, password=None, tenant_name=None):
212 """
213 We allow overriding of the credentials used within the various
214 client classes managed by the Manager object. Left as None, the
215 standard username/password/tenant_name is used.
216
217 :param username: Override of the username
218 :param password: Override of the password
219 :param tenant_name: Override of the tenant name
220 """
221 super(ComputeFuzzClientManager, self).__init__()
222
223 # If no creds are provided, we fall back on the defaults
224 # in the config file for the Compute API.
Attila Fazekascadcb1f2013-01-21 23:10:53 +0100225 username = username or self.config.identity.username
226 password = password or self.config.identity.password
227 tenant_name = tenant_name or self.config.identity.tenant_name
Jay Pipes051075a2012-04-28 17:39:37 -0400228
229 if None in (username, password, tenant_name):
230 msg = ("Missing required credentials. "
231 "username: %(username)s, password: %(password)s, "
232 "tenant_name: %(tenant_name)s") % locals()
233 raise exceptions.InvalidConfiguration(msg)
234
Jay Pipes7c88eb22013-01-16 21:32:43 -0500235 auth_url = self.config.identity.uri
236
237 # Ensure /tokens is in the URL for Keystone...
238 if 'tokens' not in auth_url:
239 auth_url = auth_url.rstrip('/') + '/tokens'
Jay Pipes051075a2012-04-28 17:39:37 -0400240
241 if self.config.identity.strategy == 'keystone':
242 client_args = (self.config, username, password, auth_url,
243 tenant_name)
244 else:
245 client_args = (self.config, username, password, auth_url)
246
247 self.servers_client = ServersClient(*client_args)
248 self.flavors_client = FlavorsClient(*client_args)
249 self.images_client = ImagesClient(*client_args)
250 self.limits_client = LimitsClient(*client_args)
251 self.extensions_client = ExtensionsClient(*client_args)
252 self.keypairs_client = KeyPairsClient(*client_args)
253 self.security_groups_client = SecurityGroupsClient(*client_args)
254 self.floating_ips_client = FloatingIPsClient(*client_args)
Rohit Karajgidd47d7e2012-07-31 04:11:01 -0700255 self.volumes_extensions_client = VolumesExtensionsClient(*client_args)
Jay Pipes051075a2012-04-28 17:39:37 -0400256 self.volumes_client = VolumesClient(*client_args)
257 self.console_outputs_client = ConsoleOutputsClient(*client_args)
Rohit Karajgi07599c52012-11-02 05:35:16 -0700258 self.quotas_client = QuotasClient(*client_args)
Jay Pipes051075a2012-04-28 17:39:37 -0400259 self.network_client = NetworkClient(*client_args)
260
261
262class ComputeFuzzClientAltManager(Manager):
263
264 """
265 Manager object that uses the alt_XXX credentials for its
266 managed client objects
267 """
268
269 def __init__(self):
270 conf = tempest.config.TempestConfig()
271 super(ComputeFuzzClientAltManager, self).__init__(
Attila Fazekascadcb1f2013-01-21 23:10:53 +0100272 conf.identity.alt_username,
273 conf.identity.alt_password,
274 conf.identity.alt_tenant_name)
Jay Pipes051075a2012-04-28 17:39:37 -0400275
276
277class ComputeFuzzClientAdminManager(Manager):
278
279 """
280 Manager object that uses the alt_XXX credentials for its
281 managed client objects
282 """
283
284 def __init__(self):
285 conf = tempest.config.TempestConfig()
286 super(ComputeFuzzClientAdminManager, self).__init__(
rajalakshmi-ganesand793d692012-12-25 12:54:50 +0530287 conf.compute_admin.username,
288 conf.compute_admin.password,
289 conf.compute_admin.tenant_name)