From c385180df2338a52e89b1dfdf4d59dd698eaba67 Mon Sep 17 00:00:00 2001 From: Dean Troyer <dtroyer@gmail.com> Date: Mon, 29 Jul 2013 11:29:16 -0500 Subject: [PATCH] Remove tenant round 2 - Identity API Rename everything in the Identity v2 code including the file and classes. * role, tenant, user Change-Id: I0b99c60a24f5875120136d2f216aa3b6bce1c641 --- .../identity/v2_0/{tenant.py => project.py} | 133 ++++++++++-------- openstackclient/identity/v2_0/role.py | 69 +++++---- openstackclient/identity/v2_0/user.py | 107 +++++++++++--- setup.cfg | 12 +- 4 files changed, 205 insertions(+), 116 deletions(-) rename openstackclient/identity/v2_0/{tenant.py => project.py} (59%) diff --git a/openstackclient/identity/v2_0/tenant.py b/openstackclient/identity/v2_0/project.py similarity index 59% rename from openstackclient/identity/v2_0/tenant.py rename to openstackclient/identity/v2_0/project.py index d535716cac..d2d74ed004 100644 --- a/openstackclient/identity/v2_0/tenant.py +++ b/openstackclient/identity/v2_0/project.py @@ -13,11 +13,10 @@ # under the License. # -"""Tenant action implementations""" +"""Identity v2 Project action implementations""" import logging import six -import sys from cliff import command from cliff import lister @@ -26,82 +25,90 @@ from cliff import show from openstackclient.common import utils -class CreateTenant(show.ShowOne): - """Create tenant command""" +class CreateProject(show.ShowOne): + """Create new project""" - log = logging.getLogger(__name__ + '.CreateTenant') + log = logging.getLogger(__name__ + '.CreateProject') def get_parser(self, prog_name): - parser = super(CreateTenant, self).get_parser(prog_name) + parser = super(CreateProject, self).get_parser(prog_name) parser.add_argument( - 'tenant_name', - metavar='<tenant-name>', - help='New tenant name') + 'project_name', + metavar='<project-name>', + help='New project name', + ) parser.add_argument( '--description', - metavar='<tenant-description>', - help='New tenant description') + metavar='<project-description>', + help='New project description', + ) enable_group = parser.add_mutually_exclusive_group() enable_group.add_argument( '--enable', dest='enabled', action='store_true', default=True, - help='Enable tenant') + help='Enable project', + ) enable_group.add_argument( '--disable', dest='enabled', action='store_false', - help='Disable tenant') + help='Disable project', + ) return parser def take_action(self, parsed_args): self.log.debug('take_action(%s)' % parsed_args) identity_client = self.app.client_manager.identity - tenant = identity_client.tenants.create( - parsed_args.tenant_name, + project = identity_client.tenants.create( + parsed_args.project_name, description=parsed_args.description, enabled=parsed_args.enabled) info = {} - info.update(tenant._info) + info.update(project._info) return zip(*sorted(six.iteritems(info))) -class DeleteTenant(command.Command): - """Delete tenant command""" +class DeleteProject(command.Command): + """Delete project""" - log = logging.getLogger(__name__ + '.DeleteTenant') + log = logging.getLogger(__name__ + '.DeleteProject') def get_parser(self, prog_name): - parser = super(DeleteTenant, self).get_parser(prog_name) + parser = super(DeleteProject, self).get_parser(prog_name) parser.add_argument( - 'tenant', - metavar='<tenant>', - help='Name or ID of tenant to delete') + 'project', + metavar='<project>', + help='Project to delete (name or ID)', + ) return parser def take_action(self, parsed_args): self.log.debug('take_action(%s)' % parsed_args) identity_client = self.app.client_manager.identity - tenant = utils.find_resource(identity_client.tenants, - parsed_args.tenant) - identity_client.tenants.delete(tenant.id) + project = utils.find_resource( + identity_client.tenants, + parsed_args.project, + ) + identity_client.tenants.delete(project.id) return -class ListTenant(lister.Lister): - """List tenant command""" +class ListProject(lister.Lister): + """List projects""" - log = logging.getLogger(__name__ + '.ListTenant') + log = logging.getLogger(__name__ + '.ListProject') def get_parser(self, prog_name): - parser = super(ListTenant, self).get_parser(prog_name) + parser = super(ListProject, self).get_parser(prog_name) parser.add_argument( '--long', action='store_true', default=False, - help='Additional fields are listed in output') + help='List additional fields in output', + ) return parser def take_action(self, parsed_args): @@ -118,44 +125,51 @@ class ListTenant(lister.Lister): ) for s in data)) -class SetTenant(command.Command): - """Set tenant command""" +class SetProject(command.Command): + """Set project properties""" - log = logging.getLogger(__name__ + '.SetTenant') + log = logging.getLogger(__name__ + '.SetProject') def get_parser(self, prog_name): - parser = super(SetTenant, self).get_parser(prog_name) + parser = super(SetProject, self).get_parser(prog_name) parser.add_argument( - 'tenant', - metavar='<tenant>', - help='Name or ID of tenant to change') + 'project', + metavar='<project>', + help='Project to change (name or ID)', + ) parser.add_argument( '--name', - metavar='<new-tenant-name>', - help='New tenant name') + metavar='<new-project-name>', + help='New project name', + ) parser.add_argument( '--description', - metavar='<tenant-description>', - help='New tenant description') + metavar='<project-description>', + help='New project description', + ) enable_group = parser.add_mutually_exclusive_group() enable_group.add_argument( '--enable', dest='enabled', action='store_true', default=True, - help='Enable tenant (default)') + help='Enable project (default)', + ) enable_group.add_argument( '--disable', dest='enabled', action='store_false', - help='Disable tenant') + help='Disable project', + ) return parser def take_action(self, parsed_args): self.log.debug('take_action(%s)' % parsed_args) identity_client = self.app.client_manager.identity - tenant = utils.find_resource(identity_client.tenants, - parsed_args.tenant) + project = utils.find_resource( + identity_client.tenants, + parsed_args.project, + ) kwargs = {} if parsed_args.name: kwargs['name'] = parsed_args.name @@ -164,32 +178,31 @@ class SetTenant(command.Command): if 'enabled' in parsed_args: kwargs['enabled'] = parsed_args.enabled - if kwargs == {}: - sys.stdout.write("Tenant not updated, no arguments present") - return 0 - tenant.update(**kwargs) + project.update(**kwargs) return -class ShowTenant(show.ShowOne): - """Show tenant command""" +class ShowProject(show.ShowOne): + """Show project details""" - log = logging.getLogger(__name__ + '.ShowTenant') + log = logging.getLogger(__name__ + '.ShowProject') def get_parser(self, prog_name): - parser = super(ShowTenant, self).get_parser(prog_name) + parser = super(ShowProject, self).get_parser(prog_name) parser.add_argument( - 'tenant', - metavar='<tenant>', - help='Name or ID of tenant to display') + 'project', + metavar='<project>', + help='Project to display (name or ID)') return parser def take_action(self, parsed_args): self.log.debug('take_action(%s)' % parsed_args) identity_client = self.app.client_manager.identity - tenant = utils.find_resource(identity_client.tenants, - parsed_args.tenant) + project = utils.find_resource( + identity_client.tenants, + parsed_args.project, + ) info = {} - info.update(tenant._info) + info.update(project._info) return zip(*sorted(six.iteritems(info))) diff --git a/openstackclient/identity/v2_0/role.py b/openstackclient/identity/v2_0/role.py index 61a83af575..580525367c 100644 --- a/openstackclient/identity/v2_0/role.py +++ b/openstackclient/identity/v2_0/role.py @@ -13,7 +13,7 @@ # under the License. # -"""Role action implementations""" +"""Identity v2 Role action implementations""" import logging import six @@ -26,7 +26,7 @@ from openstackclient.common import utils class AddRole(show.ShowOne): - """Add role to tenant:user""" + """Add role to project:user""" log = logging.getLogger(__name__ + '.AddRole') @@ -37,10 +37,11 @@ class AddRole(show.ShowOne): metavar='<role>', help='Role name or ID to add to user') parser.add_argument( - '--tenant', - metavar='<tenant>', + '--project', + metavar='<project>', required=True, - help='Name or ID of tenant to include') + help='Include project (name or ID)', + ) parser.add_argument( '--user', metavar='<user>', @@ -52,13 +53,15 @@ class AddRole(show.ShowOne): self.log.debug('take_action(%s)' % parsed_args) identity_client = self.app.client_manager.identity role = utils.find_resource(identity_client.roles, parsed_args.role) - tenant = utils.find_resource(identity_client.tenants, - parsed_args.tenant) + project = utils.find_resource( + identity_client.tenants, + parsed_args.project, + ) user = utils.find_resource(identity_client.users, parsed_args.user) role = identity_client.roles.add_user_role( user, role, - tenant) + project) info = {} info.update(role._info) @@ -138,34 +141,43 @@ class ListUserRole(lister.Lister): nargs='?', help='Name or ID of user to include') parser.add_argument( - '--tenant', - metavar='<tenant>', - help='Name or ID of tenant to include') + '--project', + metavar='<project>', + help='Include project (name or ID)', + ) return parser def take_action(self, parsed_args): self.log.debug('take_action(%s)' % parsed_args) - columns = ('ID', 'Name', 'Tenant ID', 'User ID') identity_client = self.app.client_manager.identity # user-only roles are not supported in KSL so we are - # required to have a user and tenant; default to the + # required to have a user and project; default to the # values used for authentication if not specified - if not parsed_args.tenant: - parsed_args.tenant = identity_client.auth_tenant_id + if not parsed_args.project: + parsed_args.project = identity_client.auth_tenant_id if not parsed_args.user: parsed_args.user = identity_client.auth_user_id - tenant = utils.find_resource(identity_client.tenants, - parsed_args.tenant) + project = utils.find_resource( + identity_client.tenants, + parsed_args.project, + ) user = utils.find_resource(identity_client.users, parsed_args.user) - data = identity_client.roles.roles_for_user(user.id, tenant.id) + data = identity_client.roles.roles_for_user(user.id, project.id) + + columns = ( + 'ID', + 'Name', + 'Project', + 'User', + ) # Add the names to the output even though they will be constant for role in data: - role.user_id = user.name - role.tenant_id = tenant.name + role.user = user.name + role.project = project.name return (columns, (utils.get_item_properties( @@ -175,7 +187,7 @@ class ListUserRole(lister.Lister): class RemoveRole(command.Command): - """Remove role from tenant:user""" + """Remove role from project:user""" log = logging.getLogger(__name__ + '.RemoveRole') @@ -186,10 +198,11 @@ class RemoveRole(command.Command): metavar='<role>', help='Role name or ID to remove from user') parser.add_argument( - '--tenant', - metavar='<tenant>', + '--project', + metavar='<project>', required=True, - help='Name or ID of tenant') + help='Project to include (name or ID)', + ) parser.add_argument( '--user', metavar='<user>', @@ -201,13 +214,15 @@ class RemoveRole(command.Command): self.log.debug('take_action(%s)' % parsed_args) identity_client = self.app.client_manager.identity role = utils.find_resource(identity_client.roles, parsed_args.role) - tenant = utils.find_resource(identity_client.tenants, - parsed_args.tenant) + project = utils.find_resource( + identity_client.tenants, + parsed_args.project, + ) user = utils.find_resource(identity_client.users, parsed_args.user) identity_client.roles.remove_user_role( user.id, role.id, - tenant.id) + project.id) class ShowRole(show.ShowOne): diff --git a/openstackclient/identity/v2_0/user.py b/openstackclient/identity/v2_0/user.py index 8c8e2622db..78f2164637 100644 --- a/openstackclient/identity/v2_0/user.py +++ b/openstackclient/identity/v2_0/user.py @@ -46,9 +46,10 @@ class CreateUser(show.ShowOne): metavar='<user-email>', help='New user email address') parser.add_argument( - '--tenant', - metavar='<tenant>', - help='New default tenant name or ID') + '--project', + metavar='<project>', + help='Set default project (name or ID)', + ) enable_group = parser.add_mutually_exclusive_group() enable_group.add_argument( '--enable', @@ -66,17 +67,23 @@ class CreateUser(show.ShowOne): def take_action(self, parsed_args): self.log.debug('take_action(%s)' % parsed_args) identity_client = self.app.client_manager.identity - if parsed_args.tenant: - tenant_id = utils.find_resource(identity_client.tenants, - parsed_args.tenant).id + if parsed_args.project: + project_id = utils.find_resource( + identity_client.tenants, + parsed_args.project, + ).id else: - tenant_id = None + project_id = None user = identity_client.users.create( parsed_args.name, parsed_args.password, parsed_args.email, - tenant_id=tenant_id, - enabled=parsed_args.enabled) + tenant_id=project_id, + enabled=parsed_args.enabled, + ) + user._info.update( + {'project_id': user._info.pop('tenantId')} + ) info = {} info.update(user._info) @@ -112,9 +119,10 @@ class ListUser(lister.Lister): def get_parser(self, prog_name): parser = super(ListUser, self).get_parser(prog_name) parser.add_argument( - '--tenant', - metavar='<tenant>', - help='Name or ID of tenant to filter users') + '--project', + metavar='<project>', + help='Filter users by project (name or ID)', + ) parser.add_argument( '--long', action='store_true', @@ -124,15 +132,57 @@ class ListUser(lister.Lister): def take_action(self, parsed_args): self.log.debug('take_action(%s)' % parsed_args) + + def _format_project(project): + if not project: + return "" + if project in project_cache.keys(): + return project_cache[project].name + else: + return project + if parsed_args.long: - columns = ('ID', 'Name', 'Tenant Id', 'Email', 'Enabled') + columns = ( + 'ID', + 'Name', + 'tenantId', + 'Email', + 'Enabled', + ) + column_headers = ( + 'ID', + 'Name', + 'Project', + 'Email', + 'Enabled', + ) + # Cache the project list + project_cache = {} + try: + for p in self.app.client_manager.identity.tenants.list(): + project_cache[p.id] = p + except Exception: + # Just forget it if there's any trouble + pass else: - columns = ('ID', 'Name') + columns = column_headers = ('ID', 'Name') data = self.app.client_manager.identity.users.list() - return (columns, + + if parsed_args.long: + # FIXME(dtroyer): Sometimes user objects have 'tenant_id' instead + # of 'tenantId'. Why? Dunno yet, but until that + # is fixed we need to handle it; auth_token.py + # only looks for 'tenantId'. + for d in data: + if 'tenant_id' in d._info: + d._info['tenantId'] = d._info.pop('tenant_id') + d._add_details(d._info) + + return (column_headers, (utils.get_item_properties( s, columns, - formatters={}, + mixed_case_fields=('tenantId',), + formatters={'tenantId': _format_project}, ) for s in data)) @@ -160,9 +210,10 @@ class SetUser(command.Command): metavar='<user-email>', help='New user email address') parser.add_argument( - '--tenant', - metavar='<tenant>', - help='New default tenant name or ID') + '--project', + metavar='<project>', + help='New default project (name or ID)', + ) enable_group = parser.add_mutually_exclusive_group() enable_group.add_argument( '--enable', @@ -186,10 +237,12 @@ class SetUser(command.Command): kwargs['name'] = parsed_args.name if parsed_args.email: kwargs['email'] = parsed_args.email - if parsed_args.tenant: - tenant_id = utils.find_resource(identity_client.tenants, - parsed_args.tenant).id - kwargs['tenantId'] = tenant_id + if parsed_args.project: + project = utils.find_resource( + identity_client.tenants, + parsed_args.project, + ) + kwargs['tenantId'] = project.id if 'enabled' in parsed_args: kwargs['enabled'] = parsed_args.enabled @@ -217,6 +270,14 @@ class ShowUser(show.ShowOne): self.log.debug('take_action(%s)' % parsed_args) identity_client = self.app.client_manager.identity user = utils.find_resource(identity_client.users, parsed_args.user) + if 'tenantId' in user._info: + user._info.update( + {'project_id': user._info.pop('tenantId')} + ) + if 'tenant_id' in user._info: + user._info.update( + {'project_id': user._info.pop('tenant_id')} + ) info = {} info.update(user._info) diff --git a/setup.cfg b/setup.cfg index f1f5cf82f2..34da1631b2 100644 --- a/setup.cfg +++ b/setup.cfg @@ -47,6 +47,12 @@ openstack.identity.v2_0 = endpoint_list = openstackclient.identity.v2_0.endpoint:ListEndpoint endpoint_show = openstackclient.identity.v2_0.endpoint:ShowEndpoint + project_create = openstackclient.identity.v2_0.project:CreateProject + project_delete = openstackclient.identity.v2_0.project:DeleteProject + project_list = openstackclient.identity.v2_0.project:ListProject + project_set = openstackclient.identity.v2_0.project:SetProject + project_show = openstackclient.identity.v2_0.project:ShowProject + role_add = openstackclient.identity.v2_0.role:AddRole role_create = openstackclient.identity.v2_0.role:CreateRole role_delete = openstackclient.identity.v2_0.role:DeleteRole @@ -59,12 +65,6 @@ openstack.identity.v2_0 = service_list =openstackclient.identity.v2_0.service:ListService service_show =openstackclient.identity.v2_0.service:ShowService - tenant_create = openstackclient.identity.v2_0.tenant:CreateTenant - tenant_delete = openstackclient.identity.v2_0.tenant:DeleteTenant - tenant_list = openstackclient.identity.v2_0.tenant:ListTenant - tenant_set = openstackclient.identity.v2_0.tenant:SetTenant - tenant_show = openstackclient.identity.v2_0.tenant:ShowTenant - user_role_list = openstackclient.identity.v2_0.role:ListUserRole user_create = openstackclient.identity.v2_0.user:CreateUser