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
This commit is contained in:
Huanxuan Ao 2016-11-07 17:19:24 +08:00
parent 0e3e05098c
commit e07b0e0919
6 changed files with 211 additions and 10 deletions

View File

@ -88,12 +88,43 @@ List volume backups
.. code:: bash .. code:: bash
os volume backup list os volume backup list
[--long]
[--name <name>]
[--status <status>]
[--volume <volume>]
[--marker <marker>]
[--limit <limit>]
.. _volume_backup_list-backup: .. _volume_backup_list-backup:
.. option:: --long .. option:: --long
List additional fields in output List additional fields in output
.. options:: --name <name>
Filters results by the backup name
.. options:: --status <status>
Filters results by the backup status
('creating', 'available', 'deleting', 'error', 'restoring' or 'error_restoring')
.. options:: --volume <volume>
Filters results by the volume which they backup (name or ID)"
.. options:: --marker <marker>
The last backup of the previous page (name or ID)
*Volume version 2 only*
.. options:: --limit <limit>
Maximum number of backups to display
*Volume version 2 only*
volume backup restore volume backup restore
--------------------- ---------------------

View File

@ -249,26 +249,60 @@ class TestBackupList(TestBackup):
self.volumes_mock.list.return_value = [self.volume] self.volumes_mock.list.return_value = [self.volume]
self.backups_mock.list.return_value = self.backups self.backups_mock.list.return_value = self.backups
self.volumes_mock.get.return_value = self.volume
# Get the command to test # Get the command to test
self.cmd = backup.ListVolumeBackup(self.app, None) self.cmd = backup.ListVolumeBackup(self.app, None)
def test_backup_list_without_options(self): def test_backup_list_without_options(self):
arglist = [] arglist = []
verifylist = [("long", False)] verifylist = [
("long", False),
("name", None),
("status", None),
("volume", None),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args) 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.columns, columns)
self.assertEqual(self.data, list(data)) self.assertEqual(self.data, list(data))
def test_backup_list_with_options(self): def test_backup_list_with_options(self):
arglist = ["--long"] arglist = [
verifylist = [("long", True)] "--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) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args) 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.columns_long, columns)
self.assertEqual(self.data_long, list(data)) self.assertEqual(self.data_long, list(data))

View File

@ -280,26 +280,73 @@ class TestBackupList(TestBackup):
self.volumes_mock.list.return_value = [self.volume] self.volumes_mock.list.return_value = [self.volume]
self.backups_mock.list.return_value = self.backups 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 # Get the command to test
self.cmd = backup.ListVolumeBackup(self.app, None) self.cmd = backup.ListVolumeBackup(self.app, None)
def test_backup_list_without_options(self): def test_backup_list_without_options(self):
arglist = [] 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) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args) 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.columns, columns)
self.assertEqual(self.data, list(data)) self.assertEqual(self.data, list(data))
def test_backup_list_with_options(self): def test_backup_list_with_options(self):
arglist = ["--long"] arglist = [
verifylist = [("long", True)] "--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) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args) 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.columns_long, columns)
self.assertEqual(self.data_long, list(data)) self.assertEqual(self.data_long, list(data))

View File

@ -152,9 +152,30 @@ class ListVolumeBackup(command.Lister):
default=False, default=False,
help=_('List additional fields in output'), help=_('List additional fields in output'),
) )
parser.add_argument(
"--name",
metavar="<name>",
help=_("Filters results by the backup name")
)
parser.add_argument(
"--status",
metavar="<status>",
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="<volume>",
help=_("Filters results by the volume which they "
"backup (name or ID)")
)
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
def _format_volume_id(volume_id): def _format_volume_id(volume_id):
"""Return a volume name if available """Return a volume name if available
@ -180,13 +201,24 @@ class ListVolumeBackup(command.Lister):
# Cache the volume list # Cache the volume list
volume_cache = {} volume_cache = {}
try: try:
for s in self.app.client_manager.volume.volumes.list(): for s in volume_client.volumes.list():
volume_cache[s.id] = s volume_cache[s.id] = s
except Exception: except Exception:
# Just forget it if there's any trouble # Just forget it if there's any trouble
pass 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, return (column_headers,
(utils.get_item_properties( (utils.get_item_properties(

View File

@ -17,6 +17,7 @@
import copy import copy
import logging import logging
from osc_lib.cli import parseractions
from osc_lib.command import command from osc_lib.command import command
from osc_lib import exceptions from osc_lib import exceptions
from osc_lib import utils from osc_lib import utils
@ -179,9 +180,42 @@ class ListVolumeBackup(command.Lister):
default=False, default=False,
help=_("List additional fields in output") help=_("List additional fields in output")
) )
parser.add_argument(
"--name",
metavar="<name>",
help=_("Filters results by the backup name")
)
parser.add_argument(
"--status",
metavar="<status>",
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="<volume>",
help=_("Filters results by the volume which they "
"backup (name or ID)")
)
parser.add_argument(
'--marker',
metavar='<marker>',
help=_('The last backup of the previous page (name or ID)'),
)
parser.add_argument(
'--limit',
type=int,
action=parseractions.NonNegativeAction,
metavar='<limit>',
help=_('Maximum number of backups to display'),
)
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
def _format_volume_id(volume_id): def _format_volume_id(volume_id):
"""Return a volume name if available """Return a volume name if available
@ -207,13 +241,30 @@ class ListVolumeBackup(command.Lister):
# Cache the volume list # Cache the volume list
volume_cache = {} volume_cache = {}
try: try:
for s in self.app.client_manager.volume.volumes.list(): for s in volume_client.volumes.list():
volume_cache[s.id] = s volume_cache[s.id] = s
except Exception: except Exception:
# Just forget it if there's any trouble # Just forget it if there's any trouble
pass 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, return (column_headers,
(utils.get_item_properties( (utils.get_item_properties(

View File

@ -0,0 +1,6 @@
---
features:
- |
Add ``--name``, ``--status``, ``--volume``, ``--marker`` and ``--limit`` options
to ``volume backup list`` command
[Bug `1639712 <https://bugs.launchpad.net/bugs/1639712>`_]