blob: 77d29a5814e9c737260f350d956f7ebbeecb094a [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
Daisuke Morita2c87d372013-10-31 19:39:19 +090016import urllib
17
Mate Lakat23a58a32013-08-23 02:06:22 +010018from tempest.common import http
Eiichi Aikawaca3d9bd2014-03-06 15:06:21 +090019from tempest.common import rest_client
Matthew Treinish684d8992014-01-30 16:27:40 +000020from tempest import config
harika-vakadi6ab397b2012-12-20 12:16:17 +053021from tempest import exceptions
dwalleck5d734432012-10-04 01:11:47 -050022
Matthew Treinish684d8992014-01-30 16:27:40 +000023CONF = config.CONF
24
dwalleck5d734432012-10-04 01:11:47 -050025
Eiichi Aikawaca3d9bd2014-03-06 15:06:21 +090026class ObjectClient(rest_client.RestClient):
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000027 def __init__(self, auth_provider):
28 super(ObjectClient, self).__init__(auth_provider)
dwalleck5d734432012-10-04 01:11:47 -050029
Matthew Treinish684d8992014-01-30 16:27:40 +000030 self.service = CONF.object_storage.catalog_type
dwalleck5d734432012-10-04 01:11:47 -050031
Daisuke Morita2c87d372013-10-31 19:39:19 +090032 def create_object(self, container, object_name, data, params=None):
Sean Daguef237ccb2013-01-04 15:19:14 -050033 """Create storage object."""
dwalleck5d734432012-10-04 01:11:47 -050034
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +020035 headers = self.get_headers()
Martina Kollarova03720a52013-06-18 15:08:46 +020036 if not data:
37 headers['content-length'] = '0'
dwalleck5d734432012-10-04 01:11:47 -050038 url = "%s/%s" % (str(container), str(object_name))
Daisuke Morita2c87d372013-10-31 19:39:19 +090039 if params:
40 url += '?%s' % urllib.urlencode(params)
41
Martina Kollarova03720a52013-06-18 15:08:46 +020042 resp, body = self.put(url, data, headers)
dwalleck5d734432012-10-04 01:11:47 -050043 return resp, body
44
45 def update_object(self, container, object_name, data):
Sean Daguef237ccb2013-01-04 15:19:14 -050046 """Upload data to replace current storage object."""
Attila Fazekasfa756cb2013-02-12 10:52:42 +010047 return self.create_object(container, object_name, data)
dwalleck5d734432012-10-04 01:11:47 -050048
Daisuke Morita2c87d372013-10-31 19:39:19 +090049 def delete_object(self, container, object_name, params=None):
Sean Daguef237ccb2013-01-04 15:19:14 -050050 """Delete storage object."""
dwalleck5d734432012-10-04 01:11:47 -050051 url = "%s/%s" % (str(container), str(object_name))
Daisuke Morita2c87d372013-10-31 19:39:19 +090052 if params:
53 url += '?%s' % urllib.urlencode(params)
vponomaryov67b58fe2014-02-06 19:05:41 +020054 resp, body = self.delete(url, headers={})
dwalleck5d734432012-10-04 01:11:47 -050055 return resp, body
56
57 def update_object_metadata(self, container, object_name, metadata,
58 metadata_prefix='X-Object-Meta-'):
Sean Daguef237ccb2013-01-04 15:19:14 -050059 """Add, remove, or change X-Object-Meta metadata for storage object."""
dwalleck5d734432012-10-04 01:11:47 -050060
61 headers = {}
62 for key in metadata:
63 headers["%s%s" % (str(metadata_prefix), str(key))] = metadata[key]
64
65 url = "%s/%s" % (str(container), str(object_name))
66 resp, body = self.post(url, None, headers=headers)
67 return resp, body
68
69 def list_object_metadata(self, container, object_name):
Sean Daguef237ccb2013-01-04 15:19:14 -050070 """List all storage object X-Object-Meta- metadata."""
dwalleck5d734432012-10-04 01:11:47 -050071
72 url = "%s/%s" % (str(container), str(object_name))
73 resp, body = self.head(url)
74 return resp, body
Larisa Ustalov6c3c7802012-11-05 12:25:19 +020075
76 def get_object(self, container, object_name):
77 """Retrieve object's data."""
78
79 url = "{0}/{1}".format(container, object_name)
80 resp, body = self.get(url)
81 return resp, body
82
rajalakshmi-ganesan925e2392012-11-30 19:17:24 +053083 def copy_object_in_same_container(self, container, src_object_name,
84 dest_object_name, metadata=None):
Sean Daguef237ccb2013-01-04 15:19:14 -050085 """Copy storage object's data to the new object using PUT."""
Larisa Ustalov6c3c7802012-11-05 12:25:19 +020086
87 url = "{0}/{1}".format(container, dest_object_name)
88 headers = {}
89 headers['X-Copy-From'] = "%s/%s" % (str(container),
90 str(src_object_name))
91 headers['content-length'] = '0'
92 if metadata:
93 for key in metadata:
94 headers[str(key)] = metadata[key]
95
96 resp, body = self.put(url, None, headers=headers)
97 return resp, body
98
rajalakshmi-ganesan925e2392012-11-30 19:17:24 +053099 def copy_object_across_containers(self, src_container, src_object_name,
100 dst_container, dst_object_name,
101 metadata=None):
Sean Daguef237ccb2013-01-04 15:19:14 -0500102 """Copy storage object's data to the new object using PUT."""
rajalakshmi-ganesan925e2392012-11-30 19:17:24 +0530103
104 url = "{0}/{1}".format(dst_container, dst_object_name)
105 headers = {}
106 headers['X-Copy-From'] = "%s/%s" % (str(src_container),
107 str(src_object_name))
108 headers['content-length'] = '0'
109 if metadata:
110 for key in metadata:
111 headers[str(key)] = metadata[key]
112
113 resp, body = self.put(url, None, headers=headers)
114 return resp, body
115
Larisa Ustalov6c3c7802012-11-05 12:25:19 +0200116 def copy_object_2d_way(self, container, src_object_name, dest_object_name,
117 metadata=None):
Sean Daguef237ccb2013-01-04 15:19:14 -0500118 """Copy storage object's data to the new object using COPY."""
Larisa Ustalov6c3c7802012-11-05 12:25:19 +0200119
120 url = "{0}/{1}".format(container, src_object_name)
121 headers = {}
122 headers['Destination'] = "%s/%s" % (str(container),
123 str(dest_object_name))
124 if metadata:
125 for key in metadata:
126 headers[str(key)] = metadata[key]
127
128 resp, body = self.copy(url, headers=headers)
129 return resp, body
harika-vakadi1a9ad612012-12-14 19:12:08 +0530130
harika-vakadi7cfc5182013-01-16 13:59:25 +0530131 def create_object_segments(self, container, object_name, segment, data):
132 """Creates object segments."""
133 url = "{0}/{1}/{2}".format(container, object_name, segment)
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200134 resp, body = self.put(url, data)
ravikumar-venkatesane43b77a2013-01-09 07:27:13 +0000135 return resp, body
136
harika-vakadi1a9ad612012-12-14 19:12:08 +0530137
Eiichi Aikawaca3d9bd2014-03-06 15:06:21 +0900138class ObjectClientCustomizedHeader(rest_client.RestClient):
harika-vakadi1a9ad612012-12-14 19:12:08 +0530139
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000140 # TODO(andreaf) This class is now redundant, to be removed in next patch
141
142 def __init__(self, auth_provider):
143 super(ObjectClientCustomizedHeader, self).__init__(
144 auth_provider)
Eiichi Aikawaca3d9bd2014-03-06 15:06:21 +0900145 # Overwrites json-specific header encoding in rest_client.RestClient
Matthew Treinish684d8992014-01-30 16:27:40 +0000146 self.service = CONF.object_storage.catalog_type
harika-vakadi1a9ad612012-12-14 19:12:08 +0530147 self.format = 'json'
148
Attila Fazekasb8aa7592013-01-26 01:25:45 +0100149 def request(self, method, url, headers=None, body=None):
harika-vakadi1a9ad612012-12-14 19:12:08 +0530150 """A simple HTTP request interface."""
Matthew Treinish684d8992014-01-30 16:27:40 +0000151 dscv = CONF.identity.disable_ssl_certificate_validation
Mate Lakat23a58a32013-08-23 02:06:22 +0100152 self.http_obj = http.ClosingHttp(
153 disable_ssl_certificate_validation=dscv)
harika-vakadi1a9ad612012-12-14 19:12:08 +0530154 if headers is None:
155 headers = {}
harika-vakadi1a9ad612012-12-14 19:12:08 +0530156
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000157 # Authorize the request
158 req_url, req_headers, req_body = self.auth_provider.auth_request(
159 method=method, url=url, headers=headers, body=body,
160 filters=self.filters
161 )
162 # Use original method
Attila Fazekas11d2a772013-01-29 17:46:52 +0100163 self._log_request(method, req_url, headers, body)
harika-vakadi1a9ad612012-12-14 19:12:08 +0530164 resp, resp_body = self.http_obj.request(req_url, method,
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000165 headers=req_headers,
166 body=req_body)
Attila Fazekas11d2a772013-01-29 17:46:52 +0100167 self._log_response(resp, resp_body)
harika-vakadi6ab397b2012-12-20 12:16:17 +0530168 if resp.status == 401 or resp.status == 403:
harika-vakadi6ab397b2012-12-20 12:16:17 +0530169 raise exceptions.Unauthorized()
170
harika-vakadi1a9ad612012-12-14 19:12:08 +0530171 return resp, resp_body
172
173 def get_object(self, container, object_name, metadata=None):
174 """Retrieve object's data."""
175 headers = {}
176 if metadata:
177 for key in metadata:
178 headers[str(key)] = metadata[key]
179
180 url = "{0}/{1}".format(container, object_name)
181 resp, body = self.get(url, headers=headers)
182 return resp, body
harika-vakadi6ab397b2012-12-20 12:16:17 +0530183
184 def create_object(self, container, object_name, data, metadata=None):
Sean Daguef237ccb2013-01-04 15:19:14 -0500185 """Create storage object."""
harika-vakadi6ab397b2012-12-20 12:16:17 +0530186
187 headers = {}
188 if metadata:
189 for key in metadata:
190 headers[str(key)] = metadata[key]
191
Martina Kollarova03720a52013-06-18 15:08:46 +0200192 if not data:
193 headers['content-length'] = '0'
harika-vakadi6ab397b2012-12-20 12:16:17 +0530194 url = "%s/%s" % (str(container), str(object_name))
195 resp, body = self.put(url, data, headers=headers)
196 return resp, body
197
harika-vakadi2daed0a2013-01-01 20:51:39 +0530198 def delete_object(self, container, object_name, metadata=None):
Sean Daguef237ccb2013-01-04 15:19:14 -0500199 """Delete storage object."""
harika-vakadi6ab397b2012-12-20 12:16:17 +0530200
harika-vakadi2daed0a2013-01-01 20:51:39 +0530201 headers = {}
202 if metadata:
203 for key in metadata:
204 headers[str(key)] = metadata[key]
205
harika-vakadi6ab397b2012-12-20 12:16:17 +0530206 url = "%s/%s" % (str(container), str(object_name))
harika-vakadi2daed0a2013-01-01 20:51:39 +0530207 resp, body = self.delete(url, headers=headers)
harika-vakadi6ab397b2012-12-20 12:16:17 +0530208 return resp, body