]> git.proxmox.com Git - ceph.git/blame - ceph/qa/tasks/radosgw_admin_rest.py
import quincy beta 17.1.0
[ceph.git] / ceph / qa / tasks / radosgw_admin_rest.py
CommitLineData
7c673cae
FG
1"""
2Run a series of rgw admin commands through the rest interface.
3
4The test cases in this file have been annotated for inventory.
5To extract the inventory (in csv format) use the command:
6
7 grep '^ *# TESTCASE' | sed 's/^ *# TESTCASE //'
8
9"""
7c673cae 10import logging
9f95a23c 11
7c673cae
FG
12
13import boto.exception
14import boto.s3.connection
15import boto.s3.acl
16
17import requests
18import time
19
20from boto.connection import AWSAuthConnection
21from teuthology import misc as teuthology
e306af50 22from tasks.util.rgw import get_user_summary, get_user_successful_ops, rgwadmin
7c673cae
FG
23
24log = logging.getLogger(__name__)
25
7c673cae
FG
26def rgwadmin_rest(connection, cmd, params=None, headers=None, raw=False):
27 """
28 perform a rest command
29 """
30 log.info('radosgw-admin-rest: %s %s' % (cmd, params))
31 put_cmds = ['create', 'link', 'add']
32 post_cmds = ['unlink', 'modify']
33 delete_cmds = ['trim', 'rm', 'process']
20effc67 34 get_cmds = ['check', 'info', 'show', 'list', '']
7c673cae
FG
35
36 bucket_sub_resources = ['object', 'policy', 'index']
37 user_sub_resources = ['subuser', 'key', 'caps']
38 zone_sub_resources = ['pool', 'log', 'garbage']
39
40 def get_cmd_method_and_handler(cmd):
41 """
42 Get the rest command and handler from information in cmd and
43 from the imported requests object.
44 """
45 if cmd[1] in put_cmds:
46 return 'PUT', requests.put
47 elif cmd[1] in delete_cmds:
48 return 'DELETE', requests.delete
49 elif cmd[1] in post_cmds:
50 return 'POST', requests.post
51 elif cmd[1] in get_cmds:
52 return 'GET', requests.get
53
54 def get_resource(cmd):
55 """
56 Get the name of the resource from information in cmd.
57 """
58 if cmd[0] == 'bucket' or cmd[0] in bucket_sub_resources:
59 if cmd[0] == 'bucket':
60 return 'bucket', ''
61 else:
62 return 'bucket', cmd[0]
63 elif cmd[0] == 'user' or cmd[0] in user_sub_resources:
64 if cmd[0] == 'user':
65 return 'user', ''
66 else:
67 return 'user', cmd[0]
68 elif cmd[0] == 'usage':
69 return 'usage', ''
20effc67
TL
70 elif cmd[0] == 'info':
71 return 'info', ''
72 elif cmd[0] == 'ratelimit':
73 return 'ratelimit', ''
7c673cae
FG
74 elif cmd[0] == 'zone' or cmd[0] in zone_sub_resources:
75 if cmd[0] == 'zone':
76 return 'zone', ''
77 else:
78 return 'zone', cmd[0]
79
80 def build_admin_request(conn, method, resource = '', headers=None, data='',
81 query_args=None, params=None):
82 """
83 Build an administative request adapted from the build_request()
84 method of boto.connection
85 """
86
87 path = conn.calling_format.build_path_base('admin', resource)
88 auth_path = conn.calling_format.build_auth_path('admin', resource)
89 host = conn.calling_format.build_host(conn.server_name(), 'admin')
90 if query_args:
91 path += '?' + query_args
92 boto.log.debug('path=%s' % path)
93 auth_path += '?' + query_args
94 boto.log.debug('auth_path=%s' % auth_path)
95 return AWSAuthConnection.build_base_http_request(conn, method, path,
96 auth_path, params, headers, data, host)
97
98 method, handler = get_cmd_method_and_handler(cmd)
99 resource, query_args = get_resource(cmd)
100 request = build_admin_request(connection, method, resource,
101 query_args=query_args, headers=headers)
102
103 url = '{protocol}://{host}{path}'.format(protocol=request.protocol,
104 host=request.host, path=request.path)
105
106 request.authorize(connection=connection)
107 result = handler(url, params=params, headers=request.headers)
108
109 if raw:
11fdf7f2
TL
110 log.info(' text result: %s' % result.text)
111 return result.status_code, result.text
112 elif len(result.content) == 0:
113 # many admin requests return no body, so json() throws a JSONDecodeError
114 log.info(' empty result')
115 return result.status_code, None
7c673cae
FG
116 else:
117 log.info(' json result: %s' % result.json())
118 return result.status_code, result.json()
119
120
121def task(ctx, config):
122 """
123 Test radosgw-admin functionality through the RESTful interface
124 """
125 assert config is None or isinstance(config, list) \
126 or isinstance(config, dict), \
127 "task s3tests only supports a list or dictionary for configuration"
128 all_clients = ['client.{id}'.format(id=id_)
129 for id_ in teuthology.all_roles_of_type(ctx.cluster, 'client')]
130 if config is None:
131 config = all_clients
132 if isinstance(config, list):
133 config = dict.fromkeys(config)
134 clients = config.keys()
135
136 # just use the first client...
e306af50 137 client = next(iter(clients))
7c673cae
FG
138
139 ##
140 admin_user = 'ada'
141 admin_display_name = 'Ms. Admin User'
142 admin_access_key = 'MH1WC2XQ1S8UISFDZC8W'
143 admin_secret_key = 'dQyrTPA0s248YeN5bBv4ukvKU0kh54LWWywkrpoG'
20effc67 144 admin_caps = 'users=read, write; usage=read, write; buckets=read, write; zone=read, write; info=read;ratelimit=read, write'
7c673cae
FG
145
146 user1 = 'foo'
147 user2 = 'fud'
20effc67 148 ratelimit_user = 'ratelimit_user'
7c673cae
FG
149 subuser1 = 'foo:foo1'
150 subuser2 = 'foo:foo2'
151 display_name1 = 'Foo'
152 display_name2 = 'Fud'
153 email = 'foo@foo.com'
154 access_key = '9te6NH5mcdcq0Tc5i8i1'
155 secret_key = 'Ny4IOauQoL18Gp2zM7lC1vLmoawgqcYP/YGcWfXu'
156 access_key2 = 'p5YnriCv1nAtykxBrupQ'
157 secret_key2 = 'Q8Tk6Q/27hfbFSYdSkPtUqhqx1GgzvpXa4WARozh'
158 swift_secret1 = 'gpS2G9RREMrnbqlp29PP2D36kgPR1tm72n5fPYfL'
159 swift_secret2 = 'ri2VJQcKSYATOY6uaDUX7pxgkW+W1YmC6OCxPHwy'
160
161 bucket_name = 'myfoo'
162
163 # legend (test cases can be easily grep-ed out)
164 # TESTCASE 'testname','object','method','operation','assertion'
165 # TESTCASE 'create-admin-user','user','create','administrative user','succeeds'
166 (err, out) = rgwadmin(ctx, client, [
167 'user', 'create',
168 '--uid', admin_user,
169 '--display-name', admin_display_name,
170 '--access-key', admin_access_key,
171 '--secret', admin_secret_key,
172 '--max-buckets', '0',
173 '--caps', admin_caps
174 ])
175 logging.error(out)
176 logging.error(err)
177 assert not err
178
11fdf7f2
TL
179 assert hasattr(ctx, 'rgw'), 'radosgw-admin-rest must run after the rgw task'
180 endpoint = ctx.rgw.role_endpoints.get(client)
181 assert endpoint, 'no rgw endpoint for {}'.format(client)
182
7c673cae
FG
183 admin_conn = boto.s3.connection.S3Connection(
184 aws_access_key_id=admin_access_key,
185 aws_secret_access_key=admin_secret_key,
11fdf7f2
TL
186 is_secure=True if endpoint.cert else False,
187 port=endpoint.port,
188 host=endpoint.hostname,
7c673cae
FG
189 calling_format=boto.s3.connection.OrdinaryCallingFormat(),
190 )
191
192 # TESTCASE 'info-nosuch','user','info','non-existent user','fails'
193 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'info'], {"uid": user1})
194 assert ret == 404
195
196 # TESTCASE 'create-ok','user','create','w/all valid info','succeeds'
197 (ret, out) = rgwadmin_rest(admin_conn,
198 ['user', 'create'],
199 {'uid' : user1,
200 'display-name' : display_name1,
201 'email' : email,
202 'access-key' : access_key,
203 'secret-key' : secret_key,
204 'max-buckets' : '4'
205 })
206
207 assert ret == 200
208
11fdf7f2
TL
209 # TESTCASE 'list-no-user','user','list','list user keys','user list object'
210 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'list'], {'list' : '', 'max-entries' : 0})
211 assert ret == 200
212 assert out['count'] == 0
213 assert out['truncated'] == True
214 assert len(out['keys']) == 0
215 assert len(out['marker']) > 0
216
217 # TESTCASE 'list-user-without-marker','user','list','list user keys','user list object'
218 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'list'], {'list' : '', 'max-entries' : 1})
219 assert ret == 200
220 assert out['count'] == 1
221 assert out['truncated'] == True
222 assert len(out['keys']) == 1
223 assert len(out['marker']) > 0
224 marker = out['marker']
225
226 # TESTCASE 'list-user-with-marker','user','list','list user keys','user list object'
227 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'list'], {'list' : '', 'max-entries' : 1, 'marker': marker})
228 assert ret == 200
229 assert out['count'] == 1
230 assert out['truncated'] == False
231 assert len(out['keys']) == 1
232
7c673cae
FG
233 # TESTCASE 'info-existing','user','info','existing user','returns correct info'
234 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'info'], {'uid' : user1})
235
236 assert out['user_id'] == user1
237 assert out['email'] == email
238 assert out['display_name'] == display_name1
239 assert len(out['keys']) == 1
240 assert out['keys'][0]['access_key'] == access_key
241 assert out['keys'][0]['secret_key'] == secret_key
242 assert not out['suspended']
11fdf7f2
TL
243 assert out['tenant'] == ''
244 assert out['max_buckets'] == 4
245 assert out['caps'] == []
246 assert out['op_mask'] == 'read, write, delete'
247 assert out['default_placement'] == ''
248 assert out['default_storage_class'] == ''
249 assert out['placement_tags'] == []
250 assert not out['bucket_quota']['enabled']
251 assert not out['bucket_quota']['check_on_raw']
252 assert out['bucket_quota']['max_size'] == -1
253 assert out['bucket_quota']['max_size_kb'] == 0
254 assert out['bucket_quota']['max_objects'] == -1
255 assert not out['user_quota']['enabled']
256 assert not out['user_quota']['check_on_raw']
257 assert out['user_quota']['max_size'] == -1
258 assert out['user_quota']['max_size_kb'] == 0
259 assert out['user_quota']['max_objects'] == -1
260 assert out['temp_url_keys'] == []
261 assert out['type'] == 'rgw'
262 assert out['mfa_ids'] == []
263 # TESTCASE 'info-existing','user','info','existing user query with wrong uid but correct access key','returns correct info'
264 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'info'], {'access-key' : access_key, 'uid': 'uid_not_exist'})
265
266 assert out['user_id'] == user1
267 assert out['email'] == email
268 assert out['display_name'] == display_name1
269 assert len(out['keys']) == 1
270 assert out['keys'][0]['access_key'] == access_key
271 assert out['keys'][0]['secret_key'] == secret_key
272 assert not out['suspended']
273 assert out['tenant'] == ''
274 assert out['max_buckets'] == 4
275 assert out['caps'] == []
276 assert out['op_mask'] == "read, write, delete"
277 assert out['default_placement'] == ''
278 assert out['default_storage_class'] == ''
279 assert out['placement_tags'] == []
280 assert not out['bucket_quota']['enabled']
281 assert not out['bucket_quota']['check_on_raw']
282 assert out ['bucket_quota']['max_size'] == -1
283 assert out ['bucket_quota']['max_size_kb'] == 0
284 assert out ['bucket_quota']['max_objects'] == -1
285 assert not out['user_quota']['enabled']
286 assert not out['user_quota']['check_on_raw']
287 assert out['user_quota']['max_size'] == -1
288 assert out['user_quota']['max_size_kb'] == 0
289 assert out['user_quota']['max_objects'] == -1
290 assert out['temp_url_keys'] == []
291 assert out['type'] == 'rgw'
292 assert out['mfa_ids'] == []
7c673cae
FG
293
294 # TESTCASE 'suspend-ok','user','suspend','active user','succeeds'
295 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'modify'], {'uid' : user1, 'suspended' : True})
296 assert ret == 200
297
298 # TESTCASE 'suspend-suspended','user','suspend','suspended user','succeeds w/advisory'
299 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'info'], {'uid' : user1})
300 assert ret == 200
301 assert out['suspended']
28e407b8 302 assert out['email'] == email
7c673cae
FG
303
304 # TESTCASE 're-enable','user','enable','suspended user','succeeds'
305 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'modify'], {'uid' : user1, 'suspended' : 'false'})
306 assert not err
307
308 # TESTCASE 'info-re-enabled','user','info','re-enabled user','no longer suspended'
309 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'info'], {'uid' : user1})
310 assert ret == 200
311 assert not out['suspended']
312
313 # TESTCASE 'add-keys','key','create','w/valid info','succeeds'
314 (ret, out) = rgwadmin_rest(admin_conn,
315 ['key', 'create'],
316 {'uid' : user1,
317 'access-key' : access_key2,
318 'secret-key' : secret_key2
319 })
320
321
322 assert ret == 200
323
324 # TESTCASE 'info-new-key','user','info','after key addition','returns all keys'
325 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'info'], {'uid' : user1})
326 assert ret == 200
327 assert len(out['keys']) == 2
328 assert out['keys'][0]['access_key'] == access_key2 or out['keys'][1]['access_key'] == access_key2
329 assert out['keys'][0]['secret_key'] == secret_key2 or out['keys'][1]['secret_key'] == secret_key2
330
331 # TESTCASE 'rm-key','key','rm','newly added key','succeeds, key is removed'
332 (ret, out) = rgwadmin_rest(admin_conn,
333 ['key', 'rm'],
334 {'uid' : user1,
335 'access-key' : access_key2
336 })
337
338 assert ret == 200
339
340 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'info'], {'uid' : user1})
341
342 assert len(out['keys']) == 1
343 assert out['keys'][0]['access_key'] == access_key
344 assert out['keys'][0]['secret_key'] == secret_key
345
346 # TESTCASE 'add-swift-key','key','create','swift key','succeeds'
347 (ret, out) = rgwadmin_rest(admin_conn,
348 ['subuser', 'create'],
349 {'subuser' : subuser1,
350 'secret-key' : swift_secret1,
351 'key-type' : 'swift'
352 })
353
354 assert ret == 200
355
356 # TESTCASE 'info-swift-key','user','info','after key addition','returns all keys'
357 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'info'], {'uid' : user1})
358 assert ret == 200
359 assert len(out['swift_keys']) == 1
360 assert out['swift_keys'][0]['user'] == subuser1
361 assert out['swift_keys'][0]['secret_key'] == swift_secret1
362
363 # TESTCASE 'add-swift-subuser','key','create','swift sub-user key','succeeds'
364 (ret, out) = rgwadmin_rest(admin_conn,
365 ['subuser', 'create'],
366 {'subuser' : subuser2,
367 'secret-key' : swift_secret2,
368 'key-type' : 'swift'
369 })
370
371 assert ret == 200
372
373 # TESTCASE 'info-swift-subuser','user','info','after key addition','returns all sub-users/keys'
374 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'info'], {'uid' : user1})
375 assert ret == 200
376 assert len(out['swift_keys']) == 2
377 assert out['swift_keys'][0]['user'] == subuser2 or out['swift_keys'][1]['user'] == subuser2
378 assert out['swift_keys'][0]['secret_key'] == swift_secret2 or out['swift_keys'][1]['secret_key'] == swift_secret2
379
380 # TESTCASE 'rm-swift-key1','key','rm','subuser','succeeds, one key is removed'
381 (ret, out) = rgwadmin_rest(admin_conn,
382 ['key', 'rm'],
383 {'subuser' : subuser1,
384 'key-type' :'swift'
385 })
386
387 assert ret == 200
388
389 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'info'], {'uid' : user1})
390 assert len(out['swift_keys']) == 1
391
392 # TESTCASE 'rm-subuser','subuser','rm','subuser','success, subuser is removed'
393 (ret, out) = rgwadmin_rest(admin_conn,
394 ['subuser', 'rm'],
395 {'subuser' : subuser1
396 })
397
398 assert ret == 200
399
400 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'info'], {'uid' : user1})
401 assert len(out['subusers']) == 1
402
403 # TESTCASE 'rm-subuser-with-keys','subuser','rm','subuser','succeeds, second subser and key is removed'
404 (ret, out) = rgwadmin_rest(admin_conn,
405 ['subuser', 'rm'],
406 {'subuser' : subuser2,
407 'key-type' : 'swift',
408 '{purge-keys' :True
409 })
410
411 assert ret == 200
412
413 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'info'], {'uid' : user1})
414 assert len(out['swift_keys']) == 0
415 assert len(out['subusers']) == 0
416
417 # TESTCASE 'bucket-stats','bucket','info','no session/buckets','succeeds, empty list'
418 (ret, out) = rgwadmin_rest(admin_conn, ['bucket', 'info'], {'uid' : user1})
419 assert ret == 200
420 assert len(out) == 0
421
422 # connect to rgw
423 connection = boto.s3.connection.S3Connection(
424 aws_access_key_id=access_key,
425 aws_secret_access_key=secret_key,
11fdf7f2
TL
426 is_secure=True if endpoint.cert else False,
427 port=endpoint.port,
428 host=endpoint.hostname,
7c673cae
FG
429 calling_format=boto.s3.connection.OrdinaryCallingFormat(),
430 )
431
432 # TESTCASE 'bucket-stats2','bucket','stats','no buckets','succeeds, empty list'
433 (ret, out) = rgwadmin_rest(admin_conn, ['bucket', 'info'], {'uid' : user1, 'stats' : True})
434 assert ret == 200
435 assert len(out) == 0
436
437 # create a first bucket
438 bucket = connection.create_bucket(bucket_name)
439
440 # TESTCASE 'bucket-list','bucket','list','one bucket','succeeds, expected list'
441 (ret, out) = rgwadmin_rest(admin_conn, ['bucket', 'info'], {'uid' : user1})
442 assert ret == 200
443 assert len(out) == 1
444 assert out[0] == bucket_name
445
446 # TESTCASE 'bucket-stats3','bucket','stats','new empty bucket','succeeds, empty list'
447 (ret, out) = rgwadmin_rest(admin_conn,
448 ['bucket', 'info'], {'bucket' : bucket_name, 'stats' : True})
449
450 assert ret == 200
451 assert out['owner'] == user1
11fdf7f2 452 assert out['tenant'] == ''
7c673cae
FG
453 bucket_id = out['id']
454
455 # TESTCASE 'bucket-stats4','bucket','stats','new empty bucket','succeeds, expected bucket ID'
456 (ret, out) = rgwadmin_rest(admin_conn, ['bucket', 'info'], {'uid' : user1, 'stats' : True})
457 assert ret == 200
458 assert len(out) == 1
459 assert out[0]['id'] == bucket_id # does it return the same ID twice in a row?
460
461 # use some space
462 key = boto.s3.key.Key(bucket)
463 key.set_contents_from_string('one')
464
465 # TESTCASE 'bucket-stats5','bucket','stats','after creating key','succeeds, lists one non-empty object'
466 (ret, out) = rgwadmin_rest(admin_conn, ['bucket', 'info'], {'bucket' : bucket_name, 'stats' : True})
467 assert ret == 200
468 assert out['id'] == bucket_id
469 assert out['usage']['rgw.main']['num_objects'] == 1
470 assert out['usage']['rgw.main']['size_kb'] > 0
471
adb31ebb
TL
472 # TESTCASE 'bucket-stats6', 'bucket', 'stats', 'non-existent bucket', 'fails, 'bucket not found error'
473 (ret, out) = rgwadmin_rest(admin_conn, ['bucket', 'info'], {'bucket' : 'doesnotexist'})
474 assert ret == 404
475 assert out['Code'] == 'NoSuchBucket'
476
7c673cae
FG
477 # reclaim it
478 key.delete()
479
480 # TESTCASE 'bucket unlink', 'bucket', 'unlink', 'unlink bucket from user', 'fails', 'access denied error'
481 (ret, out) = rgwadmin_rest(admin_conn, ['bucket', 'unlink'], {'uid' : user1, 'bucket' : bucket_name})
482
483 assert ret == 200
484
485 # create a second user to link the bucket to
486 (ret, out) = rgwadmin_rest(admin_conn,
487 ['user', 'create'],
488 {'uid' : user2,
489 'display-name' : display_name2,
490 'access-key' : access_key2,
491 'secret-key' : secret_key2,
492 'max-buckets' : '1',
493 })
494
495 assert ret == 200
496
497 # try creating an object with the first user before the bucket is relinked
498 denied = False
499 key = boto.s3.key.Key(bucket)
500
501 try:
502 key.set_contents_from_string('two')
503 except boto.exception.S3ResponseError:
504 denied = True
505
506 assert not denied
507
508 # delete the object
509 key.delete()
510
511 # link the bucket to another user
11fdf7f2
TL
512 (ret, out) = rgwadmin_rest(admin_conn,
513 ['bucket', 'link'],
514 {'uid' : user2,
515 'bucket' : bucket_name,
516 'bucket-id' : bucket_id,
517 })
7c673cae
FG
518
519 assert ret == 200
520
521 # try creating an object with the first user which should cause an error
522 key = boto.s3.key.Key(bucket)
523
524 try:
525 key.set_contents_from_string('three')
526 except boto.exception.S3ResponseError:
527 denied = True
528
529 assert denied
530
531 # relink the bucket to the first user and delete the second user
11fdf7f2
TL
532 (ret, out) = rgwadmin_rest(admin_conn,
533 ['bucket', 'link'],
534 {'uid' : user1,
535 'bucket' : bucket_name,
536 'bucket-id' : bucket_id,
537 })
7c673cae
FG
538 assert ret == 200
539
540 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'rm'], {'uid' : user2})
541 assert ret == 200
542
543 # TESTCASE 'object-rm', 'object', 'rm', 'remove object', 'succeeds, object is removed'
544
545 # upload an object
546 object_name = 'four'
547 key = boto.s3.key.Key(bucket, object_name)
548 key.set_contents_from_string(object_name)
549
550 # now delete it
551 (ret, out) = rgwadmin_rest(admin_conn, ['object', 'rm'], {'bucket' : bucket_name, 'object' : object_name})
552 assert ret == 200
553
554 # TESTCASE 'bucket-stats6','bucket','stats','after deleting key','succeeds, lists one no objects'
555 (ret, out) = rgwadmin_rest(admin_conn, ['bucket', 'info'], {'bucket' : bucket_name, 'stats' : True})
556 assert ret == 200
557 assert out['id'] == bucket_id
558 assert out['usage']['rgw.main']['num_objects'] == 0
559
560 # create a bucket for deletion stats
9f95a23c 561 useless_bucket = connection.create_bucket('useless-bucket')
7c673cae
FG
562 useless_key = useless_bucket.new_key('useless_key')
563 useless_key.set_contents_from_string('useless string')
564
565 # delete it
566 useless_key.delete()
567 useless_bucket.delete()
568
569 # wait for the statistics to flush
570 time.sleep(60)
571
572 # need to wait for all usage data to get flushed, should take up to 30 seconds
573 timestamp = time.time()
574 while time.time() - timestamp <= (20 * 60): # wait up to 20 minutes
575 (ret, out) = rgwadmin_rest(admin_conn, ['usage', 'show'], {'categories' : 'delete_obj'}) # last operation we did is delete obj, wait for it to flush
576
577 if get_user_successful_ops(out, user1) > 0:
578 break
579 time.sleep(1)
580
581 assert time.time() - timestamp <= (20 * 60)
582
583 # TESTCASE 'usage-show' 'usage' 'show' 'all usage' 'succeeds'
584 (ret, out) = rgwadmin_rest(admin_conn, ['usage', 'show'])
585 assert ret == 200
586 assert len(out['entries']) > 0
587 assert len(out['summary']) > 0
588 user_summary = get_user_summary(out, user1)
589 total = user_summary['total']
590 assert total['successful_ops'] > 0
591
592 # TESTCASE 'usage-show2' 'usage' 'show' 'user usage' 'succeeds'
593 (ret, out) = rgwadmin_rest(admin_conn, ['usage', 'show'], {'uid' : user1})
594 assert ret == 200
595 assert len(out['entries']) > 0
596 assert len(out['summary']) > 0
597 user_summary = out['summary'][0]
598 for entry in user_summary['categories']:
599 assert entry['successful_ops'] > 0
600 assert user_summary['user'] == user1
601
602 # TESTCASE 'usage-show3' 'usage' 'show' 'user usage categories' 'succeeds'
603 test_categories = ['create_bucket', 'put_obj', 'delete_obj', 'delete_bucket']
604 for cat in test_categories:
605 (ret, out) = rgwadmin_rest(admin_conn, ['usage', 'show'], {'uid' : user1, 'categories' : cat})
606 assert ret == 200
607 assert len(out['summary']) > 0
608 user_summary = out['summary'][0]
609 assert user_summary['user'] == user1
610 assert len(user_summary['categories']) == 1
611 entry = user_summary['categories'][0]
612 assert entry['category'] == cat
613 assert entry['successful_ops'] > 0
614
615 # TESTCASE 'usage-trim' 'usage' 'trim' 'user usage' 'succeeds, usage removed'
616 (ret, out) = rgwadmin_rest(admin_conn, ['usage', 'trim'], {'uid' : user1})
617 assert ret == 200
618 (ret, out) = rgwadmin_rest(admin_conn, ['usage', 'show'], {'uid' : user1})
619 assert ret == 200
620 assert len(out['entries']) == 0
621 assert len(out['summary']) == 0
622
623 # TESTCASE 'user-suspend2','user','suspend','existing user','succeeds'
624 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'modify'], {'uid' : user1, 'suspended' : True})
625 assert ret == 200
626
627 # TESTCASE 'user-suspend3','user','suspend','suspended user','cannot write objects'
628 try:
629 key = boto.s3.key.Key(bucket)
630 key.set_contents_from_string('five')
631 except boto.exception.S3ResponseError as e:
632 assert e.status == 403
633
634 # TESTCASE 'user-renable2','user','enable','suspended user','succeeds'
635 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'modify'], {'uid' : user1, 'suspended' : 'false'})
636 assert ret == 200
637
638 # TESTCASE 'user-renable3','user','enable','reenabled user','can write objects'
639 key = boto.s3.key.Key(bucket)
640 key.set_contents_from_string('six')
641
642 # TESTCASE 'garbage-list', 'garbage', 'list', 'get list of objects ready for garbage collection'
643
644 # create an object large enough to be split into multiple parts
645 test_string = 'foo'*10000000
646
647 big_key = boto.s3.key.Key(bucket)
648 big_key.set_contents_from_string(test_string)
649
650 # now delete the head
651 big_key.delete()
652
653 # TESTCASE 'rm-user-buckets','user','rm','existing user','fails, still has buckets'
654 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'rm'], {'uid' : user1})
655 assert ret == 409
656
657 # delete should fail because ``key`` still exists
658 try:
659 bucket.delete()
660 except boto.exception.S3ResponseError as e:
661 assert e.status == 409
662
663 key.delete()
664 bucket.delete()
665
666 # TESTCASE 'policy', 'bucket', 'policy', 'get bucket policy', 'returns S3 policy'
667 bucket = connection.create_bucket(bucket_name)
668
669 # create an object
670 key = boto.s3.key.Key(bucket)
671 key.set_contents_from_string('seven')
672
673 # should be private already but guarantee it
674 key.set_acl('private')
675
676 (ret, out) = rgwadmin_rest(admin_conn, ['policy', 'show'], {'bucket' : bucket.name, 'object' : key.key})
677 assert ret == 200
11fdf7f2 678 assert len(out['acl']['grant_map']) == 1
7c673cae
FG
679
680 # add another grantee by making the object public read
681 key.set_acl('public-read')
682
683 (ret, out) = rgwadmin_rest(admin_conn, ['policy', 'show'], {'bucket' : bucket.name, 'object' : key.key})
684 assert ret == 200
11fdf7f2 685 assert len(out['acl']['grant_map']) == 2
7c673cae
FG
686
687 # TESTCASE 'rm-bucket', 'bucket', 'rm', 'bucket with objects', 'succeeds'
688 bucket = connection.create_bucket(bucket_name)
689 key_name = ['eight', 'nine', 'ten', 'eleven']
690 for i in range(4):
691 key = boto.s3.key.Key(bucket)
692 key.set_contents_from_string(key_name[i])
693
694 (ret, out) = rgwadmin_rest(admin_conn, ['bucket', 'rm'], {'bucket' : bucket_name, 'purge-objects' : True})
695 assert ret == 200
696
697 # TESTCASE 'caps-add', 'caps', 'add', 'add user cap', 'succeeds'
698 caps = 'usage=read'
699 (ret, out) = rgwadmin_rest(admin_conn, ['caps', 'add'], {'uid' : user1, 'user-caps' : caps})
700 assert ret == 200
701 assert out[0]['perm'] == 'read'
702
703 # TESTCASE 'caps-rm', 'caps', 'rm', 'remove existing cap from user', 'succeeds'
704 (ret, out) = rgwadmin_rest(admin_conn, ['caps', 'rm'], {'uid' : user1, 'user-caps' : caps})
705 assert ret == 200
706 assert not out
707
708 # TESTCASE 'rm-user','user','rm','existing user','fails, still has buckets'
709 bucket = connection.create_bucket(bucket_name)
710 key = boto.s3.key.Key(bucket)
711
712 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'rm'], {'uid' : user1})
713 assert ret == 409
714
715 # TESTCASE 'rm-user2', 'user', 'rm', user with data', 'succeeds'
716 bucket = connection.create_bucket(bucket_name)
717 key = boto.s3.key.Key(bucket)
718 key.set_contents_from_string('twelve')
719
720 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'rm'], {'uid' : user1, 'purge-data' : True})
721 assert ret == 200
722
723 # TESTCASE 'rm-user3','user','info','deleted user','fails'
724 (ret, out) = rgwadmin_rest(admin_conn, ['user', 'info'], {'uid' : user1})
725 assert ret == 404
726
20effc67
TL
727 # TESTCASE 'info' 'display info' 'succeeds'
728 (ret, out) = rgwadmin_rest(admin_conn, ['info', ''])
729 assert ret == 200
730 info = out['info']
731 backends = info['storage_backends']
732 name = backends[0]['name']
733 fsid = backends[0]['cluster_id']
734 # name is always "rados" at time of writing, but zipper would allow
735 # other backends, at some point
736 assert len(name) > 0
737 # fsid is a uuid, but I'm not going to try to parse it
738 assert len(fsid) > 0
739
740 # TESTCASE 'ratelimit' 'user' 'info' 'succeeds'
741 (ret, out) = rgwadmin_rest(admin_conn,
742 ['user', 'create'],
743 {'uid' : ratelimit_user,
744 'display-name' : display_name1,
745 'email' : email,
746 'access-key' : access_key,
747 'secret-key' : secret_key,
748 'max-buckets' : '1000'
749 })
750 (ret, out) = rgwadmin_rest(admin_conn, ['ratelimit', 'info'], {'ratelimit-scope' : 'user', 'uid' : ratelimit_user})
751 assert ret == 200
752
753 # TESTCASE 'ratelimit' 'user' 'info' 'not existing user' 'fails'
754 (ret, out) = rgwadmin_rest(admin_conn, ['ratelimit', 'info'], {'ratelimit-scope' : 'user', 'uid' : ratelimit_user + 'string'})
755 assert ret == 404
756
757 # TESTCASE 'ratelimit' 'user' 'info' 'uid not specified' 'fails'
758 (ret, out) = rgwadmin_rest(admin_conn, ['ratelimit', 'info'], {'ratelimit-scope' : 'user'})
759 assert ret == 400
760
761 # TESTCASE 'ratelimit' 'bucket' 'info' 'succeeds'
762 ratelimit_bucket = 'ratelimitbucket'
763 connection.create_bucket(ratelimit_bucket)
764 (ret, out) = rgwadmin_rest(admin_conn, ['ratelimit', 'info'], {'ratelimit-scope' : 'bucket', 'bucket' : ratelimit_bucket})
765 assert ret == 200
766
767 # TESTCASE 'ratelimit' 'bucket' 'info' 'not existing bucket' 'fails'
768 (ret, out) = rgwadmin_rest(admin_conn, ['ratelimit', 'info'], {'ratelimit-scope' : 'bucket', 'bucket' : ratelimit_bucket + 'string'})
769 assert ret == 404
770
771 # TESTCASE 'ratelimit' 'bucket' 'info' 'bucket not specified' 'fails'
772 (ret, out) = rgwadmin_rest(admin_conn, ['ratelimit', 'info'], {'ratelimit-scope' : 'bucket'})
773 assert ret == 400
774
775 # TESTCASE 'ratelimit' 'global' 'info' 'succeeds'
776 (ret, out) = rgwadmin_rest(admin_conn, ['ratelimit', 'info'], {'global' : 'true'})
777 assert ret == 200
778
779 # TESTCASE 'ratelimit' 'user' 'modify' 'not existing user' 'fails'
780 (ret, out) = rgwadmin_rest(admin_conn, ['ratelimit', 'modify'], {'ratelimit-scope' : 'user', 'uid' : ratelimit_user + 'string', 'enabled' : 'true'})
781 assert ret == 404
782
783 # TESTCASE 'ratelimit' 'user' 'modify' 'uid not specified' 'fails'
784 (ret, out) = rgwadmin_rest(admin_conn, ['ratelimit', 'modify'], {'ratelimit-scope' : 'user'})
785 assert ret == 400
786
787 # TESTCASE 'ratelimit' 'bucket' 'modify' 'not existing bucket' 'fails'
788 (ret, out) = rgwadmin_rest(admin_conn, ['ratelimit', 'modify'], {'ratelimit-scope' : 'bucket', 'bucket' : ratelimit_bucket + 'string', 'enabled' : 'true'})
789 assert ret == 404
790
791 # TESTCASE 'ratelimit' 'bucket' 'modify' 'bucket not specified' 'fails'
792 (ret, out) = rgwadmin_rest(admin_conn, ['ratelimit', 'modify'], {'ratelimit-scope' : 'bucket', 'enabled' : 'true'})
793 assert ret == 400
794
795 # TESTCASE 'ratelimit' 'user' 'modifiy' 'enabled' 'max-read-bytes = 2' 'succeeds'
796 (ret, out) = rgwadmin_rest(admin_conn, ['ratelimit', 'modify'], {'ratelimit-scope' : 'user', 'uid' : ratelimit_user, 'enabled' : 'true', 'max-read-bytes' : '2'})
797 assert ret == 200
798 (ret, out) = rgwadmin_rest(admin_conn, ['ratelimit', 'info'], {'ratelimit-scope' : 'user', 'uid' : ratelimit_user})
799 assert ret == 200
800 user_ratelimit = out['user_ratelimit']
801 assert user_ratelimit['enabled'] == True
802 assert user_ratelimit['max_read_bytes'] == 2
803
804 # TESTCASE 'ratelimit' 'bucket' 'modifiy' 'enabled' 'max-write-bytes = 2' 'succeeds'
805 (ret, out) = rgwadmin_rest(admin_conn, ['ratelimit', 'modify'], {'ratelimit-scope' : 'bucket', 'bucket' : ratelimit_bucket, 'enabled' : 'true', 'max-write-bytes' : '2'})
806 assert ret == 200
807 (ret, out) = rgwadmin_rest(admin_conn, ['ratelimit', 'info'], {'ratelimit-scope' : 'bucket', 'bucket' : ratelimit_bucket})
808 assert ret == 200
809 bucket_ratelimit = out['bucket_ratelimit']
810 assert bucket_ratelimit['enabled'] == True
811 assert bucket_ratelimit['max_write_bytes'] == 2
812
813 # TESTCASE 'ratelimit' 'global' 'modify' 'anonymous' 'enabled' 'succeeds'
814 (ret, out) = rgwadmin_rest(admin_conn, ['ratelimit', 'modify'], {'ratelimit-scope' : 'bucket', 'global': 'true', 'enabled' : 'true'})
815 assert ret == 200