summaryrefslogtreecommitdiffstats
path: root/keystone/assignment
diff options
context:
space:
mode:
Diffstat (limited to 'keystone/assignment')
-rw-r--r--keystone/assignment/backends/kvs.py86
-rw-r--r--keystone/assignment/backends/ldap.py6
-rw-r--r--keystone/assignment/backends/sql.py162
-rw-r--r--keystone/assignment/core.py121
4 files changed, 283 insertions, 92 deletions
diff --git a/keystone/assignment/backends/kvs.py b/keystone/assignment/backends/kvs.py
index 4ed3937b..4dfd908f 100644
--- a/keystone/assignment/backends/kvs.py
+++ b/keystone/assignment/backends/kvs.py
@@ -33,10 +33,16 @@ class Assignment(kvs.Base, assignment.Driver):
except exception.NotFound:
raise exception.ProjectNotFound(project_id=tenant_id)
- def list_projects(self):
- tenant_keys = filter(lambda x: x.startswith("tenant-"),
- self.db.keys())
- return [self.db.get(key) for key in tenant_keys]
+ def list_projects(self, domain_id=None):
+ project_keys = filter(lambda x: x.startswith("tenant-"),
+ self.db.keys())
+ project_refs = [self.db.get(key) for key in project_keys]
+
+ if domain_id:
+ self.get_domain(domain_id)
+ project_refs = filter(lambda x: domain_id in x['domain_id'],
+ project_refs)
+ return project_refs
def get_project_by_name(self, tenant_name, domain_id):
try:
@@ -105,13 +111,16 @@ class Assignment(kvs.Base, assignment.Driver):
metadata_ref = self._get_metadata(user_id, tenant_id)
except exception.MetadataNotFound:
metadata_ref = {}
- roles = set(metadata_ref.get('roles', []))
- if role_id in roles:
+
+ try:
+ metadata_ref['roles'] = self._add_role_to_role_dicts(
+ role_id, False, metadata_ref.get('roles', []),
+ allow_existing=False)
+ except KeyError:
msg = ('User %s already has role %s in tenant %s'
% (user_id, role_id, tenant_id))
raise exception.Conflict(type='role grant', details=msg)
- roles.add(role_id)
- metadata_ref['roles'] = list(roles)
+
self._update_metadata(user_id, tenant_id, metadata_ref)
def remove_role_from_user_and_project(self, user_id, tenant_id, role_id):
@@ -119,23 +128,25 @@ class Assignment(kvs.Base, assignment.Driver):
metadata_ref = self._get_metadata(user_id, tenant_id)
except exception.MetadataNotFound:
metadata_ref = {}
- roles = set(metadata_ref.get('roles', []))
- if role_id not in roles:
- msg = 'Cannot remove role that has not been granted, %s' % role_id
- raise exception.RoleNotFound(message=msg)
- roles.remove(role_id)
- metadata_ref['roles'] = list(roles)
+ try:
+ metadata_ref['roles'] = self._remove_role_from_role_dicts(
+ role_id, False, metadata_ref.get('roles', []))
+ except KeyError:
+ raise exception.RoleNotFound(message=_(
+ 'Cannot remove role that has not been granted, %s') %
+ role_id)
+
+ if len(metadata_ref['roles']):
+ self._update_metadata(user_id, tenant_id, metadata_ref)
+ else:
- if not len(roles):
self.db.delete('metadata-%s-%s' % (tenant_id, user_id))
user_ref = self._get_user(user_id)
tenants = set(user_ref.get('tenants', []))
tenants.remove(tenant_id)
user_ref['tenants'] = list(tenants)
self.identity_api.update_user(user_id, user_ref)
- else:
- self._update_metadata(user_id, tenant_id, metadata_ref)
def list_role_assignments(self):
"""List the role assignments.
@@ -144,7 +155,7 @@ class Assignment(kvs.Base, assignment.Driver):
"metadata-{target}-{actor}", with the value being a role list
- i.e. "metadata-MyProjectID-MyUserID" [role1, role2]
+ i.e. "metadata-MyProjectID-MyUserID" [{'id': role1}, {'id': role2}]
...so we enumerate the list and extract the targets, actors
and roles.
@@ -169,7 +180,8 @@ class Assignment(kvs.Base, assignment.Driver):
template['group_id'] = meta_id2
entry = self.db.get(key)
- for r in entry.get('roles', []):
+ for r in self._roles_from_role_dicts(entry.get('roles', {}),
+ False):
role_assignment = template.copy()
role_assignment['role_id'] = r
assignment_list.append(role_assignment)
@@ -324,7 +336,8 @@ class Assignment(kvs.Base, assignment.Driver):
self.db.set('role_list', list(role_list))
def create_grant(self, role_id, user_id=None, group_id=None,
- domain_id=None, project_id=None):
+ domain_id=None, project_id=None,
+ inherited_to_projects=False):
self.get_role(role_id)
if user_id:
@@ -341,14 +354,16 @@ class Assignment(kvs.Base, assignment.Driver):
domain_id, group_id)
except exception.MetadataNotFound:
metadata_ref = {}
- roles = set(metadata_ref.get('roles', []))
- roles.add(role_id)
- metadata_ref['roles'] = list(roles)
+
+ metadata_ref['roles'] = self._add_role_to_role_dicts(
+ role_id, inherited_to_projects, metadata_ref.get('roles', []))
+
self._update_metadata(user_id, project_id, metadata_ref,
domain_id, group_id)
def list_grants(self, user_id=None, group_id=None,
- domain_id=None, project_id=None):
+ domain_id=None, project_id=None,
+ inherited_to_projects=False):
if user_id:
self.identity_api.get_user(user_id)
if group_id:
@@ -363,10 +378,14 @@ class Assignment(kvs.Base, assignment.Driver):
domain_id, group_id)
except exception.MetadataNotFound:
metadata_ref = {}
- return [self.get_role(x) for x in metadata_ref.get('roles', [])]
+
+ return [self.get_role(x) for x in
+ self._roles_from_role_dicts(metadata_ref.get('roles', []),
+ inherited_to_projects)]
def get_grant(self, role_id, user_id=None, group_id=None,
- domain_id=None, project_id=None):
+ domain_id=None, project_id=None,
+ inherited_to_projects=False):
self.get_role(role_id)
if user_id:
self.identity_api.get_user(user_id)
@@ -382,13 +401,17 @@ class Assignment(kvs.Base, assignment.Driver):
domain_id, group_id)
except exception.MetadataNotFound:
metadata_ref = {}
- role_ids = set(metadata_ref.get('roles', []))
+
+ role_ids = set(self._roles_from_role_dicts(
+ metadata_ref.get('roles', []), inherited_to_projects))
+
if role_id not in role_ids:
raise exception.RoleNotFound(role_id=role_id)
return self.get_role(role_id)
def delete_grant(self, role_id, user_id=None, group_id=None,
- domain_id=None, project_id=None):
+ domain_id=None, project_id=None,
+ inherited_to_projects=False):
self.get_role(role_id)
if user_id:
self.identity_api.get_user(user_id)
@@ -404,12 +427,13 @@ class Assignment(kvs.Base, assignment.Driver):
domain_id, group_id)
except exception.MetadataNotFound:
metadata_ref = {}
- roles = set(metadata_ref.get('roles', []))
+
try:
- roles.remove(role_id)
+ metadata_ref['roles'] = self._remove_role_from_role_dicts(
+ role_id, inherited_to_projects, metadata_ref.get('roles', []))
except KeyError:
raise exception.RoleNotFound(role_id=role_id)
- metadata_ref['roles'] = list(roles)
+
self._update_metadata(user_id, project_id, metadata_ref,
domain_id, group_id)
diff --git a/keystone/assignment/backends/ldap.py b/keystone/assignment/backends/ldap.py
index 09539c9f..b1b3f99f 100644
--- a/keystone/assignment/backends/ldap.py
+++ b/keystone/assignment/backends/ldap.py
@@ -72,7 +72,9 @@ class Assignment(assignment.Driver):
def get_project(self, tenant_id):
return self._set_default_domain(self.project.get(tenant_id))
- def list_projects(self):
+ def list_projects(self, domain_id=None):
+ # We don't support multiple domains within this driver, so ignore
+ # any domain passed.
return self._set_default_domain(self.project.get_all())
def get_project_by_name(self, tenant_name, domain_id):
@@ -117,7 +119,7 @@ class Assignment(assignment.Driver):
metadata_ref = _get_roles_for_just_user_and_project(user_id, tenant_id)
if not metadata_ref:
return {}
- return {'roles': metadata_ref}
+ return {'roles': [self._role_to_dict(r, False) for r in metadata_ref]}
def get_role(self, role_id):
return self.role.get(role_id)
diff --git a/keystone/assignment/backends/sql.py b/keystone/assignment/backends/sql.py
index 237330ce..5ec435ff 100644
--- a/keystone/assignment/backends/sql.py
+++ b/keystone/assignment/backends/sql.py
@@ -96,7 +96,8 @@ class Assignment(sql.Base, assignment.Driver):
raise exception.MetadataNotFound()
def create_grant(self, role_id, user_id=None, group_id=None,
- domain_id=None, project_id=None):
+ domain_id=None, project_id=None,
+ inherited_to_projects=False):
if user_id:
self.identity_api.get_user(user_id)
if group_id:
@@ -110,6 +111,10 @@ class Assignment(sql.Base, assignment.Driver):
if project_id:
self._get_project(session, project_id)
+ if project_id and inherited_to_projects:
+ msg = _('Inherited roles can only be assigned to domains')
+ raise exception.Conflict(type='role grant', details=msg)
+
try:
metadata_ref = self._get_metadata(user_id, project_id,
domain_id, group_id)
@@ -117,9 +122,10 @@ class Assignment(sql.Base, assignment.Driver):
except exception.MetadataNotFound:
metadata_ref = {}
is_new = True
- roles = set(metadata_ref.get('roles', []))
- roles.add(role_id)
- metadata_ref['roles'] = list(roles)
+
+ metadata_ref['roles'] = self._add_role_to_role_dicts(
+ role_id, inherited_to_projects, metadata_ref.get('roles', []))
+
if is_new:
self._create_metadata(user_id, project_id, metadata_ref,
domain_id, group_id)
@@ -128,7 +134,8 @@ class Assignment(sql.Base, assignment.Driver):
domain_id, group_id)
def list_grants(self, user_id=None, group_id=None,
- domain_id=None, project_id=None):
+ domain_id=None, project_id=None,
+ inherited_to_projects=False):
if user_id:
self.identity_api.get_user(user_id)
if group_id:
@@ -144,10 +151,14 @@ class Assignment(sql.Base, assignment.Driver):
domain_id, group_id)
except exception.MetadataNotFound:
metadata_ref = {}
- return [self.get_role(x) for x in metadata_ref.get('roles', [])]
+
+ return [self.get_role(x) for x in
+ self._roles_from_role_dicts(metadata_ref.get('roles', []),
+ inherited_to_projects)]
def get_grant(self, role_id, user_id=None, group_id=None,
- domain_id=None, project_id=None):
+ domain_id=None, project_id=None,
+ inherited_to_projects=False):
if user_id:
self.identity_api.get_user(user_id)
if group_id:
@@ -166,13 +177,15 @@ class Assignment(sql.Base, assignment.Driver):
domain_id, group_id)
except exception.MetadataNotFound:
metadata_ref = {}
- role_ids = set(metadata_ref.get('roles', []))
+ role_ids = set(self._roles_from_role_dicts(
+ metadata_ref.get('roles', []), inherited_to_projects))
if role_id not in role_ids:
raise exception.RoleNotFound(role_id=role_id)
return role_ref.to_dict()
def delete_grant(self, role_id, user_id=None, group_id=None,
- domain_id=None, project_id=None):
+ domain_id=None, project_id=None,
+ inherited_to_projects=False):
if user_id:
self.identity_api.get_user(user_id)
if group_id:
@@ -193,25 +206,43 @@ class Assignment(sql.Base, assignment.Driver):
except exception.MetadataNotFound:
metadata_ref = {}
is_new = True
- roles = set(metadata_ref.get('roles', []))
+
try:
- roles.remove(role_id)
+ metadata_ref['roles'] = self._remove_role_from_role_dicts(
+ role_id, inherited_to_projects, metadata_ref.get('roles', []))
except KeyError:
raise exception.RoleNotFound(role_id=role_id)
- metadata_ref['roles'] = list(roles)
+
if is_new:
+ # TODO(henry-nash) It seems odd that you would create a new
+ # entry in response to trying to delete a role that was not
+ # assigned. Although benign, this should probably be removed.
self._create_metadata(user_id, project_id, metadata_ref,
domain_id, group_id)
else:
self._update_metadata(user_id, project_id, metadata_ref,
domain_id, group_id)
- def list_projects(self):
+ def list_projects(self, domain_id=None):
session = self.get_session()
- tenant_refs = session.query(Project).all()
- return [tenant_ref.to_dict() for tenant_ref in tenant_refs]
+ if domain_id:
+ self._get_domain(session, domain_id)
+
+ query = session.query(Project)
+ if domain_id:
+ query = query.filter_by(domain_id=domain_id)
+ project_refs = query.all()
+ return [project_ref.to_dict() for project_ref in project_refs]
def get_projects_for_user(self, user_id):
+
+ # FIXME(henry-nash) The following should take into account
+ # both group and inherited roles. In fact, I don't see why this
+ # call can't be handled at the controller level like we do
+ # with 'get_roles_for_user_and_project()'. Further, this
+ # call seems essentially the same as 'list_user_projects()'
+ # later in this driver. Both should be removed.
+
self.identity_api.get_user(user_id)
session = self.get_session()
query = session.query(UserProjectGrant)
@@ -230,13 +261,16 @@ class Assignment(sql.Base, assignment.Driver):
except exception.MetadataNotFound:
metadata_ref = {}
is_new = True
- roles = set(metadata_ref.get('roles', []))
- if role_id in roles:
+
+ try:
+ metadata_ref['roles'] = self._add_role_to_role_dicts(
+ role_id, False, metadata_ref.get('roles', []),
+ allow_existing=False)
+ except KeyError:
msg = ('User %s already has role %s in tenant %s'
% (user_id, role_id, tenant_id))
raise exception.Conflict(type='role grant', details=msg)
- roles.add(role_id)
- metadata_ref['roles'] = list(roles)
+
if is_new:
self._create_metadata(user_id, tenant_id, metadata_ref)
else:
@@ -245,14 +279,15 @@ class Assignment(sql.Base, assignment.Driver):
def remove_role_from_user_and_project(self, user_id, tenant_id, role_id):
try:
metadata_ref = self._get_metadata(user_id, tenant_id)
- roles = set(metadata_ref.get('roles', []))
- if role_id not in roles:
+ try:
+ metadata_ref['roles'] = self._remove_role_from_role_dicts(
+ role_id, False, metadata_ref.get('roles', []))
+ except KeyError:
raise exception.RoleNotFound(message=_(
'Cannot remove role that has not been granted, %s') %
role_id)
- roles.remove(role_id)
- metadata_ref['roles'] = list(roles)
- if len(roles):
+
+ if len(metadata_ref['roles']):
self._update_metadata(user_id, tenant_id, metadata_ref)
else:
session = self.get_session()
@@ -277,28 +312,44 @@ class Assignment(sql.Base, assignment.Driver):
assignment_list = []
refs = session.query(UserDomainGrant).all()
for x in refs:
- for r in x.data.get('roles', []):
- assignment_list.append({'user_id': x.user_id,
- 'domain_id': x.domain_id,
- 'role_id': r})
+ for r in self._roles_from_role_dicts(
+ x.data.get('roles', {}), False):
+ assignment_list.append({'user_id': x.user_id,
+ 'domain_id': x.domain_id,
+ 'role_id': r})
+ for r in self._roles_from_role_dicts(
+ x.data.get('roles', {}), True):
+ assignment_list.append({'user_id': x.user_id,
+ 'domain_id': x.domain_id,
+ 'role_id': r,
+ 'inherited_to_projects': True})
refs = session.query(UserProjectGrant).all()
for x in refs:
- for r in x.data.get('roles', []):
- assignment_list.append({'user_id': x.user_id,
- 'project_id': x.project_id,
- 'role_id': r})
+ for r in self._roles_from_role_dicts(
+ x.data.get('roles', {}), False):
+ assignment_list.append({'user_id': x.user_id,
+ 'project_id': x.project_id,
+ 'role_id': r})
refs = session.query(GroupDomainGrant).all()
for x in refs:
- for r in x.data.get('roles', []):
- assignment_list.append({'group_id': x.group_id,
- 'domain_id': x.domain_id,
- 'role_id': r})
+ for r in self._roles_from_role_dicts(
+ x.data.get('roles', {}), False):
+ assignment_list.append({'group_id': x.group_id,
+ 'domain_id': x.domain_id,
+ 'role_id': r})
+ for r in self._roles_from_role_dicts(
+ x.data.get('roles', {}), True):
+ assignment_list.append({'group_id': x.group_id,
+ 'domain_id': x.domain_id,
+ 'role_id': r,
+ 'inherited_to_projects': True})
refs = session.query(GroupProjectGrant).all()
for x in refs:
- for r in x.data.get('roles', []):
- assignment_list.append({'group_id': x.group_id,
- 'project_id': x.project_id,
- 'role_id': r})
+ for r in self._roles_from_role_dicts(
+ x.data.get('roles', {}), False):
+ assignment_list.append({'group_id': x.group_id,
+ 'project_id': x.project_id,
+ 'role_id': r})
return assignment_list
# CRUD
@@ -473,6 +524,14 @@ class Assignment(sql.Base, assignment.Driver):
session.flush()
def list_user_projects(self, user_id):
+
+ # FIXME(henry-nash) The following should take into account
+ # both group and inherited roles. In fact, I don't see why this
+ # call can't be handled at the controller level like we do
+ # with 'get_roles_for_user_and_project()'. Further, this
+ # call seems essentially the same as 'get_projects_for_user()'
+ # earlier in this driver. Both should be removed.
+
session = self.get_session()
user = self.identity_api.get_user(user_id)
metadata_refs = session\
@@ -627,6 +686,29 @@ class Role(sql.ModelBase, sql.DictBase):
class BaseGrant(sql.DictBase):
+ """Base Grant class.
+
+ There are four grant tables in the current implementation, one for
+ each type of grant:
+
+ - User for Project
+ - User for Domain
+ - Group for Project
+ - Group for Domain
+
+ Each is a table with the two attributes above as a combined primary key,
+ with the data field holding all roles for that combination. The data
+ field is a list of dicts. For regular role assignments each dict in
+ the list of of the form:
+
+ {'id': role_id}
+
+ If the OS-INHERIT extension is enabled and the role on a domain is an
+ inherited role, the dict will be of the form:
+
+ {'id': role_id, 'inherited_to': 'projects'}
+
+ """
def to_dict(self):
"""Override parent to_dict() method with a simpler implementation.
diff --git a/keystone/assignment/core.py b/keystone/assignment/core.py
index 531da02e..b71e2a18 100644
--- a/keystone/assignment/core.py
+++ b/keystone/assignment/core.py
@@ -59,33 +59,72 @@ class Manager(manager.Manager):
self.identity_api.assignment_api = self
def get_roles_for_user_and_project(self, user_id, tenant_id):
- def _get_group_project_roles(user_id, tenant_id):
+ """Get the roles associated with a user within given project.
+
+ This includes roles directly assigned to the user on the
+ project, as well as those by virtue of group membership. If
+ the OS-INHERIT extension is enabled, then this will also
+ include roles inherited from the domain.
+
+ :returns: a list of role ids.
+ :raises: keystone.exception.UserNotFound,
+ keystone.exception.ProjectNotFound
+
+ """
+ def _get_group_project_roles(user_id, project_ref):
role_list = []
group_refs = (self.identity_api.list_groups_for_user
(user_id=user_id))
for x in group_refs:
try:
- metadata_ref = self._get_metadata(group_id=x['id'],
- tenant_id=tenant_id)
- role_list += metadata_ref.get('roles', [])
+ metadata_ref = self._get_metadata(
+ group_id=x['id'], tenant_id=project_ref['id'])
+ role_list += self._roles_from_role_dicts(
+ metadata_ref.get('roles', {}), False)
except exception.MetadataNotFound:
# no group grant, skip
pass
+
+ if CONF.os_inherit.enabled:
+ # Now get any inherited group roles for the owning domain
+ try:
+ metadata_ref = self._get_metadata(
+ group_id=x['id'],
+ domain_id=project_ref['domain_id'])
+ role_list += self._roles_from_role_dicts(
+ metadata_ref.get('roles', {}), True)
+ except (exception.MetadataNotFound,
+ exception.NotImplemented):
+ pass
+
return role_list
- def _get_user_project_roles(user_id, tenant_id):
- metadata_ref = {}
+ def _get_user_project_roles(user_id, project_ref):
+ role_list = []
try:
metadata_ref = self._get_metadata(user_id=user_id,
- tenant_id=tenant_id)
+ tenant_id=project_ref['id'])
+ role_list = self._roles_from_role_dicts(
+ metadata_ref.get('roles', {}), False)
except exception.MetadataNotFound:
pass
- return metadata_ref.get('roles', [])
+
+ if CONF.os_inherit.enabled:
+ # Now get any inherited roles for the owning domain
+ try:
+ metadata_ref = self._get_metadata(
+ user_id=user_id, domain_id=project_ref['domain_id'])
+ role_list += self._roles_from_role_dicts(
+ metadata_ref.get('roles', {}), True)
+ except (exception.MetadataNotFound, exception.NotImplemented):
+ pass
+
+ return role_list
self.identity_api.get_user(user_id)
- self.get_project(tenant_id)
- user_role_list = _get_user_project_roles(user_id, tenant_id)
- group_role_list = _get_group_project_roles(user_id, tenant_id)
+ project_ref = self.get_project(tenant_id)
+ user_role_list = _get_user_project_roles(user_id, project_ref)
+ group_role_list = _get_group_project_roles(user_id, project_ref)
# Use set() to process the list to remove any duplicates
return list(set(user_role_list + group_role_list))
@@ -106,11 +145,12 @@ class Manager(manager.Manager):
try:
metadata_ref = self._get_metadata(group_id=x['id'],
domain_id=domain_id)
- role_list += metadata_ref.get('roles', [])
+ role_list += self._roles_from_role_dicts(
+ metadata_ref.get('roles', {}), False)
except (exception.MetadataNotFound, exception.NotImplemented):
# MetadataNotFound implies no group grant, so skip.
# Ignore NotImplemented since not all backends support
- # domains. pass
+ # domains.
pass
return role_list
@@ -124,7 +164,8 @@ class Manager(manager.Manager):
# Ignore NotImplemented since not all backends support
# domains
pass
- return metadata_ref.get('roles', [])
+ return self._roles_from_role_dicts(
+ metadata_ref.get('roles', {}), False)
self.identity_api.get_user(user_id)
self.get_domain(domain_id)
@@ -160,6 +201,40 @@ class Manager(manager.Manager):
class Driver(object):
+ def _role_to_dict(self, role_id, inherited):
+ role_dict = {'id': role_id}
+ if inherited:
+ role_dict['inherited_to'] = 'projects'
+ return role_dict
+
+ def _roles_from_role_dicts(self, dict_list, inherited):
+ role_list = []
+ for d in dict_list:
+ if ((not d.get('inherited_to') and not inherited) or
+ (d.get('inherited_to') == 'projects' and inherited)):
+ role_list.append(d['id'])
+ return role_list
+
+ def _add_role_to_role_dicts(self, role_id, inherited, dict_list,
+ allow_existing=True):
+ # There is a difference in error semantics when trying to
+ # assign a role that already exists between the coded v2 and v3
+ # API calls. v2 will error if the assignment already exists,
+ # while v3 is silent. Setting the 'allow_existing' parameter
+ # appropriately lets this call be used for both.
+ role_set = set([frozenset(r.items()) for r in dict_list])
+ key = frozenset(self._role_to_dict(role_id, inherited).items())
+ if not allow_existing and key in role_set:
+ raise KeyError
+ role_set.add(key)
+ return [dict(r) for r in role_set]
+
+ def _remove_role_from_role_dicts(self, role_id, inherited, dict_list):
+ role_set = set([frozenset(r.items()) for r in dict_list])
+ role_set.remove(frozenset(self._role_to_dict(role_id,
+ inherited).items()))
+ return [dict(r) for r in role_set]
+
def get_project_by_name(self, tenant_name, domain_id):
"""Get a tenant by name.
@@ -209,9 +284,14 @@ class Driver(object):
# assignment/grant crud
def create_grant(self, role_id, user_id=None, group_id=None,
- domain_id=None, project_id=None):
+ domain_id=None, project_id=None,
+ inherited_to_projects=False):
"""Creates a new assignment/grant.
+ If the assignment is to a domain, then optionally it may be
+ specified as inherited to owned projects (this requires
+ the OS-INHERIT extension to be enabled).
+
:raises: keystone.exception.UserNotFound,
keystone.exception.GroupNotFound,
keystone.exception.ProjectNotFound,
@@ -223,7 +303,8 @@ class Driver(object):
raise exception.NotImplemented()
def list_grants(self, user_id=None, group_id=None,
- domain_id=None, project_id=None):
+ domain_id=None, project_id=None,
+ inherited_to_projects=False):
"""Lists assignments/grants.
:raises: keystone.exception.UserNotFound,
@@ -237,7 +318,8 @@ class Driver(object):
raise exception.NotImplemented()
def get_grant(self, role_id, user_id=None, group_id=None,
- domain_id=None, project_id=None):
+ domain_id=None, project_id=None,
+ inherited_to_projects=False):
"""Lists assignments/grants.
:raises: keystone.exception.UserNotFound,
@@ -251,7 +333,8 @@ class Driver(object):
raise exception.NotImplemented()
def delete_grant(self, role_id, user_id=None, group_id=None,
- domain_id=None, project_id=None):
+ domain_id=None, project_id=None,
+ inherited_to_projects=False):
"""Lists assignments/grants.
:raises: keystone.exception.UserNotFound,
@@ -329,7 +412,7 @@ class Driver(object):
"""
raise exception.NotImplemented()
- def list_projects(self):
+ def list_projects(self, domain_id=None):
"""List all projects in the system.
:returns: a list of project_refs or an empty list.