diff options
Diffstat (limited to 'openstackclient')
| -rw-r--r-- | openstackclient/common/quota.py | 34 | ||||
| -rw-r--r-- | openstackclient/compute/v2/availability_zone.py | 102 | ||||
| -rw-r--r-- | openstackclient/compute/v2/flavor.py | 31 | ||||
| -rw-r--r-- | openstackclient/compute/v2/usage.py | 83 | ||||
| -rw-r--r-- | openstackclient/identity/v2_0/ec2creds.py | 14 | ||||
| -rw-r--r-- | openstackclient/identity/v2_0/service.py | 41 | ||||
| -rw-r--r-- | openstackclient/identity/v3/domain.py | 24 | ||||
| -rw-r--r-- | openstackclient/identity/v3/group.py | 39 | ||||
| -rw-r--r-- | openstackclient/identity/v3/region.py | 38 | ||||
| -rw-r--r-- | openstackclient/identity/v3/user.py | 13 | ||||
| -rw-r--r-- | openstackclient/object/v1/container.py | 18 | ||||
| -rw-r--r-- | openstackclient/object/v1/object.py | 32 | ||||
| -rw-r--r-- | openstackclient/tests/identity/v2_0/test_service.py | 75 | ||||
| -rw-r--r-- | openstackclient/tests/identity/v3/fakes.py | 2 | ||||
| -rw-r--r-- | openstackclient/tests/identity/v3/test_domain.py | 10 | ||||
| -rw-r--r-- | openstackclient/tests/identity/v3/test_user.py | 61 |
16 files changed, 459 insertions, 158 deletions
diff --git a/openstackclient/common/quota.py b/openstackclient/common/quota.py index edf4ffdb..6d04b5c9 100644 --- a/openstackclient/common/quota.py +++ b/openstackclient/common/quota.py @@ -147,6 +147,21 @@ class ShowQuota(show.ShowOne): ) return parser + def get_quota(self, client, parsed_args): + try: + if parsed_args.quota_class: + quota = client.quota_classes.get(parsed_args.project) + elif parsed_args.default: + quota = client.quotas.defaults(parsed_args.project) + else: + quota = client.quotas.get(parsed_args.project) + except Exception as e: + if type(e).__name__ == 'EndpointNotFound': + return {} + else: + raise e + return quota._info + def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) @@ -159,23 +174,12 @@ class ShowQuota(show.ShowOne): # does not exist. If this is determined to be the # intended behaviour of the API we will validate # the argument with Identity ourselves later. - if parsed_args.quota_class: - compute_quota = compute_client.quota_classes.get( - parsed_args.project) - volume_quota = volume_client.quota_classes.get( - parsed_args.project) - elif parsed_args.default: - compute_quota = compute_client.quotas.defaults( - parsed_args.project) - volume_quota = volume_client.quotas.defaults( - parsed_args.project) - else: - compute_quota = compute_client.quotas.get(parsed_args.project) - volume_quota = volume_client.quotas.get(parsed_args.project) + compute_quota_info = self.get_quota(compute_client, parsed_args) + volume_quota_info = self.get_quota(volume_client, parsed_args) info = {} - info.update(compute_quota._info) - info.update(volume_quota._info) + info.update(compute_quota_info) + info.update(volume_quota_info) # Map the internal quota names to the external ones for k, v in itertools.chain( diff --git a/openstackclient/compute/v2/availability_zone.py b/openstackclient/compute/v2/availability_zone.py new file mode 100644 index 00000000..648c0ee4 --- /dev/null +++ b/openstackclient/compute/v2/availability_zone.py @@ -0,0 +1,102 @@ +# 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. +# + +"""Compute v2 Availability Zone action implementations""" + +import copy +import logging + +from cliff import lister +from novaclient import exceptions as nova_exceptions +import six + +from openstackclient.common import utils +from openstackclient.i18n import _ # noqa + + +def _xform_availability_zone(az, include_extra): + result = [] + zone_info = {} + if hasattr(az, 'zoneState'): + zone_info['zone_status'] = ('available' if az.zoneState['available'] + else 'not available') + if hasattr(az, 'zoneName'): + zone_info['zone_name'] = az.zoneName + + if not include_extra: + result.append(zone_info) + return result + + if hasattr(az, 'hosts') and az.hosts: + for host, services in six.iteritems(az.hosts): + host_info = copy.deepcopy(zone_info) + host_info['host_name'] = host + + for svc, state in six.iteritems(services): + info = copy.deepcopy(host_info) + info['service_name'] = svc + info['service_status'] = '%s %s %s' % ( + 'enabled' if state['active'] else 'disabled', + ':-)' if state['available'] else 'XXX', + state['updated_at']) + result.append(info) + else: + zone_info['host_name'] = '' + zone_info['service_name'] = '' + zone_info['service_status'] = '' + result.append(zone_info) + return result + + +class ListAvailabilityZone(lister.Lister): + """List availability zones and their status""" + + log = logging.getLogger(__name__ + '.ListAvailabilityZone') + + def get_parser(self, prog_name): + parser = super(ListAvailabilityZone, 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 = ('Zone Name', 'Zone Status', + 'Host Name', 'Service Name', 'Service Status') + else: + columns = ('Zone Name', 'Zone Status') + + compute_client = self.app.client_manager.compute + try: + data = compute_client.availability_zones.list() + except nova_exceptions.Forbidden as e: # policy doesn't allow + try: + data = compute_client.availability_zones.list(detailed=False) + except Exception: + raise e + + # Argh, the availability zones are not iterable... + result = [] + for zone in data: + result += _xform_availability_zone(zone, parsed_args.long) + + return (columns, + (utils.get_dict_properties( + s, columns + ) for s in result)) diff --git a/openstackclient/compute/v2/flavor.py b/openstackclient/compute/v2/flavor.py index 6dd00b1b..6f3788a0 100644 --- a/openstackclient/compute/v2/flavor.py +++ b/openstackclient/compute/v2/flavor.py @@ -34,64 +34,71 @@ class CreateFlavor(show.ShowOne): parser = super(CreateFlavor, self).get_parser(prog_name) parser.add_argument( "name", - metavar="<name>", + metavar="<flavor-name>", help="New flavor name", ) parser.add_argument( "--id", metavar="<id>", default='auto', - help="Unique flavor ID; 'auto' will create a UUID " - "(default: auto)") + help="Unique flavor ID; 'auto' creates a UUID " + "(default: auto)", + ) parser.add_argument( "--ram", type=int, metavar="<size-mb>", default=256, - help="Memory size in MB (default 256M)") + help="Memory size in MB (default 256M)", + ) parser.add_argument( "--disk", type=int, metavar="<size-gb>", default=0, - help="Disk size in GB (default 0G)") + help="Disk size in GB (default 0G)", + ) parser.add_argument( "--ephemeral", type=int, metavar="<size-gb>", + default=0, help="Ephemeral disk size in GB (default 0G)", - default=0) + ) parser.add_argument( "--swap", type=int, metavar="<size-gb>", + default=0, help="Swap space size in GB (default 0G)", - default=0) + ) parser.add_argument( "--vcpus", type=int, metavar="<vcpus>", default=1, - help="Number of vcpus (default 1)") + help="Number of vcpus (default 1)", + ) parser.add_argument( "--rxtx-factor", type=int, metavar="<factor>", + default=1, help="RX/TX factor (default 1)", - default=1) + ) public_group = parser.add_mutually_exclusive_group() public_group.add_argument( "--public", dest="public", action="store_true", default=True, - help="Flavor is accessible to other projects (default)", + help="Flavor is available to other projects (default)", ) public_group.add_argument( "--private", dest="public", action="store_false", - help="Flavor is inaccessible to other projects", + help="Flavor is not available to other projects", ) return parser @@ -168,7 +175,7 @@ class ListFlavor(lister.Lister): class ShowFlavor(show.ShowOne): - """Show flavor details""" + """Display flavor details""" log = logging.getLogger(__name__ + ".ShowFlavor") diff --git a/openstackclient/compute/v2/usage.py b/openstackclient/compute/v2/usage.py index ed98af26..308241cf 100644 --- a/openstackclient/compute/v2/usage.py +++ b/openstackclient/compute/v2/usage.py @@ -20,6 +20,8 @@ import logging import sys from cliff import lister +from cliff import show +import six from openstackclient.common import utils @@ -60,12 +62,14 @@ class ListUsage(lister.Lister): compute_client = self.app.client_manager.compute columns = ( "tenant_id", + "server_usages", "total_memory_mb_usage", "total_vcpus_usage", "total_local_gb_usage" ) column_headers = ( "Project", + "Servers", "RAM MB-Hours", "CPU Hours", "Disk GB-Hours" @@ -84,7 +88,7 @@ class ListUsage(lister.Lister): else: end = now + datetime.timedelta(days=1) - usage_list = compute_client.usage.list(start, end) + usage_list = compute_client.usage.list(start, end, detailed=True) # Cache the project list project_cache = {} @@ -95,8 +99,8 @@ class ListUsage(lister.Lister): # Just forget it if there's any trouble pass - if len(usage_list) > 0: - sys.stdout.write("Usage from %s to %s:" % ( + if parsed_args.formatter == 'table' and len(usage_list) > 0: + sys.stdout.write("Usage from %s to %s: \n" % ( start.strftime(dateformat), end.strftime(dateformat), )) @@ -106,8 +110,81 @@ class ListUsage(lister.Lister): s, columns, formatters={ 'tenant_id': _format_project, + 'server_usages': lambda x: len(x), 'total_memory_mb_usage': lambda x: float("%.2f" % x), 'total_vcpus_usage': lambda x: float("%.2f" % x), 'total_local_gb_usage': lambda x: float("%.2f" % x), }, ) for s in usage_list)) + + +class ShowUsage(show.ShowOne): + """Show resource usage for a single project. """ + + log = logging.getLogger(__name__ + ".ShowUsage") + + def get_parser(self, prog_name): + parser = super(ShowUsage, self).get_parser(prog_name) + parser.add_argument( + "--project", + metavar="<project>", + default=None, + help="Name or ID of project to show usage for." + ) + parser.add_argument( + "--start", + metavar="<start>", + default=None, + help="Usage range start date, ex 2012-01-20" + " (default: 4 weeks ago)." + ) + parser.add_argument( + "--end", + metavar="<end>", + default=None, + help="Usage range end date, ex 2012-01-20 (default: tomorrow)." + ) + return parser + + def take_action(self, parsed_args): + self.log.debug("take_action(%s)", parsed_args) + + identity_client = self.app.client_manager.identity + compute_client = self.app.client_manager.compute + dateformat = "%Y-%m-%d" + now = datetime.datetime.utcnow() + + if parsed_args.start: + start = datetime.datetime.strptime(parsed_args.start, dateformat) + else: + start = now - datetime.timedelta(weeks=4) + + if parsed_args.end: + end = datetime.datetime.strptime(parsed_args.end, dateformat) + else: + end = now + datetime.timedelta(days=1) + + if parsed_args.project: + project = utils.find_resource( + identity_client.projects, + parsed_args.project, + ).id + else: + # Get the project from the current auth + project = self.app.client_manager.auth_ref.project_id + + usage = compute_client.usage.get(project, start, end) + + if parsed_args.formatter == 'table': + sys.stdout.write("Usage from %s to %s on project %s: \n" % ( + start.strftime(dateformat), + end.strftime(dateformat), + project + )) + + info = {} + info['Servers'] = len(usage.server_usages) + info['RAM MB-Hours'] = float("%.2f" % usage.total_memory_mb_usage) + info['CPU Hours'] = float("%.2f" % usage.total_vcpus_usage) + info['Disk GB-Hours'] = float("%.2f" % usage.total_local_gb_usage) + return zip(*sorted(six.iteritems(info))) diff --git a/openstackclient/identity/v2_0/ec2creds.py b/openstackclient/identity/v2_0/ec2creds.py index a20ffd4b..90553eb1 100644 --- a/openstackclient/identity/v2_0/ec2creds.py +++ b/openstackclient/identity/v2_0/ec2creds.py @@ -37,12 +37,14 @@ class CreateEC2Creds(show.ShowOne): parser.add_argument( '--project', metavar='<project>', - help=_('Specify a project [admin only]'), + help=_('Specify an alternate project' + ' (default: current authenticated project)'), ) parser.add_argument( '--user', metavar='<user>', - help=_('Specify a user [admin only]'), + help=_('Specify an alternate user' + ' (default: current authenticated user)'), ) return parser @@ -95,7 +97,7 @@ class DeleteEC2Creds(command.Command): parser.add_argument( '--user', metavar='<user>', - help=_('Specify a user [admin only]'), + help=_('Specify a user'), ) return parser @@ -125,7 +127,7 @@ class ListEC2Creds(lister.Lister): parser.add_argument( '--user', metavar='<user>', - help=_('Specify a user [admin only]'), + help=_('Specify a user'), ) return parser @@ -154,7 +156,7 @@ class ListEC2Creds(lister.Lister): class ShowEC2Creds(show.ShowOne): - """Show EC2 credentials""" + """Display EC2 credentials details""" log = logging.getLogger(__name__ + '.ShowEC2Creds') @@ -168,7 +170,7 @@ class ShowEC2Creds(show.ShowOne): parser.add_argument( '--user', metavar='<user>', - help=_('Specify a user [admin only]'), + help=_('Specify a user'), ) return parser diff --git a/openstackclient/identity/v2_0/service.py b/openstackclient/identity/v2_0/service.py index e8848dde..0b98a903 100644 --- a/openstackclient/identity/v2_0/service.py +++ b/openstackclient/identity/v2_0/service.py @@ -15,6 +15,7 @@ """Service action implementations""" +import argparse import logging import six @@ -36,15 +37,20 @@ class CreateService(show.ShowOne): def get_parser(self, prog_name): parser = super(CreateService, self).get_parser(prog_name) parser.add_argument( - 'name', - metavar='<service-name>', - help=_('New service name'), + 'type_or_name', + metavar='<type>', + help=_('New service type (compute, image, identity, volume, etc)'), ) - parser.add_argument( + type_or_name_group = parser.add_mutually_exclusive_group() + type_or_name_group.add_argument( '--type', metavar='<service-type>', - required=True, - help=_('New service type (compute, image, identity, volume, etc)'), + help=argparse.SUPPRESS, + ) + type_or_name_group.add_argument( + '--name', + metavar='<name>', + help=_('New service name'), ) parser.add_argument( '--description', @@ -57,9 +63,28 @@ class CreateService(show.ShowOne): self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity + type_or_name = parsed_args.type_or_name + name = parsed_args.name + type = parsed_args.type + + # If only a single positional is present, it's a <type>. + # This is not currently legal so it is considered a new case. + if not type and not name: + type = type_or_name + # If --type option is present then positional is handled as <name>; + # display deprecation message. + elif type: + name = type_or_name + self.log.warning(_('The argument --type is deprecated, use service' + ' create --name <service-name> type instead.')) + # If --name option is present the positional is handled as <type>. + # Making --type optional is new, but back-compatible + elif name: + type = type_or_name + service = identity_client.services.create( - parsed_args.name, - parsed_args.type, + name, + type, parsed_args.description) info = {} diff --git a/openstackclient/identity/v3/domain.py b/openstackclient/identity/v3/domain.py index 727f5b18..189f0970 100644 --- a/openstackclient/identity/v3/domain.py +++ b/openstackclient/identity/v3/domain.py @@ -48,15 +48,14 @@ class CreateDomain(show.ShowOne): enable_group = parser.add_mutually_exclusive_group() enable_group.add_argument( '--enable', - dest='enabled', action='store_true', - default=True, - help='Enable domain') + help='Enable domain (default)', + ) enable_group.add_argument( '--disable', - dest='enabled', - action='store_false', - help='Disable domain') + action='store_true', + help='Disable domain', + ) parser.add_argument( '--or-show', action='store_true', @@ -68,11 +67,15 @@ class CreateDomain(show.ShowOne): self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity + enabled = True + if parsed_args.disable: + enabled = False + try: domain = identity_client.domains.create( name=parsed_args.name, description=parsed_args.description, - enabled=parsed_args.enabled, + enabled=enabled, ) except ksc_exc.Conflict as e: if parsed_args.or_show: @@ -150,13 +153,11 @@ class SetDomain(command.Command): enable_group = parser.add_mutually_exclusive_group() enable_group.add_argument( '--enable', - dest='enabled', action='store_true', help='Enable domain', ) enable_group.add_argument( '--disable', - dest='disabled', action='store_true', help='Disable domain', ) @@ -172,9 +173,10 @@ class SetDomain(command.Command): kwargs['name'] = parsed_args.name if parsed_args.description: kwargs['description'] = parsed_args.description - if parsed_args.enabled: + + if parsed_args.enable: kwargs['enabled'] = True - if parsed_args.disabled: + if parsed_args.disable: kwargs['enabled'] = False if not kwargs: diff --git a/openstackclient/identity/v3/group.py b/openstackclient/identity/v3/group.py index fbd8dd72..94e101f3 100644 --- a/openstackclient/identity/v3/group.py +++ b/openstackclient/identity/v3/group.py @@ -39,12 +39,12 @@ class AddUserToGroup(command.Command): parser.add_argument( 'group', metavar='<group>', - help='Group that user will be added to (name or ID)', + help='Group to contain <user> (name or ID)', ) parser.add_argument( 'user', metavar='<user>', - help='User to add to group (name or ID)', + help='User to add to <group> (name or ID)', ) return parser @@ -68,7 +68,7 @@ class AddUserToGroup(command.Command): class CheckUserInGroup(command.Command): - """Check user in group""" + """Check user membership in group""" log = logging.getLogger(__name__ + '.CheckUserInGroup') @@ -77,7 +77,7 @@ class CheckUserInGroup(command.Command): parser.add_argument( 'group', metavar='<group>', - help='Group to check if user belongs to (name or ID)', + help='Group to check (name or ID)', ) parser.add_argument( 'user', @@ -115,15 +115,18 @@ class CreateGroup(show.ShowOne): parser.add_argument( 'name', metavar='<group-name>', - help='New group name') - parser.add_argument( - '--description', - metavar='<description>', - help='New group description') + help='New group name', + ) parser.add_argument( '--domain', metavar='<domain>', - help='References the domain ID or name which owns the group') + help='Domain to contain new group (name or ID)', + ) + parser.add_argument( + '--description', + metavar='<description>', + help='New group description', + ) parser.add_argument( '--or-show', action='store_true', @@ -173,7 +176,7 @@ class DeleteGroup(command.Command): parser.add_argument( '--domain', metavar='<domain>', - help='Domain where group resides (name or ID)', + help='Domain containing group(s) (name or ID)', ) return parser @@ -211,7 +214,7 @@ class ListGroup(lister.Lister): parser.add_argument( '--user', metavar='<user>', - help='List group memberships for <user> (name or ID)', + help='Filter group list by <user> (name or ID)', ) parser.add_argument( '--long', @@ -259,7 +262,7 @@ class ListGroup(lister.Lister): class RemoveUserFromGroup(command.Command): - """Remove user to group""" + """Remove user from group""" log = logging.getLogger(__name__ + '.RemoveUserFromGroup') @@ -268,12 +271,12 @@ class RemoveUserFromGroup(command.Command): parser.add_argument( 'group', metavar='<group>', - help='Group that user will be removed from (name or ID)', + help='Group containing <user> (name or ID)', ) parser.add_argument( 'user', metavar='<user>', - help='User to remove from group (name or ID)', + help='User to remove from <group> (name or ID)', ) return parser @@ -314,7 +317,7 @@ class SetGroup(command.Command): parser.add_argument( '--domain', metavar='<domain>', - help='New domain that will now own the group (name or ID)') + help='New domain to contain <group> (name or ID)') parser.add_argument( '--description', metavar='<description>', @@ -341,7 +344,7 @@ class SetGroup(command.Command): class ShowGroup(show.ShowOne): - """Show group details""" + """Display group details""" log = logging.getLogger(__name__ + '.ShowGroup') @@ -355,7 +358,7 @@ class ShowGroup(show.ShowOne): parser.add_argument( '--domain', metavar='<domain>', - help='Domain where group resides (name or ID)', + help='Domain containing <group> (name or ID)', ) return parser diff --git a/openstackclient/identity/v3/region.py b/openstackclient/identity/v3/region.py index cce3417d..5fb73913 100644 --- a/openstackclient/identity/v3/region.py +++ b/openstackclient/identity/v3/region.py @@ -35,22 +35,22 @@ class CreateRegion(show.ShowOne): # seems like poor UX, we will only support user-defined IDs. parser.add_argument( 'region', - metavar='<region>', - help=_('New region'), + metavar='<region-id>', + help=_('New region ID'), ) parser.add_argument( '--parent-region', - metavar='<parent-region>', - help=_('The parent region of new region'), + metavar='<region-id>', + help=_('Parent region ID'), ) parser.add_argument( '--description', - metavar='<region-description>', + metavar='<description>', help=_('New region description'), ) parser.add_argument( '--url', - metavar='<region-url>', + metavar='<url>', help=_('New region url'), ) @@ -82,8 +82,8 @@ class DeleteRegion(command.Command): parser = super(DeleteRegion, self).get_parser(prog_name) parser.add_argument( 'region', - metavar='<region>', - help=_('Region to delete'), + metavar='<region-id>', + help=_('Region ID to delete'), ) return parser @@ -104,8 +104,8 @@ class ListRegion(lister.Lister): parser = super(ListRegion, self).get_parser(prog_name) parser.add_argument( '--parent-region', - metavar='<parent-region>', - help=_('Filter by parent region'), + metavar='<region-id>', + help=_('Filter by parent region ID'), ) return parser @@ -137,22 +137,22 @@ class SetRegion(command.Command): parser = super(SetRegion, self).get_parser(prog_name) parser.add_argument( 'region', - metavar='<region>', - help=_('Region to change'), + metavar='<region-id>', + help=_('Region ID to modify'), ) parser.add_argument( '--parent-region', - metavar='<parent-region>', - help=_('New parent region of the region'), + metavar='<region-id>', + help=_('New parent region ID'), ) parser.add_argument( '--description', - metavar='<region-description>', + metavar='<description>', help=_('New region description'), ) parser.add_argument( '--url', - metavar='<region-url>', + metavar='<url>', help=_('New region url'), ) return parser @@ -179,7 +179,7 @@ class SetRegion(command.Command): class ShowRegion(show.ShowOne): - """Show region""" + """Display region details""" log = logging.getLogger(__name__ + '.ShowRegion') @@ -187,8 +187,8 @@ class ShowRegion(show.ShowOne): parser = super(ShowRegion, self).get_parser(prog_name) parser.add_argument( 'region', - metavar='<region>', - help=_('Region to display'), + metavar='<region-id>', + help=_('Region ID to display'), ) return parser diff --git a/openstackclient/identity/v3/user.py b/openstackclient/identity/v3/user.py index dc5468ff..a60c8c83 100644 --- a/openstackclient/identity/v3/user.py +++ b/openstackclient/identity/v3/user.py @@ -15,6 +15,7 @@ """Identity v3 User action implementations""" +import copy import logging import six @@ -220,17 +221,21 @@ class ListUser(lister.Lister): # List users if parsed_args.long: - columns = ('ID', 'Name', 'Project Id', 'Domain Id', - 'Description', 'Email', 'Enabled') + columns = ['ID', 'Name', 'Default Project Id', 'Domain Id', + 'Description', 'Email', 'Enabled'] + column_headers = copy.deepcopy(columns) + column_headers[2] = 'Project' + column_headers[3] = 'Domain' else: - columns = ('ID', 'Name') + columns = ['ID', 'Name'] + column_headers = copy.deepcopy(columns) data = identity_client.users.list( domain=domain, group=group, ) return ( - columns, + column_headers, (utils.get_item_properties( s, columns, formatters={}, diff --git a/openstackclient/object/v1/container.py b/openstackclient/object/v1/container.py index ead3df45..b75888e4 100644 --- a/openstackclient/object/v1/container.py +++ b/openstackclient/object/v1/container.py @@ -27,7 +27,7 @@ from openstackclient.common import utils class CreateContainer(lister.Lister): - """Create a container""" + """Create new container""" log = logging.getLogger(__name__ + '.CreateContainer') @@ -35,9 +35,9 @@ class CreateContainer(lister.Lister): parser = super(CreateContainer, self).get_parser(prog_name) parser.add_argument( 'containers', - metavar='<container>', + metavar='<container-name>', nargs="+", - help='Container name(s) to create', + help='New container name(s)', ) return parser @@ -60,7 +60,7 @@ class CreateContainer(lister.Lister): class DeleteContainer(command.Command): - """Delete a container""" + """Delete container""" log = logging.getLogger(__name__ + '.DeleteContainer') @@ -70,7 +70,7 @@ class DeleteContainer(command.Command): 'containers', metavar='<container>', nargs="+", - help='Container name(s) to delete', + help='Container(s) to delete', ) return parser @@ -157,7 +157,7 @@ class ListContainer(lister.Lister): class SaveContainer(command.Command): - """Save the contents of a container locally""" + """Save container contents locally""" log = logging.getLogger(__name__ + ".SaveContainer") @@ -166,7 +166,7 @@ class SaveContainer(command.Command): parser.add_argument( 'container', metavar='<container>', - help='Container name to save', + help='Container to save', ) return parser @@ -179,7 +179,7 @@ class SaveContainer(command.Command): class ShowContainer(show.ShowOne): - """Show container information""" + """Show container details""" log = logging.getLogger(__name__ + '.ShowContainer') @@ -188,7 +188,7 @@ class ShowContainer(show.ShowOne): parser.add_argument( 'container', metavar='<container>', - help='Container name to display', + help='Container to display', ) return parser diff --git a/openstackclient/object/v1/object.py b/openstackclient/object/v1/object.py index cbe9da2f..781dd047 100644 --- a/openstackclient/object/v1/object.py +++ b/openstackclient/object/v1/object.py @@ -27,7 +27,7 @@ from openstackclient.common import utils class CreateObject(lister.Lister): - """Upload an object to a container""" + """Upload object to container""" log = logging.getLogger(__name__ + '.CreateObject') @@ -36,13 +36,13 @@ class CreateObject(lister.Lister): parser.add_argument( 'container', metavar='<container>', - help='Container to store new object', + help='Container for new object', ) parser.add_argument( 'objects', - metavar='<object-name>', + metavar='<filename>', nargs="+", - help='Local path of object(s) to upload', + help='Local filename(s) to upload', ) return parser @@ -66,7 +66,7 @@ class CreateObject(lister.Lister): class DeleteObject(command.Command): - """Delete an object within a container""" + """Delete object from container""" log = logging.getLogger(__name__ + '.DeleteObject') @@ -75,11 +75,11 @@ class DeleteObject(command.Command): parser.add_argument( 'container', metavar='<container>', - help='Container that stores the object to delete', + help='Delete object(s) from <container>', ) parser.add_argument( 'objects', - metavar='<object-name>', + metavar='<object>', nargs="+", help='Object(s) to delete', ) @@ -104,8 +104,8 @@ class ListObject(lister.Lister): parser = super(ListObject, self).get_parser(prog_name) parser.add_argument( "container", - metavar="<container-name>", - help="List contents of container-name", + metavar="<container>", + help="Container to list", ) parser.add_argument( "--prefix", @@ -188,7 +188,7 @@ class ListObject(lister.Lister): class SaveObject(command.Command): - """Save an object locally""" + """Save object locally""" log = logging.getLogger(__name__ + ".SaveObject") @@ -197,17 +197,17 @@ class SaveObject(command.Command): parser.add_argument( "--file", metavar="<filename>", - help="Downloaded object filename [defaults to object name]", + help="Destination filename (defaults to object name)", ) parser.add_argument( 'container', metavar='<container>', - help='Container name that has the object', + help='Download <object> from <container>', ) parser.add_argument( "object", metavar="<object>", - help="Name of the object to save", + help="Object to save", ) return parser @@ -222,7 +222,7 @@ class SaveObject(command.Command): class ShowObject(show.ShowOne): - """Show object information""" + """Show object details""" log = logging.getLogger(__name__ + '.ShowObject') @@ -231,12 +231,12 @@ class ShowObject(show.ShowOne): parser.add_argument( 'container', metavar='<container>', - help='Container name for object to display', + help='Display <object> from <container>', ) parser.add_argument( 'object', metavar='<object>', - help='Object name to display', + help='Object to display', ) return parser diff --git a/openstackclient/tests/identity/v2_0/test_service.py b/openstackclient/tests/identity/v2_0/test_service.py index 6c93574b..a0adea4e 100644 --- a/openstackclient/tests/identity/v2_0/test_service.py +++ b/openstackclient/tests/identity/v2_0/test_service.py @@ -44,14 +44,80 @@ class TestServiceCreate(TestService): # Get the command object to test self.cmd = service.CreateService(self.app, None) - def test_service_create_name_type(self): + def test_service_create_with_type_positional(self): + arglist = [ + identity_fakes.service_type, + ] + verifylist = [ + ('type_or_name', identity_fakes.service_type), + ('type', None), + ('description', None), + ('name', None), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + # ServiceManager.create(name, service_type, description) + self.services_mock.create.assert_called_with( + None, + identity_fakes.service_type, + None, + ) + + collist = ('description', 'id', 'name', 'type') + self.assertEqual(columns, collist) + datalist = ( + identity_fakes.service_description, + identity_fakes.service_id, + identity_fakes.service_name, + identity_fakes.service_type, + ) + self.assertEqual(data, datalist) + + def test_service_create_with_type_option(self): arglist = [ '--type', identity_fakes.service_type, identity_fakes.service_name, ] verifylist = [ + ('type_or_name', identity_fakes.service_name), ('type', identity_fakes.service_type), ('description', None), + ('name', None), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + # ServiceManager.create(name, service_type, description) + self.services_mock.create.assert_called_with( + identity_fakes.service_name, + identity_fakes.service_type, + None, + ) + + collist = ('description', 'id', 'name', 'type') + self.assertEqual(columns, collist) + datalist = ( + identity_fakes.service_description, + identity_fakes.service_id, + identity_fakes.service_name, + identity_fakes.service_type, + ) + self.assertEqual(data, datalist) + + def test_service_create_with_name_option(self): + arglist = [ + '--name', identity_fakes.service_name, + identity_fakes.service_type, + ] + verifylist = [ + ('type_or_name', identity_fakes.service_type), + ('type', None), + ('description', None), ('name', identity_fakes.service_name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -78,12 +144,13 @@ class TestServiceCreate(TestService): def test_service_create_description(self): arglist = [ - '--type', identity_fakes.service_type, + '--name', identity_fakes.service_name, '--description', identity_fakes.service_description, - identity_fakes.service_name, + identity_fakes.service_type, ] verifylist = [ - ('type', identity_fakes.service_type), + ('type_or_name', identity_fakes.service_type), + ('type', None), ('description', identity_fakes.service_description), ('name', identity_fakes.service_name), ] diff --git a/openstackclient/tests/identity/v3/fakes.py b/openstackclient/tests/identity/v3/fakes.py index fbdac4ed..3afb0cd9 100644 --- a/openstackclient/tests/identity/v3/fakes.py +++ b/openstackclient/tests/identity/v3/fakes.py @@ -181,7 +181,7 @@ user_email = 'paul@applecorps.com' USER = { 'id': user_id, 'name': user_name, - 'project_id': project_id, + 'default_project_id': project_id, 'email': user_email, 'enabled': True, 'domain_id': domain_id, diff --git a/openstackclient/tests/identity/v3/test_domain.py b/openstackclient/tests/identity/v3/test_domain.py index 8dad5bcc..cfec10e7 100644 --- a/openstackclient/tests/identity/v3/test_domain.py +++ b/openstackclient/tests/identity/v3/test_domain.py @@ -46,7 +46,6 @@ class TestDomainCreate(TestDomain): identity_fakes.domain_name, ] verifylist = [ - ('enabled', True), ('name', identity_fakes.domain_name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -81,7 +80,6 @@ class TestDomainCreate(TestDomain): ] verifylist = [ ('description', 'new desc'), - ('enabled', True), ('name', identity_fakes.domain_name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -115,7 +113,7 @@ class TestDomainCreate(TestDomain): identity_fakes.domain_name, ] verifylist = [ - ('enabled', True), + ('enable', True), ('name', identity_fakes.domain_name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -149,7 +147,7 @@ class TestDomainCreate(TestDomain): identity_fakes.domain_name, ] verifylist = [ - ('enabled', False), + ('disable', True), ('name', identity_fakes.domain_name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -333,7 +331,7 @@ class TestDomainSet(TestDomain): identity_fakes.domain_id, ] verifylist = [ - ('enabled', True), + ('enable', True), ('domain', identity_fakes.domain_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -356,7 +354,7 @@ class TestDomainSet(TestDomain): identity_fakes.domain_id, ] verifylist = [ - ('disabled', True), + ('disable', True), ('domain', identity_fakes.domain_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) diff --git a/openstackclient/tests/identity/v3/test_user.py b/openstackclient/tests/identity/v3/test_user.py index 9740ed82..dd517e19 100644 --- a/openstackclient/tests/identity/v3/test_user.py +++ b/openstackclient/tests/identity/v3/test_user.py @@ -102,15 +102,16 @@ class TestUserCreate(TestUser): **kwargs ) - collist = ('domain_id', 'email', 'enabled', 'id', 'name', 'project_id') + collist = ('default_project_id', 'domain_id', 'email', + 'enabled', 'id', 'name') self.assertEqual(columns, collist) datalist = ( + identity_fakes.project_id, identity_fakes.domain_id, identity_fakes.user_email, True, identity_fakes.user_id, identity_fakes.user_name, - identity_fakes.project_id, ) self.assertEqual(data, datalist) @@ -147,15 +148,16 @@ class TestUserCreate(TestUser): **kwargs ) - collist = ('domain_id', 'email', 'enabled', 'id', 'name', 'project_id') + collist = ('default_project_id', 'domain_id', 'email', + 'enabled', 'id', 'name') self.assertEqual(columns, collist) datalist = ( + identity_fakes.project_id, identity_fakes.domain_id, identity_fakes.user_email, True, identity_fakes.user_id, identity_fakes.user_name, - identity_fakes.project_id, ) self.assertEqual(data, datalist) @@ -195,15 +197,16 @@ class TestUserCreate(TestUser): **kwargs ) - collist = ('domain_id', 'email', 'enabled', 'id', 'name', 'project_id') + collist = ('default_project_id', 'domain_id', 'email', + 'enabled', 'id', 'name') self.assertEqual(columns, collist) datalist = ( + identity_fakes.project_id, identity_fakes.domain_id, identity_fakes.user_email, True, identity_fakes.user_id, identity_fakes.user_name, - identity_fakes.project_id, ) self.assertEqual(data, datalist) @@ -239,15 +242,16 @@ class TestUserCreate(TestUser): **kwargs ) - collist = ('domain_id', 'email', 'enabled', 'id', 'name', 'project_id') + collist = ('default_project_id', 'domain_id', 'email', + 'enabled', 'id', 'name') self.assertEqual(columns, collist) datalist = ( + identity_fakes.project_id, identity_fakes.domain_id, identity_fakes.user_email, True, identity_fakes.user_id, identity_fakes.user_name, - identity_fakes.project_id, ) self.assertEqual(data, datalist) @@ -260,7 +264,7 @@ class TestUserCreate(TestUser): ) # Set up to return an updated user USER_2 = copy.deepcopy(identity_fakes.USER) - USER_2['project_id'] = identity_fakes.PROJECT_2['id'] + USER_2['default_project_id'] = identity_fakes.PROJECT_2['id'] self.users_mock.create.return_value = fakes.FakeResource( None, USER_2, @@ -298,15 +302,16 @@ class TestUserCreate(TestUser): **kwargs ) - collist = ('domain_id', 'email', 'enabled', 'id', 'name', 'project_id') + collist = ('default_project_id', 'domain_id', 'email', + 'enabled', 'id', 'name') self.assertEqual(columns, collist) datalist = ( + identity_fakes.PROJECT_2['id'], identity_fakes.domain_id, identity_fakes.user_email, True, identity_fakes.user_id, identity_fakes.user_name, - identity_fakes.PROJECT_2['id'], ) self.assertEqual(data, datalist) @@ -342,15 +347,16 @@ class TestUserCreate(TestUser): **kwargs ) - collist = ('domain_id', 'email', 'enabled', 'id', 'name', 'project_id') + collist = ('default_project_id', 'domain_id', 'email', + 'enabled', 'id', 'name') self.assertEqual(columns, collist) datalist = ( + identity_fakes.project_id, identity_fakes.domain_id, identity_fakes.user_email, True, identity_fakes.user_id, identity_fakes.user_name, - identity_fakes.project_id, ) self.assertEqual(data, datalist) @@ -385,15 +391,16 @@ class TestUserCreate(TestUser): **kwargs ) - collist = ('domain_id', 'email', 'enabled', 'id', 'name', 'project_id') + collist = ('default_project_id', 'domain_id', 'email', + 'enabled', 'id', 'name') self.assertEqual(columns, collist) datalist = ( + identity_fakes.project_id, identity_fakes.domain_id, identity_fakes.user_email, True, identity_fakes.user_id, identity_fakes.user_name, - identity_fakes.project_id, ) self.assertEqual(data, datalist) @@ -427,15 +434,16 @@ class TestUserCreate(TestUser): **kwargs ) - collist = ('domain_id', 'email', 'enabled', 'id', 'name', 'project_id') + collist = ('default_project_id', 'domain_id', 'email', + 'enabled', 'id', 'name') self.assertEqual(columns, collist) datalist = ( + identity_fakes.project_id, identity_fakes.domain_id, identity_fakes.user_email, True, identity_fakes.user_id, identity_fakes.user_name, - identity_fakes.project_id, ) self.assertEqual(data, datalist) @@ -524,7 +532,7 @@ class TestUserList(TestUser): **kwargs ) - collist = ('ID', 'Name') + collist = ['ID', 'Name'] self.assertEqual(columns, collist) datalist = (( identity_fakes.user_id, @@ -554,7 +562,7 @@ class TestUserList(TestUser): **kwargs ) - collist = ('ID', 'Name') + collist = ['ID', 'Name'] self.assertEqual(columns, collist) datalist = (( identity_fakes.user_id, @@ -584,7 +592,7 @@ class TestUserList(TestUser): **kwargs ) - collist = ('ID', 'Name') + collist = ['ID', 'Name'] self.assertEqual(columns, collist) datalist = (( identity_fakes.user_id, @@ -614,15 +622,15 @@ class TestUserList(TestUser): **kwargs ) - collist = ( + collist = [ 'ID', 'Name', - 'Project Id', - 'Domain Id', + 'Project', + 'Domain', 'Description', 'Email', 'Enabled', - ) + ] self.assertEqual(columns, collist) datalist = (( identity_fakes.user_id, @@ -1020,14 +1028,15 @@ class TestUserShow(TestUser): self.users_mock.get.assert_called_with(identity_fakes.user_id) - collist = ('domain_id', 'email', 'enabled', 'id', 'name', 'project_id') + collist = ('default_project_id', 'domain_id', 'email', + 'enabled', 'id', 'name') self.assertEqual(columns, collist) datalist = ( + identity_fakes.project_id, identity_fakes.domain_id, identity_fakes.user_email, True, identity_fakes.user_id, identity_fakes.user_name, - identity_fakes.project_id, ) self.assertEqual(data, datalist) |
