Skip to content

Commit 7489fa3

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Add support for domain specific roles"
2 parents 8cef12c + 5eb7e62 commit 7489fa3

9 files changed

Lines changed: 505 additions & 18 deletions

File tree

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ List role assignments
1414
1515
os role assignment list
1616
[--role <role>]
17+
[--role-domain <role-domain>]
1718
[--user <user>]
1819
[--user-domain <user-domain>]
1920
[--group <group>]
@@ -31,6 +32,13 @@ List role assignments
3132

3233
.. versionadded:: 3
3334

35+
.. option:: --role-domain <role-domain>
36+
37+
Domain the role belongs to (name or ID).
38+
This can be used in case collisions between role names exist.
39+
40+
.. versionadded:: 3
41+
3442
.. option:: --user <user>
3543

3644
User to filter (name or ID)

doc/source/command-objects/role.rst

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Add role assignment to a user or group in a project or domain
1515
os role add
1616
--domain <domain> | --project <project> [--project-domain <project-domain>]
1717
--user <user> [--user-domain <user-domain>] | --group <group> [--group-domain <group-domain>]
18+
--role-domain <role-domain>
1819
--inherited
1920
<role>
2021
@@ -65,6 +66,13 @@ Add role assignment to a user or group in a project or domain
6566

6667
.. versionadded:: 3
6768

69+
.. option:: --role-domain <role-domain>
70+
71+
Domain the role belongs to (name or ID).
72+
This must be specified when the name of a domain specific role is used.
73+
74+
.. versionadded:: 3
75+
6876
.. describe:: <role>
6977

7078
Role to add to <project>:<user> (name or ID)
@@ -79,8 +87,15 @@ Create new role
7987
8088
os role create
8189
[--or-show]
90+
[--domain <domain>]
8291
<name>
8392
93+
.. option:: --domain <domain>
94+
95+
Domain the role belongs to (name or ID).
96+
97+
.. versionadded:: 3
98+
8499
.. option:: --or-show
85100

86101
Return existing role
@@ -101,11 +116,18 @@ Delete role(s)
101116
102117
os role delete
103118
<role> [<role> ...]
119+
[--domain <domain>]
104120
105121
.. describe:: <role>
106122

107123
Role to delete (name or ID)
108124

125+
.. option:: --domain <domain>
126+
127+
Domain the role belongs to (name or ID).
128+
129+
.. versionadded:: 3
130+
109131
role list
110132
---------
111133

@@ -123,7 +145,8 @@ List roles
123145

124146
Filter roles by <domain> (name or ID)
125147

126-
(Deprecated, please use ``role assignment list`` instead)
148+
(Deprecated if being used to list assignments in conjunction with the
149+
``--user <user>``, option, please use ``role assignment list`` instead)
127150

128151
.. option:: --project <project>
129152

@@ -189,6 +212,7 @@ Remove role assignment from domain/project : user/group
189212
os role remove
190213
--domain <domain> | --project <project> [--project-domain <project-domain>]
191214
--user <user> [--user-domain <user-domain>] | --group <group> [--group-domain <group-domain>]
215+
--role-domain <role-domain>
192216
--inherited
193217
<role>
194218
@@ -239,6 +263,13 @@ Remove role assignment from domain/project : user/group
239263

240264
.. versionadded:: 3
241265

266+
.. option:: --role-domain <role-domain>
267+
268+
Domain the role belongs to (name or ID).
269+
This must be specified when the name of a domain specific role is used.
270+
271+
.. versionadded:: 3
272+
242273
.. describe:: <role>
243274

244275
Role to remove (name or ID)
@@ -255,12 +286,19 @@ Set role properties
255286
256287
os role set
257288
[--name <name>]
289+
[--domain <domain>]
258290
<role>
259291
260292
.. option:: --name <name>
261293

262294
Set role name
263295

296+
.. option:: --domain <domain>
297+
298+
Domain the role belongs to (name or ID).
299+
300+
.. versionadded:: 3
301+
264302
.. describe:: <role>
265303

266304
Role to modify (name or ID)
@@ -274,8 +312,15 @@ Display role details
274312
.. code:: bash
275313
276314
os role show
315+
[--domain <domain>]
277316
<role>
278317
318+
.. option:: --domain <domain>
319+
320+
Domain the role belongs to (name or ID).
321+
322+
.. versionadded:: 3
323+
279324
.. describe:: <role>
280325

281326
Role to display (name or ID)

