Fix create, update or delete container metadata method
Swift provides a single API to Create, Update or Delete container metadata. With different headers or values those operation can be achieved. For example: - delete metadata by passing metadata without value - update metadata by passing updated value with same key Details- https://developer.openstack.org/api-ref/object-store/?expanded=create-update-or-delete-container-metadata-detail But current service client for account has 2 different method for these operation. update_, delete_ To make it consistent with other service client and to have single service client method per API, this patch merge those methods. Partially implements blueprint consistent-service-method-names Change-Id: I75e40fc5c19d5b56d2be5f68e6cdb41bda4f9595
This commit is contained in:
parent
871b1a837e
commit
7351cbdc09
@ -41,10 +41,11 @@ class ObjectTestACLs(base.BaseObjectTest):
|
||||
tenant_name = self.os_roles_operator_alt.credentials.tenant_name
|
||||
username = self.os_roles_operator_alt.credentials.username
|
||||
cont_headers = {'X-Container-Read': tenant_name + ':' + username}
|
||||
container_client = self.os_roles_operator.container_client
|
||||
resp_meta, _ = (
|
||||
self.os_roles_operator.container_client.update_container_metadata(
|
||||
self.container_name, metadata=cont_headers,
|
||||
metadata_prefix=''))
|
||||
container_client.create_update_or_delete_container_metadata(
|
||||
self.container_name, create_update_metadata=cont_headers,
|
||||
create_update_metadata_prefix=''))
|
||||
self.assertHeaders(resp_meta, 'Container', 'POST')
|
||||
# create object
|
||||
object_name = data_utils.rand_name(name='Object')
|
||||
@ -68,10 +69,11 @@ class ObjectTestACLs(base.BaseObjectTest):
|
||||
tenant_name = self.os_roles_operator_alt.credentials.tenant_name
|
||||
username = self.os_roles_operator_alt.credentials.username
|
||||
cont_headers = {'X-Container-Write': tenant_name + ':' + username}
|
||||
container_client = self.os_roles_operator.container_client
|
||||
resp_meta, _ = (
|
||||
self.os_roles_operator.container_client.update_container_metadata(
|
||||
self.container_name, metadata=cont_headers,
|
||||
metadata_prefix=''))
|
||||
container_client.create_update_or_delete_container_metadata(
|
||||
self.container_name, create_update_metadata=cont_headers,
|
||||
create_update_metadata_prefix=''))
|
||||
self.assertHeaders(resp_meta, 'Container', 'POST')
|
||||
# set alternative authentication data; cannot simply use the
|
||||
# other object client.
|
||||
|
@ -133,9 +133,10 @@ class ObjectACLsNegativeTest(base.BaseObjectTest):
|
||||
# attempt to read object using non-authorized user
|
||||
# update X-Container-Read metadata ACL
|
||||
cont_headers = {'X-Container-Read': 'badtenant:baduser'}
|
||||
resp_meta, _ = self.container_client.update_container_metadata(
|
||||
self.container_name, metadata=cont_headers,
|
||||
metadata_prefix='')
|
||||
resp_meta, _ = (
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
self.container_name, create_update_metadata=cont_headers,
|
||||
create_update_metadata_prefix=''))
|
||||
self.assertHeaders(resp_meta, 'Container', 'POST')
|
||||
# create object
|
||||
object_name = data_utils.rand_name(name='Object')
|
||||
@ -157,9 +158,10 @@ class ObjectACLsNegativeTest(base.BaseObjectTest):
|
||||
# attempt to write object using non-authorized user
|
||||
# update X-Container-Write metadata ACL
|
||||
cont_headers = {'X-Container-Write': 'badtenant:baduser'}
|
||||
resp_meta, _ = self.container_client.update_container_metadata(
|
||||
self.container_name, metadata=cont_headers,
|
||||
metadata_prefix='')
|
||||
resp_meta, _ = (
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
self.container_name, create_update_metadata=cont_headers,
|
||||
create_update_metadata_prefix=''))
|
||||
self.assertHeaders(resp_meta, 'Container', 'POST')
|
||||
# Trying to write the object without rights
|
||||
self.object_client.auth_provider.set_alt_auth_data(
|
||||
@ -182,9 +184,10 @@ class ObjectACLsNegativeTest(base.BaseObjectTest):
|
||||
cont_headers = {'X-Container-Read':
|
||||
tenant_name + ':' + username,
|
||||
'X-Container-Write': ''}
|
||||
resp_meta, _ = self.container_client.update_container_metadata(
|
||||
self.container_name, metadata=cont_headers,
|
||||
metadata_prefix='')
|
||||
resp_meta, _ = (
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
self.container_name, create_update_metadata=cont_headers,
|
||||
create_update_metadata_prefix=''))
|
||||
self.assertHeaders(resp_meta, 'Container', 'POST')
|
||||
# Trying to write the object without write rights
|
||||
self.object_client.auth_provider.set_alt_auth_data(
|
||||
@ -207,9 +210,10 @@ class ObjectACLsNegativeTest(base.BaseObjectTest):
|
||||
cont_headers = {'X-Container-Read':
|
||||
tenant_name + ':' + username,
|
||||
'X-Container-Write': ''}
|
||||
resp_meta, _ = self.container_client.update_container_metadata(
|
||||
self.container_name, metadata=cont_headers,
|
||||
metadata_prefix='')
|
||||
resp_meta, _ = (
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
self.container_name, create_update_metadata=cont_headers,
|
||||
create_update_metadata_prefix=''))
|
||||
self.assertHeaders(resp_meta, 'Container', 'POST')
|
||||
# create object
|
||||
object_name = data_utils.rand_name(name='Object')
|
||||
|
@ -40,8 +40,8 @@ class ContainerQuotasTest(base.BaseObjectTest):
|
||||
self.container_name = self.create_container()
|
||||
metadata = {"quota-bytes": str(QUOTA_BYTES),
|
||||
"quota-count": str(QUOTA_COUNT), }
|
||||
self.container_client.update_container_metadata(
|
||||
self.container_name, metadata)
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
self.container_name, create_update_metadata=metadata)
|
||||
|
||||
def tearDown(self):
|
||||
"""Cleans the container of any object after each test."""
|
||||
|
@ -277,9 +277,9 @@ class ContainerTest(base.BaseObjectTest):
|
||||
container_name = self.create_container()
|
||||
|
||||
metadata = {'name': 'Pictures'}
|
||||
self.container_client.update_container_metadata(
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
container_name,
|
||||
metadata=metadata)
|
||||
create_update_metadata=metadata)
|
||||
|
||||
resp, _ = self.container_client.list_container_metadata(
|
||||
container_name)
|
||||
@ -307,10 +307,11 @@ class ContainerTest(base.BaseObjectTest):
|
||||
self.containers.append(container_name)
|
||||
|
||||
metadata_2 = {'test-container-meta2': 'Meta2'}
|
||||
resp, _ = self.container_client.update_container_metadata(
|
||||
container_name,
|
||||
metadata=metadata_2,
|
||||
remove_metadata=metadata_1)
|
||||
resp, _ = (
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
container_name,
|
||||
create_update_metadata=metadata_2,
|
||||
delete_metadata=metadata_1))
|
||||
self.assertHeaders(resp, 'Container', 'POST')
|
||||
|
||||
resp, _ = self.container_client.list_container_metadata(
|
||||
@ -326,9 +327,10 @@ class ContainerTest(base.BaseObjectTest):
|
||||
container_name = self.create_container()
|
||||
|
||||
metadata = {'test-container-meta1': 'Meta1'}
|
||||
resp, _ = self.container_client.update_container_metadata(
|
||||
container_name,
|
||||
metadata=metadata)
|
||||
resp, _ = (
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
container_name,
|
||||
create_update_metadata=metadata))
|
||||
self.assertHeaders(resp, 'Container', 'POST')
|
||||
|
||||
resp, _ = self.container_client.list_container_metadata(
|
||||
@ -346,9 +348,10 @@ class ContainerTest(base.BaseObjectTest):
|
||||
metadata=metadata)
|
||||
self.containers.append(container_name)
|
||||
|
||||
resp, _ = self.container_client.delete_container_metadata(
|
||||
container_name,
|
||||
metadata=metadata)
|
||||
resp, _ = (
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
container_name,
|
||||
delete_metadata=metadata))
|
||||
self.assertHeaders(resp, 'Container', 'POST')
|
||||
|
||||
resp, _ = self.container_client.list_container_metadata(
|
||||
@ -361,9 +364,10 @@ class ContainerTest(base.BaseObjectTest):
|
||||
container_name = self.create_container()
|
||||
|
||||
metadata = {'test-container-meta1': ''}
|
||||
resp, _ = self.container_client.update_container_metadata(
|
||||
container_name,
|
||||
metadata=metadata)
|
||||
resp, _ = (
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
container_name,
|
||||
create_update_metadata=metadata))
|
||||
self.assertHeaders(resp, 'Container', 'POST')
|
||||
|
||||
resp, _ = self.container_client.list_container_metadata(
|
||||
@ -380,9 +384,10 @@ class ContainerTest(base.BaseObjectTest):
|
||||
self.containers.append(container_name)
|
||||
|
||||
metadata = {'test-container-meta1': ''}
|
||||
resp, _ = self.container_client.delete_container_metadata(
|
||||
container_name,
|
||||
metadata=metadata)
|
||||
resp, _ = (
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
container_name,
|
||||
delete_metadata=metadata))
|
||||
self.assertHeaders(resp, 'Container', 'POST')
|
||||
|
||||
resp, _ = self.container_client.list_container_metadata(container_name)
|
||||
|
@ -120,9 +120,10 @@ class ContainerNegativeTest(base.BaseObjectTest):
|
||||
# Attempts to update metadata using a nonexistent container name.
|
||||
metadata = {'animal': 'penguin'}
|
||||
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
self.container_client.update_container_metadata,
|
||||
'nonexistent_container_name', metadata)
|
||||
self.assertRaises(
|
||||
exceptions.NotFound,
|
||||
self.container_client.create_update_or_delete_container_metadata,
|
||||
'nonexistent_container_name', create_update_metadata=metadata)
|
||||
|
||||
@decorators.attr(type=["negative"])
|
||||
@decorators.idempotent_id('65387dbf-a0e2-4aac-9ddc-16eb3f1f69ba')
|
||||
@ -130,9 +131,10 @@ class ContainerNegativeTest(base.BaseObjectTest):
|
||||
# Attempts to delete metadata using a nonexistent container name.
|
||||
metadata = {'animal': 'penguin'}
|
||||
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
self.container_client.delete_container_metadata,
|
||||
'nonexistent_container_name', metadata)
|
||||
self.assertRaises(
|
||||
exceptions.NotFound,
|
||||
self.container_client.create_update_or_delete_container_metadata,
|
||||
'nonexistent_container_name', delete_metadata=metadata)
|
||||
|
||||
@decorators.attr(type=["negative"])
|
||||
@decorators.idempotent_id('14331d21-1e81-420a-beea-19cb5e5207f5')
|
||||
|
@ -34,10 +34,10 @@ class StaticWebTest(base.BaseObjectTest):
|
||||
cls.object_name, cls.object_data = cls.create_object(
|
||||
cls.container_name)
|
||||
|
||||
cls.container_client.update_container_metadata(
|
||||
cls.container_client.create_update_or_delete_container_metadata(
|
||||
cls.container_name,
|
||||
metadata=headers_public_read_acl,
|
||||
metadata_prefix="X-Container-")
|
||||
create_update_metadata=headers_public_read_acl,
|
||||
create_update_metadata_prefix="X-Container-")
|
||||
|
||||
@classmethod
|
||||
def resource_cleanup(cls):
|
||||
@ -49,8 +49,8 @@ class StaticWebTest(base.BaseObjectTest):
|
||||
def test_web_index(self):
|
||||
headers = {'web-index': self.object_name}
|
||||
|
||||
self.container_client.update_container_metadata(
|
||||
self.container_name, metadata=headers)
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
self.container_name, create_update_metadata=headers)
|
||||
|
||||
# Maintain original headers, no auth added
|
||||
self.account_client.auth_provider.set_alt_auth_data(
|
||||
@ -68,8 +68,9 @@ class StaticWebTest(base.BaseObjectTest):
|
||||
self.assertEqual(body, self.object_data)
|
||||
|
||||
# clean up before exiting
|
||||
self.container_client.update_container_metadata(self.container_name,
|
||||
{'web-index': ""})
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
self.container_name,
|
||||
create_update_metadata={'web-index': ""})
|
||||
|
||||
_, body = self.container_client.list_container_metadata(
|
||||
self.container_name)
|
||||
@ -80,8 +81,8 @@ class StaticWebTest(base.BaseObjectTest):
|
||||
def test_web_listing(self):
|
||||
headers = {'web-listings': 'true'}
|
||||
|
||||
self.container_client.update_container_metadata(
|
||||
self.container_name, metadata=headers)
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
self.container_name, create_update_metadata=headers)
|
||||
|
||||
# test GET on http://account_url/container_name
|
||||
# we should retrieve a listing of objects
|
||||
@ -100,9 +101,9 @@ class StaticWebTest(base.BaseObjectTest):
|
||||
self.assertIn(self.object_name, body.decode())
|
||||
|
||||
# clean up before exiting
|
||||
self.container_client.update_container_metadata(self.container_name,
|
||||
{'web-listings': ""})
|
||||
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
self.container_name,
|
||||
create_update_metadata={'web-listings': ""})
|
||||
_, body = self.container_client.list_container_metadata(
|
||||
self.container_name)
|
||||
self.assertNotIn('x-container-meta-web-listings', body)
|
||||
@ -113,8 +114,8 @@ class StaticWebTest(base.BaseObjectTest):
|
||||
headers = {'web-listings': 'true',
|
||||
'web-listings-css': 'listings.css'}
|
||||
|
||||
self.container_client.update_container_metadata(
|
||||
self.container_name, metadata=headers)
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
self.container_name, create_update_metadata=headers)
|
||||
|
||||
# Maintain original headers, no auth added
|
||||
self.account_client.auth_provider.set_alt_auth_data(
|
||||
@ -136,8 +137,8 @@ class StaticWebTest(base.BaseObjectTest):
|
||||
headers = {'web-listings': 'true',
|
||||
'web-error': self.object_name}
|
||||
|
||||
self.container_client.update_container_metadata(
|
||||
self.container_name, metadata=headers)
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
self.container_name, create_update_metadata=headers)
|
||||
|
||||
# Create object to return when requested object not found
|
||||
object_name_404 = "404" + self.object_name
|
||||
|
@ -990,8 +990,11 @@ class PublicObjectTest(base.BaseObjectTest):
|
||||
|
||||
# update container metadata to make it publicly readable
|
||||
cont_headers = {'X-Container-Read': '.r:*,.rlistings'}
|
||||
resp_meta, body = self.container_client.update_container_metadata(
|
||||
self.container_name, metadata=cont_headers, metadata_prefix='')
|
||||
resp_meta, body = (
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
self.container_name,
|
||||
create_update_metadata=cont_headers,
|
||||
create_update_metadata_prefix=''))
|
||||
self.assertHeaders(resp_meta, 'Container', 'POST')
|
||||
|
||||
# create object
|
||||
@ -1025,9 +1028,10 @@ class PublicObjectTest(base.BaseObjectTest):
|
||||
# make container public-readable and access an object in it using
|
||||
# another user's credentials
|
||||
cont_headers = {'X-Container-Read': '.r:*,.rlistings'}
|
||||
resp_meta, body = self.container_client.update_container_metadata(
|
||||
self.container_name, metadata=cont_headers,
|
||||
metadata_prefix='')
|
||||
resp_meta, body = (
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
self.container_name, create_update_metadata=cont_headers,
|
||||
create_update_metadata_prefix=''))
|
||||
self.assertHeaders(resp_meta, 'Container', 'POST')
|
||||
|
||||
# create object
|
||||
|
@ -1367,8 +1367,8 @@ class ObjectStorageScenarioTest(ScenarioTest):
|
||||
def change_container_acl(self, container_name, acl):
|
||||
metadata_param = {'metadata_prefix': 'x-container-',
|
||||
'metadata': {'read': acl}}
|
||||
self.container_client.update_container_metadata(container_name,
|
||||
**metadata_param)
|
||||
self.container_client.create_update_or_delete_container_metadata(
|
||||
container_name, create_update_metadata=metadata_param)
|
||||
resp, _ = self.container_client.list_container_metadata(container_name)
|
||||
self.assertEqual(resp['x-container-read'], acl)
|
||||
|
||||
|
@ -55,40 +55,37 @@ class ContainerClient(rest_client.RestClient):
|
||||
self.expected_success(204, resp.status)
|
||||
return resp, body
|
||||
|
||||
def update_container_metadata(
|
||||
def create_update_or_delete_container_metadata(
|
||||
self, container_name,
|
||||
metadata=None,
|
||||
remove_metadata=None,
|
||||
metadata_prefix='X-Container-Meta-',
|
||||
remove_metadata_prefix='X-Remove-Container-Meta-'):
|
||||
"""Updates arbitrary metadata on container."""
|
||||
create_update_metadata=None,
|
||||
delete_metadata=None,
|
||||
create_update_metadata_prefix='X-Container-Meta-',
|
||||
delete_metadata_prefix='X-Remove-Container-Meta-'):
|
||||
"""Creates, Updates or deletes an containter metadata entry.
|
||||
|
||||
Container Metadata can be created, updated or deleted based on
|
||||
metadata header or value. For detailed info, please refer to the
|
||||
official API reference:
|
||||
https://developer.openstack.org/api-ref/object-store/#create-update-or-delete-container-metadata
|
||||
"""
|
||||
url = str(container_name)
|
||||
headers = {}
|
||||
if create_update_metadata:
|
||||
for key in create_update_metadata:
|
||||
metadata_header_name = create_update_metadata_prefix + key
|
||||
headers[metadata_header_name] = create_update_metadata[key]
|
||||
if delete_metadata:
|
||||
for key in delete_metadata:
|
||||
headers[delete_metadata_prefix + key] = delete_metadata[key]
|
||||
|
||||
if metadata is not None:
|
||||
for key in metadata:
|
||||
headers[metadata_prefix + key] = metadata[key]
|
||||
if remove_metadata is not None:
|
||||
for key in remove_metadata:
|
||||
headers[remove_metadata_prefix + key] = remove_metadata[key]
|
||||
|
||||
resp, body = self.post(url, body=None, headers=headers)
|
||||
resp, body = self.post(url, headers=headers, body=None)
|
||||
self.expected_success(204, resp.status)
|
||||
return resp, body
|
||||
|
||||
def delete_container_metadata(self, container_name, metadata,
|
||||
metadata_prefix='X-Remove-Container-Meta-'):
|
||||
"""Deletes arbitrary metadata on container."""
|
||||
url = str(container_name)
|
||||
headers = {}
|
||||
|
||||
if metadata is not None:
|
||||
for item in metadata:
|
||||
headers[metadata_prefix + item] = metadata[item]
|
||||
|
||||
resp, body = self.post(url, body=None, headers=headers)
|
||||
self.expected_success(204, resp.status)
|
||||
return resp, body
|
||||
update_container_metadata = debtcollector.moves.moved_function(
|
||||
create_update_or_delete_container_metadata,
|
||||
'update_container_metadata', __name__,
|
||||
version='Queens', removal_version='Rocky')
|
||||
|
||||
def list_container_metadata(self, container_name):
|
||||
"""List all container metadata."""
|
||||
|
Loading…
x
Reference in New Issue
Block a user