From e07b0e0919784b48dc47ae9cd8836342b8c13480 Mon Sep 17 00:00:00 2001 From: Huanxuan Ao Date: Mon, 7 Nov 2016 17:19:24 +0800 Subject: [PATCH] Add options to "volume backup list" command Add "--name", "--status", "--volume", "--marker" (v2 only) and "--limit" (v2 only) options to "volume backup list" command Change-Id: If20cb7650f2359d393ee314d9e055a8659c73009 Closes-Bug: #1612484 Closes-Bug: #1639712 --- doc/source/command-objects/volume-backup.rst | 31 +++++++++++ .../tests/unit/volume/v1/test_backup.py | 40 +++++++++++++- .../tests/unit/volume/v2/test_backup.py | 53 +++++++++++++++++- openstackclient/volume/v1/backup.py | 36 +++++++++++- openstackclient/volume/v2/backup.py | 55 ++++++++++++++++++- .../notes/bug-1639712-a7b9d1a35a042049.yaml | 6 ++ 6 files changed, 211 insertions(+), 10 deletions(-) create mode 100644 releasenotes/notes/bug-1639712-a7b9d1a35a042049.yaml diff --git a/doc/source/command-objects/volume-backup.rst b/doc/source/command-objects/volume-backup.rst index 246fd38eb..7ce8a4eb3 100644 --- a/doc/source/command-objects/volume-backup.rst +++ b/doc/source/command-objects/volume-backup.rst @@ -88,12 +88,43 @@ List volume backups .. code:: bash os volume backup list + [--long] + [--name ] + [--status ] + [--volume ] + [--marker ] + [--limit ] .. _volume_backup_list-backup: .. option:: --long List additional fields in output +.. options:: --name + + Filters results by the backup name + +.. options:: --status + + Filters results by the backup status + ('creating', 'available', 'deleting', 'error', 'restoring' or 'error_restoring') + +.. options:: --volume + + Filters results by the volume which they backup (name or ID)" + +.. options:: --marker + + The last backup of the previous page (name or ID) + + *Volume version 2 only* + +.. options:: --limit + + Maximum number of backups to display + + *Volume version 2 only* + volume backup restore --------------------- diff --git a/openstackclient/tests/unit/volume/v1/test_backup.py b/openstackclient/tests/unit/volume/v1/test_backup.py index 32c2fd224..f4a3b5e5c 100644 --- a/openstackclient/tests/unit/volume/v1/test_backup.py +++ b/openstackclient/tests/unit/volume/v1/test_backup.py @@ -249,26 +249,60 @@ class TestBackupList(TestBackup): self.volumes_mock.list.return_value = [self.volume] self.backups_mock.list.return_value = self.backups + self.volumes_mock.get.return_value = self.volume # Get the command to test self.cmd = backup.ListVolumeBackup(self.app, None) def test_backup_list_without_options(self): arglist = [] - verifylist = [("long", False)] + verifylist = [ + ("long", False), + ("name", None), + ("status", None), + ("volume", None), + ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) + search_opts = { + "name": None, + "status": None, + "volume_id": None, + } + self.volumes_mock.get.assert_not_called + self.backups_mock.list.assert_called_with( + search_opts=search_opts, + ) self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) def test_backup_list_with_options(self): - arglist = ["--long"] - verifylist = [("long", True)] + arglist = [ + "--long", + "--name", self.backups[0].name, + "--status", "error", + "--volume", self.volume.id, + ] + verifylist = [ + ("long", True), + ("name", self.backups[0].name), + ("status", "error"), + ("volume", self.volume.id), + ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) + search_opts = { + "name": self.backups[0].name, + "status": "error", + "volume_id": self.volume.id, + } + self.volumes_mock.get.assert_called_once_with(self.volume.id) + self.backups_mock.list.assert_called_with( + search_opts=search_opts, + ) self.assertEqual(self.columns_long, columns) self.assertEqual(self.data_long, list(data)) diff --git a/openstackclient/tests/unit/volume/v2/test_backup.py b/openstackclient/tests/unit/volume/v2/test_backup.py index 306c9eb3e..dd2b26891 100644 --- a/openstackclient/tests/unit/volume/v2/test_backup.py +++ b/openstackclient/tests/unit/volume/v2/test_backup.py @@ -280,26 +280,73 @@ class TestBackupList(TestBackup): self.volumes_mock.list.return_value = [self.volume] self.backups_mock.list.return_value = self.backups + self.volumes_mock.get.return_value = self.volume + self.backups_mock.get.return_value = self.backups[0] # Get the command to test self.cmd = backup.ListVolumeBackup(self.app, None) def test_backup_list_without_options(self): arglist = [] - verifylist = [("long", False)] + verifylist = [ + ("long", False), + ("name", None), + ("status", None), + ("volume", None), + ("marker", None), + ("limit", None), + ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) + search_opts = { + "name": None, + "status": None, + "volume_id": None, + } + self.volumes_mock.get.assert_not_called + self.backups_mock.get.assert_not_called + self.backups_mock.list.assert_called_with( + search_opts=search_opts, + marker=None, + limit=None, + ) self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) def test_backup_list_with_options(self): - arglist = ["--long"] - verifylist = [("long", True)] + arglist = [ + "--long", + "--name", self.backups[0].name, + "--status", "error", + "--volume", self.volume.id, + "--marker", self.backups[0].id, + "--limit", "3", + ] + verifylist = [ + ("long", True), + ("name", self.backups[0].name), + ("status", "error"), + ("volume", self.volume.id), + ("marker", self.backups[0].id), + ("limit", 3), + ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) + search_opts = { + "name": self.backups[0].name, + "status": "error", + "volume_id": self.volume.id, + } + self.volumes_mock.get.assert_called_once_with(self.volume.id) + self.backups_mock.get.assert_called_once_with(self.backups[0].id) + self.backups_mock.list.assert_called_with( + search_opts=search_opts, + marker=self.backups[0].id, + limit=3, + ) self.assertEqual(self.columns_long, columns) self.assertEqual(self.data_long, list(data)) diff --git a/openstackclient/volume/v1/backup.py b/openstackclient/volume/v1/backup.py index c9d0ca0d8..bf4e8625b 100644 --- a/openstackclient/volume/v1/backup.py +++ b/openstackclient/volume/v1/backup.py @@ -152,9 +152,30 @@ class ListVolumeBackup(command.Lister): default=False, help=_('List additional fields in output'), ) + parser.add_argument( + "--name", + metavar="", + help=_("Filters results by the backup name") + ) + parser.add_argument( + "--status", + metavar="", + choices=['creating', 'available', 'deleting', + 'error', 'restoring', 'error_restoring'], + help=_("Filters results by the backup status " + "('creating', 'available', 'deleting', " + "'error', 'restoring' or 'error_restoring')") + ) + parser.add_argument( + "--volume", + metavar="", + help=_("Filters results by the volume which they " + "backup (name or ID)") + ) return parser def take_action(self, parsed_args): + volume_client = self.app.client_manager.volume def _format_volume_id(volume_id): """Return a volume name if available @@ -180,13 +201,24 @@ class ListVolumeBackup(command.Lister): # Cache the volume list volume_cache = {} try: - for s in self.app.client_manager.volume.volumes.list(): + for s in volume_client.volumes.list(): volume_cache[s.id] = s except Exception: # Just forget it if there's any trouble pass - data = self.app.client_manager.volume.backups.list() + filter_volume_id = None + if parsed_args.volume: + filter_volume_id = utils.find_resource(volume_client.volumes, + parsed_args.volume).id + search_opts = { + 'name': parsed_args.name, + 'status': parsed_args.status, + 'volume_id': filter_volume_id, + } + data = volume_client.backups.list( + search_opts=search_opts, + ) return (column_headers, (utils.get_item_properties( diff --git a/openstackclient/volume/v2/backup.py b/openstackclient/volume/v2/backup.py index 2ca35b24b..e674ef2bb 100644 --- a/openstackclient/volume/v2/backup.py +++ b/openstackclient/volume/v2/backup.py @@ -17,6 +17,7 @@ import copy import logging +from osc_lib.cli import parseractions from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils @@ -179,9 +180,42 @@ class ListVolumeBackup(command.Lister): default=False, help=_("List additional fields in output") ) + parser.add_argument( + "--name", + metavar="", + help=_("Filters results by the backup name") + ) + parser.add_argument( + "--status", + metavar="", + choices=['creating', 'available', 'deleting', + 'error', 'restoring', 'error_restoring'], + help=_("Filters results by the backup status " + "('creating', 'available', 'deleting', " + "'error', 'restoring' or 'error_restoring')") + ) + parser.add_argument( + "--volume", + metavar="", + help=_("Filters results by the volume which they " + "backup (name or ID)") + ) + parser.add_argument( + '--marker', + metavar='', + help=_('The last backup of the previous page (name or ID)'), + ) + parser.add_argument( + '--limit', + type=int, + action=parseractions.NonNegativeAction, + metavar='', + help=_('Maximum number of backups to display'), + ) return parser def take_action(self, parsed_args): + volume_client = self.app.client_manager.volume def _format_volume_id(volume_id): """Return a volume name if available @@ -207,13 +241,30 @@ class ListVolumeBackup(command.Lister): # Cache the volume list volume_cache = {} try: - for s in self.app.client_manager.volume.volumes.list(): + for s in volume_client.volumes.list(): volume_cache[s.id] = s except Exception: # Just forget it if there's any trouble pass - data = self.app.client_manager.volume.backups.list() + filter_volume_id = None + if parsed_args.volume: + filter_volume_id = utils.find_resource(volume_client.volumes, + parsed_args.volume).id + marker_backup_id = None + if parsed_args.marker: + marker_backup_id = utils.find_resource(volume_client.backups, + parsed_args.marker).id + search_opts = { + 'name': parsed_args.name, + 'status': parsed_args.status, + 'volume_id': filter_volume_id, + } + data = volume_client.backups.list( + search_opts=search_opts, + marker=marker_backup_id, + limit=parsed_args.limit, + ) return (column_headers, (utils.get_item_properties( diff --git a/releasenotes/notes/bug-1639712-a7b9d1a35a042049.yaml b/releasenotes/notes/bug-1639712-a7b9d1a35a042049.yaml new file mode 100644 index 000000000..f9c09c4b4 --- /dev/null +++ b/releasenotes/notes/bug-1639712-a7b9d1a35a042049.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Add ``--name``, ``--status``, ``--volume``, ``--marker`` and ``--limit`` options + to ``volume backup list`` command + [Bug `1639712 `_]