blob: 166c945f7b15154da666a3389b63a2896f6fd7d3 [file] [log] [blame]
dwalleck5d734432012-10-04 01:11:47 -05001# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
ZhiQiang Fan39f97222013-09-20 04:49:44 +08003# Copyright 2012 OpenStack Foundation
dwalleck5d734432012-10-04 01:11:47 -05004# 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 json
Matthew Treinish26dd0fa2012-12-04 17:14:37 -050019import urllib
dwalleck5d734432012-10-04 01:11:47 -050020
21from tempest.common.rest_client import RestClient
22
23
24class ContainerClient(RestClient):
25 def __init__(self, config, username, password, auth_url, tenant_name=None):
26 super(ContainerClient, self).__init__(config, username, password,
27 auth_url, tenant_name)
28
Attila Fazekasa8b5fe72013-08-01 16:59:06 +020029 # Overwrites json-specific header encoding in RestClient
dwalleck5d734432012-10-04 01:11:47 -050030 self.headers = {}
31 self.service = self.config.object_storage.catalog_type
32 self.format = 'json'
33
34 def create_container(self, container_name, metadata=None,
35 metadata_prefix='X-Container-Meta-'):
36 """
37 Creates a container, with optional metadata passed in as a
Chang Bo Guocc1623c2013-09-13 20:11:27 -070038 dictionary
dwalleck5d734432012-10-04 01:11:47 -050039 """
Matthew Treinish26dd0fa2012-12-04 17:14:37 -050040 url = str(container_name)
dwalleck5d734432012-10-04 01:11:47 -050041 headers = {}
42
43 if metadata is not None:
44 for key in metadata:
45 headers[metadata_prefix + key] = metadata[key]
46
47 resp, body = self.put(url, body=None, headers=headers)
48 return resp, body
49
50 def delete_container(self, container_name):
Sean Daguef237ccb2013-01-04 15:19:14 -050051 """Deletes the container (if it's empty)."""
Matthew Treinish26dd0fa2012-12-04 17:14:37 -050052 url = str(container_name)
dwalleck5d734432012-10-04 01:11:47 -050053 resp, body = self.delete(url)
54 return resp, body
55
56 def update_container_metadata(self, container_name, metadata,
57 metadata_prefix='X-Container-Meta-'):
Sean Daguef237ccb2013-01-04 15:19:14 -050058 """Updates arbitrary metadata on container."""
Matthew Treinish26dd0fa2012-12-04 17:14:37 -050059 url = str(container_name)
dwalleck5d734432012-10-04 01:11:47 -050060 headers = {}
61
62 if metadata is not None:
63 for key in metadata:
64 headers[metadata_prefix + key] = metadata[key]
65
66 resp, body = self.post(url, body=None, headers=headers)
Larisa Ustalov6c3c7802012-11-05 12:25:19 +020067 return resp, body
dwalleck5d734432012-10-04 01:11:47 -050068
Larisa Ustalov6c3c7802012-11-05 12:25:19 +020069 def delete_container_metadata(self, container_name, metadata,
70 metadata_prefix='X-Remove-Container-Meta-'):
Sean Daguef237ccb2013-01-04 15:19:14 -050071 """Deletes arbitrary metadata on container."""
Matthew Treinish26dd0fa2012-12-04 17:14:37 -050072 url = str(container_name)
Larisa Ustalov6c3c7802012-11-05 12:25:19 +020073 headers = {}
74
75 if metadata is not None:
76 for item in metadata:
77 headers[metadata_prefix + item] = 'x'
78
79 resp, body = self.post(url, body=None, headers=headers)
80 return resp, body
81
82 def list_container_metadata(self, container_name):
83 """
84 Retrieves container metadata headers
85 """
Matthew Treinish26dd0fa2012-12-04 17:14:37 -050086 url = str(container_name)
Larisa Ustalov6c3c7802012-11-05 12:25:19 +020087 headers = {"X-Storage-Token": self.token}
88 resp, body = self.head(url, headers=headers)
89 return resp, body
dwalleck5d734432012-10-04 01:11:47 -050090
91 def list_all_container_objects(self, container, params=None):
92 """
93 Returns complete list of all objects in the container, even if
94 item count is beyond 10,000 item listing limit.
Chang Bo Guocc1623c2013-09-13 20:11:27 -070095 Does not require any parameters aside from container name.
dwalleck5d734432012-10-04 01:11:47 -050096 """
Chang Bo Guocc1623c2013-09-13 20:11:27 -070097 # TODO(dwalleck): Rewrite using json format to avoid newlines at end of
Attila Fazekasa8b5fe72013-08-01 16:59:06 +020098 # obj names. Set limit to API limit - 1 (max returned items = 9999)
dwalleck5d734432012-10-04 01:11:47 -050099 limit = 9999
dwalleck5d734432012-10-04 01:11:47 -0500100 if params is not None:
101 if 'limit' in params:
102 limit = params['limit']
103
104 if 'marker' in params:
105 limit = params['marker']
106
107 resp, objlist = self.list_container_contents(container,
108 params={'limit': limit})
109 return objlist
110 """tmp = []
111 for obj in objlist:
112 tmp.append(obj['name'])
113 objlist = tmp
114
115 if len(objlist) >= limit:
116
Attila Fazekasa8b5fe72013-08-01 16:59:06 +0200117 # Increment marker
dwalleck5d734432012-10-04 01:11:47 -0500118 marker = objlist[len(objlist) - 1]
119
Attila Fazekasa8b5fe72013-08-01 16:59:06 +0200120 # Get the next chunk of the list
dwalleck5d734432012-10-04 01:11:47 -0500121 objlist.extend(_list_all_container_objects(container,
122 params={'marker': marker,
123 'limit': limit}))
124 return objlist
125 else:
Attila Fazekasa8b5fe72013-08-01 16:59:06 +0200126 # Return final, complete list
dwalleck5d734432012-10-04 01:11:47 -0500127 return objlist"""
128
129 def list_container_contents(self, container, params=None):
130 """
131 List the objects in a container, given the container name
132
133 Returns the container object listing as a plain text list, or as
134 xml or json if that option is specified via the 'format' argument.
135
136 Optional Arguments:
137 limit = integer
138 For an integer value n, limits the number of results to at most
139 n values.
140
141 marker = 'string'
142 Given a string value x, return object names greater in value
143 than the specified marker.
144
145 prefix = 'string'
146 For a string value x, causes the results to be limited to names
147 beginning with the substring x.
148
149 format = 'json' or 'xml'
150 Specify either json or xml to return the respective serialized
151 response.
152 If json, returns a list of json objects
153 if xml, returns a string of xml
154
155 path = 'string'
156 For a string value x, return the object names nested in the
157 pseudo path (assuming preconditions are met - see below).
158
159 delimiter = 'character'
160 For a character c, return all the object names nested in the
161 container (without the need for the directory marker objects).
162 """
163
164 url = str(container)
Matthew Treinish26dd0fa2012-12-04 17:14:37 -0500165 url += '?format=%s' % self.format
166 if params:
167 url += '&%s' % urllib.urlencode(params)
dwalleck5d734432012-10-04 01:11:47 -0500168
169 resp, body = self.get(url)
170 body = json.loads(body)
171 return resp, body