openstackclient/identity/common.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,16 @@ def add_project_domain_option_to_parser(parser):
201201
)
202202

203203

204+
def add_role_domain_option_to_parser(parser):
205+
parser.add_argument(
206+
'--role-domain',
207+
metavar='<role-domain>',
208+
help=_('Domain the role belongs to (name or ID). '
209+
'This must be specified when the name of a domain specific '
210+
'role is used.'),
211+
)
212+
213+
204214
def add_inherited_option_to_parser(parser):
205215
parser.add_argument(
206216
'--inherited',

openstackclient/identity/v3/role.py

Lines changed: 89 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def _process_identity_and_resource_options(parsed_args,
109109

110110

111111
class AddRole(command.Command):
112-
"""Adds a role to a user or group on a domain or project"""
112+
"""Adds a role assignment to a user or group on a domain or project"""
113113

114114
def get_parser(self, prog_name):
115115
parser = super(AddRole, self).get_parser(prog_name)
@@ -119,6 +119,7 @@ def get_parser(self, prog_name):
119119
help=_('Role to add to <user> (name or ID)'),
120120
)
121121
_add_identity_and_resource_options_to_parser(parser)
122+
common.add_role_domain_option_to_parser(parser)
122123
return parser
123124

124125
def take_action(self, parsed_args):
@@ -127,9 +128,15 @@ def take_action(self, parsed_args):
127128
if (not parsed_args.user and not parsed_args.domain
128129
and not parsed_args.group and not parsed_args.project):
129130
return
131+
132+
domain_id = None
133+
if parsed_args.role_domain:
134+
domain_id = common.find_domain(identity_client,
135+
parsed_args.role_domain).id
130136
role = utils.find_resource(
131137
identity_client.roles,
132138
parsed_args.role,
139+
domain_id=domain_id
133140
)
134141

135142
kwargs = _process_identity_and_resource_options(
@@ -153,6 +160,11 @@ def get_parser(self, prog_name):
153160
metavar='<role-name>',
154161
help=_('New role name'),
155162
)
163+
parser.add_argument(
164+
'--domain',
165+
metavar='<domain>',
166+
help=_('Domain the role belongs to (name or ID)'),
167+
)
156168
parser.add_argument(
157169
'--or-show',
158170
action='store_true',
@@ -163,12 +175,20 @@ def get_parser(self, prog_name):
163175
def take_action(self, parsed_args):
164176
identity_client = self.app.client_manager.identity
165177

178+
domain_id = None
179+
if parsed_args.domain:
180+
domain_id = common.find_domain(identity_client,
181+
parsed_args.domain).id
182+
166183
try:
167-
role = identity_client.roles.create(name=parsed_args.name)
184+
role = identity_client.roles.create(
185+
name=parsed_args.name, domain=domain_id)
186+
168187
except ks_exc.Conflict:
169188
if parsed_args.or_show:
170189
role = utils.find_resource(identity_client.roles,
171-
parsed_args.name)
190+
parsed_args.name,
191+
domain_id=domain_id)
172192
LOG.info(_('Returning existing role %s'), role.name)
173193
else:
174194
raise
@@ -188,15 +208,26 @@ def get_parser(self, prog_name):
188208
nargs="+",
189209
help=_('Role(s) to delete (name or ID)'),
190210
)
211+
parser.add_argument(
212+
'--domain',
213+
metavar='<domain>',
214+
help=_('Domain the role belongs to (name or ID)'),
215+
)
191216
return parser
192217

193218
def take_action(self, parsed_args):
194219
identity_client = self.app.client_manager.identity
195220

221+
domain_id = None
222+
if parsed_args.domain:
223+
domain_id = common.find_domain(identity_client,
224+
parsed_args.domain).id
225+
196226
for role in parsed_args.roles:
197227
role_obj = utils.find_resource(
198228
identity_client.roles,
199229
role,
230+
domain_id=domain_id
200231
)
201232
identity_client.roles.delete(role_obj.id)
202233

@@ -206,6 +237,18 @@ class ListRole(command.Lister):
206237

207238
def get_parser(self, prog_name):
208239
parser = super(ListRole, self).get_parser(prog_name)
240+
241+
# TODO(henry-nash): The use of the List Role command to list
242+
# assignments (as well as roles) has been deprecated. In order
243+
# to support domain specific roles, we are overriding the domain
244+
# option to allow specification of the domain for the role. This does
245+
# not conflict with any existing commands, since for the deprecated
246+
# assignments listing you were never allowed to only specify a domain
247+
# (you also needed to specify a user).
248+
#
249+
# Once we have removed the deprecated options entirely, we must
250+
# replace the call to _add_identity_and_resource_options_to_parser()
251+
# below with just adding the domain option into the parser.
209252
_add_identity_and_resource_options_to_parser(parser)
210253
return parser
211254

