blob: efac5f5a335415abaed9d11bd65c95cb2f0be688 [file] [log] [blame]
ZhiQiang Fan39f97222013-09-20 04:49:44 +08001# Copyright 2012 OpenStack Foundation
dwalleck5d734432012-10-04 01:11:47 -05002# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
16import json
Matthew Treinish26dd0fa2012-12-04 17:14:37 -050017import urllib
dwalleck5d734432012-10-04 01:11:47 -050018
Mate Lakat23a58a32013-08-23 02:06:22 +010019from tempest.common import http
dwalleck5d734432012-10-04 01:11:47 -050020from tempest.common.rest_client import RestClient
Matthew Treinish684d8992014-01-30 16:27:40 +000021from tempest import config
harika-vakadi2daed0a2013-01-01 20:51:39 +053022from tempest import exceptions
dwalleck5d734432012-10-04 01:11:47 -050023
Matthew Treinish684d8992014-01-30 16:27:40 +000024CONF = config.CONF
25
dwalleck5d734432012-10-04 01:11:47 -050026
27class AccountClient(RestClient):
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000028 def __init__(self, auth_provider):
29 super(AccountClient, self).__init__(auth_provider)
Matthew Treinish684d8992014-01-30 16:27:40 +000030 self.service = CONF.object_storage.catalog_type
dwalleck5d734432012-10-04 01:11:47 -050031 self.format = 'json'
32
Daisuke Morita499bba32013-11-28 18:44:49 +090033 def create_account(self, data=None,
34 params=None,
35 metadata={},
36 remove_metadata={},
37 metadata_prefix='X-Account-Meta-',
38 remove_metadata_prefix='X-Remove-Account-Meta-'):
39 """Create an account."""
40 url = ''
41 if params:
42 url += '?%s' % urllib.urlencode(params)
43
44 headers = {}
45 for key in metadata:
46 headers[metadata_prefix + key] = metadata[key]
47 for key in remove_metadata:
48 headers[remove_metadata_prefix + key] = remove_metadata[key]
49
50 resp, body = self.put(url, data, headers)
51 return resp, body
52
53 def delete_account(self, data=None, params=None):
54 """Delete an account."""
55 url = ''
56 if params:
57 if 'bulk-delete' in params:
58 url += 'bulk-delete&'
59 url = '?%s%s' % (url, urllib.urlencode(params))
60
vponomaryov67b58fe2014-02-06 19:05:41 +020061 resp, body = self.delete(url, headers={}, body=data)
Daisuke Morita499bba32013-11-28 18:44:49 +090062 return resp, body
63
dwalleck5d734432012-10-04 01:11:47 -050064 def list_account_metadata(self):
65 """
66 HEAD on the storage URL
67 Returns all account metadata headers
68 """
Chmouel Boudjnahdcf40ea2014-01-06 18:35:34 -080069 resp, body = self.head('')
dwalleck5d734432012-10-04 01:11:47 -050070 return resp, body
71
72 def create_account_metadata(self, metadata,
73 metadata_prefix='X-Account-Meta-'):
Sean Daguef237ccb2013-01-04 15:19:14 -050074 """Creates an account metadata entry."""
dwalleck5d734432012-10-04 01:11:47 -050075 headers = {}
76 for key in metadata:
77 headers[metadata_prefix + key] = metadata[key]
78
79 resp, body = self.post('', headers=headers, body=None)
80 return resp, body
81
Larisa Ustalov6c3c7802012-11-05 12:25:19 +020082 def delete_account_metadata(self, metadata,
83 metadata_prefix='X-Remove-Account-Meta-'):
84 """
85 Deletes an account metadata entry.
86 """
87
Chmouel Boudjnahdcf40ea2014-01-06 18:35:34 -080088 headers = {}
Larisa Ustalov6c3c7802012-11-05 12:25:19 +020089 for item in metadata:
90 headers[metadata_prefix + item] = 'x'
91 resp, body = self.post('', headers=headers, body=None)
92 return resp, body
93
dwalleck5d734432012-10-04 01:11:47 -050094 def list_account_containers(self, params=None):
95 """
96 GET on the (base) storage URL
Chmouel Boudjnahdcf40ea2014-01-06 18:35:34 -080097 Given valid X-Auth-Token, returns a list of all containers for the
98 account.
dwalleck5d734432012-10-04 01:11:47 -050099
100 Optional Arguments:
101 limit=[integer value N]
102 Limits the number of results to at most N values
103 DEFAULT: 10,000
104
105 marker=[string value X]
106 Given string value X, return object names greater in value
107 than the specified marker.
108 DEFAULT: No Marker
109
110 format=[string value, either 'json' or 'xml']
111 Specify either json or xml to return the respective serialized
112 response.
113 DEFAULT: Python-List returned in response body
114 """
115
Matthew Treinish26dd0fa2012-12-04 17:14:37 -0500116 if params:
Fabien Boucherfaab4312013-08-06 15:36:23 +0200117 if 'format' not in params:
118 params['format'] = self.format
119 else:
120 params = {'format': self.format}
dwalleck5d734432012-10-04 01:11:47 -0500121
Fabien Boucherfaab4312013-08-06 15:36:23 +0200122 url = '?' + urllib.urlencode(params)
dwalleck5d734432012-10-04 01:11:47 -0500123 resp, body = self.get(url)
Daisuke Morita499bba32013-11-28 18:44:49 +0900124
125 if params and params.get('format') == 'json':
126 body = json.loads(body)
dwalleck5d734432012-10-04 01:11:47 -0500127 return resp, body
harika-vakadi2daed0a2013-01-01 20:51:39 +0530128
Joe H. Rahme9e07bf02014-01-13 18:58:02 +0100129 def list_extensions(self):
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000130 self.skip_path()
Joe H. Rahme9e07bf02014-01-13 18:58:02 +0100131 resp, body = self.get('info')
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000132 self.reset_path()
Joe H. Rahme9e07bf02014-01-13 18:58:02 +0100133 body = json.loads(body)
134 return resp, body
135
harika-vakadi2daed0a2013-01-01 20:51:39 +0530136
137class AccountClientCustomizedHeader(RestClient):
138
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000139 # TODO(andreaf) This class is now redundant, to be removed in next patch
140
141 def __init__(self, auth_provider):
142 super(AccountClientCustomizedHeader, self).__init__(
143 auth_provider)
Attila Fazekasa8b5fe72013-08-01 16:59:06 +0200144 # Overwrites json-specific header encoding in RestClient
Matthew Treinish684d8992014-01-30 16:27:40 +0000145 self.service = CONF.object_storage.catalog_type
harika-vakadi2daed0a2013-01-01 20:51:39 +0530146 self.format = 'json'
147
Attila Fazekasb8aa7592013-01-26 01:25:45 +0100148 def request(self, method, url, headers=None, body=None):
harika-vakadi2daed0a2013-01-01 20:51:39 +0530149 """A simple HTTP request interface."""
Mate Lakat23a58a32013-08-23 02:06:22 +0100150 self.http_obj = http.ClosingHttp()
harika-vakadi2daed0a2013-01-01 20:51:39 +0530151 if headers is None:
152 headers = {}
harika-vakadi2daed0a2013-01-01 20:51:39 +0530153
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000154 # Authorize the request
155 req_url, req_headers, req_body = self.auth_provider.auth_request(
156 method=method, url=url, headers=headers, body=body,
157 filters=self.filters
158 )
Attila Fazekas11d2a772013-01-29 17:46:52 +0100159 self._log_request(method, req_url, headers, body)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000160 # use original body
harika-vakadi2daed0a2013-01-01 20:51:39 +0530161 resp, resp_body = self.http_obj.request(req_url, method,
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000162 headers=req_headers,
163 body=req_body)
Attila Fazekas11d2a772013-01-29 17:46:52 +0100164 self._log_response(resp, resp_body)
harika-vakadi2daed0a2013-01-01 20:51:39 +0530165
166 if resp.status == 401 or resp.status == 403:
harika-vakadi2daed0a2013-01-01 20:51:39 +0530167 raise exceptions.Unauthorized()
168
169 return resp, resp_body
170
171 def list_account_containers(self, params=None, metadata=None):
172 """
173 GET on the (base) storage URL
Chmouel Boudjnahdcf40ea2014-01-06 18:35:34 -0800174 Given a valid X-Auth-Token, returns a list of all containers for the
175 account.
harika-vakadi2daed0a2013-01-01 20:51:39 +0530176
177 Optional Arguments:
178 limit=[integer value N]
179 Limits the number of results to at most N values
180 DEFAULT: 10,000
181
182 marker=[string value X]
183 Given string value X, return object names greater in value
184 than the specified marker.
185 DEFAULT: No Marker
186
187 format=[string value, either 'json' or 'xml']
188 Specify either json or xml to return the respective serialized
189 response.
190 DEFAULT: Python-List returned in response body
191 """
192
193 url = '?format=%s' % self.format
194 if params:
195 url += '&%s' + urllib.urlencode(params)
196
197 headers = {}
198 if metadata:
199 for key in metadata:
200 headers[str(key)] = metadata[key]
201
202 resp, body = self.get(url, headers=headers)
203 return resp, body