summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/common/quota.py34
-rw-r--r--openstackclient/compute/v2/availability_zone.py102
-rw-r--r--openstackclient/compute/v2/flavor.py31
-rw-r--r--openstackclient/compute/v2/usage.py83
-rw-r--r--openstackclient/identity/v2_0/ec2creds.py14
-rw-r--r--openstackclient/identity/v2_0/service.py41
-rw-r--r--openstackclient/identity/v3/domain.py24
-rw-r--r--openstackclient/identity/v3/group.py39
-rw-r--r--openstackclient/identity/v3/region.py38
-rw-r--r--openstackclient/identity/v3/user.py13
-rw-r--r--openstackclient/object/v1/container.py18
-rw-r--r--openstackclient/object/v1/object.py32
-rw-r--r--openstackclient/tests/identity/v2_0/test_service.py75
-rw-r--r--openstackclient/tests/identity/v3/fakes.py2
-rw-r--r--openstackclient/tests/identity/v3/test_domain.py10
-rw-r--r--openstackclient/tests/identity/v3/test_user.py61
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)