Fix setting initial object/container metadata.

As of now we can not easily set object_store resources metadata on the
creation when using proxy layer directly. While create_object claimed
that it was never really working. As a prerequisite for switching cloud
layer to rely on proxy we need to address this.

Change-Id: Icacef2044efd6e1096bb88aa830dc64cac43bde5
This commit is contained in:
Artem Goncharov 2021-09-09 15:11:39 +02:00
parent 5f9cc4fe00
commit bba9c5c508
7 changed files with 45 additions and 14 deletions

View File

@ -26,6 +26,23 @@ class BaseResource(resource.Resource):
_custom_metadata_prefix = None
_system_metadata = dict()
def __init__(self, metadata=None, **attrs):
"""Process and save metadata known at creation stage
"""
super().__init__(**attrs)
if metadata is not None:
for k, v in metadata.items():
if not k.lower().startswith(
self._custom_metadata_prefix.lower()):
self.metadata[self._custom_metadata_prefix + k] = v
else:
self.metadata[k] = v
def _prepare_request(self, **kwargs):
request = super()._prepare_request(**kwargs)
request.headers.update(self._calculate_headers(self.metadata))
return request
def _calculate_headers(self, metadata):
headers = {}
for key in metadata:

View File

@ -359,11 +359,6 @@ class Proxy(proxy.Proxy):
headers[self._connection._OBJECT_MD5_KEY] = md5 or ''
if sha256:
headers[self._connection._OBJECT_SHA256_KEY] = sha256 or ''
for (k, v) in metadata.items():
if not k.lower().startswith('x-object-meta-'):
headers['x-object-meta-' + k] = v
else:
headers[k] = v
container_name = self._get_container_name(container=container)
endpoint = '{container}/{name}'.format(container=container_name,
@ -376,7 +371,8 @@ class Proxy(proxy.Proxy):
# TODO(gtema): custom headers need to be somehow injected
return self._create(
_obj.Object, container=container_name,
name=name, data=data, **headers)
name=name, data=data, metadata=metadata,
**headers)
# segment_size gets used as a step value in a range call, so needs
# to be an int

View File

@ -175,7 +175,7 @@ class Object(_base.BaseResource):
has_body = False
def __init__(self, data=None, **attrs):
super(_base.BaseResource, self).__init__(**attrs)
super().__init__(**attrs)
self.data = data
# The Object Store treats the metadata for its resources inconsistently so
@ -290,7 +290,8 @@ class Object(_base.BaseResource):
response = session.put(
request.url,
data=self.data,
headers=request.headers)
headers=request.headers
)
self._translate_response(response, has_body=False)
return self

View File

@ -137,6 +137,7 @@ class TestContainer(base.TestCase):
"x-container-read": "some ACL",
"x-container-write": "another ACL",
"x-detect-content-type": 'True',
"X-Container-Meta-foo": "bar"
}
self.register_uris([
dict(method=sess_method, uri=self.container_endpoint,
@ -148,11 +149,13 @@ class TestContainer(base.TestCase):
self.assert_calls()
def test_create(self):
sot = container.Container.new(name=self.container)
sot = container.Container.new(
name=self.container, metadata={'foo': 'bar'})
self._test_create_update(sot, sot.create, 'PUT')
def test_commit(self):
sot = container.Container.new(name=self.container)
sot = container.Container.new(
name=self.container, metadata={'foo': 'bar'})
self._test_create_update(sot, sot.commit, 'POST')
def test_to_dict_recursion(self):

View File

@ -128,10 +128,14 @@ class TestObject(base_test_object.BaseTestObject):
self.assert_calls()
def _test_create(self, method, data):
sot = obj.Object.new(container=self.container, name=self.object,
data=data)
sot = obj.Object.new(
container=self.container, name=self.object,
data=data, metadata={'foo': 'bar'})
sot.is_newest = True
sent_headers = {"x-newest": 'True'}
sent_headers = {
"x-newest": 'True',
"X-Object-Meta-foo": "bar"
}
self.register_uris([
dict(method=method, uri=self.object_endpoint,
headers=self.headers,

View File

@ -93,7 +93,12 @@ class TestObjectStoreProxy(test_proxy_base.TestProxyBase):
self._test_object_delete(True)
def test_object_create_attrs(self):
kwargs = {"name": "test", "data": "data", "container": "name"}
kwargs = {
"name": "test",
"data": "data",
"container": "name",
"metadata": {}
}
self._verify(
"openstack.proxy.Proxy._create",

View File

@ -0,0 +1,5 @@
---
fixes:
- |
It is now possible to pass `metadata` parameter directly into the create_container,
create_object object_store methods and will not be ignored.