diff --git a/openstackclient/identity/v3/group.py b/openstackclient/identity/v3/group.py index c5a4401722..4eb144896d 100644 --- a/openstackclient/identity/v3/group.py +++ b/openstackclient/identity/v3/group.py @@ -164,17 +164,21 @@ class DeleteGroup(command.Command): class ListGroup(lister.Lister): - """List groups and optionally roles assigned to groups""" + """List groups""" log = logging.getLogger(__name__ + '.ListGroup') def get_parser(self, prog_name): parser = super(ListGroup, self).get_parser(prog_name) parser.add_argument( - 'group', - metavar='', - nargs='?', - help='Name or ID of group to list [required with --role]', + '--domain', + metavar='', + help='Filter group list by ', + ) + parser.add_argument( + '--user', + metavar='', + help='List group memberships for (name or ID)', ) parser.add_argument( '--long', @@ -188,18 +192,39 @@ class ListGroup(lister.Lister): self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity + if parsed_args.domain: + domain = utils.find_resource( + identity_client.domains, + parsed_args.domain, + ).id + else: + domain = None + + if parsed_args.user: + user = utils.find_resource( + identity_client.users, + parsed_args.user, + ).id + else: + user = None + # List groups if parsed_args.long: columns = ('ID', 'Name', 'Domain ID', 'Description') else: columns = ('ID', 'Name') - data = identity_client.groups.list() + data = identity_client.groups.list( + domain=domain, + user=user, + ) - return (columns, - (utils.get_item_properties( - s, columns, - formatters={}, - ) for s in data)) + return ( + columns, + (utils.get_item_properties( + s, columns, + formatters={}, + ) for s in data) + ) class RemoveUserFromGroup(command.Command): diff --git a/openstackclient/identity/v3/user.py b/openstackclient/identity/v3/user.py index c4adb225ca..38c3497339 100644 --- a/openstackclient/identity/v3/user.py +++ b/openstackclient/identity/v3/user.py @@ -148,17 +148,21 @@ class DeleteUser(command.Command): class ListUser(lister.Lister): - """List users and optionally roles assigned to users""" + """List users""" log = logging.getLogger(__name__ + '.ListUser') def get_parser(self, prog_name): parser = super(ListUser, self).get_parser(prog_name) parser.add_argument( - 'user', - metavar='', - nargs='?', - help='Name or ID of user to list [required with --role]', + '--domain', + metavar='', + help='Filter group list by ', + ) + parser.add_argument( + '--group', + metavar='', + help='List memberships of (name or ID)', ) parser.add_argument( '--long', @@ -169,7 +173,24 @@ class ListUser(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) + identity_client = self.app.client_manager.identity + + if parsed_args.domain: + domain = utils.find_resource( + identity_client.domains, + parsed_args.domain, + ).id + else: + domain = None + + if parsed_args.group: + group = utils.find_resource( + identity_client.groups, + parsed_args.group, + ).id + else: + group = None # List users if parsed_args.long: @@ -177,13 +198,18 @@ class ListUser(lister.Lister): 'Description', 'Email', 'Enabled') else: columns = ('ID', 'Name') - data = self.app.client_manager.identity.users.list() + data = identity_client.users.list( + domain=domain, + group=group, + ) - return (columns, - (utils.get_item_properties( - s, columns, - formatters={}, - ) for s in data)) + return ( + columns, + (utils.get_item_properties( + s, columns, + formatters={}, + ) for s in data) + ) class SetUser(command.Command): diff --git a/openstackclient/tests/identity/v3/test_group.py b/openstackclient/tests/identity/v3/test_group.py new file mode 100644 index 0000000000..dce5636281 --- /dev/null +++ b/openstackclient/tests/identity/v3/test_group.py @@ -0,0 +1,193 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import copy + +from openstackclient.identity.v3 import group +from openstackclient.tests import fakes +from openstackclient.tests.identity.v3 import fakes as identity_fakes + + +class TestGroup(identity_fakes.TestIdentityv3): + + def setUp(self): + super(TestGroup, self).setUp() + + # Get a shortcut to the DomainManager Mock + self.domains_mock = self.app.client_manager.identity.domains + self.domains_mock.reset_mock() + + # Get a shortcut to the GroupManager Mock + self.groups_mock = self.app.client_manager.identity.groups + self.groups_mock.reset_mock() + + # Get a shortcut to the UserManager Mock + self.users_mock = self.app.client_manager.identity.users + self.users_mock.reset_mock() + + +class TestGroupList(TestGroup): + + def setUp(self): + super(TestGroupList, self).setUp() + + self.groups_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.GROUP), + loaded=True, + ) + self.groups_mock.list.return_value = [ + fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.GROUP), + loaded=True, + ), + ] + + self.domains_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.DOMAIN), + loaded=True, + ) + + self.users_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.USER), + loaded=True, + ) + + # Get the command object to test + self.cmd = group.ListGroup(self.app, None) + + def test_group_list_no_options(self): + arglist = [] + verifylist = [] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + # Set expected values + kwargs = { + 'domain': None, + 'user': None, + } + + self.groups_mock.list.assert_called_with( + **kwargs + ) + + collist = ('ID', 'Name') + self.assertEqual(columns, collist) + datalist = (( + identity_fakes.group_id, + identity_fakes.group_name, + ), ) + self.assertEqual(datalist, tuple(data)) + + def test_group_list_domain(self): + arglist = [ + '--domain', identity_fakes.domain_id, + ] + verifylist = [ + ('domain', identity_fakes.domain_id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + # Set expected values + kwargs = { + 'domain': identity_fakes.domain_id, + 'user': None, + } + + self.groups_mock.list.assert_called_with( + **kwargs + ) + + collist = ('ID', 'Name') + self.assertEqual(columns, collist) + datalist = (( + identity_fakes.group_id, + identity_fakes.group_name, + ), ) + self.assertEqual(datalist, tuple(data)) + + def test_group_list_user(self): + arglist = [ + '--user', identity_fakes.user_name, + ] + verifylist = [ + ('user', identity_fakes.user_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + # Set expected values + kwargs = { + 'domain': None, + 'user': identity_fakes.user_id, + } + + self.groups_mock.list.assert_called_with( + **kwargs + ) + + collist = ('ID', 'Name') + self.assertEqual(columns, collist) + datalist = (( + identity_fakes.group_id, + identity_fakes.group_name, + ), ) + self.assertEqual(datalist, tuple(data)) + + def test_group_list_long(self): + arglist = [ + '--long', + ] + verifylist = [ + ('long', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + # Set expected values + kwargs = { + 'domain': None, + 'user': None, + } + + self.groups_mock.list.assert_called_with( + **kwargs + ) + + collist = ( + 'ID', + 'Name', + 'Domain ID', + 'Description', + ) + self.assertEqual(columns, collist) + datalist = (( + identity_fakes.group_id, + identity_fakes.group_name, + '', + '', + ), ) + self.assertEqual(datalist, tuple(data)) diff --git a/openstackclient/tests/identity/v3/test_user.py b/openstackclient/tests/identity/v3/test_user.py index b9c060d767..569d91401c 100644 --- a/openstackclient/tests/identity/v3/test_user.py +++ b/openstackclient/tests/identity/v3/test_user.py @@ -34,9 +34,9 @@ class TestUser(identity_fakes.TestIdentityv3): self.projects_mock = self.app.client_manager.identity.projects self.projects_mock.reset_mock() - # Get a shortcut to the RoleManager Mock - self.roles_mock = self.app.client_manager.identity.roles - self.roles_mock.reset_mock() + # Get a shortcut to the GroupManager Mock + self.groups_mock = self.app.client_manager.identity.groups + self.groups_mock.reset_mock() # Get a shortcut to the UserManager Mock self.users_mock = self.app.client_manager.identity.users @@ -489,6 +489,18 @@ class TestUserList(TestUser): ), ] + self.domains_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.DOMAIN), + loaded=True, + ) + + self.groups_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.GROUP), + loaded=True, + ) + # Get the command object to test self.cmd = user.ListUser(self.app, None) @@ -500,7 +512,15 @@ class TestUserList(TestUser): # DisplayCommandBase.take_action() returns two tuples columns, data = self.cmd.take_action(parsed_args) - self.users_mock.list.assert_called_with() + # Set expected values + kwargs = { + 'domain': None, + 'group': None, + } + + self.users_mock.list.assert_called_with( + **kwargs + ) collist = ('ID', 'Name') self.assertEqual(columns, collist) @@ -508,7 +528,67 @@ class TestUserList(TestUser): identity_fakes.user_id, identity_fakes.user_name, ), ) - self.assertEqual(tuple(data), datalist) + self.assertEqual(datalist, tuple(data)) + + def test_user_list_domain(self): + arglist = [ + '--domain', identity_fakes.domain_id, + ] + verifylist = [ + ('domain', identity_fakes.domain_id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + # Set expected values + kwargs = { + 'domain': identity_fakes.domain_id, + 'group': None, + } + + self.users_mock.list.assert_called_with( + **kwargs + ) + + collist = ('ID', 'Name') + self.assertEqual(columns, collist) + datalist = (( + identity_fakes.user_id, + identity_fakes.user_name, + ), ) + self.assertEqual(datalist, tuple(data)) + + def test_user_list_group(self): + arglist = [ + '--group', identity_fakes.group_name, + ] + verifylist = [ + ('group', identity_fakes.group_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + # Set expected values + kwargs = { + 'domain': None, + 'group': identity_fakes.group_id, + } + + self.users_mock.list.assert_called_with( + **kwargs + ) + + collist = ('ID', 'Name') + self.assertEqual(columns, collist) + datalist = (( + identity_fakes.user_id, + identity_fakes.user_name, + ), ) + self.assertEqual(datalist, tuple(data)) def test_user_list_long(self): arglist = [ @@ -522,7 +602,15 @@ class TestUserList(TestUser): # DisplayCommandBase.take_action() returns two tuples columns, data = self.cmd.take_action(parsed_args) - self.users_mock.list.assert_called_with() + # Set expected values + kwargs = { + 'domain': None, + 'group': None, + } + + self.users_mock.list.assert_called_with( + **kwargs + ) collist = ( 'ID', @@ -543,7 +631,7 @@ class TestUserList(TestUser): identity_fakes.user_email, True, ), ) - self.assertEqual(tuple(data), datalist) + self.assertEqual(datalist, tuple(data)) class TestUserSet(TestUser):