Add options to "volume snapshot list" command
Add "--name", "--status" and "--volume" options to "volume snapshot list" command for filtering results. Change-Id: I72db1abce7701f31598deec34801a4d1f5713870 Closes-Bug:#1645252
This commit is contained in:
parent
e05c8d7bb0
commit
6ca4dc3533
@ -71,6 +71,9 @@ List volume snapshots
|
|||||||
[--long]
|
[--long]
|
||||||
[--limit <limit>]
|
[--limit <limit>]
|
||||||
[--marker <marker>]
|
[--marker <marker>]
|
||||||
|
[--name <name>]
|
||||||
|
[--status <status>]
|
||||||
|
[--volume <volume>]
|
||||||
|
|
||||||
.. option:: --all-projects
|
.. option:: --all-projects
|
||||||
|
|
||||||
@ -80,6 +83,19 @@ List volume snapshots
|
|||||||
|
|
||||||
List additional fields in output
|
List additional fields in output
|
||||||
|
|
||||||
|
.. option:: --status <status>
|
||||||
|
|
||||||
|
Filters results by a status.
|
||||||
|
('available', 'error', 'creating', 'deleting' or 'error-deleting')
|
||||||
|
|
||||||
|
.. option:: --name <name>
|
||||||
|
|
||||||
|
Filters results by a name.
|
||||||
|
|
||||||
|
.. option:: --volume <volume>
|
||||||
|
|
||||||
|
Filters results by a volume (name or ID).
|
||||||
|
|
||||||
.. option:: --limit <limit>
|
.. option:: --limit <limit>
|
||||||
|
|
||||||
Maximum number of snapshots to display
|
Maximum number of snapshots to display
|
||||||
|
@ -268,6 +268,7 @@ class TestSnapshotList(TestSnapshot):
|
|||||||
super(TestSnapshotList, self).setUp()
|
super(TestSnapshotList, self).setUp()
|
||||||
|
|
||||||
self.volumes_mock.list.return_value = [self.volume]
|
self.volumes_mock.list.return_value = [self.volume]
|
||||||
|
self.volumes_mock.get.return_value = self.volume
|
||||||
self.snapshots_mock.list.return_value = self.snapshots
|
self.snapshots_mock.list.return_value = self.snapshots
|
||||||
# Get the command to test
|
# Get the command to test
|
||||||
self.cmd = volume_snapshot.ListVolumeSnapshot(self.app, None)
|
self.cmd = volume_snapshot.ListVolumeSnapshot(self.app, None)
|
||||||
@ -283,7 +284,13 @@ class TestSnapshotList(TestSnapshot):
|
|||||||
columns, data = self.cmd.take_action(parsed_args)
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.snapshots_mock.list.assert_called_once_with(
|
self.snapshots_mock.list.assert_called_once_with(
|
||||||
search_opts={'all_tenants': False})
|
search_opts={
|
||||||
|
'all_tenants': False,
|
||||||
|
'display_name': None,
|
||||||
|
'status': None,
|
||||||
|
'volume_id': None
|
||||||
|
}
|
||||||
|
)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, list(data))
|
self.assertEqual(self.data, list(data))
|
||||||
|
|
||||||
@ -300,11 +307,88 @@ class TestSnapshotList(TestSnapshot):
|
|||||||
columns, data = self.cmd.take_action(parsed_args)
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.snapshots_mock.list.assert_called_once_with(
|
self.snapshots_mock.list.assert_called_once_with(
|
||||||
search_opts={'all_tenants': False}
|
search_opts={
|
||||||
|
'all_tenants': False,
|
||||||
|
'display_name': None,
|
||||||
|
'status': None,
|
||||||
|
'volume_id': None
|
||||||
|
}
|
||||||
)
|
)
|
||||||
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))
|
||||||
|
|
||||||
|
def test_snapshot_list_name_option(self):
|
||||||
|
arglist = [
|
||||||
|
'--name', self.snapshots[0].display_name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('all_projects', False),
|
||||||
|
('long', False),
|
||||||
|
('name', self.snapshots[0].display_name),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self.snapshots_mock.list.assert_called_once_with(
|
||||||
|
search_opts={
|
||||||
|
'all_tenants': False,
|
||||||
|
'display_name': self.snapshots[0].display_name,
|
||||||
|
'status': None,
|
||||||
|
'volume_id': None
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.assertEqual(self.columns, columns)
|
||||||
|
self.assertEqual(self.data, list(data))
|
||||||
|
|
||||||
|
def test_snapshot_list_status_option(self):
|
||||||
|
arglist = [
|
||||||
|
'--status', self.snapshots[0].status,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('all_projects', False),
|
||||||
|
('long', False),
|
||||||
|
('status', self.snapshots[0].status),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self.snapshots_mock.list.assert_called_once_with(
|
||||||
|
search_opts={
|
||||||
|
'all_tenants': False,
|
||||||
|
'display_name': None,
|
||||||
|
'status': self.snapshots[0].status,
|
||||||
|
'volume_id': None
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.assertEqual(self.columns, columns)
|
||||||
|
self.assertEqual(self.data, list(data))
|
||||||
|
|
||||||
|
def test_snapshot_list_volumeid_option(self):
|
||||||
|
arglist = [
|
||||||
|
'--volume', self.volume.id,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('all_projects', False),
|
||||||
|
('long', False),
|
||||||
|
('volume', self.volume.id),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self.snapshots_mock.list.assert_called_once_with(
|
||||||
|
search_opts={
|
||||||
|
'all_tenants': False,
|
||||||
|
'display_name': None,
|
||||||
|
'status': None,
|
||||||
|
'volume_id': self.volume.id
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.assertEqual(self.columns, columns)
|
||||||
|
self.assertEqual(self.data, list(data))
|
||||||
|
|
||||||
def test_snapshot_list_all_projects(self):
|
def test_snapshot_list_all_projects(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
'--all-projects',
|
'--all-projects',
|
||||||
@ -318,7 +402,13 @@ class TestSnapshotList(TestSnapshot):
|
|||||||
columns, data = self.cmd.take_action(parsed_args)
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.snapshots_mock.list.assert_called_once_with(
|
self.snapshots_mock.list.assert_called_once_with(
|
||||||
search_opts={'all_tenants': True})
|
search_opts={
|
||||||
|
'all_tenants': True,
|
||||||
|
'display_name': None,
|
||||||
|
'status': None,
|
||||||
|
'volume_id': None
|
||||||
|
}
|
||||||
|
)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, list(data))
|
self.assertEqual(self.data, list(data))
|
||||||
|
|
||||||
|
@ -275,6 +275,7 @@ class TestSnapshotList(TestSnapshot):
|
|||||||
super(TestSnapshotList, self).setUp()
|
super(TestSnapshotList, self).setUp()
|
||||||
|
|
||||||
self.volumes_mock.list.return_value = [self.volume]
|
self.volumes_mock.list.return_value = [self.volume]
|
||||||
|
self.volumes_mock.get.return_value = self.volume
|
||||||
self.snapshots_mock.list.return_value = self.snapshots
|
self.snapshots_mock.list.return_value = self.snapshots
|
||||||
# Get the command to test
|
# Get the command to test
|
||||||
self.cmd = volume_snapshot.ListVolumeSnapshot(self.app, None)
|
self.cmd = volume_snapshot.ListVolumeSnapshot(self.app, None)
|
||||||
@ -283,14 +284,21 @@ class TestSnapshotList(TestSnapshot):
|
|||||||
arglist = []
|
arglist = []
|
||||||
verifylist = [
|
verifylist = [
|
||||||
('all_projects', False),
|
('all_projects', False),
|
||||||
("long", False)
|
('long', False)
|
||||||
]
|
]
|
||||||
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)
|
||||||
|
|
||||||
self.snapshots_mock.list.assert_called_once_with(
|
self.snapshots_mock.list.assert_called_once_with(
|
||||||
limit=None, marker=None, search_opts={'all_tenants': False})
|
limit=None, marker=None,
|
||||||
|
search_opts={
|
||||||
|
'all_tenants': False,
|
||||||
|
'name': None,
|
||||||
|
'status': None,
|
||||||
|
'volume_id': None
|
||||||
|
}
|
||||||
|
)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, list(data))
|
self.assertEqual(self.data, list(data))
|
||||||
|
|
||||||
@ -313,7 +321,12 @@ class TestSnapshotList(TestSnapshot):
|
|||||||
self.snapshots_mock.list.assert_called_once_with(
|
self.snapshots_mock.list.assert_called_once_with(
|
||||||
limit=2,
|
limit=2,
|
||||||
marker=self.snapshots[0].id,
|
marker=self.snapshots[0].id,
|
||||||
search_opts={'all_tenants': False}
|
search_opts={
|
||||||
|
'all_tenants': False,
|
||||||
|
'name': None,
|
||||||
|
'status': None,
|
||||||
|
'volume_id': None
|
||||||
|
}
|
||||||
)
|
)
|
||||||
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))
|
||||||
@ -331,7 +344,89 @@ class TestSnapshotList(TestSnapshot):
|
|||||||
columns, data = self.cmd.take_action(parsed_args)
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.snapshots_mock.list.assert_called_once_with(
|
self.snapshots_mock.list.assert_called_once_with(
|
||||||
limit=None, marker=None, search_opts={'all_tenants': True})
|
limit=None, marker=None,
|
||||||
|
search_opts={
|
||||||
|
'all_tenants': True,
|
||||||
|
'name': None,
|
||||||
|
'status': None,
|
||||||
|
'volume_id': None
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.assertEqual(self.columns, columns)
|
||||||
|
self.assertEqual(self.data, list(data))
|
||||||
|
|
||||||
|
def test_snapshot_list_name_option(self):
|
||||||
|
arglist = [
|
||||||
|
'--name', self.snapshots[0].name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('all_projects', False),
|
||||||
|
('long', False),
|
||||||
|
('name', self.snapshots[0].name),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self.snapshots_mock.list.assert_called_once_with(
|
||||||
|
limit=None, marker=None,
|
||||||
|
search_opts={
|
||||||
|
'all_tenants': False,
|
||||||
|
'name': self.snapshots[0].name,
|
||||||
|
'status': None,
|
||||||
|
'volume_id': None
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.assertEqual(self.columns, columns)
|
||||||
|
self.assertEqual(self.data, list(data))
|
||||||
|
|
||||||
|
def test_snapshot_list_status_option(self):
|
||||||
|
arglist = [
|
||||||
|
'--status', self.snapshots[0].status,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('all_projects', False),
|
||||||
|
('long', False),
|
||||||
|
('status', self.snapshots[0].status),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self.snapshots_mock.list.assert_called_once_with(
|
||||||
|
limit=None, marker=None,
|
||||||
|
search_opts={
|
||||||
|
'all_tenants': False,
|
||||||
|
'name': None,
|
||||||
|
'status': self.snapshots[0].status,
|
||||||
|
'volume_id': None
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.assertEqual(self.columns, columns)
|
||||||
|
self.assertEqual(self.data, list(data))
|
||||||
|
|
||||||
|
def test_snapshot_list_volumeid_option(self):
|
||||||
|
arglist = [
|
||||||
|
'--volume', self.volume.id,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('all_projects', False),
|
||||||
|
('long', False),
|
||||||
|
('volume', self.volume.id),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self.snapshots_mock.list.assert_called_once_with(
|
||||||
|
limit=None, marker=None,
|
||||||
|
search_opts={
|
||||||
|
'all_tenants': False,
|
||||||
|
'name': None,
|
||||||
|
'status': None,
|
||||||
|
'volume_id': self.volume.id
|
||||||
|
}
|
||||||
|
)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, list(data))
|
self.assertEqual(self.data, list(data))
|
||||||
|
|
||||||
|
@ -135,9 +135,31 @@ class ListVolumeSnapshot(command.Lister):
|
|||||||
default=False,
|
default=False,
|
||||||
help=_('List additional fields in output'),
|
help=_('List additional fields in output'),
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--name',
|
||||||
|
metavar='<name>',
|
||||||
|
default=None,
|
||||||
|
help=_('Filters results by a name.')
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--status',
|
||||||
|
metavar='<status>',
|
||||||
|
choices=['available', 'error', 'creating', 'deleting',
|
||||||
|
'error-deleting'],
|
||||||
|
help=_("Filters results by a status. "
|
||||||
|
"('available', 'error', 'creating', 'deleting'"
|
||||||
|
" or 'error-deleting')")
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--volume',
|
||||||
|
metavar='<volume>',
|
||||||
|
default=None,
|
||||||
|
help=_('Filters results by a volume (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
|
||||||
@ -169,17 +191,25 @@ class ListVolumeSnapshot(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
|
||||||
|
|
||||||
|
volume_id = None
|
||||||
|
if parsed_args.volume:
|
||||||
|
volume_id = utils.find_resource(
|
||||||
|
volume_client.volumes, parsed_args.volume).id
|
||||||
|
|
||||||
search_opts = {
|
search_opts = {
|
||||||
'all_tenants': parsed_args.all_projects,
|
'all_tenants': parsed_args.all_projects,
|
||||||
|
'display_name': parsed_args.name,
|
||||||
|
'status': parsed_args.status,
|
||||||
|
'volume_id': volume_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
data = self.app.client_manager.volume.volume_snapshots.list(
|
data = volume_client.volume_snapshots.list(
|
||||||
search_opts=search_opts)
|
search_opts=search_opts)
|
||||||
return (column_headers,
|
return (column_headers,
|
||||||
(utils.get_item_properties(
|
(utils.get_item_properties(
|
||||||
|
@ -151,9 +151,31 @@ class ListVolumeSnapshot(command.Lister):
|
|||||||
metavar='<limit>',
|
metavar='<limit>',
|
||||||
help=_('Maximum number of snapshots to display'),
|
help=_('Maximum number of snapshots to display'),
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--name',
|
||||||
|
metavar='<name>',
|
||||||
|
default=None,
|
||||||
|
help=_('Filters results by a name.')
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--status',
|
||||||
|
metavar='<status>',
|
||||||
|
choices=['available', 'error', 'creating', 'deleting',
|
||||||
|
'error-deleting'],
|
||||||
|
help=_("Filters results by a status. "
|
||||||
|
"('available', 'error', 'creating', 'deleting'"
|
||||||
|
" or 'error-deleting')")
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--volume',
|
||||||
|
metavar='<volume>',
|
||||||
|
default=None,
|
||||||
|
help=_('Filters results by a volume (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,17 +202,25 @@ class ListVolumeSnapshot(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
|
||||||
|
|
||||||
|
volume_id = None
|
||||||
|
if parsed_args.volume:
|
||||||
|
volume_id = utils.find_resource(
|
||||||
|
volume_client.volumes, parsed_args.volume).id
|
||||||
|
|
||||||
search_opts = {
|
search_opts = {
|
||||||
'all_tenants': parsed_args.all_projects,
|
'all_tenants': parsed_args.all_projects,
|
||||||
|
'name': parsed_args.name,
|
||||||
|
'status': parsed_args.status,
|
||||||
|
'volume_id': volume_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
data = self.app.client_manager.volume.volume_snapshots.list(
|
data = volume_client.volume_snapshots.list(
|
||||||
search_opts=search_opts,
|
search_opts=search_opts,
|
||||||
marker=parsed_args.marker,
|
marker=parsed_args.marker,
|
||||||
limit=parsed_args.limit,
|
limit=parsed_args.limit,
|
||||||
|
6
releasenotes/notes/bug-1645252-219bfd50c8f04846.yaml
Normal file
6
releasenotes/notes/bug-1645252-219bfd50c8f04846.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Add ``--name``, ``--status`` and ``--volume`` options
|
||||||
|
to ``volume snapshot list`` command
|
||||||
|
[Bug `1645252 <https://bugs.launchpad.net/bugs/1645252>`_]
|
Loading…
x
Reference in New Issue
Block a user