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:
Brian Curtin 2015-07-13 14:24:33 -05:00
parent c7440a03a1
commit a3a5c2f2f0
7 changed files with 147 additions and 76 deletions

View 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

View File

@ -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.

View 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")

View File

@ -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)

View 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)

View File

@ -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):

View File

@ -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,