Skip to content

Commit 514a168

Browse files
committed
Add recursive object delete for containers
Change-Id: Ib291e79864c218464e842a08efd3742193ba5ff0
1 parent 42b607e commit 514a168

4 files changed

Lines changed: 114 additions & 2 deletions

File tree

doc/source/command-objects/container.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,13 @@ Delete container
2828
.. code:: bash
2929
3030
os container delete
31+
[-r] | [--recursive]
3132
<container> [<container> ...]
3233
34+
.. option:: --recursive, -r
35+
36+
Recursively delete objects in container before container delete
37+
3338
.. describe:: <container>
3439

3540
Container(s) to delete
@@ -40,7 +45,7 @@ container list
4045
List containers
4146

4247
.. program:: container list
43-
.. code::bash
48+
.. code:: bash
4449
4550
os container list
4651
[--prefix <prefix>]

functional/tests/object/v1/test_object.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,8 @@ def test_object(self):
7474
+ ' ' + self.OBJECT_NAME)
7575
self.assertEqual(0, len(raw_output))
7676

77-
raw_output = self.openstack('container delete ' + self.CONTAINER_NAME)
77+
self.openstack('object create ' + self.CONTAINER_NAME
78+
+ ' ' + self.OBJECT_NAME)
79+
raw_output = self.openstack('container delete -r ' +
80+
self.CONTAINER_NAME)
7881
self.assertEqual(0, len(raw_output))

openstackclient/object/v1/container.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ class DeleteContainer(command.Command):
5858

5959
def get_parser(self, prog_name):
6060
parser = super(DeleteContainer, self).get_parser(prog_name)
61+
parser.add_argument(
62+
'--recursive', '-r',
63+
action='store_true',
64+
default=False,
65+
help='Recursively delete objects and container',
66+
)
6167
parser.add_argument(
6268
'containers',
6369
metavar='<container>',
@@ -69,6 +75,14 @@ def get_parser(self, prog_name):
6975
def take_action(self, parsed_args):
7076

7177
for container in parsed_args.containers:
78+
if parsed_args.recursive:
79+
objs = self.app.client_manager.object_store.object_list(
80+
container=container)
81+
for obj in objs:
82+
self.app.client_manager.object_store.object_delete(
83+
container=container,
84+
object=obj['name'],
85+
)
7286
self.app.client_manager.object_store.container_delete(
7387
container=container,
7488
)

openstackclient/tests/object/v1/test_container.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,96 @@ def setUp(self):
4444
self.api = self.app.client_manager.object_store
4545

4646

47+
@mock.patch('openstackclient.api.object_store_v1.APIv1.object_delete')
48+
@mock.patch('openstackclient.api.object_store_v1.APIv1.object_list')
49+
@mock.patch('openstackclient.api.object_store_v1.APIv1.container_delete')
50+
class TestContainerDelete(TestContainer):
51+
52+
def setUp(self):
53+
super(TestContainerDelete, self).setUp()
54+
55+
# Get the command object to test
56+
self.cmd = container.DeleteContainer(self.app, None)
57+
58+
def test_container_delete(self, c_mock, o_list_mock, o_delete_mock):
59+
c_mock.return_value = None
60+
61+
arglist = [
62+
object_fakes.container_name,
63+
]
64+
verifylist = [
65+
('containers', [object_fakes.container_name]),
66+
('recursive', False),
67+
]
68+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
69+
70+
self.assertEqual(None, self.cmd.take_action(parsed_args))
71+
72+
kwargs = {}
73+
c_mock.assert_called_with(
74+
container=object_fakes.container_name,
75+
**kwargs
76+
)
77+
self.assertFalse(o_list_mock.called)
78+
self.assertFalse(o_delete_mock.called)
79+
80+
def test_recursive_delete(self, c_mock, o_list_mock, o_delete_mock):
81+
c_mock.return_value = None
82+
o_list_mock.return_value = [object_fakes.OBJECT]
83+
o_delete_mock.return_value = None
84+
85+
arglist = [
86+
'--recursive',
87+
object_fakes.container_name,
88+
]
89+
verifylist = [
90+
('containers', [object_fakes.container_name]),
91+
('recursive', True),
92+
]
93+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
94+
95+
self.assertEqual(None, self.cmd.take_action(parsed_args))
96+
97+
kwargs = {}
98+
c_mock.assert_called_with(
99+
container=object_fakes.container_name,
100+
**kwargs
101+
)
102+
o_list_mock.assert_called_with(container=object_fakes.container_name)
103+
o_delete_mock.assert_called_with(
104+
container=object_fakes.container_name,
105+
object=object_fakes.OBJECT['name'],
106+
)
107+
108+
def test_r_delete(self, c_mock, o_list_mock, o_delete_mock):
109+
c_mock.return_value = None
110+
o_list_mock.return_value = [object_fakes.OBJECT]
111+
o_delete_mock.return_value = None
112+
113+
arglist = [
114+
'-r',
115+
object_fakes.container_name,
116+
]
117+
verifylist = [
118+
('containers', [object_fakes.container_name]),
119+
('recursive', True),
120+
]
121+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
122+
123+
self.assertEqual(None, self.cmd.take_action(parsed_args))
124+
125+
kwargs = {}
126+
c_mock.assert_called_with(
127+
container=object_fakes.container_name,
128+
**kwargs
129+
)
130+
o_list_mock.assert_called_with(container=object_fakes.container_name)
131+
o_delete_mock.assert_called_with(
132+
container=object_fakes.container_name,
133+
object=object_fakes.OBJECT['name'],
134+
)
135+
136+
47137
@mock.patch(
48138
'openstackclient.api.object_store_v1.APIv1.container_list'
49139
)

0 commit comments

Comments
 (0)