diff --git a/openstackclient/identity/v3/role_assignment.py b/openstackclient/identity/v3/role_assignment.py index 92168498f7..169c6cb970 100644 --- a/openstackclient/identity/v3/role_assignment.py +++ b/openstackclient/identity/v3/role_assignment.py @@ -64,12 +64,12 @@ class ListRoleAssignment(lister.Lister): help='Project to filter (name or ID)', ) common.add_project_domain_option_to_parser(parser) - + common.add_inherited_option_to_parser(parser) return parser def _as_tuple(self, assignment): return (assignment.role, assignment.user, assignment.group, - assignment.project, assignment.domain) + assignment.project, assignment.domain, assignment.inherited) def take_action(self, parsed_args): self.log.debug('take_action(%s)' % parsed_args) @@ -115,14 +115,17 @@ class ListRoleAssignment(lister.Lister): effective = True if parsed_args.effective else False self.log.debug('take_action(%s)' % parsed_args) - columns = ('Role', 'User', 'Group', 'Project', 'Domain') + columns = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited') + + inherited_to = 'projects' if parsed_args.inherited else None data = identity_client.role_assignments.list( domain=domain, user=user, group=group, project=project, role=role, - effective=effective) + effective=effective, + os_inherit_extension_inherited_to=inherited_to) data_parsed = [] for assignment in data: @@ -139,6 +142,9 @@ class ListRoleAssignment(lister.Lister): assignment.domain = '' assignment.project = '' + inherited = scope.get('OS-INHERIT:inherited_to') == 'projects' + assignment.inherited = inherited + del assignment.scope if hasattr(assignment, 'user'): diff --git a/openstackclient/tests/identity/v3/fakes.py b/openstackclient/tests/identity/v3/fakes.py index ae7a684cf0..9c4de9cc0d 100644 --- a/openstackclient/tests/identity/v3/fakes.py +++ b/openstackclient/tests/identity/v3/fakes.py @@ -313,6 +313,13 @@ ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID = { 'role': {'id': role_id}, } +ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID_INHERITED = { + 'scope': {'project': {'id': project_id}, + 'OS-INHERIT:inherited_to': 'projects'}, + 'user': {'id': user_id}, + 'role': {'id': role_id}, +} + ASSIGNMENT_WITH_PROJECT_ID_AND_GROUP_ID = { 'scope': {'project': {'id': project_id}}, 'group': {'id': group_id}, @@ -325,6 +332,13 @@ ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID = { 'role': {'id': role_id}, } +ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID_INHERITED = { + 'scope': {'domain': {'id': domain_id}, + 'OS-INHERIT:inherited_to': 'projects'}, + 'user': {'id': user_id}, + 'role': {'id': role_id}, +} + ASSIGNMENT_WITH_DOMAIN_ID_AND_GROUP_ID = { 'scope': {'domain': {'id': domain_id}}, 'group': {'id': group_id}, diff --git a/openstackclient/tests/identity/v3/test_role_assignment.py b/openstackclient/tests/identity/v3/test_role_assignment.py index b1ce8b297f..9817f53a4d 100644 --- a/openstackclient/tests/identity/v3/test_role_assignment.py +++ b/openstackclient/tests/identity/v3/test_role_assignment.py @@ -86,21 +86,24 @@ class TestRoleAssignmentList(TestRoleAssignment): effective=False, role=None, user=None, - project=None) + project=None, + os_inherit_extension_inherited_to=None) - collist = ('Role', 'User', 'Group', 'Project', 'Domain') - self.assertEqual(collist, columns) + collist = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited') + self.assertEqual(columns, collist) datalist = (( identity_fakes.role_id, identity_fakes.user_id, '', identity_fakes.project_id, - '' + '', + False ), (identity_fakes.role_id, '', identity_fakes.group_id, identity_fakes.project_id, - '' + '', + False ),) self.assertEqual(datalist, tuple(data)) @@ -131,6 +134,7 @@ class TestRoleAssignmentList(TestRoleAssignment): ('project', None), ('role', None), ('effective', False), + ('inherited', False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -143,21 +147,24 @@ class TestRoleAssignmentList(TestRoleAssignment): group=None, project=None, role=None, - effective=False) + effective=False, + os_inherit_extension_inherited_to=None) - collist = ('Role', 'User', 'Group', 'Project', 'Domain') - self.assertEqual(collist, columns) + collist = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited') + self.assertEqual(columns, collist) datalist = (( identity_fakes.role_id, identity_fakes.user_id, '', '', - identity_fakes.domain_id + identity_fakes.domain_id, + False ), (identity_fakes.role_id, identity_fakes.user_id, '', identity_fakes.project_id, - '' + '', + False ),) self.assertEqual(datalist, tuple(data)) @@ -188,6 +195,7 @@ class TestRoleAssignmentList(TestRoleAssignment): ('project', None), ('role', None), ('effective', False), + ('inherited', False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -200,21 +208,24 @@ class TestRoleAssignmentList(TestRoleAssignment): effective=False, project=None, role=None, - user=None) + user=None, + os_inherit_extension_inherited_to=None) - collist = ('Role', 'User', 'Group', 'Project', 'Domain') - self.assertEqual(collist, columns) + collist = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited') + self.assertEqual(columns, collist) datalist = (( identity_fakes.role_id, '', identity_fakes.group_id, '', - identity_fakes.domain_id + identity_fakes.domain_id, + False ), (identity_fakes.role_id, '', identity_fakes.group_id, identity_fakes.project_id, - '' + '', + False ),) self.assertEqual(datalist, tuple(data)) @@ -245,6 +256,7 @@ class TestRoleAssignmentList(TestRoleAssignment): ('project', None), ('role', None), ('effective', False), + ('inherited', False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -257,21 +269,24 @@ class TestRoleAssignmentList(TestRoleAssignment): effective=False, project=None, role=None, - user=None) + user=None, + os_inherit_extension_inherited_to=None) - collist = ('Role', 'User', 'Group', 'Project', 'Domain') - self.assertEqual(collist, columns) + collist = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited') + self.assertEqual(columns, collist) datalist = (( identity_fakes.role_id, identity_fakes.user_id, '', '', - identity_fakes.domain_id + identity_fakes.domain_id, + False ), (identity_fakes.role_id, '', identity_fakes.group_id, '', - identity_fakes.domain_id + identity_fakes.domain_id, + False ),) self.assertEqual(datalist, tuple(data)) @@ -302,6 +317,7 @@ class TestRoleAssignmentList(TestRoleAssignment): ('project', identity_fakes.project_name), ('role', None), ('effective', False), + ('inherited', False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -314,21 +330,24 @@ class TestRoleAssignmentList(TestRoleAssignment): effective=False, project=self.projects_mock.get(), role=None, - user=None) + user=None, + os_inherit_extension_inherited_to=None) - collist = ('Role', 'User', 'Group', 'Project', 'Domain') - self.assertEqual(collist, columns) + collist = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited') + self.assertEqual(columns, collist) datalist = (( identity_fakes.role_id, identity_fakes.user_id, '', identity_fakes.project_id, - '' + '', + False ), (identity_fakes.role_id, '', identity_fakes.group_id, identity_fakes.project_id, - '' + '', + False ),) self.assertEqual(datalist, tuple(data)) @@ -357,6 +376,7 @@ class TestRoleAssignmentList(TestRoleAssignment): ('project', None), ('role', None), ('effective', True), + ('inherited', False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -369,20 +389,84 @@ class TestRoleAssignmentList(TestRoleAssignment): effective=True, project=None, role=None, - user=None) + user=None, + os_inherit_extension_inherited_to=None) - collist = ('Role', 'User', 'Group', 'Project', 'Domain') - self.assertEqual(collist, columns) + collist = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited') + self.assertEqual(columns, collist) datalist = (( identity_fakes.role_id, identity_fakes.user_id, '', identity_fakes.project_id, - '' + '', + False ), (identity_fakes.role_id, identity_fakes.user_id, '', '', identity_fakes.domain_id, + False + ),) + self.assertEqual(tuple(data), datalist) + + def test_role_assignment_list_inherited(self): + + self.role_assignments_mock.list.return_value = [ + fakes.FakeResource( + None, + copy.deepcopy( + (identity_fakes. + ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID_INHERITED)), + loaded=True, + ), + fakes.FakeResource( + None, + copy.deepcopy( + (identity_fakes. + ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID_INHERITED)), + loaded=True, + ), + ] + + arglist = ['--inherited'] + verifylist = [ + ('user', None), + ('group', None), + ('domain', None), + ('project', None), + ('role', None), + ('effective', False), + ('inherited', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + self.role_assignments_mock.list.assert_called_with( + domain=None, + group=None, + effective=False, + project=None, + role=None, + user=None, + os_inherit_extension_inherited_to='projects') + + collist = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited') + self.assertEqual(columns, collist) + datalist = (( + identity_fakes.role_id, + identity_fakes.user_id, + '', + identity_fakes.project_id, + '', + True + ), (identity_fakes.role_id, + identity_fakes.user_id, + '', + '', + identity_fakes.domain_id, + True ),) self.assertEqual(datalist, tuple(data))