Add support for Bulk Delete in NeutronClient
The following patch adds support for BulkDelete in NeutronClient. Currently, the core existing Neutron CLIs are going to support Bulk Deletion in NeutronClient. However, if any extension does not require Bulk Delete, it can be disabled by updating the class attribute 'bulk_delete'. DocImpact Depends-On: Ib23d1e53947b5dffcff8db0dde77cae0a0b31243 Change-Id: I3b8a05698625baad3906784e3ecffb0f0242d660 Closes-Bug: #1495440
This commit is contained in:
parent
389aae7d16
commit
b16c9a8d3d
|
@ -478,17 +478,19 @@ class DeleteCommand(NeutronCommand):
|
|||
log = None
|
||||
allow_names = True
|
||||
help_resource = None
|
||||
bulk_delete = True
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteCommand, self).get_parser(prog_name)
|
||||
if self.allow_names:
|
||||
help_str = _('ID or name of %s to delete.')
|
||||
else:
|
||||
help_str = _('ID of %s to delete.')
|
||||
if not self.help_resource:
|
||||
self.help_resource = self.resource
|
||||
if self.allow_names:
|
||||
help_str = _('ID(s) or name(s) of %s to delete.')
|
||||
else:
|
||||
help_str = _('ID(s) of %s to delete.')
|
||||
parser.add_argument(
|
||||
'id', metavar=self.resource.upper(),
|
||||
nargs='+' if self.bulk_delete else 1,
|
||||
help=help_str % self.help_resource)
|
||||
self.add_known_arguments(parser)
|
||||
return parser
|
||||
|
@ -498,24 +500,62 @@ class DeleteCommand(NeutronCommand):
|
|||
neutron_client = self.get_client()
|
||||
obj_deleter = getattr(neutron_client,
|
||||
"delete_%s" % self.cmd_resource)
|
||||
|
||||
if self.bulk_delete:
|
||||
self._bulk_delete(obj_deleter, neutron_client, parsed_args.id)
|
||||
else:
|
||||
self.delete_item(obj_deleter, neutron_client, parsed_args.id)
|
||||
print((_('Deleted %(resource)s: %(id)s')
|
||||
% {'id': parsed_args.id,
|
||||
'resource': self.resource}),
|
||||
file=self.app.stdout)
|
||||
return
|
||||
|
||||
def _bulk_delete(self, obj_deleter, neutron_client, parsed_args_ids):
|
||||
successful_delete = []
|
||||
non_existent = []
|
||||
multiple_ids = []
|
||||
for item_id in parsed_args_ids:
|
||||
try:
|
||||
self.delete_item(obj_deleter, neutron_client, item_id)
|
||||
successful_delete.append(item_id)
|
||||
except exceptions.NotFound:
|
||||
non_existent.append(item_id)
|
||||
except exceptions.NeutronClientNoUniqueMatch:
|
||||
multiple_ids.append(item_id)
|
||||
if successful_delete:
|
||||
print((_('Deleted %(resource)s(s): %(id)s'))
|
||||
% {'id': ", ".join(successful_delete),
|
||||
'resource': self.cmd_resource},
|
||||
file=self.app.stdout)
|
||||
if non_existent:
|
||||
print((_("Unable to find %(resource)s(s) with id(s) "
|
||||
"'%(id)s'") %
|
||||
{'resource': self.cmd_resource,
|
||||
'id': ", ".join(non_existent)}),
|
||||
file=self.app.stdout)
|
||||
if multiple_ids:
|
||||
print((_("Multiple %(resource)s(s) matches found for name(s)"
|
||||
" '%(id)s'. Please use an ID to be more specific.")) %
|
||||
{'resource': self.cmd_resource,
|
||||
'id': ", ".join(multiple_ids)},
|
||||
file=self.app.stdout)
|
||||
|
||||
def delete_item(self, obj_deleter, neutron_client, item_id):
|
||||
if self.allow_names:
|
||||
params = {'cmd_resource': self.cmd_resource,
|
||||
'parent_id': self.parent_id}
|
||||
_id = find_resourceid_by_name_or_id(neutron_client,
|
||||
self.resource,
|
||||
parsed_args.id,
|
||||
item_id,
|
||||
**params)
|
||||
else:
|
||||
_id = parsed_args.id
|
||||
_id = item_id
|
||||
|
||||
if self.parent_id:
|
||||
obj_deleter(_id, self.parent_id)
|
||||
else:
|
||||
obj_deleter(_id)
|
||||
print((_('Deleted %(resource)s: %(id)s')
|
||||
% {'id': parsed_args.id,
|
||||
'resource': self.resource}),
|
||||
file=self.app.stdout)
|
||||
return
|
||||
|
||||
|
||||
|
|
|
@ -504,14 +504,7 @@ class CLITestV20Base(base.BaseTestCase):
|
|||
self.assertIn(myid, _str)
|
||||
self.assertIn('myname', _str)
|
||||
|
||||
def _test_delete_resource(self, resource, cmd, myid, args,
|
||||
cmd_resource=None, parent_id=None):
|
||||
self.mox.StubOutWithMock(cmd, "get_client")
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
cmd.get_client().MultipleTimes().AndReturn(self.client)
|
||||
if not cmd_resource:
|
||||
cmd_resource = resource
|
||||
path = getattr(self.client, cmd_resource + "_path")
|
||||
def _test_set_path_and_delete(self, path, parent_id, myid):
|
||||
if parent_id:
|
||||
path = path % (parent_id, myid)
|
||||
else:
|
||||
|
@ -521,6 +514,20 @@ class CLITestV20Base(base.BaseTestCase):
|
|||
body=None,
|
||||
headers=mox.ContainsKeyValue(
|
||||
'X-Auth-Token', TOKEN)).AndReturn((MyResp(204), None))
|
||||
|
||||
def _test_delete_resource(self, resource, cmd, myid, args,
|
||||
cmd_resource=None, parent_id=None,
|
||||
extra_ids=None):
|
||||
self.mox.StubOutWithMock(cmd, "get_client")
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
cmd.get_client().MultipleTimes().AndReturn(self.client)
|
||||
if not cmd_resource:
|
||||
cmd_resource = resource
|
||||
path = getattr(self.client, cmd_resource + "_path")
|
||||
self._test_set_path_and_delete(path, parent_id, myid)
|
||||
# extra_ids is used to test for bulk_delete
|
||||
if extra_ids:
|
||||
self._test_set_path_and_delete(path, parent_id, extra_ids)
|
||||
self.mox.ReplayAll()
|
||||
cmd_parser = cmd.get_parser("delete_" + cmd_resource)
|
||||
shell.run_command(cmd, cmd_parser, args)
|
||||
|
@ -528,6 +535,8 @@ class CLITestV20Base(base.BaseTestCase):
|
|||
self.mox.UnsetStubs()
|
||||
_str = self.fake_stdout.make_string()
|
||||
self.assertIn(myid, _str)
|
||||
if extra_ids:
|
||||
self.assertIn(extra_ids, _str)
|
||||
|
||||
def _test_update_resource_action(self, resource, cmd, myid, action, args,
|
||||
body, retval=None, cmd_resource=None):
|
||||
|
|
|
@ -588,6 +588,15 @@ class CLITestV20NetworkJSON(test_cli20.CLITestV20Base):
|
|||
args = [myid]
|
||||
self._test_delete_resource(resource, cmd, myid, args)
|
||||
|
||||
def test_bulk_delete_network(self):
|
||||
# Delete net: myid1 myid2.
|
||||
resource = 'network'
|
||||
cmd = network.DeleteNetwork(test_cli20.MyApp(sys.stdout), None)
|
||||
myid1 = 'myid1'
|
||||
myid2 = 'myid2'
|
||||
args = [myid1, myid2]
|
||||
self._test_delete_resource(resource, cmd, myid1, args, extra_ids=myid2)
|
||||
|
||||
def _test_extend_list(self, mox_calls):
|
||||
data = [{'id': 'netid%d' % i, 'name': 'net%d' % i,
|
||||
'subnets': ['mysubid%d' % i]}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
CLI support for bulk delete.
|
||||
|
||||
* By using this feature, multiple resource
|
||||
can be deleted using a single command.
|
||||
* Example: ``neutron router-delete router_a router_b``
|
||||
deletes both router_a and router_b.
|
Loading…
Reference in New Issue