Add role assignments list support to identity v3

The assignments manager and its test class were created.
Some fake stubs were also added on the fakes.py module.

The "openstack role assignment list" command was created.

Change-Id: Iae94f4fee608ea3e09ff38961ad22edc38efb89c
Implements: blueprint roles-assignment-list
Closes-Bug: 1246310
This commit is contained in:
henriquetruta 2014-05-28 11:09:46 -03:00
parent fb65652753
commit 58f80e4c75
4 changed files with 572 additions and 0 deletions

View File

@ -0,0 +1,156 @@
# 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.
#
"""Identity v3 Assignment action implementations """
import logging
from cliff import lister
from openstackclient.common import utils
class ListRoleAssignment(lister.Lister):
"""Lists role assignments according to the given filters"""
log = logging.getLogger(__name__ + '.ListRoleAssignment')
def get_parser(self, prog_name):
parser = super(ListRoleAssignment, self).get_parser(prog_name)
parser.add_argument(
'--effective',
action="store_true",
default=False,
help='Returns only effective role assignments',
)
parser.add_argument(
'--role',
metavar='<role>',
help='Name or ID of role to filter',
)
user_or_group = parser.add_mutually_exclusive_group()
user_or_group.add_argument(
'--user',
metavar='<user>',
help='Name or ID of user to filter',
)
user_or_group.add_argument(
'--group',
metavar='<group>',
help='Name or ID of group to filter',
)
domain_or_project = parser.add_mutually_exclusive_group()
domain_or_project.add_argument(
'--domain',
metavar='<domain>',
help='Name or ID of domain to filter',
)
domain_or_project.add_argument(
'--project',
metavar='<project>',
help='Name or ID of project to filter',
)
return parser
def _as_tuple(self, assignment):
return (assignment.role, assignment.user, assignment.group,
assignment.project, assignment.domain)
def take_action(self, parsed_args):
self.log.debug('take_action(%s)' % parsed_args)
identity_client = self.app.client_manager.identity
role = None
if parsed_args.role:
role = utils.find_resource(
identity_client.roles,
parsed_args.role,
)
user = None
if parsed_args.user:
user = utils.find_resource(
identity_client.users,
parsed_args.user,
)
domain = None
if parsed_args.domain:
domain = utils.find_resource(
identity_client.domains,
parsed_args.domain,
)
project = None
if parsed_args.project:
project = utils.find_resource(
identity_client.projects,
parsed_args.project,
)
group = None
if parsed_args.group:
group = utils.find_resource(
identity_client.groups,
parsed_args.group,
)
effective = True if parsed_args.effective else False
self.log.debug('take_action(%s)' % parsed_args)
columns = ('Role', 'User', 'Group', 'Project', 'Domain')
data = identity_client.role_assignments.list(
domain=domain,
user=user,
group=group,
project=project,
role=role,
effective=effective)
data_parsed = []
for assignment in data:
# Removing the extra "scope" layer in the assignment json
scope = assignment.scope
if 'project' in scope:
setattr(assignment, 'project', scope['project']['id'])
assignment.domain = ''
elif 'domain' in scope:
setattr(assignment, 'domain', scope['domain']['id'])
assignment.project = ''
else:
assignment.domain = ''
assignment.project = ''
del assignment.scope
if hasattr(assignment, 'user'):
setattr(assignment, 'user', assignment.user['id'])
assignment.group = ''
elif hasattr(assignment, 'group'):
setattr(assignment, 'group', assignment.group['id'])
assignment.user = ''
else:
assignment.user = ''
assignment.group = ''
if hasattr(assignment, 'role'):
setattr(assignment, 'role', assignment.role['id'])
else:
assignment.role = ''
# Creating a tuple from data object fields
# (including the blank ones)
data_parsed.append(self._as_tuple(assignment))
return columns, tuple(data_parsed)

View File

