blob: 53a33255752613242c9e2fffb2e89d403fd022d6 [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 Moritacf6f6952014-03-19 21:25:50 +090032 def create_object(self, container, object_name, data,
33 params=None, metadata=None):
Sean Daguef237ccb2013-01-04 15:19:14 -050034 """Create storage object."""
dwalleck5d734432012-10-04 01:11:47 -050035
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +020036 headers = self.get_headers()
Martina Kollarova03720a52013-06-18 15:08:46 +020037 if not data:
38 headers['content-length'] = '0'
Daisuke Moritacf6f6952014-03-19 21:25:50 +090039 if metadata:
40 for key in metadata:
41 headers[str(key)] = metadata[key]
dwalleck5d734432012-10-04 01:11:47 -050042 url = "%s/%s" % (str(container), str(object_name))
Daisuke Morita2c87d372013-10-31 19:39:19 +090043 if params:
44 url += '?%s' % urllib.urlencode(params)
45
Martina Kollarova03720a52013-06-18 15:08:46 +020046 resp, body = self.put(url, data, headers)
dwalleck5d734432012-10-04 01:11:47 -050047 return resp, body
48
49 def update_object(self, container, object_name, data):
Sean Daguef237ccb2013-01-04 15:19:14 -050050 """Upload data to replace current storage object."""
Attila Fazekasfa756cb2013-02-12 10:52:42 +010051 return self.create_object(container, object_name, data)
dwalleck5d734432012-10-04 01:11:47 -050052
Daisuke Morita2c87d372013-10-31 19:39:19 +090053 def delete_object(self, container, object_name, params=None):
Sean Daguef237ccb2013-01-04 15:19:14 -050054 """Delete storage object."""
dwalleck5d734432012-10-04 01:11:47 -050055 url = "%s/%s" % (str(container), str(object_name))
Daisuke Morita2c87d372013-10-31 19:39:19 +090056 if params:
57 url += '?%s' % urllib.urlencode(params)
vponomaryov67b58fe2014-02-06 19:05:41 +020058 resp, body = self.delete(url, headers={})
dwalleck5d734432012-10-04 01:11:47 -050059 return resp, body
60
61 def update_object_metadata(self, container, object_name, metadata,
62 metadata_prefix='X-Object-Meta-'):
Sean Daguef237ccb2013-01-04 15:19:14 -050063 """Add, remove, or change X-Object-Meta metadata for storage object."""
dwalleck5d734432012-10-04 01:11:47 -050064
65 headers = {}
66 for key in metadata:
67 headers["%s%s" % (str(metadata_prefix), str(key))] = metadata[key]
68
69 url = "%s/%s" % (str(container), str(object_name))
70 resp, body = self.post(url, None, headers=headers)
71 return resp, body
72
73 def list_object_metadata(self, container, object_name):
Sean Daguef237ccb2013-01-04 15:19:14 -050074 """List all storage object X-Object-Meta- metadata."""
dwalleck5d734432012-10-04 01:11:47 -050075
76 url = "%s/%s" % (str(container), str(object_name))
77 resp, body = self.head(url)
78 return resp, body
Larisa Ustalov6c3c7802012-11-05 12:25:19 +020079
80 def get_object(self, container, object_name):
81 """Retrieve object's data."""
82
83 url = "{0}/{1}".format(container, object_name)
84 resp, body = self.get(url)
85 return resp, body
86
rajalakshmi-ganesan925e2392012-11-30 19:17:24 +053087 def copy_object_in_same_container(self, container, src_object_name,
88 dest_object_name, metadata=None):
Sean Daguef237ccb2013-01-04 15:19:14 -050089 """Copy storage object's data to the new object using PUT."""
Larisa Ustalov6c3c7802012-11-05 12:25:19 +020090
91 url = "{0}/{1}".format(container, dest_object_name)
92 headers = {}
93 headers['X-Copy-From'] = "%s/%s" % (str(container),
94 str(src_object_name))
95 headers['content-length'] = '0'
96 if metadata:
97 for key in metadata:
98 headers[str(key)] = metadata[key]
99
100 resp, body = self.put(url, None, headers=headers)
101 return resp, body
102
rajalakshmi-ganesan925e2392012-11-30 19:17:24 +0530103 def copy_object_across_containers(self, src_container, src_object_name,
104 dst_container, dst_object_name,
105 metadata=None):
Sean Daguef237ccb2013-01-04 15:19:14 -0500106 """Copy storage object's data to the new object using PUT."""
rajalakshmi-ganesan925e2392012-11-30 19:17:24 +0530107
108 url = "{0}/{1}".format(dst_container, dst_object_name)
109 headers = {}
110 headers['X-Copy-From'] = "%s/%s" % (str(src_container),
111 str(src_object_name))
112 headers['content-length'] = '0'
113 if metadata:
114 for key in metadata:
115 headers[str(key)] = metadata[key]
116
117 resp, body = self.put(url, None, headers=headers)
118 return resp, body
119
Larisa Ustalov6c3c7802012-11-05 12:25:19 +0200120 def copy_object_2d_way(self, container, src_object_name, dest_object_name,
121 metadata=None):
Sean Daguef237ccb2013-01-04 15:19:14 -0500122 """Copy storage object's data to the new object using COPY."""
Larisa Ustalov6c3c7802012-11-05 12:25:19 +0200123
124 url = "{0}/{1}".format(container, src_object_name)
125 headers = {}
126 headers['Destination'] = "%s/%s" % (str(container),
127 str(dest_object_name))
128 if metadata:
129 for key in metadata:
130 headers[str(key)] = metadata[key]
131
132 resp, body = self.copy(url, headers=headers)
133 return resp, body
harika-vakadi1a9ad612012-12-14 19:12:08 +0530134
harika-vakadi7cfc5182013-01-16 13:59:25 +0530135 def create_object_segments(self, container, object_name, segment, data):
136 """Creates object segments."""
137 url = "{0}/{1}/{2}".format(container, object_name, segment)
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200138 resp, body = self.put(url, data)
ravikumar-venkatesane43b77a2013-01-09 07:27:13 +0000139 return resp, body
140
harika-vakadi1a9ad612012-12-14 19:12:08 +0530141
Eiichi Aikawaca3d9bd2014-03-06 15:06:21 +0900142class ObjectClientCustomizedHeader(rest_client.RestClient):
harika-vakadi1a9ad612012-12-14 19:12:08 +0530143
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000144 # TODO(andreaf) This class is now redundant, to be removed in next patch
145
146 def __init__(self, auth_provider):
147 super(ObjectClientCustomizedHeader, self).__init__(
148 auth_provider)
Eiichi Aikawaca3d9bd2014-03-06 15:06:21 +0900149 # Overwrites json-specific header encoding in rest_client.RestClient
Matthew Treinish684d8992014-01-30 16:27:40 +0000150 self.service = CONF.object_storage.catalog_type
harika-vakadi1a9ad612012-12-14 19:12:08 +0530151 self.format = 'json'
152
Sergey Murashov4fccd322014-03-22 09:58:52 +0400153 def request(self, method, url, extra_headers=False, headers=None,
154 body=None):
harika-vakadi1a9ad612012-12-14 19:12:08 +0530155 """A simple HTTP request interface."""
Matthew Treinish684d8992014-01-30 16:27:40 +0000156 dscv = CONF.identity.disable_ssl_certificate_validation
Mate Lakat23a58a32013-08-23 02:06:22 +0100157 self.http_obj = http.ClosingHttp(
158 disable_ssl_certificate_validation=dscv)
harika-vakadi1a9ad612012-12-14 19:12:08 +0530159 if headers is None:
160 headers = {}
Sergey Murashov4fccd322014-03-22 09:58:52 +0400161 elif extra_headers:
162 try:
163 headers.update(self.get_headers())
164 except (ValueError, TypeError):
165 headers = {}
harika-vakadi1a9ad612012-12-14 19:12:08 +0530166
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000167 # Authorize the request
168 req_url, req_headers, req_body = self.auth_provider.auth_request(
169 method=method, url=url, headers=headers, body=body,
170 filters=self.filters
171 )
172 # Use original method
harika-vakadi1a9ad612012-12-14 19:12:08 +0530173 resp, resp_body = self.http_obj.request(req_url, method,
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000174 headers=req_headers,
175 body=req_body)
Sean Dague89a85912014-03-19 16:37:29 -0400176 self._log_request(method, req_url, resp)
harika-vakadi6ab397b2012-12-20 12:16:17 +0530177 if resp.status == 401 or resp.status == 403:
harika-vakadi6ab397b2012-12-20 12:16:17 +0530178 raise exceptions.Unauthorized()
179
harika-vakadi1a9ad612012-12-14 19:12:08 +0530180 return resp, resp_body
181
182 def get_object(self, container, object_name, metadata=None):
183 """Retrieve object's data."""
184 headers = {}
185 if metadata:
186 for key in metadata:
187 headers[str(key)] = metadata[key]
188
189 url = "{0}/{1}".format(container, object_name)
190 resp, body = self.get(url, headers=headers)
191 return resp, body
harika-vakadi6ab397b2012-12-20 12:16:17 +0530192
193 def create_object(self, container, object_name, data, metadata=None):
Sean Daguef237ccb2013-01-04 15:19:14 -0500194 """Create storage object."""
harika-vakadi6ab397b2012-12-20 12:16:17 +0530195
196 headers = {}
197 if metadata:
198 for key in metadata:
199 headers[str(key)] = metadata[key]
200
Martina Kollarova03720a52013-06-18 15:08:46 +0200201 if not data:
202 headers['content-length'] = '0'
harika-vakadi6ab397b2012-12-20 12:16:17 +0530203 url = "%s/%s" % (str(container), str(object_name))
204 resp, body = self.put(url, data, headers=headers)
205 return resp, body
206
harika-vakadi2daed0a2013-01-01 20:51:39 +0530207 def delete_object(self, container, object_name, metadata=None):
Sean Daguef237ccb2013-01-04 15:19:14 -0500208 """Delete storage object."""
harika-vakadi6ab397b2012-12-20 12:16:17 +0530209
harika-vakadi2daed0a2013-01-01 20:51:39 +0530210 headers = {}
211 if metadata:
212 for key in metadata:
213 headers[str(key)] = metadata[key]
214
harika-vakadi6ab397b2012-12-20 12:16:17 +0530215 url = "%s/%s" % (str(container), str(object_name))
harika-vakadi2daed0a2013-01-01 20:51:39 +0530216 resp, body = self.delete(url, headers=headers)
harika-vakadi6ab397b2012-12-20 12:16:17 +0530217 return resp, body