Split account/container metadata to own resources
The account data being handled within the Container resource makes for some oddity within that resource as well as from the proxy. They share some commonality that is now in a base class, but their properties are now properly separated. Change-Id: Id81b8a878424498777edea2a985894cc93f7b225 Closes-Bug: 1462641
This commit is contained in:
parent
c7440a03a1
commit
a3a5c2f2f0
39
openstack/object_store/v1/_base.py
Normal file
39
openstack/object_store/v1/_base.py
Normal file
@ -0,0 +1,39 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from openstack.object_store import object_store_service
|
||||
from openstack import resource
|
||||
|
||||
|
||||
class BaseResource(resource.Resource):
|
||||
service = object_store_service.ObjectStoreService()
|
||||
|
||||
@classmethod
|
||||
def update_by_id(cls, session, resource_id, attrs, path_args=None):
|
||||
"""Update a Resource with the given attributes.
|
||||
|
||||
:param session: The session to use for making this request.
|
||||
:type session: :class:`~openstack.session.Session`
|
||||
:param resource_id: This resource's identifier, if needed by
|
||||
the request. The default is ``None``.
|
||||
:param dict attrs: The attributes to be sent in the body
|
||||
of the request.
|
||||
:param dict path_args: This parameter is sent by the base
|
||||
class but is ignored for this method.
|
||||
|
||||
:return: A ``dict`` representing the response headers.
|
||||
"""
|
||||
url = cls._get_url(None, resource_id)
|
||||
headers = attrs.get(resource.HEADERS, dict())
|
||||
return session.post(url, service=cls.service, accept=None,
|
||||
headers=headers).headers
|
@ -10,6 +10,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from openstack.object_store.v1 import account as _account
|
||||
from openstack.object_store.v1 import container as _container
|
||||
from openstack.object_store.v1 import obj as _obj
|
||||
from openstack import proxy
|
||||
@ -21,22 +22,22 @@ class Proxy(proxy.BaseProxy):
|
||||
"""Get metatdata for this account
|
||||
|
||||
:rtype:
|
||||
:class:`~openstack.object_store.v1.container.Container`
|
||||
:class:`~openstack.object_store.v1.account.Account`
|
||||
"""
|
||||
return self._head(_container.Container)
|
||||
return self._head(_account.Account)
|
||||
|
||||
def set_account_metadata(self, container):
|
||||
def set_account_metadata(self, account):
|
||||
"""Set metatdata for this account.
|
||||
|
||||
:param container: Account metadata specified on a
|
||||
:class:`~openstack.object_store.v1.container.Container` object
|
||||
:param account: Account metadata specified on a
|
||||
:class:`~openstack.object_store.v1.account.Account` object
|
||||
to be sent to the server.
|
||||
:type container:
|
||||
:class:`~openstack.object_store.v1.container.Container`
|
||||
:type account:
|
||||
:class:`~openstack.object_store.v1.account.Account`
|
||||
|
||||
:rtype: ``None``
|
||||
"""
|
||||
container.update(self.session)
|
||||
account.update(self.session)
|
||||
|
||||
def containers(self, **query):
|
||||
"""Obtain Container objects for this account.
|
||||
|
38
openstack/object_store/v1/account.py
Normal file
38
openstack/object_store/v1/account.py
Normal file
@ -0,0 +1,38 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from openstack.object_store.v1 import _base
|
||||
from openstack import resource
|
||||
|
||||
|
||||
class Account(_base.BaseResource):
|
||||
base_path = "/"
|
||||
|
||||
allow_retrieve = True
|
||||
allow_update = True
|
||||
allow_head = True
|
||||
|
||||
#: The total number of bytes that are stored in Object Storage for
|
||||
#: the account.
|
||||
account_bytes_used = resource.header("x-account-bytes-used", type=int)
|
||||
#: The number of containers.
|
||||
account_container_count = resource.header("x-account-container-count",
|
||||
type=int)
|
||||
#: The number of objects in the account.
|
||||
account_object_count = resource.header("x-account-object-count", type=int)
|
||||
#: The secret key value for temporary URLs. If not set,
|
||||
#: this header is not returned by this operation.
|
||||
meta_temp_url_key = resource.header("x-account-meta-temp-url-key")
|
||||
#: A second secret key value for temporary URLs. If not set,
|
||||
#: this header is not returned by this operation.
|
||||
meta_temp_url_key_2 = resource.header("x-account-meta-temp-url-key-2")
|
@ -11,13 +11,12 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from openstack.object_store import object_store_service
|
||||
from openstack.object_store.v1 import _base
|
||||
from openstack import resource
|
||||
|
||||
|
||||
class Container(resource.Resource):
|
||||
class Container(_base.BaseResource):
|
||||
base_path = "/"
|
||||
service = object_store_service.ObjectStoreService()
|
||||
id_attribute = "name"
|
||||
|
||||
allow_create = True
|
||||
@ -27,22 +26,6 @@ class Container(resource.Resource):
|
||||
allow_list = True
|
||||
allow_head = True
|
||||
|
||||
# Account data (when id=None)
|
||||
#: The total number of bytes that are stored in Object Storage for
|
||||
#: the account.
|
||||
account_bytes_used = resource.header("x-account-bytes-used", type=int)
|
||||
#: The number of containers.
|
||||
account_container_count = resource.header("x-account-container-count",
|
||||
type=int)
|
||||
#: The number of objects in the account.
|
||||
account_object_count = resource.header("x-account-object-count", type=int)
|
||||
#: The secret key value for temporary URLs. If not set,
|
||||
#: this header is not returned by this operation.
|
||||
meta_temp_url_key = resource.header("x-account-meta-temp-url-key")
|
||||
#: A second secret key value for temporary URLs. If not set,
|
||||
#: this header is not returned by this operation.
|
||||
meta_temp_url_key_2 = resource.header("x-account-meta-temp-url-key-2")
|
||||
|
||||
# Container body data (when id=None)
|
||||
#: The name of the container.
|
||||
name = resource.prop("name")
|
||||
@ -97,29 +80,9 @@ class Container(resource.Resource):
|
||||
#: has a copy of the object before any data is sent.
|
||||
if_none_match = resource.header("if-none-match")
|
||||
|
||||
@classmethod
|
||||
def update_by_id(cls, session, resource_id, attrs, path_args=None):
|
||||
"""Update a Container with the given attributes.
|
||||
|
||||
:param session: The session to use for making this request.
|
||||
:type session: :class:`~openstack.session.Session`
|
||||
:param resource_id: This resource's identifier, if needed by
|
||||
the request. The default is ``None``.
|
||||
:param dict attrs: The attributes to be sent in the body
|
||||
of the request.
|
||||
:param dict path_args: This parameter is sent by the base
|
||||
class but is ignored for this method.
|
||||
|
||||
:return: A ``dict`` representing the response headers.
|
||||
"""
|
||||
url = cls._get_url(None, resource_id)
|
||||
headers = attrs.get(resource.HEADERS, dict())
|
||||
return session.post(url, service=cls.service, accept=None,
|
||||
headers=headers).headers
|
||||
|
||||
@classmethod
|
||||
def create_by_id(cls, session, attrs, resource_id=None):
|
||||
"""Create a Container from its attributes.
|
||||
"""Create a Resource from its attributes.
|
||||
|
||||
:param session: The session to use for making this request.
|
||||
:type session: :class:`~openstack.session.Session`
|
||||
@ -136,13 +99,12 @@ class Container(resource.Resource):
|
||||
headers=headers).headers
|
||||
|
||||
def create(self, session):
|
||||
"""Create a Container from this instance.
|
||||
"""Create a Resource from this instance.
|
||||
|
||||
:param session: The session to use for making this request.
|
||||
:type session: :class:`~openstack.session.Session`
|
||||
|
||||
:return: This :class:`~openstack.object_store.v1.container.Container`
|
||||
instance.
|
||||
:return: This instance.
|
||||
"""
|
||||
resp = self.create_by_id(session, self._attrs, self.id)
|
||||
self.set_headers(resp)
|
||||
|
54
openstack/tests/unit/object_store/v1/test_account.py
Normal file
54
openstack/tests/unit/object_store/v1/test_account.py
Normal file
@ -0,0 +1,54 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import testtools
|
||||
|
||||
from openstack.object_store.v1 import account
|
||||
|
||||
|
||||
CONTAINER_NAME = "mycontainer"
|
||||
|
||||
ACCOUNT_EXAMPLE = {
|
||||
'content-length': '0',
|
||||
'accept-ranges': 'bytes',
|
||||
'date': 'Sat, 05 Jul 2014 19:17:40 GMT',
|
||||
'x-account-bytes-used': '12345',
|
||||
'x-account-container-count': '678',
|
||||
'content-type': 'text/plain; charset=utf-8',
|
||||
'x-account-object-count': '98765'
|
||||
}
|
||||
|
||||
|
||||
class TestAccount(testtools.TestCase):
|
||||
|
||||
def test_basic(self):
|
||||
sot = account.Account.new(**ACCOUNT_EXAMPLE)
|
||||
self.assertIsNone(sot.resources_key)
|
||||
self.assertIsNone(sot.id)
|
||||
self.assertEqual('/', sot.base_path)
|
||||
self.assertEqual('object-store', sot.service.service_type)
|
||||
self.assertTrue(sot.allow_update)
|
||||
self.assertTrue(sot.allow_head)
|
||||
self.assertTrue(sot.allow_retrieve)
|
||||
self.assertFalse(sot.allow_delete)
|
||||
self.assertFalse(sot.allow_list)
|
||||
self.assertFalse(sot.allow_create)
|
||||
|
||||
def test_make_it(self):
|
||||
sot = account.Account.new(**{'headers': ACCOUNT_EXAMPLE})
|
||||
self.assertIsNone(sot.id)
|
||||
self.assertEqual(int(ACCOUNT_EXAMPLE['x-account-bytes-used']),
|
||||
sot.account_bytes_used)
|
||||
self.assertEqual(int(ACCOUNT_EXAMPLE['x-account-container-count']),
|
||||
sot.account_container_count)
|
||||
self.assertEqual(int(ACCOUNT_EXAMPLE['x-account-object-count']),
|
||||
sot.account_object_count)
|
@ -18,17 +18,6 @@ from openstack.object_store.v1 import container
|
||||
|
||||
CONTAINER_NAME = "mycontainer"
|
||||
|
||||
ACCOUNT_EXAMPLE = {
|
||||
'content-length': '0',
|
||||
'accept-ranges': 'bytes',
|
||||
'id': 'tx4272aa0d6e1e4f8f971f8-0053b84f54',
|
||||
'date': 'Sat, 05 Jul 2014 19:17:40 GMT',
|
||||
'x-account-bytes-used': '12345',
|
||||
'x-account-container-count': '678',
|
||||
'content-type': 'text/plain; charset=utf-8',
|
||||
'x-account-object-count': '98765'
|
||||
}
|
||||
|
||||
CONT_EXAMPLE = {
|
||||
"count": 999,
|
||||
"bytes": 12345,
|
||||
@ -64,19 +53,6 @@ LIST_EXAMPLE = [
|
||||
]
|
||||
|
||||
|
||||
class TestAccount(testtools.TestCase):
|
||||
|
||||
def test_make_it(self):
|
||||
sot = container.Container.new(**{'headers': ACCOUNT_EXAMPLE})
|
||||
self.assertIsNone(sot.id)
|
||||
self.assertEqual(int(ACCOUNT_EXAMPLE['x-account-bytes-used']),
|
||||
sot.account_bytes_used)
|
||||
self.assertEqual(int(ACCOUNT_EXAMPLE['x-account-container-count']),
|
||||
sot.account_container_count)
|
||||
self.assertEqual(int(ACCOUNT_EXAMPLE['x-account-object-count']),
|
||||
sot.account_object_count)
|
||||
|
||||
|
||||
class TestContainer(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
@ -14,6 +14,7 @@ import mock
|
||||
import six
|
||||
|
||||
from openstack.object_store.v1 import _proxy
|
||||
from openstack.object_store.v1 import account
|
||||
from openstack.object_store.v1 import container
|
||||
from openstack.object_store.v1 import obj
|
||||
from openstack import session
|
||||
@ -30,7 +31,7 @@ class TestObjectStoreProxy(test_proxy_base.TestProxyBase):
|
||||
self.proxy = _proxy.Proxy(self.session)
|
||||
|
||||
def test_account_metadata_get(self):
|
||||
self.verify_head(self.proxy.get_account_metadata, container.Container)
|
||||
self.verify_head(self.proxy.get_account_metadata, account.Account)
|
||||
|
||||
def test_container_metadata_get(self):
|
||||
self.verify_head(self.proxy.get_container_metadata,
|
||||
|
Loading…
x
Reference in New Issue
Block a user