diff --git a/manilaclient/api_versions.py b/manilaclient/api_versions.py index 777506da2..639501625 100644 --- a/manilaclient/api_versions.py +++ b/manilaclient/api_versions.py @@ -27,7 +27,7 @@ from manilaclient import utils LOG = logging.getLogger(__name__) -MAX_VERSION = '2.78' +MAX_VERSION = '2.79' MIN_VERSION = '2.0' DEPRECATED_VERSION = '1.0' _VERSIONED_METHOD_MAP = {} diff --git a/manilaclient/osc/v2/share_snapshots.py b/manilaclient/osc/v2/share_snapshots.py index 0f96ce8db..bb4afa11f 100644 --- a/manilaclient/osc/v2/share_snapshots.py +++ b/manilaclient/osc/v2/share_snapshots.py @@ -475,6 +475,16 @@ class ListShareSnapshot(command.Lister): 'property. (repeat option to filter by multiple ' 'properties)'), ) + parser.add_argument( + '--count', + action='store_true', + default=False, + help=_("The total count of share snapshots before pagination is " + "applied. This parameter is useful when applying " + "pagination parameters '--limit' and '--offset'. Available " + "only for microversion >= 2.79.") + ) + return parser def take_action(self, parsed_args): @@ -508,6 +518,15 @@ class ListShareSnapshot(command.Lister): "Pattern based filtering (name~, description~ and description)" " is only available with manila API version >= 2.36") + if parsed_args.count: + if share_client.api_version < api_versions.APIVersion("2.79"): + raise exceptions.CommandError( + "Displaying total number of share snapshots is only " + "available with manila API version >= 2.79") + if parsed_args.formatter != 'table': + raise exceptions.CommandError( + "Count can only be printed when using '--format table'") + if parsed_args.detail: columns.extend([ 'Status', @@ -522,10 +541,20 @@ class ListShareSnapshot(command.Lister): if parsed_args.all_projects: columns.append('Project ID') - snapshots = share_client.share_snapshots.list(search_opts=search_opts) + + total_count = 0 + if parsed_args.count: + search_opts['with_count'] = True + snapshots, total_count = share_client.share_snapshots.list( + search_opts=search_opts) + else: + snapshots = share_client.share_snapshots.list( + search_opts=search_opts) snapshots = utils.sort_items(snapshots, parsed_args.sort, str) + if parsed_args.count: + print("Total number of snapshots: %s" % total_count) return (columns, (utils.get_item_properties(s, columns) for s in snapshots)) diff --git a/manilaclient/tests/unit/osc/v2/test_share_snapshots.py b/manilaclient/tests/unit/osc/v2/test_share_snapshots.py index 7282dc3c2..2ffe50a1a 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_snapshots.py +++ b/manilaclient/tests/unit/osc/v2/test_share_snapshots.py @@ -17,6 +17,7 @@ from unittest import mock import uuid +import ddt from osc_lib import exceptions from osc_lib import utils as oscutils @@ -681,6 +682,7 @@ class TestShareSnapshotUnset(TestShareSnapshot): exceptions.CommandError, self.cmd.take_action, parsed_args) +@ddt.ddt class TestShareSnapshotList(TestShareSnapshot): def setUp(self): @@ -797,16 +799,24 @@ class TestShareSnapshotList(TestShareSnapshot): self.assertEqual(COLUMNS_DETAIL, columns) self.assertEqual(list(values), list(data)) - def test_list_snapshots_api_version_exception(self): - self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.35") + @ddt.data('2.35', '2.78') + def test_list_snapshots_api_version_exception(self, v): + self.app.client_manager.share.api_version = api_versions.APIVersion(v) - arglist = [ - '--description', 'Description' - ] - verifylist = [ - ('description', 'Description') - ] + if v == "2.35": + arglist = [ + '--description', 'Description' + ] + verifylist = [ + ('description', 'Description') + ] + elif v == "2.78": + arglist = [ + '--count', + ] + verifylist = [ + ('count', True) + ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -854,6 +864,39 @@ class TestShareSnapshotList(TestShareSnapshot): self.assertEqual(COLUMNS, columns) self.assertEqual(list(values), list(data)) + def test_list_snapshots_with_count(self): + self.app.client_manager.share.api_version = api_versions.APIVersion( + '2.79') + + self.snapshots_mock.list.return_value = self.snapshots_list, 2 + + arglist = [ + '--count', + ] + verifylist = [ + ('count', True) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.snapshots_mock.list.assert_called_with( + search_opts={ + 'offset': None, + 'limit': None, + 'all_tenants': False, + 'name': None, + 'status': None, + 'share_id': None, + 'usage': None, + 'metadata': {}, + 'name~': None, + 'description~': None, + 'description': None, + 'with_count': True, + }) + class TestShareSnapshotAdopt(TestShareSnapshot): diff --git a/manilaclient/tests/unit/v2/fakes.py b/manilaclient/tests/unit/v2/fakes.py index 9290a6bcc..7c3c1c407 100644 --- a/manilaclient/tests/unit/v2/fakes.py +++ b/manilaclient/tests/unit/v2/fakes.py @@ -421,6 +421,9 @@ class FakeHTTPClient(fakes.FakeHTTPClient): 'share_proto': 'type', 'export_location': 'location', }]} + if kw.get('with_count'): + snapshots.update({'count': 2}) + return (200, {}, snapshots) def post_os_share_manage(self, body, **kw): diff --git a/manilaclient/tests/unit/v2/test_share_snapshots.py b/manilaclient/tests/unit/v2/test_share_snapshots.py index 1acd84b1d..bd8a525cf 100644 --- a/manilaclient/tests/unit/v2/test_share_snapshots.py +++ b/manilaclient/tests/unit/v2/test_share_snapshots.py @@ -140,6 +140,17 @@ class ShareSnapshotsTest(utils.TestCase): cs.share_snapshots.list(detailed=True) cs.assert_called('GET', '/snapshots/detail') + def test_list_share_snapshots_detail_with_count(self): + search_opts = { + 'with_count': 'True', + } + snapshots, count = cs.share_snapshots.list(detailed=True, + search_opts=search_opts) + cs.assert_called( + 'GET', '/snapshots/detail?with_count=True') + self.assertEqual(2, count) + self.assertEqual(1, len(snapshots)) + def test_manage_snapshot(self): share_id = "1234" provider_location = "fake_location" diff --git a/manilaclient/tests/unit/v2/test_shell.py b/manilaclient/tests/unit/v2/test_shell.py index 448425349..c4b646a75 100644 --- a/manilaclient/tests/unit/v2/test_shell.py +++ b/manilaclient/tests/unit/v2/test_shell.py @@ -1244,6 +1244,25 @@ class ShellTest(test_utils.TestCase): 'snapshot-list --sort-key fake_sort_key', ) + @ddt.data('True', 'False') + def test_list_snapshots_filter_with_count(self, value): + except_url = '/snapshots/detail?with_count=' + value + if value == 'False': + except_url = '/snapshots/detail' + + for separator in self.separators: + self.run_command('snapshot-list --count' + separator + value) + self.assert_called('GET', except_url) + + @ddt.data('True', 'False') + def test_list_snapshots_filter_with_count_invalid_version(self, value): + self.assertRaises( + exceptions.CommandError, + self.run_command, + 'snapshot-list --count ' + value, + version='2.78' + ) + @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_extra_specs_list(self): self.run_command('extra-specs-list') diff --git a/manilaclient/v2/shell.py b/manilaclient/v2/shell.py index 663c80322..c2f0fae13 100644 --- a/manilaclient/v2/shell.py +++ b/manilaclient/v2/shell.py @@ -2521,12 +2521,12 @@ def do_list(cs, args): search_opts['with_count'] = args.count shares, total_count = cs.shares.list( search_opts=search_opts, sort_key=args.sort_key, - sort_dir=args.sort_dir, + sort_dir=args.sort_dir ) else: shares = cs.shares.list( search_opts=search_opts, sort_key=args.sort_key, - sort_dir=args.sort_dir, + sort_dir=args.sort_dir ) # NOTE(vponomaryov): usage of 'export_location' and # 'export_locations' columns may cause scaling issue using API 2.9+ and @@ -2839,6 +2839,14 @@ def do_share_instance_export_location_show(cs, args): nargs='*', help='Filters results by a metadata key and value. OPTIONAL: ' 'Default=None, Available only for microversion >= 2.73. ') +@cliutils.arg( + '--count', + dest='count', + metavar='', + choices=['True', 'False'], + default=False, + help='Display total number of share snapshots to return. ' + 'Available only for microversion >= 2.79.') def do_snapshot_list(cs, args): """List all the snapshots.""" all_projects = int( @@ -2878,12 +2886,29 @@ def do_snapshot_list(cs, args): "Pattern based filtering (name~, description~ and description)" " is only available with manila API version >= 2.36") - snapshots = cs.share_snapshots.list( - search_opts=search_opts, - sort_key=args.sort_key, - sort_dir=args.sort_dir, - ) + if (args.count and + cs.api_version.matches( + api_versions.APIVersion(), api_versions.APIVersion("2.78"))): + raise exceptions.CommandError( + "Display total number of share snapshots is only " + "available with manila API version >= 2.79") + + total_count = 0 + if strutils.bool_from_string(args.count, strict=True): + search_opts['with_count'] = args.count + snapshots, total_count = cs.share_snapshots.list( + search_opts=search_opts, + sort_key=args.sort_key, + sort_dir=args.sort_dir) + else: + snapshots = cs.share_snapshots.list( + search_opts=search_opts, + sort_key=args.sort_key, + sort_dir=args.sort_dir) + cliutils.print_list(snapshots, list_of_keys, sortby_index=None) + if args.count: + print("Share snapshots in total: %s" % total_count) @cliutils.arg( diff --git a/releasenotes/notes/add-count-info-in-snapshot-c9600adad648a486.yaml b/releasenotes/notes/add-count-info-in-snapshot-c9600adad648a486.yaml new file mode 100644 index 000000000..227fe2668 --- /dev/null +++ b/releasenotes/notes/add-count-info-in-snapshot-c9600adad648a486.yaml @@ -0,0 +1,3 @@ +--- +features: + - Added ``count`` option in share snapshot's list commands since 2.79.