Merge "Add role assignments list support to identity v3"

This commit is contained in:
Jenkins 2014-06-13 20:56:27 +00:00 committed by Gerrit Code Review
commit 497a38903c
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