@ -114,6 +114,31 @@ IDENTITY_PROVIDER = {
'description': idp_description
}
#Assignments
ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID = {
'scope': {'project': {'id': project_id}},
'user': {'id': user_id},
'role': {'id': role_id},
}
ASSIGNMENT_WITH_PROJECT_ID_AND_GROUP_ID = {
'scope': {'project': {'id': project_id}},
'group': {'id': group_id},
'role': {'id': role_id},
}
ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID = {
'scope': {'domain': {'id': domain_id}},
'user': {'id': user_id},
'role': {'id': role_id},
}
ASSIGNMENT_WITH_DOMAIN_ID_AND_GROUP_ID = {
'scope': {'domain': {'id': domain_id}},
'group': {'id': group_id},
'role': {'id': role_id},
}
class FakeIdentityv3Client(object):
def __init__(self, **kwargs):
@ -130,6 +155,8 @@ class FakeIdentityv3Client(object):
self.service_catalog = mock.Mock()
self.users = mock.Mock()
self.users.resource_class = fakes.FakeResource(None, {})
self.role_assignments = mock.Mock()
self.role_assignments.resource_class = fakes.FakeResource(None, {})
self.auth_token = kwargs['token']
self.management_url = kwargs['endpoint']

View File

@ -0,0 +1,388 @@
# 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 role_assignment
from openstackclient.tests import fakes
from openstackclient.tests.identity.v3 import fakes as identity_fakes
class TestRoleAssignment(identity_fakes.TestIdentityv3):
def setUp(self):
super(TestRoleAssignment, self).setUp()
class TestRoleAssignmentList(TestRoleAssignment):
def setUp(self):
super(TestRoleAssignment, self).setUp()
# Get a shortcut to the UserManager Mock
self.users_mock = self.app.client_manager.identity.users
self.users_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 DomainManager Mock
self.domains_mock = self.app.client_manager.identity.domains
self.domains_mock.reset_mock()
# Get a shortcut to the ProjectManager Mock
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()
self.role_assignments_mock = self.app.client_manager.identity.\
role_assignments
self.role_assignments_mock.reset_mock()
# Get the command object to test
self.cmd = role_assignment.ListRoleAssignment(self.app, None)
def test_role_assignment_list_no_filters(self):
self.role_assignments_mock.list.return_value = [
fakes.FakeResource(
None,
copy.deepcopy(
identity_fakes.ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID),
loaded=True,
),
fakes.FakeResource(
None,
copy.deepcopy(
identity_fakes.ASSIGNMENT_WITH_PROJECT_ID_AND_GROUP_ID),
loaded=True,
),
]
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)
self.role_assignments_mock.list.assert_called_with(
domain=None,
group=None,
effective=False,
role=None,
user=None,
project=None)
collist = ('Role', 'User', 'Group', 'Project', 'Domain')
self.assertEqual(columns, collist)
datalist = ((
identity_fakes.role_id,
identity_fakes.user_id,
'',
identity_fakes.project_id,
''
), (identity_fakes.role_id,
'',
identity_fakes.group_id,
identity_fakes.project_id,
''
),)
self.assertEqual(tuple(data), datalist)
def test_role_assignment_list_user(self):
self.role_assignments_mock.list.return_value = [
fakes.FakeResource(
None,
copy.deepcopy(
identity_fakes.ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID),
loaded=True,
),
fakes.FakeResource(
None,
copy.deepcopy(
identity_fakes.ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID),
loaded=True,
),
]
arglist = [
'--user', identity_fakes.user_name
]
verifylist = [
('user', identity_fakes.user_name),
('group', None),
('domain', None),
('project', None),
('role', None),
('effective', False),
]
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,
user=self.users_mock.get(),
group=None,
project=None,
role=None,
effective=False)
collist = ('Role', 'User', 'Group', 'Project', 'Domain')
self.assertEqual(columns, collist)
datalist = ((
identity_fakes.role_id,
identity_fakes.user_id,
'',
'',
identity_fakes.domain_id
), (identity_fakes.role_id,
identity_fakes.user_id,
'',
identity_fakes.project_id,
''
),)
self.assertEqual(tuple(data), datalist)
def test_role_assignment_list_group(self):
self.role_assignments_mock.list.return_value = [
fakes.FakeResource(
None,
copy.deepcopy(
identity_fakes.ASSIGNMENT_WITH_DOMAIN_ID_AND_GROUP_ID),
loaded=True,
),
fakes.FakeResource(
None,
copy.deepcopy(
identity_fakes.ASSIGNMENT_WITH_PROJECT_ID_AND_GROUP_ID),
loaded=True,
),
]
arglist = [
'--group', identity_fakes.group_name
]
verifylist = [
('user', None),
('group', identity_fakes.group_name),
('domain', None),
('project', None),
('role', None),
('effective', False),
]
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=self.groups_mock.get(),
effective=False,
project=None,
role=None,
user=None)
collist = ('Role', 'User', 'Group', 'Project', 'Domain')
self.assertEqual(columns, collist)
datalist = ((
identity_fakes.role_id,
'',
identity_fakes.group_id,
'',
identity_fakes.domain_id
), (identity_fakes.role_id,
'',
identity_fakes.group_id,
identity_fakes.project_id,
''
),)
self.assertEqual(tuple(data), datalist)
def test_role_assignment_list_domain(self):
self.role_assignments_mock.list.return_value = [
fakes.FakeResource(
None,
copy.deepcopy(
identity_fakes.ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID),
loaded=True,
),
fakes.FakeResource(
None,
copy.deepcopy(
identity_fakes.ASSIGNMENT_WITH_DOMAIN_ID_AND_GROUP_ID),
loaded=True,
),
]
arglist = [
'--domain', identity_fakes.domain_name
]
verifylist = [
('user', None),
('group', None),
('domain', identity_fakes.domain_name),
('project', None),
('role', None),
('effective', False),
]
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=self.domains_mock.get(),
group=None,
effective=False,
project=None,
role=None,
user=None)
collist = ('Role', 'User', 'Group', 'Project', 'Domain')
self.assertEqual(columns, collist)
datalist = ((
identity_fakes.role_id,
identity_fakes.user_id,
'',
'',
identity_fakes.domain_id
), (identity_fakes.role_id,
'',
identity_fakes.group_id,
'',
identity_fakes.domain_id
),)
self.assertEqual(tuple(data), datalist)
def test_role_assignment_list_project(self):
self.role_assignments_mock.list.return_value = [
fakes.FakeResource(
None,
copy.deepcopy(
identity_fakes.ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID),
loaded=True,
),
fakes.FakeResource(
None,
copy.deepcopy(
identity_fakes.ASSIGNMENT_WITH_PROJECT_ID_AND_GROUP_ID),
loaded=True,
),
]
arglist = [
'--project', identity_fakes.project_name
]
verifylist = [
('user', None),
('group', None),
('domain', None),
('project', identity_fakes.project_name),
('role', None),
('effective', False),
]
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=self.projects_mock.get(),
role=None,
user=None)
collist = ('Role', 'User', 'Group', 'Project', 'Domain')
self.assertEqual(columns, collist)
datalist = ((
identity_fakes.role_id,
identity_fakes.user_id,
'',
identity_fakes.project_id,
''
), (identity_fakes.role_id,
'',
identity_fakes.group_id,
identity_fakes.project_id,
''
),)
self.assertEqual(tuple(data), datalist)
def test_role_assignment_list_effective(self):
self.role_assignments_mock.list.return_value = [
fakes.FakeResource(
None,
copy.deepcopy(
identity_fakes.ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID),
loaded=True,
),
fakes.FakeResource(
None,
copy.deepcopy(
identity_fakes.ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID),
loaded=True,
),
]
arglist = ['--effective']
verifylist = [
('user', None),
('group', None),
('domain', None),
('project', None),
('role', None),
('effective', 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=True,
project=None,
role=None,
user=None)
collist = ('Role', 'User', 'Group', 'Project', 'Domain')
self.assertEqual(columns, collist)
datalist = ((
identity_fakes.role_id,
identity_fakes.user_id,
'',
identity_fakes.project_id,
''
), (identity_fakes.role_id,
identity_fakes.user_id,
'',
'',
identity_fakes.domain_id,
),)
self.assertEqual(tuple(data), datalist)

View File

@ -228,6 +228,7 @@ openstack.identity.v3 =
role_remove = openstackclient.identity.v3.role:RemoveRole
role_show = openstackclient.identity.v3.role:ShowRole
role_set = openstackclient.identity.v3.role:SetRole
role_assignment_list = openstackclient.identity.v3.role_assignment:ListRoleAssignment
service_create = openstackclient.identity.v3.service:CreateService
service_delete = openstackclient.identity.v3.service:DeleteService