summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLance Bragstad <lbragstad@gmail.com>2018-01-22 18:09:25 +0000
committerLance Bragstad <lbragstad@gmail.com>2018-01-23 23:38:34 +0000
commit1e435e6dcddb34868307b5c20c5319bf0c1d348b (patch)
tree530ed03e59965164fffd0120a6085b35c6c6eb76
parente5d44e5cea91cc512b7995a91c0c7656f70b3d13 (diff)
downloadpython-keystoneclient-1e435e6dcddb34868307b5c20c5319bf0c1d348b.tar.gz
Add system role functionality
This commit adds the necessary bits to be able to use system role assignments from python-keystoneclient. bp system-scope Change-Id: Iecbcbf020a15f2bec777334c648d4477f89f3b2c
-rw-r--r--keystoneclient/tests/unit/v3/test_role_assignments.py74
-rw-r--r--keystoneclient/v3/role_assignments.py29
-rw-r--r--keystoneclient/v3/roles.py117
3 files changed, 177 insertions, 43 deletions
diff --git a/keystoneclient/tests/unit/v3/test_role_assignments.py b/keystoneclient/tests/unit/v3/test_role_assignments.py
index b24799c..45dd13d 100644
--- a/keystoneclient/tests/unit/v3/test_role_assignments.py
+++ b/keystoneclient/tests/unit/v3/test_role_assignments.py
@@ -23,6 +23,32 @@ class RoleAssignmentsTests(utils.ClientTestCase, utils.CrudTests):
self.collection_key = 'role_assignments'
self.model = role_assignments.RoleAssignment
self.manager = self.client.role_assignments
+ self.TEST_USER_SYSTEM_LIST = [{
+ 'role': {
+ 'id': self.TEST_ROLE_ID
+ },
+ 'scope': {
+ 'system': {
+ 'all': True
+ }
+ },
+ 'user': {
+ 'id': self.TEST_USER_ID
+ }
+ }]
+ self.TEST_GROUP_SYSTEM_LIST = [{
+ 'role': {
+ 'id': self.TEST_ROLE_ID
+ },
+ 'scope': {
+ 'system': {
+ 'all': True
+ }
+ },
+ 'group': {
+ 'id': self.TEST_GROUP_ID
+ }
+ }]
self.TEST_USER_DOMAIN_LIST = [{
'role': {
'id': self.TEST_ROLE_ID
@@ -65,7 +91,9 @@ class RoleAssignmentsTests(utils.ClientTestCase, utils.CrudTests):
self.TEST_ALL_RESPONSE_LIST = (self.TEST_USER_PROJECT_LIST +
self.TEST_GROUP_PROJECT_LIST +
- self.TEST_USER_DOMAIN_LIST)
+ self.TEST_USER_DOMAIN_LIST +
+ self.TEST_USER_SYSTEM_LIST +
+ self.TEST_GROUP_SYSTEM_LIST)
def _assert_returned_list(self, ref_list, returned_list):
self.assertEqual(len(ref_list), len(returned_list))
@@ -150,6 +178,50 @@ class RoleAssignmentsTests(utils.ClientTestCase, utils.CrudTests):
kwargs = {'scope.domain.id': self.TEST_DOMAIN_ID}
self.assertQueryStringContains(**kwargs)
+ def test_system_assignment_list(self):
+ ref_list = self.TEST_USER_SYSTEM_LIST + self.TEST_GROUP_SYSTEM_LIST
+
+ self.stub_entity('GET',
+ [self.collection_key, '?scope.system=all'],
+ entity=ref_list)
+
+ returned_list = self.manager.list(system='all')
+ self._assert_returned_list(ref_list, returned_list)
+
+ kwargs = {'scope.system': 'all'}
+ self.assertQueryStringContains(**kwargs)
+
+ def test_system_assignment_list_for_user(self):
+ ref_list = self.TEST_USER_SYSTEM_LIST
+
+ self.stub_entity('GET',
+ [self.collection_key,
+ '?user.id=%s&scope.system=all' % self.TEST_USER_ID],
+ entity=ref_list)
+
+ returned_list = self.manager.list(system='all', user=self.TEST_USER_ID)
+ self._assert_returned_list(ref_list, returned_list)
+
+ kwargs = {'scope.system': 'all', 'user.id': self.TEST_USER_ID}
+ self.assertQueryStringContains(**kwargs)
+
+ def test_system_assignment_list_for_group(self):
+ ref_list = self.TEST_GROUP_SYSTEM_LIST
+
+ self.stub_entity(
+ 'GET',
+ [self.collection_key,
+ '?group.id=%s&scope.system=all' % self.TEST_GROUP_ID],
+ entity=ref_list)
+
+ returned_list = self.manager.list(
+ system='all', group=self.TEST_GROUP_ID
+ )
+ self._assert_returned_list(ref_list, returned_list)
+
+ kwargs = {'scope.system': 'all', 'group.id': self.TEST_GROUP_ID}
+ self.assertQueryStringContains(**kwargs)
+
def test_group_assignments_list(self):
ref_list = self.TEST_GROUP_PROJECT_LIST
self.stub_entity('GET',
diff --git a/keystoneclient/v3/role_assignments.py b/keystoneclient/v3/role_assignments.py
index 5360a94..ce1e550 100644
--- a/keystoneclient/v3/role_assignments.py
+++ b/keystoneclient/v3/role_assignments.py
@@ -46,9 +46,25 @@ class RoleAssignmentManager(base.CrudManager):
msg = _('Specify either a domain or project, not both')
raise exceptions.ValidationError(msg)
- def list(self, user=None, group=None, project=None, domain=None, role=None,
- effective=False, os_inherit_extension_inherited_to=None,
- include_subtree=False, include_names=False):
+ def _check_not_system_and_domain(self, system, domain):
+ if system and domain:
+ msg = _('Specify either system or domain, not both')
+ raise exceptions.ValidationError(msg)
+
+ def _check_not_system_and_project(self, system, project):
+ if system and project:
+ msg = _('Specify either system or project, not both')
+ raise exceptions.ValidationError(msg)
+
+ def _check_system_value(self, system):
+ if system and system != 'all':
+ msg = _("Only a system scope of 'all' is currently supported")
+ raise exceptions.ValidationError(msg)
+
+ def list(self, user=None, group=None, project=None, domain=None,
+ system=False, role=None, effective=False,
+ os_inherit_extension_inherited_to=None, include_subtree=False,
+ include_names=False):
"""List role assignments.
If no arguments are provided, all role assignments in the
@@ -64,6 +80,8 @@ class RoleAssignmentManager(base.CrudManager):
(optional)
:param domain: Domain to be used as query
filter. (optional)
+ :param system: Boolean to be used to filter system assignments.
+ (optional)
:param role: Role to be used as query filter. (optional)
:param boolean effective: return effective role
assignments. (optional)
@@ -76,6 +94,9 @@ class RoleAssignmentManager(base.CrudManager):
"""
self._check_not_user_and_group(user, group)
self._check_not_domain_and_project(domain, project)
+ self._check_not_system_and_domain(system, domain)
+ self._check_not_system_and_project(system, project)
+ self._check_system_value(system)
query_params = {}
if user:
@@ -86,6 +107,8 @@ class RoleAssignmentManager(base.CrudManager):
query_params['scope.project.id'] = base.getid(project)
if domain:
query_params['scope.domain.id'] = base.getid(domain)
+ if system:
+ query_params['scope.system'] = system
if role:
query_params['role.id'] = base.getid(role)
if effective:
diff --git a/keystoneclient/v3/roles.py b/keystoneclient/v3/roles.py
index ce0cfe8..a84ab39 100644
--- a/keystoneclient/v3/roles.py
+++ b/keystoneclient/v3/roles.py
@@ -54,7 +54,7 @@ class RoleManager(base.CrudManager):
key = 'role'
deprecation_msg = 'keystoneclient.v3.roles.InferenceRuleManager'
- def _role_grants_base_url(self, user, group, domain, project,
+ def _role_grants_base_url(self, user, group, system, domain, project,
use_inherit_extension):
# When called, we have already checked that only one of user & group
# and one of domain & project have been specified
@@ -66,6 +66,18 @@ class RoleManager(base.CrudManager):
elif domain:
params['domain_id'] = base.getid(domain)
base_url = '/domains/%(domain_id)s'
+ elif system:
+ if system == 'all':
+ base_url = '/system'
+ else:
+ # NOTE(lbragstad): If we've made it this far, a user is
+ # attempting to do something with system scope that isn't
+ # supported yet (e.g. 'all' is currently the only supported
+ # system scope). In the future that may change but until then
+ # we should fail like we would if a user provided a bogus
+ # project name or domain ID.
+ msg = _("Only a system scope of 'all' is currently supported")
+ raise exceptions.ValidationError(msg)
if use_inherit_extension:
base_url = '/OS-INHERIT' + base_url
@@ -79,13 +91,26 @@ class RoleManager(base.CrudManager):
return base_url % params
- def _require_domain_xor_project(self, domain, project):
- if domain and project:
- msg = _('Specify either a domain or project, not both')
- raise exceptions.ValidationError(msg)
- elif not (domain or project):
- msg = _('Must specify either a domain or project')
- raise exceptions.ValidationError(msg)
+ def _enforce_mutually_exclusive_group(self, system, domain, project):
+ if not system:
+ if domain and project:
+ msg = _('Specify either a domain or project, not both')
+ raise exceptions.ValidationError(msg)
+ elif not (domain or project):
+ msg = _('Must specify either system, domain, or project')
+ raise exceptions.ValidationError(msg)
+ elif system:
+ if domain and project:
+ msg = _(
+ 'Specify either system, domain, or project, not all three.'
+ )
+ raise exceptions.ValidationError(msg)
+ if domain:
+ msg = _('Specify either system or a domain, not both')
+ raise exceptions.ValidationError(msg)
+ if project:
+ msg = _('Specify either a system or project, not both')
+ raise exceptions.ValidationError(msg)
def _require_user_xor_group(self, user, group):
if user and group:
@@ -130,7 +155,7 @@ class RoleManager(base.CrudManager):
"""
return super(RoleManager, self).get(role_id=base.getid(role))
- def list(self, user=None, group=None, domain=None,
+ def list(self, user=None, group=None, system=None, domain=None,
project=None, os_inherit_extension_inherited=False, **kwargs):
"""List roles and role grants.
@@ -143,12 +168,12 @@ class RoleManager(base.CrudManager):
User and group are mutually exclusive.
:type group: str or :class:`keystoneclient.v3.groups.Group`
:param domain: filter in role grants on the specified domain. Either
- user or group must be specified. Project and domain
- are mutually exclusive.
+ user or group must be specified. Project, domain, and
+ system are mutually exclusive.
:type domain: str or :class:`keystoneclient.v3.domains.Domain`
:param project: filter in role grants on the specified project. Either
- user or group must be specified. Project and domain
- are mutually exclusive.
+ user or group must be specified. Project, domain and
+ system are mutually exclusive.
:type project: str or :class:`keystoneclient.v3.projects.Project`
:param bool os_inherit_extension_inherited: OS-INHERIT will be used.
It provides the ability for
@@ -166,10 +191,12 @@ class RoleManager(base.CrudManager):
kwargs['tail'] = '/inherited_to_projects'
if user or group:
self._require_user_xor_group(user, group)
- self._require_domain_xor_project(domain, project)
+ self._enforce_mutually_exclusive_group(system, domain, project)
base_url = self._role_grants_base_url(
- user, group, domain, project, os_inherit_extension_inherited)
+ user, group, system, domain, project,
+ os_inherit_extension_inherited
+ )
return super(RoleManager, self).list(base_url=base_url,
**kwargs)
@@ -208,8 +235,8 @@ class RoleManager(base.CrudManager):
return super(RoleManager, self).delete(
role_id=base.getid(role))
- def grant(self, role, user=None, group=None, domain=None, project=None,
- os_inherit_extension_inherited=False, **kwargs):
+ def grant(self, role, user=None, group=None, system=None, domain=None,
+ project=None, os_inherit_extension_inherited=False, **kwargs):
"""Grant a role to a user or group on a domain or project.
:param role: the role to be granted on the server.
@@ -222,13 +249,16 @@ class RoleManager(base.CrudManager):
resource. Domain or project must be specified.
User and group are mutually exclusive.
:type group: str or :class:`keystoneclient.v3.groups.Group`
+ :param system: system information to grant the role on. Project,
+ domain, and system are mutually exclusive.
+ :type system: str
:param domain: the domain in which the role will be granted. Either
- user or group must be specified. Project and domain
- are mutually exclusive.
+ user or group must be specified. Project, domain, and
+ system are mutually exclusive.
:type domain: str or :class:`keystoneclient.v3.domains.Domain`
:param project: the project in which the role will be granted. Either
- user or group must be specified. Project and domain
- are mutually exclusive.
+ user or group must be specified. Project, domain, and
+ system are mutually exclusive.
:type project: str or :class:`keystoneclient.v3.projects.Project`
:param bool os_inherit_extension_inherited: OS-INHERIT will be used.
It provides the ability for
@@ -242,20 +272,21 @@ class RoleManager(base.CrudManager):
:rtype: :class:`keystoneclient.v3.roles.Role`
"""
- self._require_domain_xor_project(domain, project)
+ self._enforce_mutually_exclusive_group(system, domain, project)
self._require_user_xor_group(user, group)
if os_inherit_extension_inherited:
kwargs['tail'] = '/inherited_to_projects'
base_url = self._role_grants_base_url(
- user, group, domain, project, os_inherit_extension_inherited)
+ user, group, system, domain, project,
+ os_inherit_extension_inherited)
return super(RoleManager, self).put(base_url=base_url,
role_id=base.getid(role),
**kwargs)
- def check(self, role, user=None, group=None, domain=None, project=None,
- os_inherit_extension_inherited=False, **kwargs):
+ def check(self, role, user=None, group=None, system=None, domain=None,
+ project=None, os_inherit_extension_inherited=False, **kwargs):
"""Check if a user or group has a role on a domain or project.
:param user: check for role grants for the specified user on a
@@ -266,13 +297,16 @@ class RoleManager(base.CrudManager):
resource. Domain or project must be specified.
User and group are mutually exclusive.
:type group: str or :class:`keystoneclient.v3.groups.Group`
+ :param system: check for role grants on the system. Project, domain,
+ and system are mutually exclusive.
+ :type system: str
:param domain: check for role grants on the specified domain. Either
- user or group must be specified. Project and domain
- are mutually exclusive.
+ user or group must be specified. Project, domain, and
+ system are mutually exclusive.
:type domain: str or :class:`keystoneclient.v3.domains.Domain`
:param project: check for role grants on the specified project. Either
- user or group must be specified. Project and domain
- are mutually exclusive.
+ user or group must be specified. Project, domain, and
+ system are mutually exclusive.
:type project: str or :class:`keystoneclient.v3.projects.Project`
:param bool os_inherit_extension_inherited: OS-INHERIT will be used.
It provides the ability for
@@ -290,22 +324,23 @@ class RoleManager(base.CrudManager):
:rtype: :class:`requests.models.Response`
"""
- self._require_domain_xor_project(domain, project)
+ self._enforce_mutually_exclusive_group(system, domain, project)
self._require_user_xor_group(user, group)
if os_inherit_extension_inherited:
kwargs['tail'] = '/inherited_to_projects'
base_url = self._role_grants_base_url(
- user, group, domain, project, os_inherit_extension_inherited)
+ user, group, system, domain, project,
+ os_inherit_extension_inherited)
return super(RoleManager, self).head(
base_url=base_url,
role_id=base.getid(role),
os_inherit_extension_inherited=os_inherit_extension_inherited,
**kwargs)
- def revoke(self, role, user=None, group=None, domain=None, project=None,
- os_inherit_extension_inherited=False, **kwargs):
+ def revoke(self, role, user=None, group=None, system=None, domain=None,
+ project=None, os_inherit_extension_inherited=False, **kwargs):
"""Revoke a role from a user or group on a domain or project.
:param user: revoke role grants for the specified user on a
@@ -316,13 +351,16 @@ class RoleManager(base.CrudManager):
resource. Domain or project must be specified.
User and group are mutually exclusive.
:type group: str or :class:`keystoneclient.v3.groups.Group`
+ :param system: revoke role grants on the system. Project, domain, and
+ system are mutually exclusive.
+ :type system: str
:param domain: revoke role grants on the specified domain. Either
- user or group must be specified. Project and domain
- are mutually exclusive.
+ user or group must be specified. Project, domain, and
+ system are mutually exclusive.
:type domain: str or :class:`keystoneclient.v3.domains.Domain`
:param project: revoke role grants on the specified project. Either
- user or group must be specified. Project and domain
- are mutually exclusive.
+ user or group must be specified. Project, domain, and
+ system are mutually exclusive.
:type project: str or :class:`keystoneclient.v3.projects.Project`
:param bool os_inherit_extension_inherited: OS-INHERIT will be used.
It provides the ability for
@@ -336,14 +374,15 @@ class RoleManager(base.CrudManager):
:rtype: list of :class:`keystoneclient.v3.roles.Role`
"""
- self._require_domain_xor_project(domain, project)
+ self._enforce_mutually_exclusive_group(system, domain, project)
self._require_user_xor_group(user, group)
if os_inherit_extension_inherited:
kwargs['tail'] = '/inherited_to_projects'
base_url = self._role_grants_base_url(
- user, group, domain, project, os_inherit_extension_inherited)
+ user, group, system, domain, project,
+ os_inherit_extension_inherited)
return super(RoleManager, self).delete(
base_url=base_url,
role_id=base.getid(role),