Add storage policy option to create container command
+ Add CLI option to specify swift storage policy + Add CLI flag to specify container uses public read ACLS + Show storage policy in container show data Change-Id: I08ffa0d98bd39d467aa415771675f59bd77768ff
This commit is contained in:
parent
e07324e30f
commit
d6022f96df
@ -24,6 +24,11 @@ from six.moves import urllib
|
|||||||
from openstackclient.api import api
|
from openstackclient.api import api
|
||||||
|
|
||||||
|
|
||||||
|
GLOBAL_READ_ACL = ".r:*"
|
||||||
|
LIST_CONTENTS_ACL = ".rlistings"
|
||||||
|
PUBLIC_CONTAINER_ACLS = [GLOBAL_READ_ACL, LIST_CONTENTS_ACL]
|
||||||
|
|
||||||
|
|
||||||
class APIv1(api.BaseAPI):
|
class APIv1(api.BaseAPI):
|
||||||
"""Object Store v1 API"""
|
"""Object Store v1 API"""
|
||||||
|
|
||||||
@ -33,15 +38,32 @@ class APIv1(api.BaseAPI):
|
|||||||
def container_create(
|
def container_create(
|
||||||
self,
|
self,
|
||||||
container=None,
|
container=None,
|
||||||
|
public=False,
|
||||||
|
storage_policy=None
|
||||||
):
|
):
|
||||||
"""Create a container
|
"""Create a container
|
||||||
|
|
||||||
:param string container:
|
:param string container:
|
||||||
name of container to create
|
name of container to create
|
||||||
|
:param bool public:
|
||||||
|
Boolean value indicating if the container should be publicly
|
||||||
|
readable. Defaults to False.
|
||||||
|
:param string storage_policy:
|
||||||
|
Name of the a specific storage policy to use. If not specified
|
||||||
|
swift will use its default storage policy.
|
||||||
:returns:
|
:returns:
|
||||||
dict of returned headers
|
dict of returned headers
|
||||||
"""
|
"""
|
||||||
response = self.create(urllib.parse.quote(container), method='PUT')
|
|
||||||
|
headers = {}
|
||||||
|
if public:
|
||||||
|
headers['x-container-read'] = ",".join(PUBLIC_CONTAINER_ACLS)
|
||||||
|
if storage_policy is not None:
|
||||||
|
headers['x-storage-policy'] = storage_policy
|
||||||
|
|
||||||
|
response = self.create(
|
||||||
|
urllib.parse.quote(container), method='PUT', headers=headers)
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'account': self._find_account_id(),
|
'account': self._find_account_id(),
|
||||||
'container': container,
|
'container': container,
|
||||||
@ -173,7 +195,8 @@ class APIv1(api.BaseAPI):
|
|||||||
'object_count': response.headers.get(
|
'object_count': response.headers.get(
|
||||||
'x-container-object-count'
|
'x-container-object-count'
|
||||||
),
|
),
|
||||||
'bytes_used': response.headers.get('x-container-bytes-used')
|
'bytes_used': response.headers.get('x-container-bytes-used'),
|
||||||
|
'storage_policy': response.headers.get('x-storage-policy'),
|
||||||
}
|
}
|
||||||
|
|
||||||
if 'x-container-read' in response.headers:
|
if 'x-container-read' in response.headers:
|
||||||
|
@ -33,6 +33,16 @@ class CreateContainer(command.Lister):
|
|||||||
|
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super(CreateContainer, self).get_parser(prog_name)
|
parser = super(CreateContainer, self).get_parser(prog_name)
|
||||||
|
parser.add_argument(
|
||||||
|
'--public',
|
||||||
|
action='store_true',
|
||||||
|
default=False,
|
||||||
|
help="Make the container publicly accessible"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--storage-policy',
|
||||||
|
help="Specify a particular storage policy to use."
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'containers',
|
'containers',
|
||||||
metavar='<container-name>',
|
metavar='<container-name>',
|
||||||
@ -51,6 +61,8 @@ class CreateContainer(command.Lister):
|
|||||||
' is 256'), len(container))
|
' is 256'), len(container))
|
||||||
data = self.app.client_manager.object_store.container_create(
|
data = self.app.client_manager.object_store.container_create(
|
||||||
container=container,
|
container=container,
|
||||||
|
public=parsed_args.public,
|
||||||
|
storage_policy=parsed_args.storage_policy
|
||||||
)
|
)
|
||||||
results.append(data)
|
results.append(data)
|
||||||
|
|
||||||
|
@ -151,12 +151,14 @@ class TestContainer(TestObjectAPIv1):
|
|||||||
'X-Container-Meta-Owner': FAKE_ACCOUNT,
|
'X-Container-Meta-Owner': FAKE_ACCOUNT,
|
||||||
'x-container-object-count': '1',
|
'x-container-object-count': '1',
|
||||||
'x-container-bytes-used': '577',
|
'x-container-bytes-used': '577',
|
||||||
|
'x-storage-policy': 'o1--sr-r3'
|
||||||
}
|
}
|
||||||
resp = {
|
resp = {
|
||||||
'account': FAKE_ACCOUNT,
|
'account': FAKE_ACCOUNT,
|
||||||
'container': 'qaz',
|
'container': 'qaz',
|
||||||
'object_count': '1',
|
'object_count': '1',
|
||||||
'bytes_used': '577',
|
'bytes_used': '577',
|
||||||
|
'storage_policy': 'o1--sr-r3',
|
||||||
'properties': {'Owner': FAKE_ACCOUNT},
|
'properties': {'Owner': FAKE_ACCOUNT},
|
||||||
}
|
}
|
||||||
self.requests_mock.register_uri(
|
self.requests_mock.register_uri(
|
||||||
|
@ -70,6 +70,75 @@ class TestContainerCreate(TestContainerAll):
|
|||||||
)]
|
)]
|
||||||
self.assertEqual(datalist, list(data))
|
self.assertEqual(datalist, list(data))
|
||||||
|
|
||||||
|
def test_object_create_container_storage_policy(self):
|
||||||
|
self.requests_mock.register_uri(
|
||||||
|
'PUT',
|
||||||
|
object_fakes.ENDPOINT + '/ernie',
|
||||||
|
headers={
|
||||||
|
'x-trans-id': '314159',
|
||||||
|
'x-storage-policy': 'o1--sr-r3'
|
||||||
|
},
|
||||||
|
status_code=200,
|
||||||
|
)
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'ernie',
|
||||||
|
'--storage-policy',
|
||||||
|
'o1--sr-r3'
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('containers', ['ernie']),
|
||||||
|
('storage_policy', 'o1--sr-r3')
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
# In base command class ShowOne in cliff, abstract method take_action()
|
||||||
|
# returns a two-part tuple with a tuple of column names and a tuple of
|
||||||
|
# data to be shown.
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self.assertEqual(self.columns, columns)
|
||||||
|
datalist = [(
|
||||||
|
object_fakes.ACCOUNT_ID,
|
||||||
|
'ernie',
|
||||||
|
'314159',
|
||||||
|
)]
|
||||||
|
self.assertEqual(datalist, list(data))
|
||||||
|
|
||||||
|
def test_object_create_container_public(self):
|
||||||
|
self.requests_mock.register_uri(
|
||||||
|
'PUT',
|
||||||
|
object_fakes.ENDPOINT + '/ernie',
|
||||||
|
headers={
|
||||||
|
'x-trans-id': '314159',
|
||||||
|
'x-container-read': '.r:*,.rlistings'
|
||||||
|
},
|
||||||
|
status_code=200,
|
||||||
|
)
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'ernie',
|
||||||
|
'--public'
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('containers', ['ernie']),
|
||||||
|
('public', True)
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
# In base command class ShowOne in cliff, abstract method take_action()
|
||||||
|
# returns a two-part tuple with a tuple of column names and a tuple of
|
||||||
|
# data to be shown.
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self.assertEqual(self.columns, columns)
|
||||||
|
datalist = [(
|
||||||
|
object_fakes.ACCOUNT_ID,
|
||||||
|
'ernie',
|
||||||
|
'314159',
|
||||||
|
)]
|
||||||
|
self.assertEqual(datalist, list(data))
|
||||||
|
|
||||||
def test_object_create_container_more(self):
|
def test_object_create_container_more(self):
|
||||||
self.requests_mock.register_uri(
|
self.requests_mock.register_uri(
|
||||||
'PUT',
|
'PUT',
|
||||||
@ -300,6 +369,7 @@ class TestContainerShow(TestContainerAll):
|
|||||||
'x-container-write': 'wsx',
|
'x-container-write': 'wsx',
|
||||||
'x-container-sync-to': 'edc',
|
'x-container-sync-to': 'edc',
|
||||||
'x-container-sync-key': 'rfv',
|
'x-container-sync-key': 'rfv',
|
||||||
|
'x-storage-policy': 'o1--sr-r3'
|
||||||
}
|
}
|
||||||
self.requests_mock.register_uri(
|
self.requests_mock.register_uri(
|
||||||
'HEAD',
|
'HEAD',
|
||||||
@ -327,6 +397,7 @@ class TestContainerShow(TestContainerAll):
|
|||||||
'container',
|
'container',
|
||||||
'object_count',
|
'object_count',
|
||||||
'read_acl',
|
'read_acl',
|
||||||
|
'storage_policy',
|
||||||
'sync_key',
|
'sync_key',
|
||||||
'sync_to',
|
'sync_to',
|
||||||
'write_acl',
|
'write_acl',
|
||||||
@ -338,6 +409,7 @@ class TestContainerShow(TestContainerAll):
|
|||||||
'ernie',
|
'ernie',
|
||||||
'42',
|
'42',
|
||||||
'qaz',
|
'qaz',
|
||||||
|
'o1--sr-r3',
|
||||||
'rfv',
|
'rfv',
|
||||||
'edc',
|
'edc',
|
||||||
'wsx',
|
'wsx',
|
||||||
|
Loading…
Reference in New Issue
Block a user