@@ -239,8 +282,14 @@ def take_action(self, parsed_args):
239282

240283
# no user or group specified, list all roles in the system
241284
if not parsed_args.user and not parsed_args.group:
242-
columns = ('ID', 'Name')
243-
data = identity_client.roles.list()
285+
if not parsed_args.domain:
286+
columns = ('ID', 'Name')
287+
data = identity_client.roles.list()
288+
else:
289+
columns = ('ID', 'Name', 'Domain')
290+
data = identity_client.roles.list(domain_id=domain.id)
291+
for role in data:
292+
role.domain = domain.name
244293
elif parsed_args.user and parsed_args.domain:
245294
columns = ('ID', 'Name', 'Domain', 'User')
246295
data = identity_client.roles.list(
@@ -322,7 +371,7 @@ def take_action(self, parsed_args):
322371

323372

324373
class RemoveRole(command.Command):
325-
"""Remove role from domain/project : user/group"""
374+
"""Removes a role assignment from domain/project : user/group"""
326375

327376
def get_parser(self, prog_name):
328377
parser = super(RemoveRole, self).get_parser(prog_name)
@@ -332,6 +381,8 @@ def get_parser(self, prog_name):
332381
help=_('Role to remove (name or ID)'),
333382
)
334383
_add_identity_and_resource_options_to_parser(parser)
384+
common.add_role_domain_option_to_parser(parser)
385+
335386
return parser
336387

337388
def take_action(self, parsed_args):
@@ -342,9 +393,15 @@ def take_action(self, parsed_args):
342393
sys.stderr.write(_("Incorrect set of arguments provided. "
343394
"See openstack --help for more details\n"))
344395
return
396+
397+
domain_id = None
398+
if parsed_args.role_domain:
399+
domain_id = common.find_domain(identity_client,
400+
parsed_args.role_domain).id
345401
role = utils.find_resource(
346402
identity_client.roles,
347403
parsed_args.role,
404+
domain_id=domain_id
348405
)
349406

350407
kwargs = _process_identity_and_resource_options(
@@ -367,6 +424,11 @@ def get_parser(self, prog_name):
367424
metavar='<role>',
368425
help=_('Role to modify (name or ID)'),
369426
)
427+
parser.add_argument(
428+
'--domain',
429+
metavar='<domain>',
430+
help=_('Domain the role belongs to (name or ID)'),
431+
)
370432
parser.add_argument(
371433
'--name',
372434
metavar='<name>',
@@ -377,10 +439,14 @@ def get_parser(self, prog_name):
377439
def take_action(self, parsed_args):
378440
identity_client = self.app.client_manager.identity
379441

380-
role = utils.find_resource(
381-
identity_client.roles,
382-
parsed_args.role,
383-
)
442+
domain_id = None
443+
if parsed_args.domain:
444+
domain_id = common.find_domain(identity_client,
445+
parsed_args.domain).id
446+
447+
role = utils.find_resource(identity_client.roles,
448+
parsed_args.role,
449+
domain_id=domain_id)
384450

385451
identity_client.roles.update(role.id, name=parsed_args.name)
386452

@@ -395,15 +461,24 @@ def get_parser(self, prog_name):
395461
metavar='<role>',
396462
help=_('Role to display (name or ID)'),
397463
)
464+
parser.add_argument(
465+
'--domain',
466+
metavar='<domain>',
467+
help=_('Domain the role belongs to (name or ID)'),
468+
)
398469
return parser
399470

400471
def take_action(self, parsed_args):
401472
identity_client = self.app.client_manager.identity
402473

403-
role = utils.find_resource(
404-
identity_client.roles,
405-
parsed_args.role,
406-
)
474+
domain_id = None
475+
if parsed_args.domain:
476+
domain_id = common.find_domain(identity_client,
477+
parsed_args.domain).id
478+
479+
role = utils.find_resource(identity_client.roles,
480+
parsed_args.role,
481+
domain_id=domain_id)
407482

408483
role._info.pop('links')
409484
return zip(*sorted(six.iteritems(role._info)))

0 commit comments

Comments
 (0)