From c385180df2338a52e89b1dfdf4d59dd698eaba67 Mon Sep 17 00:00:00 2001 From: Dean Troyer Date: Mon, 29 Jul 2013 11:29:16 -0500 Subject: Remove tenant round 2 - Identity API Rename everything in the Identity v2 code including the file and classes. * role, tenant, user Change-Id: I0b99c60a24f5875120136d2f216aa3b6bce1c641 --- openstackclient/identity/v2_0/project.py | 208 +++++++++++++++++++++++++++++++ openstackclient/identity/v2_0/role.py | 69 ++++++---- openstackclient/identity/v2_0/tenant.py | 195 ----------------------------- openstackclient/identity/v2_0/user.py | 107 ++++++++++++---- setup.cfg | 12 +- 5 files changed, 340 insertions(+), 251 deletions(-) create mode 100644 openstackclient/identity/v2_0/project.py delete mode 100644 openstackclient/identity/v2_0/tenant.py diff --git a/openstackclient/identity/v2_0/project.py b/openstackclient/identity/v2_0/project.py new file mode 100644 index 00000000..d2d74ed0 --- /dev/null +++ b/openstackclient/identity/v2_0/project.py @@ -0,0 +1,208 @@ +# Copyright 2012-2013 OpenStack Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +"""Identity v2 Project action implementations""" + +import logging +import six + +from cliff import command +from cliff import lister +from cliff import show + +from openstackclient.common import utils + + +class CreateProject(show.ShowOne): + """Create new project""" + + log = logging.getLogger(__name__ + '.CreateProject') + + def get_parser(self, prog_name): + parser = super(CreateProject, self).get_parser(prog_name) + parser.add_argument( + 'project_name', + metavar='', + help='New project name', + ) + parser.add_argument( + '--description', + metavar='', + 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 project', + ) + enable_group.add_argument( + '--disable', + dest='enabled', + action='store_false', + 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 + project = identity_client.tenants.create( + parsed_args.project_name, + description=parsed_args.description, + enabled=parsed_args.enabled) + + info = {} + info.update(project._info) + return zip(*sorted(six.iteritems(info))) + + +class DeleteProject(command.Command): + """Delete project""" + + log = logging.getLogger(__name__ + '.DeleteProject') + + def get_parser(self, prog_name): + parser = super(DeleteProject, self).get_parser(prog_name) + parser.add_argument( + 'project', + metavar='', + 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 + project = utils.find_resource( + identity_client.tenants, + parsed_args.project, + ) + identity_client.tenants.delete(project.id) + return + + +class ListProject(lister.Lister): + """List projects""" + + log = logging.getLogger(__name__ + '.ListProject') + + def get_parser(self, prog_name): + parser = super(ListProject, self).get_parser(prog_name) + parser.add_argument( + '--long', + action='store_true', + default=False, + help='List additional fields in output', + ) + return parser + + def take_action(self, parsed_args): + self.log.debug('take_action(%s)' % parsed_args) + if parsed_args.long: + columns = ('ID', 'Name', 'Description', 'Enabled') + else: + columns = ('ID', 'Name') + data = self.app.client_manager.identity.tenants.list() + return (columns, + (utils.get_item_properties( + s, columns, + formatters={}, + ) for s in data)) + + +class SetProject(command.Command): + """Set project properties""" + + log = logging.getLogger(__name__ + '.SetProject') + + def get_parser(self, prog_name): + parser = super(SetProject, self).get_parser(prog_name) + parser.add_argument( + 'project', + metavar='', + help='Project to change (name or ID)', + ) + parser.add_argument( + '--name', + metavar='', + help='New project name', + ) + parser.add_argument( + '--description', + metavar='', + 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 project (default)', + ) + enable_group.add_argument( + '--disable', + dest='enabled', + action='store_false', + 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 + project = utils.find_resource( + identity_client.tenants, + parsed_args.project, + ) + kwargs = {} + if parsed_args.name: + kwargs['name'] = parsed_args.name + if parsed_args.description: + kwargs['description'] = parsed_args.description + if 'enabled' in parsed_args: + kwargs['enabled'] = parsed_args.enabled + + project.update(**kwargs) + return + + +class ShowProject(show.ShowOne): + """Show project details""" + + log = logging.getLogger(__name__ + '.ShowProject') + + def get_parser(self, prog_name): + parser = super(ShowProject, self).get_parser(prog_name) + parser.add_argument( + 'project', + metavar='', + 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 + project = utils.find_resource( + identity_client.tenants, + parsed_args.project, + ) + + 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 61a83af5..58052536 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='', help='Role name or ID to add to user') parser.add_argument( - '--tenant', - metavar='', + '--project', + metavar='', required=True, - help='Name or ID of tenant to include') + help='Include project (name or ID)', + ) parser.add_argument( '--user', metavar='', @@ -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='', - help='Name or ID of tenant to include') + '--project', + metavar='', + 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='', help='Role name or ID to remove from user') parser.add_argument( - '--tenant', - metavar='', + '--project', + metavar='', required=True, - help='Name or ID of tenant') + help='Project to include (name or ID)', + ) parser.add_argument( '--user', metavar='', @@ -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/tenant.py b/openstackclient/identity/v2_0/tenant.py deleted file mode 100644 index d535716c..00000000 --- a/openstackclient/identity/v2_0/tenant.py +++ /dev/null @@ -1,195 +0,0 @@ -# Copyright 2012-2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# - -"""Tenant action implementations""" - -import logging -import six -import sys - -from cliff import command -from cliff import lister -from cliff import show - -from openstackclient.common import utils - - -class CreateTenant(show.ShowOne): - """Create tenant command""" - - log = logging.getLogger(__name__ + '.CreateTenant') - - def get_parser(self, prog_name): - parser = super(CreateTenant, self).get_parser(prog_name) - parser.add_argument( - 'tenant_name', - metavar='', - help='New tenant name') - parser.add_argument( - '--description', - metavar='', - help='New tenant description') - enable_group = parser.add_mutually_exclusive_group() - enable_group.add_argument( - '--enable', - dest='enabled', - action='store_true', - default=True, - help='Enable tenant') - enable_group.add_argument( - '--disable', - dest='enabled', - action='store_false', - help='Disable tenant') - 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, - description=parsed_args.description, - enabled=parsed_args.enabled) - - info = {} - info.update(tenant._info) - return zip(*sorted(six.iteritems(info))) - - -class DeleteTenant(command.Command): - """Delete tenant command""" - - log = logging.getLogger(__name__ + '.DeleteTenant') - - def get_parser(self, prog_name): - parser = super(DeleteTenant, self).get_parser(prog_name) - parser.add_argument( - 'tenant', - metavar='', - help='Name or ID of tenant to delete') - 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) - return - - -class ListTenant(lister.Lister): - """List tenant command""" - - log = logging.getLogger(__name__ + '.ListTenant') - - def get_parser(self, prog_name): - parser = super(ListTenant, self).get_parser(prog_name) - parser.add_argument( - '--long', - action='store_true', - default=False, - help='Additional fields are listed in output') - return parser - - def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) - if parsed_args.long: - columns = ('ID', 'Name', 'Description', 'Enabled') - else: - columns = ('ID', 'Name') - data = self.app.client_manager.identity.tenants.list() - return (columns, - (utils.get_item_properties( - s, columns, - formatters={}, - ) for s in data)) - - -class SetTenant(command.Command): - """Set tenant command""" - - log = logging.getLogger(__name__ + '.SetTenant') - - def get_parser(self, prog_name): - parser = super(SetTenant, self).get_parser(prog_name) - parser.add_argument( - 'tenant', - metavar='', - help='Name or ID of tenant to change') - parser.add_argument( - '--name', - metavar='', - help='New tenant name') - parser.add_argument( - '--description', - metavar='', - help='New tenant description') - enable_group = parser.add_mutually_exclusive_group() - enable_group.add_argument( - '--enable', - dest='enabled', - action='store_true', - default=True, - help='Enable tenant (default)') - enable_group.add_argument( - '--disable', - dest='enabled', - action='store_false', - help='Disable tenant') - 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) - kwargs = {} - if parsed_args.name: - kwargs['name'] = parsed_args.name - if parsed_args.description: - kwargs['description'] = parsed_args.description - 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) - return - - -class ShowTenant(show.ShowOne): - """Show tenant command""" - - log = logging.getLogger(__name__ + '.ShowTenant') - - def get_parser(self, prog_name): - parser = super(ShowTenant, self).get_parser(prog_name) - parser.add_argument( - 'tenant', - metavar='', - help='Name or ID of tenant to display') - 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) - - info = {} - info.update(tenant._info) - return zip(*sorted(six.iteritems(info))) diff --git a/openstackclient/identity/v2_0/user.py b/openstackclient/identity/v2_0/user.py index 8c8e2622..78f21646 100644 --- a/openstackclient/identity/v2_0/user.py +++ b/openstackclient/identity/v2_0/user.py @@ -46,9 +46,10 @@ class CreateUser(show.ShowOne): metavar='', help='New user email address') parser.add_argument( - '--tenant', - metavar='', - help='New default tenant name or ID') + '--project', + metavar='', + 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='', - help='Name or ID of tenant to filter users') + '--project', + metavar='', + 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='', help='New user email address') parser.add_argument( - '--tenant', - metavar='', - help='New default tenant name or ID') + '--project', + metavar='', + 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 f1f5cf82..34da1631 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 -- cgit v1.2.1