diff --git a/openstackclient/identity/common.py b/openstackclient/identity/common.py index 253729bddf..a1b46cb49f 100644 --- a/openstackclient/identity/common.py +++ b/openstackclient/identity/common.py @@ -17,6 +17,9 @@ from keystoneclient import exceptions as identity_exc from keystoneclient.v3 import domains +from keystoneclient.v3 import groups +from keystoneclient.v3 import projects +from keystoneclient.v3 import users from openstackclient.common import exceptions from openstackclient.common import utils @@ -56,4 +59,58 @@ def find_domain(identity_client, name_or_id): return dom except identity_exc.Forbidden: pass - return domains.Domain(None, {'id': name_or_id}) + return domains.Domain(None, {'id': name_or_id, 'name': name_or_id}) + + +def find_group(identity_client, name_or_id): + """Find a group. + + If the user does not have permissions to to perform a list groups call, + e.g., if the user is a project admin, assume that the group given is the + id rather than the name. This method is used by the role add command to + allow a role to be assigned to a group by a project admin who does not + have permission to list groups. + """ + try: + group = utils.find_resource(identity_client.groups, name_or_id) + if group is not None: + return group + except identity_exc.Forbidden: + pass + return groups.Group(None, {'id': name_or_id, 'name': name_or_id}) + + +def find_project(identity_client, name_or_id): + """Find a project. + + If the user does not have permissions to to perform a list projects + call, e.g., if the user is a project admin, assume that the project + given is the id rather than the name. This method is used by the role + add command to allow a role to be assigned to a user by a project admin + who does not have permission to list projects. + """ + try: + project = utils.find_resource(identity_client.projects, name_or_id) + if project is not None: + return project + except identity_exc.Forbidden: + pass + return projects.Project(None, {'id': name_or_id, 'name': name_or_id}) + + +def find_user(identity_client, name_or_id): + """Find a user. + + If the user does not have permissions to to perform a list users call, + e.g., if the user is a project admin, assume that the user given is the + id rather than the name. This method is used by the role add command to + allow a role to be assigned to a user by a project admin who does not + have permission to list users. + """ + try: + user = utils.find_resource(identity_client.users, name_or_id) + if user is not None: + return user + except identity_exc.Forbidden: + pass + return users.User(None, {'id': name_or_id, 'name': name_or_id}) diff --git a/openstackclient/identity/v3/role.py b/openstackclient/identity/v3/role.py index 0376070907..3dd998ba77 100644 --- a/openstackclient/identity/v3/role.py +++ b/openstackclient/identity/v3/role.py @@ -26,6 +26,7 @@ from keystoneclient import exceptions as ksc_exc from openstackclient.common import utils from openstackclient.i18n import _ # noqa +from openstackclient.identity import common class AddRole(command.Command): @@ -78,12 +79,12 @@ class AddRole(command.Command): ) if parsed_args.user and parsed_args.domain: - user = utils.find_resource( - identity_client.users, + user = common.find_user( + identity_client, parsed_args.user, ) - domain = utils.find_resource( - identity_client.domains, + domain = common.find_domain( + identity_client, parsed_args.domain, ) identity_client.roles.grant( @@ -92,12 +93,12 @@ class AddRole(command.Command): domain=domain.id, ) elif parsed_args.user and parsed_args.project: - user = utils.find_resource( - identity_client.users, + user = common.find_user( + identity_client, parsed_args.user, ) - project = utils.find_resource( - identity_client.projects, + project = common.find_project( + identity_client, parsed_args.project, ) identity_client.roles.grant( @@ -106,12 +107,12 @@ class AddRole(command.Command): project=project.id, ) elif parsed_args.group and parsed_args.domain: - group = utils.find_resource( - identity_client.groups, + group = common.find_group( + identity_client, parsed_args.group, ) - domain = utils.find_resource( - identity_client.domains, + domain = common.find_domain( + identity_client, parsed_args.domain, ) identity_client.roles.grant( @@ -120,12 +121,12 @@ class AddRole(command.Command): domain=domain.id, ) elif parsed_args.group and parsed_args.project: - group = utils.find_resource( - identity_client.groups, + group = common.find_group( + identity_client, parsed_args.group, ) - project = utils.find_resource( - identity_client.projects, + project = common.find_project( + identity_client, parsed_args.project, ) identity_client.roles.grant( @@ -240,24 +241,24 @@ class ListRole(lister.Lister): identity_client = self.app.client_manager.identity if parsed_args.user: - user = utils.find_resource( - identity_client.users, + user = common.find_user( + identity_client, parsed_args.user, ) elif parsed_args.group: - group = utils.find_resource( - identity_client.groups, + group = common.find_group( + identity_client, parsed_args.group, ) if parsed_args.domain: - domain = utils.find_resource( - identity_client.domains, + domain = common.find_domain( + identity_client, parsed_args.domain, ) elif parsed_args.project: - project = utils.find_resource( - identity_client.projects, + project = common.find_project( + identity_client, parsed_args.project, ) @@ -370,12 +371,12 @@ class RemoveRole(command.Command): ) if parsed_args.user and parsed_args.domain: - user = utils.find_resource( - identity_client.users, + user = common.find_user( + identity_client, parsed_args.user, ) - domain = utils.find_resource( - identity_client.domains, + domain = common.find_domain( + identity_client, parsed_args.domain, ) identity_client.roles.revoke( @@ -384,12 +385,12 @@ class RemoveRole(command.Command): domain=domain.id, ) elif parsed_args.user and parsed_args.project: - user = utils.find_resource( - identity_client.users, + user = common.find_user( + identity_client, parsed_args.user, ) - project = utils.find_resource( - identity_client.projects, + project = common.find_project( + identity_client, parsed_args.project, ) identity_client.roles.revoke( @@ -398,12 +399,12 @@ class RemoveRole(command.Command): project=project.id, ) elif parsed_args.group and parsed_args.domain: - group = utils.find_resource( - identity_client.groups, + group = common.find_group( + identity_client, parsed_args.group, ) - domain = utils.find_resource( - identity_client.domains, + domain = common.find_domain( + identity_client, parsed_args.domain, ) identity_client.roles.revoke( @@ -412,12 +413,12 @@ class RemoveRole(command.Command): domain=domain.id, ) elif parsed_args.group and parsed_args.project: - group = utils.find_resource( - identity_client.groups, + group = common.find_group( + identity_client, parsed_args.group, ) - project = utils.find_resource( - identity_client.projects, + project = common.find_project( + identity_client, parsed_args.project, ) identity_client.roles.revoke( diff --git a/openstackclient/identity/v3/role_assignment.py b/openstackclient/identity/v3/role_assignment.py index f053b608c5..24e3a7f709 100644 --- a/openstackclient/identity/v3/role_assignment.py +++ b/openstackclient/identity/v3/role_assignment.py @@ -18,6 +18,7 @@ import logging from cliff import lister from openstackclient.common import utils +from openstackclient.identity import common class ListRoleAssignment(lister.Lister): @@ -80,29 +81,29 @@ class ListRoleAssignment(lister.Lister): user = None if parsed_args.user: - user = utils.find_resource( - identity_client.users, + user = common.find_user( + identity_client, parsed_args.user, ) domain = None if parsed_args.domain: - domain = utils.find_resource( - identity_client.domains, + domain = common.find_domain( + identity_client, parsed_args.domain, ) project = None if parsed_args.project: - project = utils.find_resource( - identity_client.projects, + project = common.find_project( + identity_client, parsed_args.project, ) group = None if parsed_args.group: - group = utils.find_resource( - identity_client.groups, + group = common.find_group( + identity_client, parsed_args.group, )