summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
authorSteve Martinelli <stevemar@ca.ibm.com>2014-12-16 15:16:41 -0500
committerSteve Martinelli <stevemar@ca.ibm.com>2015-01-08 16:49:17 -0500
commit0ff28d5251f9e25eafdc628e29b093b7c694ea48 (patch)
tree3022b120a13987101adde3260e3623ce86303020 /openstackclient
parentcbb26724fccdbbb76913a8f2994768dea3046480 (diff)
downloadpython-openstackclient-0ff28d5251f9e25eafdc628e29b093b7c694ea48.tar.gz
Allow user list to filter by project
Adds a --project filter to `os user list`, which really calls the role assignment manager behind the scenes. Change-Id: I57a75018f12ed3acdf8f6611b6b58bd974f91da2 Closes-Bug: #1397251
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/identity/v3/user.py53
-rw-r--r--openstackclient/tests/identity/v3/test_user.py47
2 files changed, 93 insertions, 7 deletions
diff --git a/openstackclient/identity/v3/user.py b/openstackclient/identity/v3/user.py
index a60c8c83..4fb7b6d1 100644
--- a/openstackclient/identity/v3/user.py
+++ b/openstackclient/identity/v3/user.py
@@ -188,11 +188,17 @@ class ListUser(lister.Lister):
metavar='<domain>',
help='Filter users by <domain> (name or ID)',
)
- parser.add_argument(
+ project_or_group = parser.add_mutually_exclusive_group()
+ project_or_group.add_argument(
'--group',
metavar='<group>',
help='Filter users by <group> membership (name or ID)',
)
+ project_or_group.add_argument(
+ '--project',
+ metavar='<project>',
+ help='Filter users by <project> (name or ID)',
+ )
parser.add_argument(
'--long',
action='store_true',
@@ -219,7 +225,44 @@ class ListUser(lister.Lister):
else:
group = None
- # List users
+ if parsed_args.project:
+ if domain is not None:
+ project = utils.find_resource(
+ identity_client.projects,
+ parsed_args.project,
+ domain_id=domain
+ ).id
+ else:
+ project = utils.find_resource(
+ identity_client.projects,
+ parsed_args.project,
+ ).id
+
+ assignments = identity_client.role_assignments.list(
+ project=project)
+
+ # NOTE(stevemar): If a user has more than one role on a project
+ # then they will have two entries in the returned data. Since we
+ # are looking for any role, let's just track unique user IDs.
+ user_ids = set()
+ for assignment in assignments:
+ if hasattr(assignment, 'user'):
+ user_ids.add(assignment.user['id'])
+
+ # NOTE(stevemar): Call find_resource once we have unique IDs, so
+ # it's fewer trips to the Identity API, then collect the data.
+ data = []
+ for user_id in user_ids:
+ user = utils.find_resource(identity_client.users, user_id)
+ data.append(user)
+
+ else:
+ data = identity_client.users.list(
+ domain=domain,
+ group=group,
+ )
+
+ # Column handling
if parsed_args.long:
columns = ['ID', 'Name', 'Default Project Id', 'Domain Id',
'Description', 'Email', 'Enabled']
@@ -228,11 +271,7 @@ class ListUser(lister.Lister):
column_headers[3] = 'Domain'
else:
columns = ['ID', 'Name']
- column_headers = copy.deepcopy(columns)
- data = identity_client.users.list(
- domain=domain,
- group=group,
- )
+ column_headers = columns
return (
column_headers,
diff --git a/openstackclient/tests/identity/v3/test_user.py b/openstackclient/tests/identity/v3/test_user.py
index dd517e19..35dd98ee 100644
--- a/openstackclient/tests/identity/v3/test_user.py
+++ b/openstackclient/tests/identity/v3/test_user.py
@@ -44,6 +44,11 @@ class TestUser(identity_fakes.TestIdentityv3):
self.users_mock = self.app.client_manager.identity.users
self.users_mock.reset_mock()
+ # Shortcut for RoleAssignmentManager Mock
+ self.role_assignments_mock = self.app.client_manager.identity.\
+ role_assignments
+ self.role_assignments_mock.reset_mock()
+
class TestUserCreate(TestUser):
@@ -511,6 +516,21 @@ class TestUserList(TestUser):
loaded=True,
)
+ self.projects_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes.PROJECT),
+ loaded=True,
+ )
+
+ self.role_assignments_mock.list.return_value = [
+ fakes.FakeResource(
+ None,
+ copy.deepcopy(
+ identity_fakes.ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID),
+ loaded=True,
+ )
+ ]
+
# Get the command object to test
self.cmd = user.ListUser(self.app, None)
@@ -643,6 +663,33 @@ class TestUserList(TestUser):
), )
self.assertEqual(datalist, tuple(data))
+ def test_user_list_project(self):
+ arglist = [
+ '--project', identity_fakes.project_name,
+ ]
+ verifylist = [
+ ('project', identity_fakes.project_name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ kwargs = {
+ 'project': identity_fakes.project_id,
+ }
+
+ self.role_assignments_mock.list.assert_called_with(**kwargs)
+ self.users_mock.get.assert_called_with(identity_fakes.user_id)
+
+ collist = ['ID', 'Name']
+ self.assertEqual(columns, collist)
+ datalist = ((
+ identity_fakes.user_id,
+ identity_fakes.user_name,
+ ), )
+ self.assertEqual(datalist, tuple(data))
+
class TestUserSet(TestUser):