From 470b7e53a8d7e7ba088b934c49163412c8ee5ed9 Mon Sep 17 00:00:00 2001 From: wanghong Date: Wed, 10 Dec 2014 11:47:54 +0800 Subject: [PATCH] add multi-delete support for compute/image/net/volume This is part1, add support for these objects: compute.server imagev1.image imagev2.image network.network volume.volume volume.backup volume.snapshot Closes-Bug: #1400597 Change-Id: Ice21fee85203a8a55417e0ead8b509b8fd6705c1 --- doc/source/command-objects/server.rst | 8 +++---- openstackclient/compute/v2/server.py | 14 +++++++----- openstackclient/image/v1/image.py | 18 ++++++++------- openstackclient/image/v2/image.py | 18 ++++++++------- openstackclient/network/v2/network.py | 13 ++++++----- .../tests/compute/v2/test_server.py | 2 +- openstackclient/tests/image/v1/test_image.py | 2 +- openstackclient/tests/image/v2/test_image.py | 2 +- .../tests/network/v2/test_network.py | 2 +- openstackclient/volume/v1/backup.py | 14 +++++++----- openstackclient/volume/v1/snapshot.py | 14 +++++++----- openstackclient/volume/v1/volume.py | 22 ++++++++++--------- 12 files changed, 71 insertions(+), 58 deletions(-) diff --git a/doc/source/command-objects/server.rst b/doc/source/command-objects/server.rst index 482602eefc..7d5cdce56c 100644 --- a/doc/source/command-objects/server.rst +++ b/doc/source/command-objects/server.rst @@ -117,15 +117,15 @@ Create a new server :option:`` New server name -server delete -------------- +server(s) delete +---------------- -Delete server command +Delete server(s) command .. code:: bash os server delete - + [ ...] :option:`` Server (name or ID) diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py index 5ab1d5f3ff..a5d8b0c30a 100644 --- a/openstackclient/compute/v2/server.py +++ b/openstackclient/compute/v2/server.py @@ -511,25 +511,27 @@ class CreateServerImage(show.ShowOne): class DeleteServer(command.Command): - """Delete server command""" + """Delete server(s)""" log = logging.getLogger(__name__ + '.DeleteServer') def get_parser(self, prog_name): parser = super(DeleteServer, self).get_parser(prog_name) parser.add_argument( - 'server', + 'servers', metavar='', - help=_('Server (name or ID)'), + nargs="+", + help=_('Server(s) to delete (name or ID)'), ) return parser def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute - server = utils.find_resource( - compute_client.servers, parsed_args.server) - compute_client.servers.delete(server.id) + for server in parsed_args.servers: + server_obj = utils.find_resource( + compute_client.servers, server) + compute_client.servers.delete(server_obj.id) return diff --git a/openstackclient/image/v1/image.py b/openstackclient/image/v1/image.py index 32dd388c0f..ca1eead4d8 100644 --- a/openstackclient/image/v1/image.py +++ b/openstackclient/image/v1/image.py @@ -262,16 +262,17 @@ class CreateImage(show.ShowOne): class DeleteImage(command.Command): - """Delete an image""" + """Delete image(s)""" log = logging.getLogger(__name__ + ".DeleteImage") def get_parser(self, prog_name): parser = super(DeleteImage, self).get_parser(prog_name) parser.add_argument( - "image", + "images", metavar="", - help="Name or ID of image to delete", + nargs="+", + help="Image(s) to delete (name or ID)", ) return parser @@ -279,11 +280,12 @@ class DeleteImage(command.Command): self.log.debug("take_action(%s)", parsed_args) image_client = self.app.client_manager.image - image = utils.find_resource( - image_client.images, - parsed_args.image, - ) - image_client.images.delete(image.id) + for image in parsed_args.images: + image_obj = utils.find_resource( + image_client.images, + image, + ) + image_client.images.delete(image_obj.id) class ListImage(lister.Lister): diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py index c12ff11a09..63351c6d5e 100644 --- a/openstackclient/image/v2/image.py +++ b/openstackclient/image/v2/image.py @@ -27,16 +27,17 @@ from openstackclient.common import utils class DeleteImage(command.Command): - """Delete an image""" + """Delete image(s)""" log = logging.getLogger(__name__ + ".DeleteImage") def get_parser(self, prog_name): parser = super(DeleteImage, self).get_parser(prog_name) parser.add_argument( - "image", + "images", metavar="", - help="Name or ID of image to delete", + nargs="+", + help="Image(s) to delete (name or ID)", ) return parser @@ -44,11 +45,12 @@ class DeleteImage(command.Command): self.log.debug("take_action(%s)", parsed_args) image_client = self.app.client_manager.image - image = utils.find_resource( - image_client.images, - parsed_args.image, - ) - image_client.images.delete(image.id) + for image in parsed_args.images: + image_obj = utils.find_resource( + image_client.images, + image, + ) + image_client.images.delete(image_obj.id) class ListImage(lister.Lister): diff --git a/openstackclient/network/v2/network.py b/openstackclient/network/v2/network.py index f34666ba88..0d68f82dc1 100644 --- a/openstackclient/network/v2/network.py +++ b/openstackclient/network/v2/network.py @@ -86,26 +86,27 @@ class CreateNetwork(show.ShowOne): class DeleteNetwork(command.Command): - """Delete a network""" + """Delete network(s)""" log = logging.getLogger(__name__ + '.DeleteNetwork') def get_parser(self, prog_name): parser = super(DeleteNetwork, self).get_parser(prog_name) parser.add_argument( - 'identifier', + 'networks', metavar="", - help=("Name or identifier of network to delete") + nargs="+", + help=("Network(s) to delete (name or ID)") ) return parser def take_action(self, parsed_args): self.log.debug('take_action(%s)' % parsed_args) client = self.app.client_manager.network - _id = common.find(client, 'network', 'networks', - parsed_args.identifier) delete_method = getattr(client, "delete_network") - delete_method(_id) + for network in parsed_args.networks: + _id = common.find(client, 'network', 'networks', network) + delete_method(_id) return diff --git a/openstackclient/tests/compute/v2/test_server.py b/openstackclient/tests/compute/v2/test_server.py index 19c13440db..d51beef369 100644 --- a/openstackclient/tests/compute/v2/test_server.py +++ b/openstackclient/tests/compute/v2/test_server.py @@ -232,7 +232,7 @@ class TestServerDelete(TestServer): compute_fakes.server_id, ] verifylist = [ - ('server', compute_fakes.server_id), + ('servers', [compute_fakes.server_id]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) diff --git a/openstackclient/tests/image/v1/test_image.py b/openstackclient/tests/image/v1/test_image.py index a05669300e..4d21ac4858 100644 --- a/openstackclient/tests/image/v1/test_image.py +++ b/openstackclient/tests/image/v1/test_image.py @@ -288,7 +288,7 @@ class TestImageDelete(TestImage): image_fakes.image_id, ] verifylist = [ - ('image', image_fakes.image_id), + ('images', [image_fakes.image_id]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) diff --git a/openstackclient/tests/image/v2/test_image.py b/openstackclient/tests/image/v2/test_image.py index 3e9eeebb1d..bc61a89fb6 100644 --- a/openstackclient/tests/image/v2/test_image.py +++ b/openstackclient/tests/image/v2/test_image.py @@ -51,7 +51,7 @@ class TestImageDelete(TestImage): image_fakes.image_id, ] verifylist = [ - ('image', image_fakes.image_id), + ('images', [image_fakes.image_id]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) diff --git a/openstackclient/tests/network/v2/test_network.py b/openstackclient/tests/network/v2/test_network.py index 468db5e039..b893229f65 100644 --- a/openstackclient/tests/network/v2/test_network.py +++ b/openstackclient/tests/network/v2/test_network.py @@ -120,7 +120,7 @@ class TestDeleteNetwork(common.TestNetworkBase): FAKE_NAME, ] verifylist = [ - ('identifier', FAKE_NAME), + ('networks', [FAKE_NAME]), ] lister = mock.Mock(return_value={RESOURCES: [RECORD]}) self.app.client_manager.network.list_networks = lister diff --git a/openstackclient/volume/v1/backup.py b/openstackclient/volume/v1/backup.py index 992fa7be71..8c16ba256f 100644 --- a/openstackclient/volume/v1/backup.py +++ b/openstackclient/volume/v1/backup.py @@ -73,25 +73,27 @@ class CreateBackup(show.ShowOne): class DeleteBackup(command.Command): - """Delete backup command""" + """Delete backup(s)""" log = logging.getLogger(__name__ + '.DeleteBackup') def get_parser(self, prog_name): parser = super(DeleteBackup, self).get_parser(prog_name) parser.add_argument( - 'backup', + 'backups', metavar='', - help='Name or ID of backup to delete', + nargs="+", + help='Backup(s) to delete (name or ID)', ) return parser def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume - backup_id = utils.find_resource(volume_client.backups, - parsed_args.backup).id - volume_client.backups.delete(backup_id) + for backup in parsed_args.backups: + backup_id = utils.find_resource(volume_client.backups, + backup).id + volume_client.backups.delete(backup_id) return diff --git a/openstackclient/volume/v1/snapshot.py b/openstackclient/volume/v1/snapshot.py index 9cc3c4c1d5..c9e1baca92 100644 --- a/openstackclient/volume/v1/snapshot.py +++ b/openstackclient/volume/v1/snapshot.py @@ -74,25 +74,27 @@ class CreateSnapshot(show.ShowOne): class DeleteSnapshot(command.Command): - """Delete snapshot command""" + """Delete snapshot(s)""" log = logging.getLogger(__name__ + '.DeleteSnapshot') def get_parser(self, prog_name): parser = super(DeleteSnapshot, self).get_parser(prog_name) parser.add_argument( - 'snapshot', + 'snapshots', metavar='', - help='Name or ID of snapshot to delete', + nargs="+", + help='Snapshot(s) to delete (name or ID)', ) return parser def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume - snapshot_id = utils.find_resource(volume_client.volume_snapshots, - parsed_args.snapshot).id - volume_client.volume_snapshots.delete(snapshot_id) + for snapshot in parsed_args.snapshots: + snapshot_id = utils.find_resource(volume_client.volume_snapshots, + snapshot).id + volume_client.volume_snapshots.delete(snapshot_id) return diff --git a/openstackclient/volume/v1/volume.py b/openstackclient/volume/v1/volume.py index 84c216d320..73ae3a7f9c 100644 --- a/openstackclient/volume/v1/volume.py +++ b/openstackclient/volume/v1/volume.py @@ -155,35 +155,37 @@ class CreateVolume(show.ShowOne): class DeleteVolume(command.Command): - """Delete a volume""" + """Delete volume(s)""" log = logging.getLogger(__name__ + '.DeleteVolume') def get_parser(self, prog_name): parser = super(DeleteVolume, self).get_parser(prog_name) parser.add_argument( - 'volume', + 'volumes', metavar='', - help='Volume to delete (name or ID)', + nargs="+", + help='Volume(s) to delete (name or ID)', ) parser.add_argument( '--force', dest='force', action='store_true', default=False, - help='Attempt forced removal of a volume, regardless of state', + help='Attempt forced removal of volume(s), regardless of state', ) return parser def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume - volume = utils.find_resource( - volume_client.volumes, parsed_args.volume) - if parsed_args.force: - volume_client.volumes.force_delete(volume.id) - else: - volume_client.volumes.delete(volume.id) + for volume in parsed_args.volumes: + volume_obj = utils.find_resource( + volume_client.volumes, volume) + if parsed_args.force: + volume_client.volumes.force_delete(volume_obj.id) + else: + volume_client.volumes.delete(volume_obj.id) return