Skip to content

Commit 272ac55

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Return names in list role assignments"
2 parents f1ae75a + 3a48989 commit 272ac55

5 files changed

Lines changed: 162 additions & 13 deletions

File tree

doc/source/command-objects/role-assignment.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,7 @@ List role assignments
6666
.. option:: --inherited
6767

6868
Specifies if the role grant is inheritable to the sub projects
69+
70+
.. option:: --names
71+
72+
Returns role assignments with names instead of IDs

openstackclient/identity/v3/role_assignment.py

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ def get_parser(self, prog_name):
3434
metavar='<role>',
3535
help='Role to filter (name or ID)',
3636
)
37+
parser.add_argument(
38+
'--names',
39+
action="store_true",
40+
help='Display names instead of IDs',
41+
)
3742
user_or_group = parser.add_mutually_exclusive_group()
3843
user_or_group.add_argument(
3944
'--user',
@@ -107,6 +112,7 @@ def take_action(self, parsed_args):
107112
parsed_args.group_domain,
108113
)
109114

115+
include_names = True if parsed_args.names else False
110116
effective = True if parsed_args.effective else False
111117
columns = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited')
112118

@@ -118,17 +124,26 @@ def take_action(self, parsed_args):
118124
project=project,
119125
role=role,
120126
effective=effective,
121-
os_inherit_extension_inherited_to=inherited_to)
127+
os_inherit_extension_inherited_to=inherited_to,
128+
include_names=include_names)
122129

123130
data_parsed = []
124131
for assignment in data:
125132
# Removing the extra "scope" layer in the assignment json
126133
scope = assignment.scope
127134
if 'project' in scope:
128-
setattr(assignment, 'project', scope['project']['id'])
135+
if include_names:
136+
prj = '@'.join([scope['project']['name'],
137+
scope['project']['domain']['name']])
138+
setattr(assignment, 'project', prj)
139+
else:
140+
setattr(assignment, 'project', scope['project']['id'])
129141
assignment.domain = ''
130142
elif 'domain' in scope:
131-
setattr(assignment, 'domain', scope['domain']['id'])
143+
if include_names:
144+
setattr(assignment, 'domain', scope['domain']['name'])
145+
else:
146+
setattr(assignment, 'domain', scope['domain']['id'])
132147
assignment.project = ''
133148

134149
else:
@@ -141,17 +156,30 @@ def take_action(self, parsed_args):
141156
del assignment.scope
142157

143158
if hasattr(assignment, 'user'):
144-
setattr(assignment, 'user', assignment.user['id'])
159+
if include_names:
160+
usr = '@'.join([assignment.user['name'],
161+
assignment.user['domain']['name']])
162+
setattr(assignment, 'user', usr)
163+
else:
164+
setattr(assignment, 'user', assignment.user['id'])
145165
assignment.group = ''
146166
elif hasattr(assignment, 'group'):
147-
setattr(assignment, 'group', assignment.group['id'])
167+
if include_names:
168+
grp = '@'.join([assignment.group['name'],
169+
assignment.group['domain']['name']])
170+
setattr(assignment, 'group', grp)
171+
else:
172+
setattr(assignment, 'group', assignment.group['id'])
148173
assignment.user = ''
149174
else:
150175
assignment.user = ''
151176
assignment.group = ''
152177

153178
if hasattr(assignment, 'role'):
154-
setattr(assignment, 'role', assignment.role['id'])
179+
if include_names:
180+
setattr(assignment, 'role', assignment.role['name'])
181+
else:
182+
setattr(assignment, 'role', assignment.role['id'])
155183
else:
156184
assignment.role = ''
157185

openstackclient/tests/identity/v3/fakes.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,22 @@
314314
'role': {'id': role_id},
315315
}
316316

317+
ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID_INCLUDE_NAMES = {
318+
'scope': {
319+
'project': {
320+
'domain': {'id': domain_id,
321+
'name': domain_name},
322+
'id': project_id,
323+
'name': project_name}},
324+
'user': {
325+
'domain': {'id': domain_id,
326+
'name': domain_name},
327+
'id': user_id,
328+
'name': user_name},
329+
'role': {'id': role_id,
330+
'name': role_name},
331+
}
332+
317333
ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID_INHERITED = {
318334
'scope': {'project': {'id': project_id},
319335
'OS-INHERIT:inherited_to': 'projects'},
@@ -333,6 +349,19 @@
333349
'role': {'id': role_id},
334350
}
335351

352+
ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID_INCLUDE_NAMES = {
353+
'scope': {
354+
'domain': {'id': domain_id,
355+
'name': domain_name}},
356+
'user': {
357+
'domain': {'id': domain_id,
358+
'name': domain_name},
359+
'id': user_id,
360+
'name': user_name},
361+
'role': {'id': role_id,
362+
'name': role_name},
363+
}
364+
336365
ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID_INHERITED = {
337366
'scope': {'domain': {'id': domain_id},
338367
'OS-INHERIT:inherited_to': 'projects'},

openstackclient/tests/identity/v3/test_role_assignment.py

Lines changed: 89 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ def test_role_assignment_list_no_filters(self):
9898
role=None,
9999
user=None,
100100
project=None,
101-
os_inherit_extension_inherited_to=None)
101+
os_inherit_extension_inherited_to=None,
102+
include_names=False)
102103

103104
self.assertEqual(self.columns, columns)
104105
datalist = ((
@@ -145,6 +146,7 @@ def test_role_assignment_list_user(self):
145146
('role', None),
146147
('effective', False),
147148
('inherited', False),
149+
('names', False),
148150
]
149151
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
150152

@@ -160,7 +162,8 @@ def test_role_assignment_list_user(self):
160162
project=None,
161163
role=None,
162164
effective=False,
163-
os_inherit_extension_inherited_to=None)
165+
os_inherit_extension_inherited_to=None,
166+
include_names=False)
164167

