blob: f3f4eb66525b10f79fbb66538d42cadc5376554b [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
Daisuke Morita6d502682014-03-19 21:08:54 +090080 def get_object(self, container, object_name, metadata=None):
Larisa Ustalov6c3c7802012-11-05 12:25:19 +020081 """Retrieve object's data."""
82
Daisuke Morita6d502682014-03-19 21:08:54 +090083 headers = {}
84 if metadata:
85 for key in metadata:
86 headers[str(key)] = metadata[key]
87
Larisa Ustalov6c3c7802012-11-05 12:25:19 +020088 url = "{0}/{1}".format(container, object_name)
Daisuke Morita6d502682014-03-19 21:08:54 +090089 resp, body = self.get(url, headers=headers)
Larisa Ustalov6c3c7802012-11-05 12:25:19 +020090 return resp, body
91
rajalakshmi-ganesan925e2392012-11-30 19:17:24 +053092 def copy_object_in_same_container(self, container, src_object_name,
93 dest_object_name, metadata=None):
Sean Daguef237ccb2013-01-04 15:19:14 -050094 """Copy storage object's data to the new object using PUT."""
Larisa Ustalov6c3c7802012-11-05 12:25:19 +020095
96 url = "{0}/{1}".format(container, dest_object_name)
97 headers = {}
98 headers['X-Copy-From'] = "%s/%s" % (str(container),
99 str(src_object_name))
100 headers['content-length'] = '0'
101 if metadata:
102 for key in metadata:
103 headers[str(key)] = metadata[key]
104
105 resp, body = self.put(url, None, headers=headers)
106 return resp, body
107
rajalakshmi-ganesan925e2392012-11-30 19:17:24 +0530108 def copy_object_across_containers(self, src_container, src_object_name,
109 dst_container, dst_object_name,
110 metadata=None):
Sean Daguef237ccb2013-01-04 15:19:14 -0500111 """Copy storage object's data to the new object using PUT."""
rajalakshmi-ganesan925e2392012-11-30 19:17:24 +0530112
113 url = "{0}/{1}".format(dst_container, dst_object_name)
114 headers = {}
115 headers['X-Copy-From'] = "%s/%s" % (str(src_container),
116 str(src_object_name))
117 headers['content-length'] = '0'
118 if metadata:
119 for key in metadata:
120 headers[str(key)] = metadata[key]
121
122 resp, body = self.put(url, None, headers=headers)
123 return resp, body
124
Larisa Ustalov6c3c7802012-11-05 12:25:19 +0200125 def copy_object_2d_way(self, container, src_object_name, dest_object_name,
126 metadata=None):
Sean Daguef237ccb2013-01-04 15:19:14 -0500127 """Copy storage object's data to the new object using COPY."""
Larisa Ustalov6c3c7802012-11-05 12:25:19 +0200128
129 url = "{0}/{1}".format(container, src_object_name)
130 headers = {}
131 headers['Destination'] = "%s/%s" % (str(container),
132 str(dest_object_name))
133 if metadata:
134 for key in metadata:
135 headers[str(key)] = metadata[key]
136
137 resp, body = self.copy(url, headers=headers)
138 return resp, body
harika-vakadi1a9ad612012-12-14 19:12:08 +0530139
harika-vakadi7cfc5182013-01-16 13:59:25 +0530140 def create_object_segments(self, container, object_name, segment, data):
141 """Creates object segments."""
142 url = "{0}/{1}/{2}".format(container, object_name, segment)
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200143 resp, body = self.put(url, data)
ravikumar-venkatesane43b77a2013-01-09 07:27:13 +0000144 return resp, body
145
harika-vakadi1a9ad612012-12-14 19:12:08 +0530146
Eiichi Aikawaca3d9bd2014-03-06 15:06:21 +0900147class ObjectClientCustomizedHeader(rest_client.RestClient):
harika-vakadi1a9ad612012-12-14 19:12:08 +0530148
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000149 # TODO(andreaf) This class is now redundant, to be removed in next patch
150
151 def __init__(self, auth_provider):
152 super(ObjectClientCustomizedHeader, self).__init__(
153 auth_provider)
Eiichi Aikawaca3d9bd2014-03-06 15:06:21 +0900154 # Overwrites json-specific header encoding in rest_client.RestClient
Matthew Treinish684d8992014-01-30 16:27:40 +0000155 self.service = CONF.object_storage.catalog_type
harika-vakadi1a9ad612012-12-14 19:12:08 +0530156 self.format = 'json'
157
Sergey Murashov4fccd322014-03-22 09:58:52 +0400158 def request(self, method, url, extra_headers=False, headers=None,
159 body=None):
harika-vakadi1a9ad612012-12-14 19:12:08 +0530160 """A simple HTTP request interface."""
Matthew Treinish684d8992014-01-30 16:27:40 +0000161 dscv = CONF.identity.disable_ssl_certificate_validation
Mate Lakat23a58a32013-08-23 02:06:22 +0100162 self.http_obj = http.ClosingHttp(
163 disable_ssl_certificate_validation=dscv)
harika-vakadi1a9ad612012-12-14 19:12:08 +0530164 if headers is None:
165 headers = {}
Sergey Murashov4fccd322014-03-22 09:58:52 +0400166 elif extra_headers:
167 try:
168 headers.update(self.get_headers())
169 except (ValueError, TypeError):
170 headers = {}
harika-vakadi1a9ad612012-12-14 19:12:08 +0530171
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000172 # Authorize the request
173 req_url, req_headers, req_body = self.auth_provider.auth_request(
174 method=method, url=url, headers=headers, body=body,
175 filters=self.filters
176 )
177 # Use original method
harika-vakadi1a9ad612012-12-14 19:12:08 +0530178 resp, resp_body = self.http_obj.request(req_url, method,
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000179 headers=req_headers,
180 body=req_body)
Sean Dague89a85912014-03-19 16:37:29 -0400181 self._log_request(method, req_url, resp)
harika-vakadi6ab397b2012-12-20 12:16:17 +0530182 if resp.status == 401 or resp.status == 403:
harika-vakadi6ab397b2012-12-20 12:16:17 +0530183 raise exceptions.Unauthorized()
184
harika-vakadi1a9ad612012-12-14 19:12:08 +0530185 return resp, resp_body
186
187 def get_object(self, container, object_name, metadata=None):
188 """Retrieve object's data."""
189 headers = {}
190 if metadata:
191 for key in metadata:
192 headers[str(key)] = metadata[key]
193
194 url = "{0}/{1}".format(container, object_name)
195 resp, body = self.get(url, headers=headers)
196 return resp, body
harika-vakadi6ab397b2012-12-20 12:16:17 +0530197
198 def create_object(self, container, object_name, data, metadata=None):
Sean Daguef237ccb2013-01-04 15:19:14 -0500199 """Create storage object."""
harika-vakadi6ab397b2012-12-20 12:16:17 +0530200
201 headers = {}
202 if metadata:
203 for key in metadata:
204 headers[str(key)] = metadata[key]
205
Martina Kollarova03720a52013-06-18 15:08:46 +0200206 if not data:
207 headers['content-length'] = '0'
harika-vakadi6ab397b2012-12-20 12:16:17 +0530208 url = "%s/%s" % (str(container), str(object_name))
209 resp, body = self.put(url, data, headers=headers)
210 return resp, body
211
harika-vakadi2daed0a2013-01-01 20:51:39 +0530212 def delete_object(self, container, object_name, metadata=None):
Sean Daguef237ccb2013-01-04 15:19:14 -0500213 """Delete storage object."""
harika-vakadi6ab397b2012-12-20 12:16:17 +0530214
harika-vakadi2daed0a2013-01-01 20:51:39 +0530215 headers = {}
216 if metadata:
217 for key in metadata:
218 headers[str(key)] = metadata[key]
219
harika-vakadi6ab397b2012-12-20 12:16:17 +0530220 url = "%s/%s" % (str(container), str(object_name))
harika-vakadi2daed0a2013-01-01 20:51:39 +0530221 resp, body = self.delete(url, headers=headers)
harika-vakadi6ab397b2012-12-20 12:16:17 +0530222 return resp, body