diff --git a/manilaclient/api_versions.py b/manilaclient/api_versions.py index 774ded60f..90d0630a0 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.40' +MAX_VERSION = '2.42' MIN_VERSION = '2.0' DEPRECATED_VERSION = '1.0' _VERSIONED_METHOD_MAP = {} diff --git a/manilaclient/base.py b/manilaclient/base.py index 0964ea31a..e4724680c 100644 --- a/manilaclient/base.py +++ b/manilaclient/base.py @@ -74,8 +74,12 @@ class Manager(utils.HookableMixin): with self.completion_cache('human_id', obj_class, mode="w"): with self.completion_cache('uuid', obj_class, mode="w"): - return [obj_class(self, res, loaded=True) - for res in data if res] + resource = [obj_class(self, res, loaded=True) + for res in data if res] + if 'count' in body: + return resource, body['count'] + else: + return resource @contextlib.contextmanager def completion_cache(self, cache_type, obj_class, mode): diff --git a/manilaclient/tests/unit/v2/fakes.py b/manilaclient/tests/unit/v2/fakes.py index d0e3dfb58..bf24b53db 100644 --- a/manilaclient/tests/unit/v2/fakes.py +++ b/manilaclient/tests/unit/v2/fakes.py @@ -233,7 +233,8 @@ class FakeHTTPClient(fakes.FakeHTTPClient): "rel": "self"}, ], }, - ] + ], + 'count': 2, } return (200, {}, shares) diff --git a/manilaclient/tests/unit/v2/test_shares.py b/manilaclient/tests/unit/v2/test_shares.py index ef377f590..e0d9ca7f7 100644 --- a/manilaclient/tests/unit/v2/test_shares.py +++ b/manilaclient/tests/unit/v2/test_shares.py @@ -321,6 +321,16 @@ class SharesTest(utils.TestCase): + value + '&is_public=True')) def test_list_shares_detailed(self): + search_opts = { + 'with_count': 'True', + } + shares, count = cs.shares.list(detailed=True, search_opts=search_opts) + cs.assert_called( + 'GET', '/shares/detail?is_public=True&with_count=True') + self.assertEqual(2, count) + self.assertEqual(1, len(shares)) + + def test_list_shares_detailed_with_count(self): cs.shares.list(detailed=True) cs.assert_called('GET', '/shares/detail?is_public=True') diff --git a/manilaclient/tests/unit/v2/test_shell.py b/manilaclient/tests/unit/v2/test_shell.py index 517ba3134..650904e8b 100644 --- a/manilaclient/tests/unit/v2/test_shell.py +++ b/manilaclient/tests/unit/v2/test_shell.py @@ -397,6 +397,25 @@ class ShellTest(test_utils.TestCase): ) self.assert_called('GET', '/share-networks/detail') + @ddt.data('True', 'False') + def test_list_filter_with_count(self, value): + except_url = '/shares/detail?with_count=' + value + if value == 'False': + except_url = '/shares/detail' + + for separator in self.separators: + self.run_command('list --count' + separator + value) + self.assert_called('GET', except_url) + + @ddt.data('True', 'False') + def test_list_filter_with_count_invalid_version(self, value): + self.assertRaises( + exceptions.CommandError, + self.run_command, + 'list --count ' + value, + version='2.41' + ) + @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_instance_list(self): self.run_command('share-instance-list') diff --git a/manilaclient/v2/shell.py b/manilaclient/v2/shell.py index b11c6d616..e9bee33b0 100644 --- a/manilaclient/v2/shell.py +++ b/manilaclient/v2/shell.py @@ -1627,6 +1627,14 @@ def do_snapshot_access_list(cs, args): action='single_alias', help='ID or path of the share export location. ' 'Available only for microversion >= 2.35.') +@cliutils.arg( + '--count', + dest='count', + metavar='', + choices=['True', 'False'], + default=False, + help='Display total number of shares to return. ' + 'Available only for microversion >= 2.42.') @cliutils.service_type('sharev2') def do_list(cs, args): """List NAS shares with filters.""" @@ -1692,14 +1700,28 @@ def do_list(cs, args): "Filtering by export location is only " "available with manila API version >= 2.35") + if (args.count and + cs.api_version.matches( + api_versions.APIVersion(), api_versions.APIVersion("2.41"))): + raise exceptions.CommandError( + "Display total number of shares is only " + "available with manila API version >= 2.42") + if share_group: search_opts['share_group_id'] = share_group.id - shares = cs.shares.list( - search_opts=search_opts, - sort_key=args.sort_key, - sort_dir=args.sort_dir, - ) + total_count = 0 + if strutils.bool_from_string(args.count, strict=True): + 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, + ) + else: + shares = cs.shares.list( + search_opts=search_opts, sort_key=args.sort_key, + sort_dir=args.sort_dir, + ) # NOTE(vponomaryov): usage of 'export_location' and # 'export_locations' columns may cause scaling issue using API 2.9+ and # when lots of shares are returned. @@ -1712,6 +1734,8 @@ def do_list(cs, args): setattr(share, 'export_locations', els) setattr(share, 'export_location', els[0] if els else None) cliutils.print_list(shares, list_of_keys) + if args.count: + print("Shares in total: %s" % total_count) @cliutils.arg( diff --git a/releasenotes/notes/add-count-info-in-share-21a6b36c0f4c87b2.yaml b/releasenotes/notes/add-count-info-in-share-21a6b36c0f4c87b2.yaml new file mode 100644 index 000000000..9ebbb8bb7 --- /dev/null +++ b/releasenotes/notes/add-count-info-in-share-21a6b36c0f4c87b2.yaml @@ -0,0 +1,3 @@ +--- +features: + - Added ``with_count`` option in share's list commands since 2.42.