165168
self.assertEqual(self.columns, columns)
166169
datalist = ((
@@ -207,6 +210,7 @@ def test_role_assignment_list_group(self):
207210
('role', None),
208211
('effective', False),
209212
('inherited', False),
213+
('names', False),
210214
]
211215
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
212216

@@ -222,7 +226,8 @@ def test_role_assignment_list_group(self):
222226
project=None,
223227
role=None,
224228
user=None,
225-
os_inherit_extension_inherited_to=None)
229+
os_inherit_extension_inherited_to=None,
230+
include_names=False)
226231

227232
self.assertEqual(self.columns, columns)
228233
datalist = ((
@@ -269,6 +274,7 @@ def test_role_assignment_list_domain(self):
269274
('role', None),
270275
('effective', False),
271276
('inherited', False),
277+
('names', False),
272278
]
273279
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
274280

@@ -284,7 +290,8 @@ def test_role_assignment_list_domain(self):
284290
project=None,
285291
role=None,
286292
user=None,
287-
os_inherit_extension_inherited_to=None)
293+
os_inherit_extension_inherited_to=None,
294+
include_names=False)
288295

289296
self.assertEqual(self.columns, columns)
290297
datalist = ((
@@ -331,6 +338,7 @@ def test_role_assignment_list_project(self):
331338
('role', None),
332339
('effective', False),
333340
('inherited', False),
341+
('names', False),
334342
]
335343
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
336344

@@ -346,7 +354,8 @@ def test_role_assignment_list_project(self):
346354
project=self.projects_mock.get(),
347355
role=None,
348356
user=None,
349-
os_inherit_extension_inherited_to=None)
357+
os_inherit_extension_inherited_to=None,
358+
include_names=False)
350359

351360
self.assertEqual(self.columns, columns)
352361
datalist = ((
@@ -391,6 +400,7 @@ def test_role_assignment_list_effective(self):
391400
('role', None),
392401
('effective', True),
393402
('inherited', False),
403+
('names', False),
394404
]
395405
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
396406

@@ -406,7 +416,8 @@ def test_role_assignment_list_effective(self):
406416
project=None,
407417
role=None,
408418
user=None,
409-
os_inherit_extension_inherited_to=None)
419+
os_inherit_extension_inherited_to=None,
420+
include_names=False)
410421

411422
self.assertEqual(self.columns, columns)
412423
datalist = ((
@@ -453,6 +464,7 @@ def test_role_assignment_list_inherited(self):
453464
('role', None),
454465
('effective', False),
455466
('inherited', True),
467+
('names', False),
456468
]
457469
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
458470

@@ -468,7 +480,8 @@ def test_role_assignment_list_inherited(self):
468480
project=None,
469481
role=None,
470482
user=None,
471-
os_inherit_extension_inherited_to='projects')
483+
os_inherit_extension_inherited_to='projects',
484+
include_names=False)
472485

473486
self.assertEqual(self.columns, columns)
474487
datalist = ((
@@ -486,3 +499,72 @@ def test_role_assignment_list_inherited(self):
486499
True
487500
),)
488501
self.assertEqual(datalist, tuple(data))
502+
503+
def test_role_assignment_list_include_names(self):
504+
505+
self.role_assignments_mock.list.return_value = [
506+
fakes.FakeResource(
507+
None,
508+
copy.deepcopy(
509+
identity_fakes
510+
.ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID_INCLUDE_NAMES),
511+
loaded=True,
512+
),
513+
fakes.FakeResource(
514+
None,
515+
copy.deepcopy(
516+
identity_fakes
517+
.ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID_INCLUDE_NAMES),
518+
loaded=True,
519+
),
520+
]
521+
522+
arglist = ['--names']
523+
verifylist = [
524+
('user', None),
525+
('group', None),
526+
('domain', None),
527+
('project', None),
528+
('role', None),
529+
('effective', False),
530+
('inherited', False),
531+
('names', True),
532+
]
533+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
534+
535+
# DisplayCommandBase.take_action() returns two tuples
536+
537+
# This test will not run correctly until the patch in the python
538+
# client is merged. Once that is done 'data' should return the
539+
# correct information
540+
columns, data = self.cmd.take_action(parsed_args)
541+
542+
self.role_assignments_mock.list.assert_called_with(
543+
domain=None,
544+
group=None,
545+
effective=False,
546+
project=None,
547+
role=None,
548+
user=None,
549+
os_inherit_extension_inherited_to=None,
550+
include_names=True)
551+
552+
collist = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited')
553+
self.assertEqual(columns, collist)
554+
555+
datalist1 = ((
556+
identity_fakes.role_name,
557+
'@'.join([identity_fakes.user_name, identity_fakes.domain_name]),
558+
'',
559+
'@'.join([identity_fakes.project_name,
560+
identity_fakes.domain_name]),
561+
'',
562+
False
563+
), (identity_fakes.role_name,
564+
'@'.join([identity_fakes.user_name, identity_fakes.domain_name]),
565+
'',
566+
'',
567+
identity_fakes.domain_name,
568+
False
569+
),)
570+
self.assertEqual(tuple(data), datalist1)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
features:
3+
- >
4+
[`bug 1479569 <https://bugs.launchpad.net/python-keystoneclient/+bug/1479569>`_]
5+
Add an optional ``--names`` argument to the `role assignment list`` command. This
6+
will output names instead of IDs for users, groups, roles, projects, and domains.

0 commit comments

Comments
 (0)