From 5378322906a636bc2b9685e7403950549ef213f5 Mon Sep 17 00:00:00 2001 From: Dean Troyer <dtroyer@gmail.com> Date: Thu, 10 May 2012 16:25:31 -0500 Subject: [PATCH] Add tenant CRUD commands * add {create|delete|set} tenant commands * move get_XXXX_properties() to common.utils.get_item_properties() add mixed_case_fields as an optional arg Change-Id: I7b3bd9cefb08e39730886b31213cbe422b5a8453 --- openstackclient/common/utils.py | 24 ++++ openstackclient/compute/v2/server.py | 26 +--- openstackclient/identity/v2_0/service.py | 73 ++++------ openstackclient/identity/v2_0/tenant.py | 168 ++++++++++++++++++----- setup.py | 5 + 5 files changed, 189 insertions(+), 107 deletions(-) diff --git a/openstackclient/common/utils.py b/openstackclient/common/utils.py index e0f35ad42f..6c613d943d 100644 --- a/openstackclient/common/utils.py +++ b/openstackclient/common/utils.py @@ -53,6 +53,30 @@ def find_resource(manager, name_or_id): raise exceptions.CommandError(msg) +def get_item_properties(item, fields, mixed_case_fields=[], formatters={}): + """Return a tuple containing the item properties. + + :param item: a single item resource (e.g. Server, Tenant, etc) + :param fields: tuple of strings with the desired field names + :param mixed_case_fields: tuple of field names to preserve case + :param formatters: dictionary mapping field names to callables + to format the values + """ + row = [] + + for field in fields: + if field in formatters: + row.append(formatters[field](item)) + else: + if field in mixed_case_fields: + field_name = field.replace(' ', '_') + else: + field_name = field.lower().replace(' ', '_') + data = getattr(item, field_name, '') + row.append(data) + return tuple(row) + + def string_to_bool(arg): return arg.strip().lower() in ('t', 'true', 'yes', '1') diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py index 69bfc7e882..1b6dbcbb03 100644 --- a/openstackclient/compute/v2/server.py +++ b/openstackclient/compute/v2/server.py @@ -44,30 +44,6 @@ def _format_servers_list_networks(server): return '; '.join(output) -def get_server_properties(server, fields, formatters={}): - """Return a tuple containing the server properties. - - :param server: a single Server resource - :param fields: tuple of strings with the desired field names - :param formatters: dictionary mapping field names to callables - to format the values - """ - row = [] - mixed_case_fields = ['serverId'] - - for field in fields: - if field in formatters: - row.append(formatters[field](server)) - else: - if field in mixed_case_fields: - field_name = field.replace(' ', '_') - else: - field_name = field.lower().replace(' ', '_') - data = getattr(server, field_name, '') - row.append(data) - return tuple(row) - - class List_Server(command.OpenStackCommand, lister.Lister): "List server command." @@ -142,7 +118,7 @@ class List_Server(command.OpenStackCommand, lister.Lister): columns = ('ID', 'Name', 'Status', 'Networks') data = nova_client.servers.list(search_opts=search_opts) return (columns, - (get_server_properties( + (utils.get_item_properties( s, columns, formatters={'Networks': _format_servers_list_networks}, ) for s in data), diff --git a/openstackclient/identity/v2_0/service.py b/openstackclient/identity/v2_0/service.py index fd1d7bf9b2..be0e7020da 100644 --- a/openstackclient/identity/v2_0/service.py +++ b/openstackclient/identity/v2_0/service.py @@ -28,51 +28,27 @@ from openstackclient.common import command from openstackclient.common import utils -def get_service_properties(service, fields, formatters={}): - """Return a tuple containing the service properties. - - :param server: a single Service resource - :param fields: tuple of strings with the desired field names - :param formatters: dictionary mapping field names to callables - to format the values - """ - row = [] - mixed_case_fields = [] - - for field in fields: - if field in formatters: - row.append(formatters[field](service)) - else: - if field in mixed_case_fields: - field_name = field.replace(' ', '_') - else: - field_name = field.lower().replace(' ', '_') - data = getattr(service, field_name, '') - row.append(data) - return tuple(row) - - class Create_Service(command.OpenStackCommand): - "Create service command." + """Create service command""" + # FIXME(dtroyer): Service commands are still WIP api = 'identity' log = logging.getLogger(__name__) def get_parser(self, prog_name): parser = super(Create_Service, self).get_parser(prog_name) parser.add_argument( - '--long', - action='store_true', - default=False, - help='Additional fields are listed in output') + 'service_name', + metavar='<service-name>', + help='New service name') return parser - def run(self, parsed_args): - self.log.info('v2.Create_Service.run(%s)' % parsed_args) + def get_data(self, parsed_args): + self.log.info('v2.Create_Service.get_data(%s)' % parsed_args) class List_Service(command.OpenStackCommand, lister.Lister): - "List service command." + """List service command""" api = 'identity' log = logging.getLogger(__name__) @@ -87,26 +63,22 @@ class List_Service(command.OpenStackCommand, lister.Lister): return parser def get_data(self, parsed_args): - self.log.debug('v2.List_Service.run(%s)' % parsed_args) + self.log.debug('v2.List_Service.get_data(%s)' % parsed_args) if parsed_args.long: columns = ('ID', 'Name', 'Type', 'Description') else: columns = ('ID', 'Name') data = self.app.client_manager.identity.services.list() - print "data: %s" % data return (columns, - (get_service_properties( + (utils.get_item_properties( s, columns, formatters={}, ) for s in data), ) - #def run(self, parsed_args): - # self.log.info('v2.List_Service.run(%s)' % parsed_args) - -class Show_Service(command.OpenStackCommand): - "Show service command." +class Show_Service(command.OpenStackCommand, show.ShowOne): + """Show service command""" api = 'identity' log = logging.getLogger(__name__) @@ -114,11 +86,20 @@ class Show_Service(command.OpenStackCommand): def get_parser(self, prog_name): parser = super(Show_Service, self).get_parser(prog_name) parser.add_argument( - '--long', - action='store_true', - default=False, - help='Additional fields are listed in output') + 'service', + metavar='<service>', + help='Name or ID of service to display') return parser - def run(self, parsed_args): - self.log.info('v2.Show_Service.run(%s)' % parsed_args) + def get_data(self, parsed_args): + self.log.info('v2.Show_Service.get_data(%s)' % parsed_args) + identity_client = self.app.client_manager.identity + service = utils.find_resource( + identity_client.services, parsed_args.service) + + info = {} + info.update(user._info) + + columns = sorted(info.keys()) + values = [info[c] for c in columns] + return (columns, values) diff --git a/openstackclient/identity/v2_0/tenant.py b/openstackclient/identity/v2_0/tenant.py index 0d12cf265e..df2818cda8 100644 --- a/openstackclient/identity/v2_0/tenant.py +++ b/openstackclient/identity/v2_0/tenant.py @@ -28,50 +28,149 @@ from openstackclient.common import command from openstackclient.common import utils -def get_tenant_properties(tenant, fields, formatters={}): - """Return a tuple containing the server properties. - - :param server: a single Server resource - :param fields: tuple of strings with the desired field names - :param formatters: dictionary mapping field names to callables - to format the values - """ - row = [] - mixed_case_fields = [] - - for field in fields: - if field in formatters: - row.append(formatters[field](tenant)) - else: - if field in mixed_case_fields: - field_name = field.replace(' ', '_') - else: - field_name = field.lower().replace(' ', '_') - data = getattr(tenant, field_name, '') - row.append(data) - return tuple(row) - - -class List_Tenant(command.OpenStackCommand, lister.Lister): - "List tenant command." +class Create_Tenant(command.OpenStackCommand, show.ShowOne): + """Create tenant command""" api = 'identity' log = logging.getLogger(__name__) + def get_parser(self, prog_name): + parser = super(Create_Tenant, self).get_parser(prog_name) + parser.add_argument( + 'tenant_name', + metavar='<tenant-name>', + help='New tenant name') + parser.add_argument( + '--description', + metavar='<tenant-description>', + help='New tenant description') + parser.add_argument( + '--enabled', + metavar='<true|false>', + default=True, + help='Initial tenant enabled status (default true)') + return parser + def get_data(self, parsed_args): - self.log.debug('v2.List_Service.run(%s)' % parsed_args) - columns = ('ID', 'Name', 'Enabled') + self.log.debug('v2_0.Create_Tenant.get_data(%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) + + columns = sorted(info.keys()) + values = [info[c] for c in columns] + return (columns, values) + + +class Delete_Tenant(command.OpenStackCommand): + """Delete tenant command""" + + api = 'identity' + log = logging.getLogger(__name__) + + def get_parser(self, prog_name): + parser = super(Delete_Tenant, self).get_parser(prog_name) + parser.add_argument( + 'tenant', + metavar='<tenant>', + help='Name or ID of tenant to delete') + return parser + + def run(self, parsed_args): + self.log.debug('v2_0.Delete_Tenant.run(%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 List_Tenant(command.OpenStackCommand, lister.Lister): + """List tenant command""" + + api = 'identity' + log = logging.getLogger(__name__) + + def get_parser(self, prog_name): + parser = super(List_Tenant, self).get_parser(prog_name) + parser.add_argument( + '--long', + action='store_true', + default=False, + help='Additional fields are listed in output') + return parser + + def get_data(self, parsed_args): + self.log.debug('v2_0.List_Tenant.get_data(%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, - (get_tenant_properties( + (utils.get_item_properties( s, columns, formatters={}, - ) for s in data), - ) + ) for s in data), + ) + + +class Set_Tenant(command.OpenStackCommand): + """Set tenant command""" + + api = 'identity' + log = logging.getLogger(__name__) + + def get_parser(self, prog_name): + parser = super(Set_Tenant, self).get_parser(prog_name) + parser.add_argument( + 'tenant', + metavar='<tenant>', + help='Name or ID of tenant to change') + parser.add_argument( + '--name', + metavar='<new-tenant-name>', + help='New tenant name') + parser.add_argument( + '--description', + metavar='<tenant-description>', + help='New tenant description') + parser.add_argument( + '--enabled', + metavar='<true|false>', + help='New tenant enabled status') + return parser + + def run(self, parsed_args): + self.log.debug('v2_0.Set_Tenant.run(%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.update({'name': parsed_args.name}) + if parsed_args.description: + kwargs.update({'description': parsed_args.description}) + if parsed_args.enabled: + kwargs.update( + {'enabled': utils.string_to_bool(parsed_args.enabled)}, + ) + + if kwargs == {}: + print "Tenant not updated, no arguments present." + return + tenant.update(**kwargs) + return class Show_Tenant(command.OpenStackCommand, show.ShowOne): - "Show server command." + """Show tenant command""" api = 'identity' log = logging.getLogger(__name__) @@ -85,7 +184,7 @@ class Show_Tenant(command.OpenStackCommand, show.ShowOne): return parser def get_data(self, parsed_args): - self.log.debug('v2.Show_Tenant.run(%s)' % parsed_args) + self.log.debug('v2_0.Show_Tenant.get_data(%s)' % parsed_args) identity_client = self.app.client_manager.identity tenant = utils.find_resource( identity_client.tenants, parsed_args.tenant) @@ -93,9 +192,6 @@ class Show_Tenant(command.OpenStackCommand, show.ShowOne): info = {} info.update(tenant._info) - # Remove a couple of values that are long and not too useful - #info.pop('links', None) - columns = sorted(info.keys()) values = [info[c] for c in columns] return (columns, values) diff --git a/setup.py b/setup.py index 6f3ac644e8..ddca8b553a 100644 --- a/setup.py +++ b/setup.py @@ -65,8 +65,13 @@ setuptools.setup( 'openstackclient.identity.v2_0.service:Create_Service', 'list_service=openstackclient.identity.v2_0.service:List_Service', 'show_service=openstackclient.identity.v2_0.service:Show_Service', + 'create_tenant=' + + 'openstackclient.identity.v2_0.tenant:Create_Tenant', + 'delete_tenant=' + + 'openstackclient.identity.v2_0.tenant:Delete_Tenant', 'list_tenant=openstackclient.identity.v2_0.tenant:List_Tenant', 'show_tenant=openstackclient.identity.v2_0.tenant:Show_Tenant', + 'set_tenant=openstackclient.identity.v2_0.tenant:Set_Tenant', ] } )