Skip to content

Commit d6022f9

Browse files
author
Simon Merrick
committed
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
1 parent e07324e commit d6022f9

File tree

4 files changed

+111
-2
lines changed

4 files changed

+111
-2
lines changed

openstackclient/api/object_store_v1.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
from openstackclient.api import api
2525

2626

27+
GLOBAL_READ_ACL = ".r:*"
28+
LIST_CONTENTS_ACL = ".rlistings"
29+
PUBLIC_CONTAINER_ACLS = [GLOBAL_READ_ACL, LIST_CONTENTS_ACL]
30+
31+
2732
class APIv1(api.BaseAPI):
2833
"""Object Store v1 API"""
2934

@@ -33,15 +38,32 @@ def __init__(self, **kwargs):
3338
def container_create(
3439
self,
3540
container=None,
41+
public=False,
42+
storage_policy=None
3643
):
3744
"""Create a container
3845
3946
:param string container:
4047
name of container to create
48+
:param bool public:
49+
Boolean value indicating if the container should be publicly
50+
readable. Defaults to False.
51+
:param string storage_policy:
52+
Name of the a specific storage policy to use. If not specified
53+
swift will use its default storage policy.
4154
:returns:
4255
dict of returned headers
4356
"""
44-
response = self.create(urllib.parse.quote(container), method='PUT')
57+
58+
headers = {}
59+
if public:
60+
headers['x-container-read'] = ",".join(PUBLIC_CONTAINER_ACLS)
61+
if storage_policy is not None:
62+
headers['x-storage-policy'] = storage_policy
63+
64+
response = self.create(
65+
urllib.parse.quote(container), method='PUT', headers=headers)
66+
4567
data = {
4668
'account': self._find_account_id(),
4769
'container': container,
@@ -173,7 +195,8 @@ def container_show(
173195
'object_count': response.headers.get(
174196
'x-container-object-count'
175197
),
176-
'bytes_used': response.headers.get('x-container-bytes-used')
198+
'bytes_used': response.headers.get('x-container-bytes-used'),
199+
'storage_policy': response.headers.get('x-storage-policy'),
177200
}
178201

179202
if 'x-container-read' in response.headers:

openstackclient/object/v1/container.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ class CreateContainer(command.Lister):
3333

3434
def get_parser(self, prog_name):
3535
parser = super(CreateContainer, self).get_parser(prog_name)
36+
parser.add_argument(
37+
'--public',
38+
action='store_true',
39+
default=False,
40+
help="Make the container publicly accessible"
41+
)
42+
parser.add_argument(
43+
'--storage-policy',
44+
help="Specify a particular storage policy to use."
45+
)
3646
parser.add_argument(
3747
'containers',
3848
metavar='<container-name>',
@@ -51,6 +61,8 @@ def take_action(self, parsed_args):
5161
' is 256'), len(container))
5262
data = self.app.client_manager.object_store.container_create(
5363
container=container,
64+
public=parsed_args.public,
65+
storage_policy=parsed_args.storage_policy
5466
)
5567
results.append(data)
5668

openstackclient/tests/unit/api/test_object_store_v1.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,14 @@ def test_container_show(self):
151151
'X-Container-Meta-Owner': FAKE_ACCOUNT,
152152
'x-container-object-count': '1',
153153
'x-container-bytes-used': '577',
154+
'x-storage-policy': 'o1--sr-r3'
154155
}
155156
resp = {
156157
'account': FAKE_ACCOUNT,
157158
'container': 'qaz',
158159
'object_count': '1',
159160
'bytes_used': '577',
161+
'storage_policy': 'o1--sr-r3',
160162
'properties': {'Owner': FAKE_ACCOUNT},
161163
}
162164
self.requests_mock.register_uri(

openstackclient/tests/unit/object/v1/test_container_all.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,75 @@ def test_object_create_container_single(self):
7070
)]
7171
self.assertEqual(datalist, list(data))
7272

73+
def test_object_create_container_storage_policy(self):
74+
self.requests_mock.register_uri(
75+
'PUT',
76+
object_fakes.ENDPOINT + '/ernie',
77+
headers={
78+
'x-trans-id': '314159',
79+
'x-storage-policy': 'o1--sr-r3'
80+
},
81+
status_code=200,
82+
)
83+
84+
arglist = [
85+
'ernie',
86+
'--storage-policy',
87+
'o1--sr-r3'
88+
]
89+
verifylist = [
90+
('containers', ['ernie']),
91+
('storage_policy', 'o1--sr-r3')
92+
]
93+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
94+
95+
# In base command class ShowOne in cliff, abstract method take_action()
96+
# returns a two-part tuple with a tuple of column names and a tuple of
97+
# data to be shown.
98+
columns, data = self.cmd.take_action(parsed_args)
99+
100+
self.assertEqual(self.columns, columns)
101+
datalist = [(
102+
object_fakes.ACCOUNT_ID,
103+
'ernie',
104+
'314159',
105+
)]
106+
self.assertEqual(datalist, list(data))
107+
108+
def test_object_create_container_public(self):
109+
self.requests_mock.register_uri(
110+
'PUT',
111+
object_fakes.ENDPOINT + '/ernie',
112+
headers={
113+
'x-trans-id': '314159',
114+
'x-container-read': '.r:*,.rlistings'
115+
},
116+
status_code=200,
117+
)
118+
119+
arglist = [
120+
'ernie',
121+
'--public'
122+
]
123+
verifylist = [
124+
('containers', ['ernie']),
125+
('public', True)
126+
]
127+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
128+
129+
# In base command class ShowOne in cliff, abstract method take_action()
130+
# returns a two-part tuple with a tuple of column names and a tuple of
131+
# data to be shown.
132+
columns, data = self.cmd.take_action(parsed_args)
133+
134+
self.assertEqual(self.columns, columns)
135+
datalist = [(
136+
object_fakes.ACCOUNT_ID,
137+
'ernie',
138+
'314159',
139+
)]
140+
self.assertEqual(datalist, list(data))
141+
73142
def test_object_create_container_more(self):
74143
self.requests_mock.register_uri(
75144
'PUT',
@@ -300,6 +369,7 @@ def test_object_show_container(self):
300369
'x-container-write': 'wsx',
301370
'x-container-sync-to': 'edc',
302371
'x-container-sync-key': 'rfv',
372+
'x-storage-policy': 'o1--sr-r3'
303373
}
304374
self.requests_mock.register_uri(
305375
'HEAD',
@@ -327,6 +397,7 @@ def test_object_show_container(self):
327397
'container',
328398
'object_count',
329399
'read_acl',
400+
'storage_policy',
330401
'sync_key',
331402
'sync_to',
332403
'write_acl',
@@ -338,6 +409,7 @@ def test_object_show_container(self):
338409
'ernie',
339410
'42',
340411
'qaz',
412+
'o1--sr-r3',
341413
'rfv',
342414
'edc',
343415
'wsx',

0 commit comments

Comments
 (0)