From 07d600dcff3aa699a32c5f7b049e54016d53919a Mon Sep 17 00:00:00 2001 From: Jimmy McCrory Date: Tue, 10 May 2016 13:26:25 -0700 Subject: [PATCH] Support users without projects in keystone library Update the ensure_user, ensure_user_role, and ensure_group_role commands and dependent functions to allow creation of and role assignment to a user without specifying a project. This will allow use of the keystone library for creating users, such as the heat stack admin, within only a domain. Since a role can only get granted to either a project or domain at one time, only attempt to grant the role within the project if both are provided. Notifications of state changes for the ensure role commands have also been fixed. Partial-Bug: 1579612 Change-Id: I6a132e5407c9881a047037b85bd6e25b85c0d8a1 --- library/keystone | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/library/keystone b/library/keystone index e8428fa..55cee5c 100644 --- a/library/keystone +++ b/library/keystone @@ -368,14 +368,16 @@ COMMAND_MAP = { 'user_name', 'project_name', 'tenant_name', - 'role_name' + 'role_name', + 'domain_name' ] }, 'ensure_group_role': { 'variables': [ 'group_name', 'project_name', - 'role_name' + 'role_name', + 'domain_name' ] }, 'ensure_project': { @@ -732,7 +734,7 @@ class ManageKeystone(object): domain = self._get_domain_from_vars(variables_dict) project = self._get_project(name=project_name) - if project is None: + if project is None and project_name is not None: self.failure( error='project [ %s ] was not found.' % project_name, rc=2, @@ -819,7 +821,7 @@ class ManageKeystone(object): user = None project = self._get_project(name=project_name) - if project is None: + if project is None and project_name is not None: self.failure( error='project [ %s ] was not found.' % project_name, rc=2, @@ -867,10 +869,11 @@ class ManageKeystone(object): return self._facts(facts={'id': role.id}) - def _get_user_roles(self, name, user, project): + def _get_user_roles(self, name, user, project, domain): role_list = self.keystone.roles.list( user=user, - project=project + project=project, + domain=domain ) for entry in role_list: if entry.name == name: @@ -902,21 +905,25 @@ class ManageKeystone(object): variables_dict.pop('tenant_name')) role_name = variables_dict.pop('role_name') + if project_name is not None: + domain = None + user, project, role, group = self._get_role_data( user_name=user_name, project_name=project_name, role_name=role_name, group_name=None, domain=domain ) user_role = self._get_user_roles( - name=role_name, user=user, project=project + name=role_name, user=user, project=project, domain=domain ) if user_role is None: + self.state_change = True self.keystone.roles.grant( - user=user, role=role, project=project + user=user, role=role, project=project, domain=domain ) user_role = self._get_user_roles( - name=role_name, user=user, project=project + name=role_name, user=user, project=project, domain=domain ) return self._facts(facts={'id': user_role.id}) @@ -930,23 +937,28 @@ class ManageKeystone(object): project_name = variables_dict.pop('project_name') role_name = variables_dict.pop('role_name') + if project_name is not None: + domain = None + user, project, role, group = self._get_role_data( group_name=group_name, project_name=project_name, role_name=role_name, user_name=None, domain=domain ) group_role = self._get_group_roles( - name=role_name, group=group, project=project + name=role_name, group=group, project=project, domain=domain ) if group_role is None: + self.state_change = True self.keystone.roles.grant( - group=group, role=role, project=project + group=group, role=role, project=project, domain=domain ) group_role = self._get_group_roles( name=role_name, group=group, - project=project + project=project, + domain=domain ) return self._facts(facts={'id': group_role.id})