Add support for Swift containers
Can GET/HEAD for account and container details. No support for objects at the moment. Change-Id: Ib6ed56db495e23ba6878c112cdcb02359b6e7398
This commit is contained in:
parent
2f11f38c18
commit
e8b06b5c9c
0
openstack/object_store/__init__.py
Normal file
0
openstack/object_store/__init__.py
Normal file
21
openstack/object_store/object_store_service.py
Normal file
21
openstack/object_store/object_store_service.py
Normal file
@ -0,0 +1,21 @@
|
||||
# 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.auth import service_filter
|
||||
|
||||
|
||||
class ObjectStoreService(service_filter.ServiceFilter):
|
||||
"""The object store service."""
|
||||
|
||||
def __init__(self):
|
||||
"""Create an object store service."""
|
||||
super(ObjectStoreService, self).__init__(service_type='object-store')
|
0
openstack/object_store/v1/__init__.py
Normal file
0
openstack/object_store/v1/__init__.py
Normal file
59
openstack/object_store/v1/container.py
Normal file
59
openstack/object_store/v1/container.py
Normal file
@ -0,0 +1,59 @@
|
||||
# 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 Container(resource.Resource):
|
||||
base_path = "/"
|
||||
service = object_store_service.ObjectStoreService()
|
||||
|
||||
allow_create = True
|
||||
allow_retrieve = True
|
||||
allow_update = True
|
||||
allow_delete = True
|
||||
allow_list = True
|
||||
allow_head = True
|
||||
|
||||
# Account data (from headers when id=None)
|
||||
timestamp = resource.prop("x-timestamp")
|
||||
account_bytes_used = resource.prop("x-account-bytes-used")
|
||||
account_container_count = resource.prop("x-account-container-count")
|
||||
account_object_count = resource.prop("x-account-object-count")
|
||||
meta_temp_url_key = resource.prop("x-account-meta-temp-url-key")
|
||||
meta_temp_url_key_2 = resource.prop("x-account-meta-temp-url-key-2")
|
||||
|
||||
# Container data (from list when id=None)
|
||||
name = resource.prop("name")
|
||||
count = resource.prop("count")
|
||||
bytes = resource.prop("bytes")
|
||||
|
||||
# Container metadata (when id=name)
|
||||
object_count = resource.prop("x-container-object-count")
|
||||
bytes_used = resource.prop("x-container-bytes-used")
|
||||
|
||||
# Optional Container metadata (from head when id=name)
|
||||
can_read = resource.prop("x-container-read")
|
||||
can_write = resource.prop("x-container-write")
|
||||
sync_to = resource.prop("x-container-sync-to")
|
||||
sync_key = resource.prop("x-container-sync-key")
|
||||
versions_location = resource.prop("x-versions-location")
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
try:
|
||||
val = self.name
|
||||
except AttributeError:
|
||||
val = None
|
||||
return val
|
0
openstack/tests/object_store/__init__.py
Normal file
0
openstack/tests/object_store/__init__.py
Normal file
25
openstack/tests/object_store/test_object_store_service.py
Normal file
25
openstack/tests/object_store/test_object_store_service.py
Normal file
@ -0,0 +1,25 @@
|
||||
# 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 import object_store_service
|
||||
|
||||
|
||||
class TestObjectStoreService(testtools.TestCase):
|
||||
|
||||
def test_service(self):
|
||||
sot = object_store_service.ObjectStoreService()
|
||||
self.assertEqual('object-store', sot.service_type)
|
||||
self.assertEqual('public', sot.visibility)
|
||||
self.assertIsNone(sot.region)
|
||||
self.assertIsNone(sot.service_name)
|
0
openstack/tests/object_store/v1/__init__.py
Normal file
0
openstack/tests/object_store/v1/__init__.py
Normal file
143
openstack/tests/object_store/v1/test_container.py
Normal file
143
openstack/tests/object_store/v1/test_container.py
Normal file
@ -0,0 +1,143 @@
|
||||
# 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 mock
|
||||
import testtools
|
||||
|
||||
from openstack.object_store.v1 import container
|
||||
|
||||
|
||||
ACCOUNT_EXAMPLE = {
|
||||
'content-length': '0',
|
||||
'accept-ranges': 'bytes',
|
||||
'x-timestamp': '1403312946.78273',
|
||||
'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,
|
||||
"name": "mycontainer"
|
||||
}
|
||||
|
||||
HEAD_EXAMPLE = {
|
||||
'content-length': '346',
|
||||
'x-container-object-count': '2',
|
||||
'accept-ranges': 'bytes',
|
||||
'id': 'tx1878fdc50f9b4978a3fdc-0053c31462',
|
||||
'date': 'Sun, 13 Jul 2014 23:21:06 GMT',
|
||||
'x-timestamp': '1403312946.79252',
|
||||
'x-container-read': 'read-settings',
|
||||
'x-container-write': 'write-settings',
|
||||
'x-container-sync-to': 'sync-to',
|
||||
'x-container-sync-key': 'sync-key',
|
||||
'x-container-bytes-used': '630666',
|
||||
'x-versions-location': 'versions-location',
|
||||
'content-type': 'application/json; charset=utf-8'
|
||||
}
|
||||
|
||||
LIST_EXAMPLE = [
|
||||
{
|
||||
"count": 999,
|
||||
"bytes": 12345,
|
||||
"name": "container1"
|
||||
},
|
||||
{
|
||||
"count": 888,
|
||||
"bytes": 54321,
|
||||
"name": "container2"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class TestAccount(testtools.TestCase):
|
||||
|
||||
def test_make_it(self):
|
||||
sot = container.Container(ACCOUNT_EXAMPLE)
|
||||
self.assertIsNone(sot.id)
|
||||
self.assertEqual(ACCOUNT_EXAMPLE['x-timestamp'], sot.timestamp)
|
||||
self.assertEqual(ACCOUNT_EXAMPLE['x-account-bytes-used'],
|
||||
sot.account_bytes_used)
|
||||
self.assertEqual(ACCOUNT_EXAMPLE['x-account-container-count'],
|
||||
sot.account_container_count)
|
||||
self.assertEqual(ACCOUNT_EXAMPLE['x-account-object-count'],
|
||||
sot.account_object_count)
|
||||
|
||||
|
||||
class TestContainer(testtools.TestCase):
|
||||
|
||||
def test_basic(self):
|
||||
sot = container.Container(CONT_EXAMPLE)
|
||||
self.assertIsNone(sot.resources_key)
|
||||
self.assertEqual('/', sot.base_path)
|
||||
self.assertEqual('object-store', sot.service.service_type)
|
||||
self.assertTrue(sot.allow_update)
|
||||
self.assertTrue(sot.allow_create)
|
||||
self.assertTrue(sot.allow_retrieve)
|
||||
self.assertTrue(sot.allow_delete)
|
||||
self.assertTrue(sot.allow_list)
|
||||
self.assertTrue(sot.allow_head)
|
||||
|
||||
def test_make_it(self):
|
||||
sot = container.Container(CONT_EXAMPLE)
|
||||
self.assertEqual(CONT_EXAMPLE['name'], sot.id)
|
||||
self.assertEqual(CONT_EXAMPLE['name'], sot.name)
|
||||
self.assertEqual(CONT_EXAMPLE['count'], sot.count)
|
||||
self.assertEqual(CONT_EXAMPLE['bytes'], sot.bytes)
|
||||
|
||||
def test_create_and_head(self):
|
||||
sot = container.Container(CONT_EXAMPLE)
|
||||
|
||||
# Update container with HEAD data
|
||||
sot._attrs.update(HEAD_EXAMPLE)
|
||||
|
||||
# Attributes from create
|
||||
self.assertEqual(CONT_EXAMPLE['name'], sot.id)
|
||||
self.assertEqual(CONT_EXAMPLE['name'], sot.name)
|
||||
self.assertEqual(CONT_EXAMPLE['count'], sot.count)
|
||||
self.assertEqual(CONT_EXAMPLE['bytes'], sot.bytes)
|
||||
|
||||
# Attributes from header
|
||||
self.assertEqual(HEAD_EXAMPLE['x-container-object-count'],
|
||||
sot.object_count)
|
||||
self.assertEqual(HEAD_EXAMPLE['x-container-bytes-used'],
|
||||
sot.bytes_used)
|
||||
self.assertEqual(HEAD_EXAMPLE['x-container-read'],
|
||||
sot.can_read)
|
||||
self.assertEqual(HEAD_EXAMPLE['x-container-write'],
|
||||
sot.can_write)
|
||||
self.assertEqual(HEAD_EXAMPLE['x-container-sync-to'],
|
||||
sot.sync_to)
|
||||
self.assertEqual(HEAD_EXAMPLE['x-container-sync-key'],
|
||||
sot.sync_key)
|
||||
self.assertEqual(HEAD_EXAMPLE['x-versions-location'],
|
||||
sot.versions_location)
|
||||
|
||||
@mock.patch("openstack.resource.Resource.list")
|
||||
def test_list(self, fake_list):
|
||||
fake_val = [container.Container.existing(**ex) for ex in LIST_EXAMPLE]
|
||||
fake_list.return_value = fake_val
|
||||
|
||||
# Since the list method is mocked out, just pass None for the session.
|
||||
response = container.Container.list(None)
|
||||
|
||||
self.assertTrue(len(response), len(LIST_EXAMPLE))
|
||||
for item in range(len(response)):
|
||||
self.assertEqual(type(response[item]), container.Container)
|
||||
self.assertEqual(response[item].name, LIST_EXAMPLE[item]["name"])
|
||||
self.assertEqual(response[item].count, LIST_EXAMPLE[item]["count"])
|
||||
self.assertEqual(response[item].bytes, LIST_EXAMPLE[item]["bytes"])
|
Loading…
Reference in New Issue
Block a user