summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/common/availability_zone.py (renamed from openstackclient/compute/v2/availability_zone.py)75
-rw-r--r--openstackclient/i18n.py2
-rw-r--r--openstackclient/image/v1/image.py65
-rw-r--r--openstackclient/image/v2/image.py85
-rw-r--r--openstackclient/locale/de/LC_MESSAGES/openstackclient.po600
-rw-r--r--openstackclient/locale/openstackclient.pot829
-rw-r--r--openstackclient/locale/zh_TW/LC_MESSAGES/openstackclient.po495
-rw-r--r--openstackclient/network/v2/subnet.py70
-rw-r--r--openstackclient/tests/common/test_availability_zone.py192
-rw-r--r--openstackclient/tests/compute/v2/fakes.py62
-rw-r--r--openstackclient/tests/image/v1/test_image.py77
-rw-r--r--openstackclient/tests/image/v2/test_image.py173
-rw-r--r--openstackclient/tests/network/v2/fakes.py68
-rw-r--r--openstackclient/tests/network/v2/test_subnet.py108
-rw-r--r--openstackclient/tests/object/v1/test_container.py18
-rw-r--r--openstackclient/tests/object/v1/test_container_all.py20
-rw-r--r--openstackclient/tests/object/v1/test_object.py53
-rw-r--r--openstackclient/tests/object/v1/test_object_all.py8
-rw-r--r--openstackclient/tests/volume/v1/test_qos_specs.py46
-rw-r--r--openstackclient/tests/volume/v1/test_volume.py302
-rw-r--r--openstackclient/tests/volume/v2/fakes.py54
-rw-r--r--openstackclient/tests/volume/v2/test_backup.py41
-rw-r--r--openstackclient/tests/volume/v2/test_qos_specs.py45
-rw-r--r--openstackclient/tests/volume/v2/test_snapshot.py30
-rw-r--r--openstackclient/tests/volume/v2/test_type.py55
-rw-r--r--openstackclient/tests/volume/v2/test_volume.py310
26 files changed, 3054 insertions, 829 deletions
diff --git a/openstackclient/compute/v2/availability_zone.py b/openstackclient/common/availability_zone.py
index 0fe6c73a..e72732e7 100644
--- a/openstackclient/compute/v2/availability_zone.py
+++ b/openstackclient/common/availability_zone.py
@@ -11,7 +11,7 @@
# under the License.
#
-"""Compute v2 Availability Zone action implementations"""
+"""Availability Zone action implementations"""
import copy
import logging
@@ -24,15 +24,19 @@ from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
-def _xform_availability_zone(az, include_extra):
- result = []
- zone_info = {}
+def _xform_common_availability_zone(az, 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
+
+def _xform_compute_availability_zone(az, include_extra):
+ result = []
+ zone_info = {}
+ _xform_common_availability_zone(az, zone_info)
+
if not include_extra:
result.append(zone_info)
return result
@@ -58,6 +62,14 @@ def _xform_availability_zone(az, include_extra):
return result
+def _xform_volume_availability_zone(az):
+ result = []
+ zone_info = {}
+ _xform_common_availability_zone(az, zone_info)
+ result.append(zone_info)
+ return result
+
+
class ListAvailabilityZone(lister.Lister):
"""List availability zones and their status"""
@@ -66,6 +78,16 @@ class ListAvailabilityZone(lister.Lister):
def get_parser(self, prog_name):
parser = super(ListAvailabilityZone, self).get_parser(prog_name)
parser.add_argument(
+ '--compute',
+ action='store_true',
+ default=False,
+ help='List compute availability zones')
+ parser.add_argument(
+ '--volume',
+ action='store_true',
+ default=False,
+ help='List volume availability zones')
+ parser.add_argument(
'--long',
action='store_true',
default=False,
@@ -73,15 +95,7 @@ class ListAvailabilityZone(lister.Lister):
)
return parser
- @utils.log_method(log)
- def take_action(self, parsed_args):
-
- if parsed_args.long:
- columns = ('Zone Name', 'Zone Status',
- 'Host Name', 'Service Name', 'Service Status')
- else:
- columns = ('Zone Name', 'Zone Status')
-
+ def get_compute_availability_zones(self, parsed_args):
compute_client = self.app.client_manager.compute
try:
data = compute_client.availability_zones.list()
@@ -94,7 +108,40 @@ class ListAvailabilityZone(lister.Lister):
# Argh, the availability zones are not iterable...
result = []
for zone in data:
- result += _xform_availability_zone(zone, parsed_args.long)
+ result += _xform_compute_availability_zone(zone, parsed_args.long)
+ return result
+
+ def get_volume_availability_zones(self, parsed_args):
+ volume_client = self.app.client_manager.volume
+ try:
+ data = volume_client.availability_zones.list()
+ except Exception:
+ message = "Availability zones list not supported by " \
+ "Block Storage API"
+ self.log.warning(message)
+
+ result = []
+ for zone in data:
+ result += _xform_volume_availability_zone(zone)
+ return result
+
+ @utils.log_method(log)
+ def take_action(self, parsed_args):
+
+ if parsed_args.long:
+ columns = ('Zone Name', 'Zone Status',
+ 'Host Name', 'Service Name', 'Service Status')
+ else:
+ columns = ('Zone Name', 'Zone Status')
+
+ # Show everything by default.
+ show_all = (not parsed_args.compute and not parsed_args.volume)
+
+ result = []
+ if parsed_args.compute or show_all:
+ result += self.get_compute_availability_zones(parsed_args)
+ if parsed_args.volume or show_all:
+ result += self.get_volume_availability_zones(parsed_args)
return (columns,
(utils.get_dict_properties(
diff --git a/openstackclient/i18n.py b/openstackclient/i18n.py
index 3a11c1d0..1d09772c 100644
--- a/openstackclient/i18n.py
+++ b/openstackclient/i18n.py
@@ -15,7 +15,7 @@
import oslo_i18n
-_translators = oslo_i18n.TranslatorFactory(domain='python-openstackclient')
+_translators = oslo_i18n.TranslatorFactory(domain='openstackclient')
# The primary translation function using the well-known name "_"
_ = _translators.primary
diff --git a/openstackclient/image/v1/image.py b/openstackclient/image/v1/image.py
index 0382501e..c18f3fc7 100644
--- a/openstackclient/image/v1/image.py
+++ b/openstackclient/image/v1/image.py
@@ -35,6 +35,7 @@ from glanceclient.common import utils as gc_utils
from openstackclient.api import utils as api_utils
from openstackclient.common import parseractions
from openstackclient.common import utils
+from openstackclient.i18n import _ # noqa
DEFAULT_CONTAINER_FORMAT = 'bare'
@@ -93,11 +94,6 @@ class CreateImage(show.ShowOne):
"(default: %s)" % DEFAULT_DISK_FORMAT,
)
parser.add_argument(
- "--owner",
- metavar="<project>",
- help="Image owner project name or ID",
- )
- parser.add_argument(
"--size",
metavar="<size>",
help="Image size, in bytes (only used with --location and"
@@ -178,12 +174,32 @@ class CreateImage(show.ShowOne):
help="Set a property on this image "
"(repeat option to set multiple properties)",
)
+ # NOTE(dtroyer): --owner is deprecated in Jan 2016 in an early
+ # 2.x release. Do not remove before Jan 2017
+ # and a 3.x release.
+ project_group = parser.add_mutually_exclusive_group()
+ project_group.add_argument(
+ "--project",
+ metavar="<project>",
+ help="Set an alternate project on this image (name or ID)",
+ )
+ project_group.add_argument(
+ "--owner",
+ metavar="<project>",
+ help=argparse.SUPPRESS,
+ )
return parser
def take_action(self, parsed_args):
self.log.debug("take_action(%s)", parsed_args)
image_client = self.app.client_manager.image
+ if getattr(parsed_args, 'owner', None) is not None:
+ self.log.warning(_(
+ 'The --owner option is deprecated, '
+ 'please use --project instead.'
+ ))
+
# Build an attribute dict from the parsed args, only include
# attributes that were actually set on the command line
kwargs = {}
@@ -198,6 +214,12 @@ class CreateImage(show.ShowOne):
# Only include a value in kwargs for attributes that are
# actually present on the command line
kwargs[attr] = val
+
+ # Special case project option back to API attribute name 'owner'
+ val = getattr(parsed_args, 'project', None)
+ if val:
+ kwargs['owner'] = val
+
# Handle exclusive booleans with care
# Avoid including attributes in kwargs if an option is not
# present on the command line. These exclusive booleans are not
@@ -383,7 +405,7 @@ class ListImage(lister.Lister):
'Status',
'Visibility',
'Protected',
- 'Owner',
+ 'Project',
'Properties',
)
else:
@@ -477,11 +499,6 @@ class SetImage(command.Command):
help="New image name",
)
parser.add_argument(
- "--owner",
- metavar="<project>",
- help="New image owner project (name or ID)",
- )
- parser.add_argument(
"--min-disk",
metavar="<disk-gb>",
type=int,
@@ -590,12 +607,32 @@ class SetImage(command.Command):
metavar="<checksum>",
help="Image hash used for verification",
)
+ # NOTE(dtroyer): --owner is deprecated in Jan 2016 in an early
+ # 2.x release. Do not remove before Jan 2017
+ # and a 3.x release.
+ project_group = parser.add_mutually_exclusive_group()
+ project_group.add_argument(
+ "--project",
+ metavar="<project>",
+ help="Set an alternate project on this image (name or ID)",
+ )
+ project_group.add_argument(
+ "--owner",
+ metavar="<project>",
+ help=argparse.SUPPRESS,
+ )
return parser
def take_action(self, parsed_args):
self.log.debug("take_action(%s)", parsed_args)
image_client = self.app.client_manager.image
+ if getattr(parsed_args, 'owner', None) is not None:
+ self.log.warning(_(
+ 'The --owner option is deprecated, '
+ 'please use --project instead.'
+ ))
+
kwargs = {}
copy_attrs = ('name', 'owner', 'min_disk', 'min_ram', 'properties',
'container_format', 'disk_format', 'size', 'store',
@@ -607,6 +644,12 @@ class SetImage(command.Command):
# Only include a value in kwargs for attributes that are
# actually present on the command line
kwargs[attr] = val
+
+ # Special case project option back to API attribute name 'owner'
+ val = getattr(parsed_args, 'project', None)
+ if val:
+ kwargs['owner'] = val
+
# Handle exclusive booleans with care
# Avoid including attributes in kwargs if an option is not
# present on the command line. These exclusive booleans are not
diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py
index ad536ba2..123599ed 100644
--- a/openstackclient/image/v2/image.py
+++ b/openstackclient/image/v2/image.py
@@ -28,6 +28,7 @@ from openstackclient.api import utils as api_utils
from openstackclient.common import exceptions
from openstackclient.common import parseractions
from openstackclient.common import utils
+from openstackclient.i18n import _ # noqa
from openstackclient.identity import common
@@ -148,11 +149,6 @@ class CreateImage(show.ShowOne):
"(default: %s)" % DEFAULT_DISK_FORMAT,
)
parser.add_argument(
- "--owner",
- metavar="<owner>",
- help="Image owner project name or ID",
- )
- parser.add_argument(
"--min-disk",
metavar="<disk-gb>",
type=int,
@@ -220,6 +216,20 @@ class CreateImage(show.ShowOne):
help="Set a tag on this image "
"(repeat option to set multiple tags)",
)
+ # NOTE(dtroyer): --owner is deprecated in Jan 2016 in an early
+ # 2.x release. Do not remove before Jan 2017
+ # and a 3.x release.
+ project_group = parser.add_mutually_exclusive_group()
+ project_group.add_argument(
+ "--project",
+ metavar="<project>",
+ help="Set an alternate project on this image (name or ID)",
+ )
+ project_group.add_argument(
+ "--owner",
+ metavar="<project>",
+ help=argparse.SUPPRESS,
+ )
common.add_project_domain_option_to_parser(parser)
for deadopt in self.deadopts:
parser.add_argument(
@@ -246,8 +256,7 @@ class CreateImage(show.ShowOne):
kwargs = {}
copy_attrs = ('name', 'id',
'container_format', 'disk_format',
- 'min_disk', 'min_ram',
- 'tags', 'owner')
+ 'min_disk', 'min_ram', 'tags')
for attr in copy_attrs:
if attr in parsed_args:
val = getattr(parsed_args, attr, None)
@@ -255,6 +264,7 @@ class CreateImage(show.ShowOne):
# Only include a value in kwargs for attributes that
# are actually present on the command line
kwargs[attr] = val
+
# properties should get flattened into the general kwargs
if getattr(parsed_args, 'properties', None):
for k, v in six.iteritems(parsed_args.properties):
@@ -275,6 +285,21 @@ class CreateImage(show.ShowOne):
if parsed_args.private:
kwargs['visibility'] = 'private'
+ # Handle deprecated --owner option
+ project_arg = parsed_args.project
+ if parsed_args.owner:
+ project_arg = parsed_args.owner
+ self.log.warning(_(
+ 'The --owner option is deprecated, '
+ 'please use --project instead.'
+ ))
+ if project_arg:
+ kwargs['owner'] = common.find_project(
+ identity_client,
+ project_arg,
+ parsed_args.project_domain,
+ ).id
+
# open the file first to ensure any failures are handled before the
# image is created
fp = gc_utils.get_data_file(parsed_args)
@@ -458,7 +483,7 @@ class ListImage(lister.Lister):
'Status',
'Visibility',
'Protected',
- 'Owner',
+ 'Project',
'Tags',
)
else:
@@ -599,11 +624,6 @@ class SetImage(command.Command):
help="New image name"
)
parser.add_argument(
- "--owner",
- metavar="<project>",
- help="New image owner project (name or ID)",
- )
- parser.add_argument(
"--min-disk",
type=int,
metavar="<disk-gb>",
@@ -713,6 +733,20 @@ class SetImage(command.Command):
action="store_true",
help="Activate the image",
)
+ # NOTE(dtroyer): --owner is deprecated in Jan 2016 in an early
+ # 2.x release. Do not remove before Jan 2017
+ # and a 3.x release.
+ project_group = parser.add_mutually_exclusive_group()
+ project_group.add_argument(
+ "--project",
+ metavar="<project>",
+ help="Set an alternate project on this image (name or ID)",
+ )
+ project_group.add_argument(
+ "--owner",
+ metavar="<project>",
+ help=argparse.SUPPRESS,
+ )
common.add_project_domain_option_to_parser(parser)
for deadopt in self.deadopts:
parser.add_argument(
@@ -738,7 +772,7 @@ class SetImage(command.Command):
copy_attrs = ('architecture', 'container_format', 'disk_format',
'file', 'instance_id', 'kernel_id', 'locations',
'min_disk', 'min_ram', 'name', 'os_distro', 'os_version',
- 'owner', 'prefix', 'progress', 'ramdisk_id', 'tags')
+ 'prefix', 'progress', 'ramdisk_id', 'tags')
for attr in copy_attrs:
if attr in parsed_args:
val = getattr(parsed_args, attr, None)
@@ -767,6 +801,21 @@ class SetImage(command.Command):
if parsed_args.private:
kwargs['visibility'] = 'private'
+ # Handle deprecated --owner option
+ project_arg = parsed_args.project
+ if parsed_args.owner:
+ project_arg = parsed_args.owner
+ self.log.warning(_(
+ 'The --owner option is deprecated, '
+ 'please use --project instead.'
+ ))
+ if project_arg:
+ kwargs['owner'] = common.find_project(
+ identity_client,
+ project_arg,
+ parsed_args.project_domain,
+ ).id
+
# Checks if anything that requires getting the image
if not (kwargs or parsed_args.deactivate or parsed_args.activate):
self.log.warning("No arguments specified")
@@ -775,6 +824,7 @@ class SetImage(command.Command):
image = utils.find_resource(
image_client.images, parsed_args.image)
+ activation_status = None
if parsed_args.deactivate:
image_client.images.deactivate(image.id)
activation_status = "deactivated"
@@ -790,13 +840,6 @@ class SetImage(command.Command):
# Tags should be extended, but duplicates removed
kwargs['tags'] = list(set(image.tags).union(set(parsed_args.tags)))
- if parsed_args.owner:
- kwargs['owner'] = common.find_project(
- identity_client,
- parsed_args.owner,
- parsed_args.project_domain,
- ).id
-
try:
image = image_client.images.update(image.id, **kwargs)
except Exception as e:
diff --git a/openstackclient/locale/de/LC_MESSAGES/openstackclient.po b/openstackclient/locale/de/LC_MESSAGES/openstackclient.po
new file mode 100644
index 00000000..1c94b9d4
--- /dev/null
+++ b/openstackclient/locale/de/LC_MESSAGES/openstackclient.po
@@ -0,0 +1,600 @@
+# Translations template for python-openstackclient.
+# Copyright (C) 2015 ORGANIZATION
+# This file is distributed under the same license as the
+# python-openstackclient project.
+#
+# Translators:
+# Ettore Atalan <atalanttore@googlemail.com>, 2014-2015
+# Andreas Jaeger <jaegerandi@gmail.com>, 2015. #zanata
+# OpenStack Infra <zanata@openstack.org>, 2015. #zanata
+msgid ""
+msgstr ""
+"Project-Id-Version: python-openstackclient 2.0.1.dev168\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2016-01-19 02:20+0000\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"PO-Revision-Date: 2015-09-19 07:10+0000\n"
+"Last-Translator: Andreas Jaeger <jaegerandi@gmail.com>\n"
+"Language: de\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Generated-By: Babel 2.0\n"
+"X-Generator: Zanata 3.7.3\n"
+"Language-Team: German\n"
+
+msgid ""
+"\n"
+"Complete\n"
+msgstr ""
+"\n"
+"Fertig\n"
+
+msgid ""
+"\n"
+"Error creating server"
+msgstr ""
+"\n"
+"Fehler beim Erstellen des Servers"
+
+msgid ""
+"\n"
+"Error creating server snapshot"
+msgstr ""
+"\n"
+"Fehler beim Erstellen der Server-Schattenkopie"
+
+msgid ""
+"\n"
+"Error deleting server"
+msgstr ""
+"\n"
+"Fehler beim Löschen des Servers"
+
+msgid ""
+"\n"
+"Error migrating server"
+msgstr ""
+"\n"
+"Fehler beim Migrieren des Servers"
+
+msgid ""
+"\n"
+"Error rebooting server\n"
+msgstr ""
+"\n"
+"Fehler beim Neustarten des Servers\n"
+
+msgid ""
+"\n"
+"Error rebuilding server"
+msgstr ""
+"\n"
+"Fehler bei der Wiederherstellung des Servers"
+
+msgid ""
+"\n"
+"Error resizing server"
+msgstr ""
+"\n"
+"Fehler bei der Größenänderung des Servers"
+
+msgid ""
+"\n"
+"Reboot complete\n"
+msgstr ""
+"\n"
+"Neustart abgeschlossen\n"
+
+msgid "Add a property to <name> (repeat option to set multiple properties)"
+msgstr ""
+"Fügen Sie eine Eigenschaft zu <Name> hinzu (wiederholen Sie die Option, um "
+"mehrere Eigenschaften festzulegen)"
+
+msgid "Allow disk over-commit on the destination host"
+msgstr "Festplattenüberladung auf dem Zielhost erlauben"
+
+msgid "Complete\n"
+msgstr "Fertig\n"
+
+msgid "Confirm server resize is complete"
+msgstr "Bestätigen Sie, ob die Größenänderung des Servers abgeschlossen ist"
+
+msgid ""
+"Create a NIC on the server. Specify option multiple times to create multiple "
+"NICs. Either net-id or port-id must be provided, but not both. net-id: "
+"attach NIC to network with this UUID, port-id: attach NIC to port with this "
+"UUID, v4-fixed-ip: IPv4 fixed address for NIC (optional), v6-fixed-ip: IPv6 "
+"fixed address for NIC (optional)."
+msgstr ""
+"Erstellen Sie ein NIC auf dem Server. Geben Sie die Option mehrfach an, um "
+"mehrere NICs zu erstellen. Entweder net-id oder port-id müssen "
+"bereitgestellt werden, aber nicht beide. net-id: NIC an Netzwerk mit dieser "
+"UUID binden, port-id: NIC an Port mit dieser UUID binden, v4-fixed-ip: Feste "
+"IPv4-Adresse für NIC (optional), v6-fixed-ip: Feste IPv6-Adresse für NIC "
+"(optional)."
+
+msgid ""
+"Create credentials for user (name or ID; default: current authenticated user)"
+msgstr ""
+"Anmeldedaten für Benutzer erstellen (Name oder Kennung; Standard: aktuell "
+"authentifizierter Benutzer)"
+
+msgid ""
+"Create credentials in project (name or ID; default: current authenticated "
+"project)"
+msgstr ""
+"Anmeldedaten in Projekt erstellen (Name oder Kennung; Standard: aktuell "
+"authentifiziertes Projekt)"
+
+msgid "Credentials access key"
+msgstr "Anmeldedaten-Zugriffsschlüssel"
+
+msgid "Default project (name or ID)"
+msgstr "Standardprojekt (Name oder Kennung)"
+
+msgid "Delete credentials for user (name or ID)"
+msgstr "Anmeldedaten für Benutzer löschen (name or ID)"
+
+msgid "Destination port (ssh -p option)"
+msgstr "Zielport (ssh -p Option)"
+
+msgid "Disable project"
+msgstr "Projekt deaktivieren"
+
+msgid "Disable user"
+msgstr "Benutzer deaktivieren"
+
+msgid "Display server diagnostics information"
+msgstr "Serverdiagnoseinformationen anzeigen"
+
+msgid "Do not over-commit disk on the destination host (default)"
+msgstr "Festplatte auf dem Zielhost nicht überladen (Standard)"
+
+msgid "Enable project"
+msgstr "Projekt aktivieren"
+
+msgid "Enable project (default)"
+msgstr "Projekt aktivieren (Standardeinstellung)"
+
+msgid "Enable user (default)"
+msgstr "Benutzer aktivieren (Standardeinstellung)"
+
+msgid "Endpoint ID to delete"
+msgstr "Zu löschende Endpunktkennung"
+
+msgid "Endpoint ID to display"
+msgstr "Anzuzeigende Endpunktkennung"
+
+#, python-format
+msgid "Error creating server snapshot: %s"
+msgstr "Fehler beim Erstellen der Server-Schattenkopie: %s"
+
+#, python-format
+msgid "Error creating server: %s"
+msgstr "Fehler beim Erstellen des Servers: %s"
+
+#, python-format
+msgid "Error deleting server: %s"
+msgstr "Fehler beim Löschen des Servers: %s"
+
+msgid "Error retrieving diagnostics data"
+msgstr "Fehler beim Abrufen der Diagnosedaten"
+
+msgid "File to inject into image before boot (repeat for multiple files)"
+msgstr ""
+"Vor dem Start auf diesem Abbild einzufügende Datei (für mehrere Dateien "
+"wiederholen)"
+
+msgid "Filter by parent region ID"
+msgstr "Nach übergeordneter Regionskennung filtern"
+
+msgid "Filter list by user (name or ID)"
+msgstr "Liste nach Benutzer filtern (Name oder Kennung)"
+
+msgid "Filter users by <project> (name or ID)"
+msgstr "Benutzer nach <project> filtern (Name oder Kennung)"
+
+msgid "Filter users by project (name or ID)"
+msgstr "Benutzer nach Projekt filtern (Name oder Kennung)"
+
+msgid "Hints for the scheduler (optional extension)"
+msgstr "Hinweise für den Planer (optionale Erweiterung)"
+
+msgid "Include <project> (name or ID)"
+msgstr "<project> miteinbeziehen (Name oder Kennung)"
+
+msgid "Include <user> (name or ID)"
+msgstr "<user> miteinbeziehen (Name oder Kennung)"
+
+msgid "Include all projects (admin only)"
+msgstr "Alle Projekte miteinbeziehen (nur Administrator)"
+
+msgid "Keypair to inject into this server (optional extension)"
+msgstr "In diesem Server einzufügendes Schlüsselpaar (optionale Erweiterung)"
+
+msgid "List additional fields in output"
+msgstr "Zusätzliche Felder in der Ausgabe auflisten"
+
+msgid "Login name (ssh -l option)"
+msgstr "Anmeldename (ssh -l Option)"
+
+msgid ""
+"Map block devices; map is <id>:<type>:<size(GB)>:<delete_on_terminate> "
+"(optional extension)"
+msgstr ""
+"Blockorientierte Geräte abbilden; Abbildung ist <Kennung>:<Typ>:<Größe(GB)>:"
+"<beim_Beenden_löschen> (optionale Erweiterung)"
+
+msgid "Maximum number of servers to launch (default=1)"
+msgstr "Maximale Anzahl der zu startenden Server (Standard=1)"
+
+msgid "Minimum number of servers to launch (default=1)"
+msgstr "Minimale Anzahl der zu startenden Server (Standard=1)"
+
+msgid "Name of new image (default is server name)"
+msgstr "Name des neuen Abbilds (Servername ist Standard)"
+
+msgid "Name or ID of security group to remove from server"
+msgstr "Name oder Kennung der vom Server zu entfernenden Sicherheitsgruppe"
+
+msgid "Name or ID of server to use"
+msgstr "Name oder Kennung des zu verwendenden Servers"
+
+msgid "New endpoint admin URL"
+msgstr "Administrator-URL des neuen Endpunktes"
+
+msgid "New endpoint internal URL"
+msgstr "Interne URL des neuen Endpunktes"
+
+msgid "New endpoint public URL (required)"
+msgstr "Öffentliche URL des neuen Endpunktes (erforderlich)"
+
+msgid "New endpoint region ID"
+msgstr "Neue Endpunkt-Regionskennung"
+
+msgid "New endpoint service (name or ID)"
+msgstr "Neuer Endpunktdienst (Name oder Kennung)"
+
+msgid "New parent region ID"
+msgstr "Neue übergeordnete Regionskennung"
+
+msgid "New password: "
+msgstr "Neues Passwort:"
+
+msgid "New project name"
+msgstr "Name des neuen Projekts"
+
+msgid "New region ID"
+msgstr "Neue Regionskennung"
+
+msgid "New region description"
+msgstr "Beschreibung des neuen Bereichs"
+
+msgid "New role name"
+msgstr "Name der neuen Rolle"
+
+msgid "New server name"
+msgstr "Neuer Servername"
+
+msgid "New service description"
+msgstr "Beschreibung des neuen Dienstes"
+
+msgid "New service name"
+msgstr "Name des neuen Dienstes"
+
+msgid "New service type (compute, image, identity, volume, etc)"
+msgstr "Neuer Diensttyp (Berechnen, Abbild, Identität, Datenträger, usw.)"
+
+msgid "New user name"
+msgstr "Neuer Benutzername"
+
+#, python-format
+msgid "No service catalog with a type, name or ID of '%s' exists."
+msgstr "Kein Dienstkatalog mit Typ, Namen oder Kennung von '%s' ist vorhanden."
+
+msgid "Only return instances that match the reservation"
+msgstr "Nur Instanzen zurückgeben, die der Einschränkung entsprechen"
+
+msgid "Options in ssh_config(5) format (ssh -o option)"
+msgstr "Optionen im ssh_config(5)-Format (ssh -o Option)"
+
+msgid "Parent region ID"
+msgstr "Übergeordnete Regionskennung"
+
+msgid "Passwords do not match, password unchanged"
+msgstr "Passwörter stimmen nicht überein, Passwort unverändert"
+
+msgid "Perform a block live migration"
+msgstr "Blockorientierte Live-Migration ausführen"
+
+msgid "Perform a hard reboot"
+msgstr "Harten Neustart ausführen"
+
+msgid "Perform a shared live migration (default)"
+msgstr "Gemeinsame Live-Migration ausführen (Standard)"
+
+msgid "Perform a soft reboot"
+msgstr "Weichen Neustart ausführen"
+
+msgid "Private key file (ssh -i option)"
+msgstr "Private Schlüsseldatei (ssh -i Option)"
+
+msgid "Project description"
+msgstr "Projektbeschreibung"
+
+msgid "Project must be specified"
+msgstr "Projekt muss angegeben werden"
+
+msgid "Project to display (name or ID)"
+msgstr "Anzuzeigendes Projekt (Name oder Kennung)"
+
+msgid "Project to modify (name or ID)"
+msgstr "Zu änderndes Projekt (Name oder Kennung)"
+
+msgid "Project(s) to delete (name or ID)"
+msgstr "Zu löschende(s) Projekt(e) (Name oder Kennung)"
+
+msgid "Prompt interactively for password"
+msgstr "Interaktiv nach dem Passwort abfragen"
+
+msgid "Property key to remove from server (repeat to unset multiple values)"
+msgstr ""
+"Vom Server zu entfernender Eigenschaftsschlüssel (zum Aufheben von mehreren "
+"Werten wiederholen)"
+
+msgid ""
+"Property to add/change for this server (repeat option to set multiple "
+"properties)"
+msgstr ""
+"Zu hinzufügende/ändernde Eigenschaft für diesen Server (wiederholen Sie die "
+"Option, um mehrere Eigenschaften festzulegen)"
+
+msgid "Region ID to delete"
+msgstr "Zu löschende Regionskennung"
+
+msgid "Region to display"
+msgstr "Anzuzeigende Region"
+
+msgid "Region to modify"
+msgstr "Zu ändernde Region"
+
+msgid "Regular expression to match IP addresses"
+msgstr "Regulärer Ausdruck zum Abgleichen mit IP-Adressen"
+
+msgid "Regular expression to match IPv6 addresses"
+msgstr "Regulärer Ausdruck zum Abgleichen mit IPv6-Adressen"
+
+msgid "Regular expression to match instance name (admin only)"
+msgstr ""
+"Regulärer Ausdruck zum Abgleichen des Instanznamens (nur Administrator) "
+
+msgid "Regular expression to match names"
+msgstr "Regulärer Ausdruck zum Abgleichen mit Namen"
+
+msgid "Resize server to specified flavor"
+msgstr "Servergröße auf angegebene Variante ändern"
+
+msgid "Restore server state before resize"
+msgstr "Serverstatus vor der Größenänderung wiederherstellen"
+
+msgid "Return existing domain"
+msgstr "Vorhandene Domäne zurückgeben"
+
+msgid "Return existing group"
+msgstr "Vorhandene Gruppe zurückgeben"
+
+msgid "Return existing project"
+msgstr "Vorhandenes Projekt zurückgeben"
+
+msgid "Return existing role"
+msgstr "Vorhandene Rolle zurückgeben"
+
+msgid "Return existing user"
+msgstr "Vorhandenen Benutzer zurückgeben"
+
+msgid "Retype new password: "
+msgstr "Neues Passwort erneut eingeben:"
+
+msgid "Role to add to <project>:<user> (name or ID)"
+msgstr "Zu <project>:<user> hinzuzufügende Rolle (Name oder Kennung)"
+
+msgid "Role to display (name or ID)"
+msgstr "Anzuzeigende Rolle (Name oder Kennung)"
+
+msgid "Role to remove (name or ID)"
+msgstr "Zu entfernende Rolle (Name oder Kennung)"
+
+msgid "Role(s) to delete (name or ID)"
+msgstr "Zu löschende Rolle(n) (Name oder Kennung)"
+
+msgid "Search by hostname"
+msgstr "Nach Hostname suchen"
+
+msgid "Search by server status"
+msgstr "Nach Serverstatus suchen"
+
+msgid "Search by user (admin only) (name or ID)"
+msgstr "Nach Benutzer suchen (nur Administrator) (Name oder Kennung)"
+
+msgid "Security group to add (name or ID)"
+msgstr "Zu hinzufügende Sicherheitsgruppe (Name oder Kennung)"
+
+msgid "Select an availability zone for the server"
+msgstr "Wählen Sie eine Verfügbarkeitszone für den Server aus"
+
+msgid "Server (name or ID)"
+msgstr "Server (Name oder Kennung)"
+
+msgid "Server internal device name for volume"
+msgstr "Serverinterner Gerätename für Datenträger"
+
+msgid "Server(s) to delete (name or ID)"
+msgstr "Zu löschende(r) Server (Name oder Kennung)"
+
+msgid "Service to delete (name or ID)"
+msgstr "Zu löschender Dienst (Name oder Kennung)"
+
+msgid "Service to display (type or name)"
+msgstr "Anzuzeigender Dienst (Typ oder Name)"
+
+msgid "Service to display (type, name or ID)"
+msgstr "Anzuzeigender Dienst (Typ, Name oder Kennung)"
+
+msgid "Set a project property (repeat option to set multiple properties)"
+msgstr ""
+"Legen Sie eine Projekteigenschaft fest (wiederholen Sie die Option, um "
+"mehrere Eigenschaften festzulegen)"
+
+msgid "Set a property on this server (repeat for multiple values)"
+msgstr ""
+"Legen Sie eine Eigenschaft auf diesem Server fest (für mehrere Werte "
+"wiederholen)"
+
+msgid ""
+"Set a scope, such as a project or domain, set a project scope with --os-"
+"project-name, OS_PROJECT_NAME or auth.project_name, set a domain scope with "
+"--os-domain-name, OS_DOMAIN_NAME or auth.domain_name"
+msgstr ""
+"Setzen Sie eine Eigenschaft, wie Projekt oder Domäne, setzen Sie eine "
+"Projekteigenschaft mit --os-project-name, OS_PROJECT_NAME oder auth."
+"project_name, setzen Sie eine Dömaneneigenschaft mit --os-domain-name, "
+"OS_DOMAIN_NAME oder auth.domain_name."
+
+msgid ""
+"Set a service AUTH_URL, with --os-auth-url, OS_AUTH_URL or auth.auth_url\n"
+msgstr ""
+"Legen Sie eine Dienst-AUTH_URL mit --os-auth-url, OS_AUTH_URL oder auth."
+"auth_url fest\n"
+
+msgid "Set a service URL, with --os-url, OS_URL or auth.url\n"
+msgstr "Legen Sie eine Dienst-URL mit --os-url, OS_URL oder auth.url fest\n"
+
+msgid "Set a token with --os-token, OS_TOKEN or auth.token\n"
+msgstr "Legen Sie einen Token mit --os-token, OS_TOKEN oder auth.token fest\n"
+
+msgid "Set a username with --os-username, OS_USERNAME, or auth.username\n"
+msgstr ""
+"Legen Sie einen Benutzernamen mit --os-username, OS_USERNAME oder auth."
+"username fest\n"
+
+msgid ""
+"Set an authentication URL, with --os-auth-url, OS_AUTH_URL or auth.auth_url\n"
+msgstr ""
+"Legen Sie eine Authentifizierungs-URL mit --os-auth-url, OS_AUTH_URL oder "
+"auth.auth_url fest\n"
+
+msgid "Set default project (name or ID)"
+msgstr "Standardprojekt festlegen (Name oder Kennung)"
+
+msgid "Set new root password (interactive only)"
+msgstr "Neues root-Passwort festlegen (Nur interaktiv)"
+
+msgid "Set project description"
+msgstr "Projektbeschreibung festlegen"
+
+msgid "Set project name"
+msgstr "Projektname festlegen"
+
+msgid "Set user email address"
+msgstr "E-Mail-Adresse des Benutzers festlegen"
+
+msgid "Set user name"
+msgstr "Benutzername festlegen"
+
+msgid "Set user password"
+msgstr "Benutzerpasswort festlegen"
+
+msgid "Show credentials for user (name or ID)"
+msgstr "Anmeldedaten für Benutzer anzeigen (name or ID)"
+
+msgid "Show service catalog information"
+msgstr "Dienstkataloginformation anzeigen"
+
+msgid "Target hostname"
+msgstr "Zielhostname"
+
+msgid ""
+"The argument --type is deprecated, use service create --name <service-name> "
+"type instead."
+msgstr ""
+"Das Argument --type ist veraltet, verwenden Sie stattdessen service create --"
+"name <Dienstname> type."
+
+msgid "Token to be deleted"
+msgstr "Zu löschender Token"
+
+msgid "Use only IPv4 addresses"
+msgstr "Nur IPv4-Adressen verwenden"
+
+msgid "Use only IPv6 addresses"
+msgstr "Nur IPv6-Adressen verwenden"
+
+msgid "Use other IP address (public, private, etc)"
+msgstr "Andere IP-Adresse verwenden (öffentlich, privat, usw.)"
+
+msgid "Use private IP address"
+msgstr "Private IP-Adresse verwenden"
+
+msgid "Use public IP address"
+msgstr "Öffentliche IP-Adresse verwenden"
+
+msgid ""
+"Use specified volume as the config drive, or 'True' to use an ephemeral drive"
+msgstr ""
+"Benutzerdefinierter Datenträger als Konfigurationslaufwerk oder 'True', um "
+"ein flüchtiges Laufwerk zu verwenden"
+
+msgid "User data file to serve from the metadata server"
+msgstr "Vom Metadatenserver anzubietende Benutzerdatendatei"
+
+msgid "User must be specified"
+msgstr "Benutzer muss angegeben werden"
+
+msgid "User to change (name or ID)"
+msgstr "Zu ändernder Benutzer (Name oder Kennung)"
+
+msgid "User to display (name or ID)"
+msgstr "Anzuzeigender Benutzer (Name oder Kennung)"
+
+msgid "User to list (name or ID)"
+msgstr "Aufzulistender Benutzer (Name oder Kennung)"
+
+msgid "User(s) to delete (name or ID)"
+msgstr "Zu löschende(r) Benutzer (Name oder Kennung)"
+
+msgid "Volume to add (name or ID)"
+msgstr "Zu hinzufügender Datenträger (Name oder Kennung)"
+
+msgid "Volume to remove (name or ID)"
+msgstr "Zu entfernender Datenträger (Name oder Kennung)"
+
+msgid "Wait for build to complete"
+msgstr "Warten Sie, bis die Herstellung abgeschlossen ist"
+
+msgid "Wait for delete to complete"
+msgstr "Warten Sie, bis das Löschen abgeschlossen ist"
+
+msgid "Wait for image create to complete"
+msgstr "Warten Sie, bis die Abbilderstellung abgeschlossen ist"
+
+msgid "Wait for reboot to complete"
+msgstr "Warten Sie, bis der Neustart abgeschlossen ist"
+
+msgid "Wait for rebuild to complete"
+msgstr "Warten Sie, bis die Wiederherstellung abgeschlossen ist"
+
+msgid "Wait for resize to complete"
+msgstr "Warten Sie, bis die Größenänderung abgeschlossen ist"
+
+msgid "either net-id or port-id should be specified but not both"
+msgstr "entweder net-id oder port-id sollten angegeben sein, aber nicht beide"
+
+msgid "max instances should be > 0"
+msgstr "max. Instanzen sollten > 0 sein"
+
+msgid "min instances should be <= max instances"
+msgstr "min. Instanzen sollten <= max. Instanzen sein"
+
+msgid "min instances should be > 0"
+msgstr "min. Instanzen sollten > 0 sein"
diff --git a/openstackclient/locale/openstackclient.pot b/openstackclient/locale/openstackclient.pot
new file mode 100644
index 00000000..afc89266
--- /dev/null
+++ b/openstackclient/locale/openstackclient.pot
@@ -0,0 +1,829 @@
+# Translations template for python-openstackclient.
+# Copyright (C) 2016 ORGANIZATION
+# This file is distributed under the same license as the
+# python-openstackclient project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: python-openstackclient 2.0.1.dev168\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2016-01-19 06:03+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.2.0\n"
+
+#: openstackclient/api/auth.py:144
+msgid "Set a username with --os-username, OS_USERNAME, or auth.username\n"
+msgstr ""
+
+#: openstackclient/api/auth.py:147
+msgid ""
+"Set an authentication URL, with --os-auth-url, OS_AUTH_URL or "
+"auth.auth_url\n"
+msgstr ""
+
+#: openstackclient/api/auth.py:155
+msgid ""
+"Set a scope, such as a project or domain, set a project scope with --os-"
+"project-name, OS_PROJECT_NAME or auth.project_name, set a domain scope "
+"with --os-domain-name, OS_DOMAIN_NAME or auth.domain_name"
+msgstr ""
+
+#: openstackclient/api/auth.py:161 openstackclient/api/auth.py:167
+msgid "Set a token with --os-token, OS_TOKEN or auth.token\n"
+msgstr ""
+
+#: openstackclient/api/auth.py:163
+msgid "Set a service AUTH_URL, with --os-auth-url, OS_AUTH_URL or auth.auth_url\n"
+msgstr ""
+
+#: openstackclient/api/auth.py:169
+msgid "Set a service URL, with --os-url, OS_URL or auth.url\n"
+msgstr ""
+
+#: openstackclient/compute/v2/availability_zone.py:72
+#: openstackclient/compute/v2/server.py:737
+#: openstackclient/identity/v2_0/endpoint.py:114
+#: openstackclient/identity/v2_0/project.py:145
+#: openstackclient/identity/v2_0/service.py:128
+#: openstackclient/identity/v2_0/user.py:174
+msgid "List additional fields in output"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:183
+#: openstackclient/compute/v2/server.py:219
+#: openstackclient/compute/v2/server.py:569
+#: openstackclient/compute/v2/server.py:923
+#: openstackclient/compute/v2/server.py:1031
+#: openstackclient/compute/v2/server.py:1086
+#: openstackclient/compute/v2/server.py:1179
+#: openstackclient/compute/v2/server.py:1219
+#: openstackclient/compute/v2/server.py:1245
+#: openstackclient/compute/v2/server.py:1336
+#: openstackclient/compute/v2/server.py:1420
+#: openstackclient/compute/v2/server.py:1457
+#: openstackclient/compute/v2/server.py:1732
+#: openstackclient/compute/v2/server.py:1756
+msgid "Server (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:188
+msgid "Security group to add (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:224
+msgid "Volume to add (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:229
+msgid "Server internal device name for volume"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:265
+#: openstackclient/compute/v2/server.py:1341
+msgid "New server name"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:273
+msgid "Create server from this image (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:278
+msgid "Create server from this volume (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:284
+msgid "Create server with this flavor (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:291
+msgid ""
+"Security group to assign to this server (name or ID) (repeat for multiple"
+" groups)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:297
+msgid "Keypair to inject into this server (optional extension)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:303
+msgid "Set a property on this server (repeat for multiple values)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:311
+msgid "File to inject into image before boot (repeat for multiple files)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:317
+msgid "User data file to serve from the metadata server"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:322
+msgid "Select an availability zone for the server"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:329
+msgid ""
+"Map block devices; map is <id>:<type>:<size(GB)>:<delete_on_terminate> "
+"(optional extension)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:339
+msgid ""
+"Create a NIC on the server. Specify option multiple times to create "
+"multiple NICs. Either net-id or port-id must be provided, but not both. "
+"net-id: attach NIC to network with this UUID, port-id: attach NIC to port"
+" with this UUID, v4-fixed-ip: IPv4 fixed address for NIC (optional), v6"
+"-fixed-ip: IPv6 fixed address for NIC (optional)."
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:352
+msgid "Hints for the scheduler (optional extension)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:358
+msgid ""
+"Use specified volume as the config drive, or 'True' to use an ephemeral "
+"drive"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:366
+msgid "Minimum number of servers to launch (default=1)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:373
+msgid "Maximum number of servers to launch (default=1)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:378
+msgid "Wait for build to complete"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:418
+msgid "min instances should be <= max instances"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:421
+msgid "min instances should be > 0"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:424
+msgid "max instances should be > 0"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:453
+msgid "Volume name or ID must be specified if --block-device-mapping is specified"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:465
+msgid "either net-id or port-id should be specified but not both"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:485
+msgid "can't create server with port specified since network endpoint not enabled"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:550
+#, python-format
+msgid "Error creating server: %s"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:552
+msgid ""
+"\n"
+"Error creating server"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:574
+msgid "Name of new image (default is server name)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:579
+msgid "Wait for image create to complete"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:609
+#, python-format
+msgid "Error creating server snapshot: %s"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:611
+msgid ""
+"\n"
+"Error creating server snapshot"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:633
+msgid "Server(s) to delete (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:638
+msgid "Wait for delete to complete"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:657
+#, python-format
+msgid "Error deleting server: %s"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:659
+msgid ""
+"\n"
+"Error deleting server"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:673
+msgid "Only return instances that match the reservation"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:678
+msgid "Regular expression to match IP addresses"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:683
+msgid "Regular expression to match IPv6 addresses"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:688
+msgid "Regular expression to match names"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:693
+msgid "Regular expression to match instance name (admin only)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:699
+msgid "Search by server status"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:704
+msgid "Search by flavor (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:709
+msgid "Search by image (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:714
+msgid "Search by hostname"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:720
+msgid "Include all projects (admin only)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:730
+msgid "Search by user (admin only) (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:888
+msgid "Server(s) to lock (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:928
+msgid "Target hostname"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:936
+msgid "Perform a shared live migration (default)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:942
+msgid "Perform a block live migration"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:949
+msgid "Allow disk over-commit on the destination host"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:956
+msgid "Do not over-commit disk on the destination host (default)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:962
+#: openstackclient/compute/v2/server.py:1265
+msgid "Wait for resize to complete"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:990
+#: openstackclient/compute/v2/server.py:1290
+msgid "Complete\n"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:992
+msgid ""
+"\n"
+"Error migrating server"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1007
+msgid "Server(s) to pause (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1040
+msgid "Perform a hard reboot"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1048
+msgid "Perform a soft reboot"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1053
+msgid "Wait for reboot to complete"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1070
+msgid ""
+"\n"
+"Reboot complete\n"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1072
+msgid ""
+"\n"
+"Error rebooting server\n"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1091
+msgid ""
+"Recreate server from the specified image (name or ID). Defaults to the "
+"currently used one."
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1102
+msgid "Wait for rebuild to complete"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1124
+msgid ""
+"\n"
+"Complete\n"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1126
+msgid ""
+"\n"
+"Error rebuilding server"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1143
+msgid "Name or ID of server to use"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1148
+msgid "Name or ID of security group to remove from server"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1184
+msgid "Volume to remove (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1250
+msgid "Resize server to specified flavor"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1255
+msgid "Confirm server resize is complete"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1260
+msgid "Restore server state before resize"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1292
+msgid ""
+"\n"
+"Error resizing server"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1311
+msgid "Server(s) to resume (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1346
+msgid "Set new root password (interactive only)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1352
+msgid ""
+"Property to add/change for this server (repeat option to set multiple "
+"properties)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1376
+msgid "New password: "
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1377
+msgid "Retype new password: "
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1381
+msgid "Passwords do not match, password unchanged"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1396
+msgid "Server(s) to shelve (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1426
+msgid "Display server diagnostics information"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1439
+msgid "Error retrieving diagnostics data"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1462
+msgid "Login name (ssh -l option)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1474
+msgid "Destination port (ssh -p option)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1486
+msgid "Private key file (ssh -i option)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1497
+msgid "Options in ssh_config(5) format (ssh -o option)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1511
+msgid "Use only IPv4 addresses"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1518
+msgid "Use only IPv6 addresses"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1527
+msgid "Use public IP address"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1535
+msgid "Use private IP address"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1542
+msgid "Use other IP address (public, private, etc)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1605
+msgid "Server(s) to start (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1630
+msgid "Server(s) to stop (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1655
+msgid "Server(s) to suspend (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1681
+msgid "Server(s) to unlock (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1707
+msgid "Server(s) to unpause (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1763
+msgid "Property key to remove from server (repeat to unset multiple values)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1794
+msgid "Server(s) to unshelve (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/catalog.py:75
+#: openstackclient/identity/v3/catalog.py:72
+msgid "Service to display (type or name)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/ec2creds.py:40
+#: openstackclient/identity/v3/ec2creds.py:65
+msgid ""
+"Create credentials in project (name or ID; default: current authenticated"
+" project)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/ec2creds.py:48
+#: openstackclient/identity/v3/ec2creds.py:73
+msgid ""
+"Create credentials for user (name or ID; default: current authenticated "
+"user)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/ec2creds.py:99
+#: openstackclient/identity/v2_0/ec2creds.py:172
+#: openstackclient/identity/v3/ec2creds.py:129
+#: openstackclient/identity/v3/ec2creds.py:187
+msgid "Credentials access key"
+msgstr ""
+
+#: openstackclient/identity/v2_0/ec2creds.py:104
+#: openstackclient/identity/v3/ec2creds.py:134
+msgid "Delete credentials for user (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/ec2creds.py:134
+#: openstackclient/identity/v3/ec2creds.py:156
+msgid "Filter list by user (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/ec2creds.py:177
+#: openstackclient/identity/v3/ec2creds.py:192
+msgid "Show credentials for user (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/endpoint.py:40
+msgid "New endpoint service (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/endpoint.py:46
+msgid "New endpoint public URL (required)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/endpoint.py:51
+msgid "New endpoint admin URL"
+msgstr ""
+
+#: openstackclient/identity/v2_0/endpoint.py:56
+msgid "New endpoint internal URL"
+msgstr ""
+
+#: openstackclient/identity/v2_0/endpoint.py:61
+msgid "New endpoint region ID"
+msgstr ""
+
+#: openstackclient/identity/v2_0/endpoint.py:93
+msgid "Endpoint ID to delete"
+msgstr ""
+
+#: openstackclient/identity/v2_0/endpoint.py:149
+msgid "Endpoint ID to display"
+msgstr ""
+
+#: openstackclient/identity/v2_0/project.py:41
+msgid "New project name"
+msgstr ""
+
+#: openstackclient/identity/v2_0/project.py:46
+msgid "Project description"
+msgstr ""
+
+#: openstackclient/identity/v2_0/project.py:52
+msgid "Enable project (default)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/project.py:57
+#: openstackclient/identity/v2_0/project.py:194
+msgid "Disable project"
+msgstr ""
+
+#: openstackclient/identity/v2_0/project.py:63
+msgid "Add a property to <name> (repeat option to set multiple properties)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/project.py:69
+#: openstackclient/identity/v3/project.py:80
+msgid "Return existing project"
+msgstr ""
+
+#: openstackclient/identity/v2_0/project.py:117
+msgid "Project(s) to delete (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/project.py:173
+#: openstackclient/identity/v2_0/project.py:313
+msgid "Project to modify (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/project.py:178
+msgid "Set project name"
+msgstr ""
+
+#: openstackclient/identity/v2_0/project.py:183
+msgid "Set project description"
+msgstr ""
+
+#: openstackclient/identity/v2_0/project.py:189
+msgid "Enable project"
+msgstr ""
+
+#: openstackclient/identity/v2_0/project.py:200
+msgid "Set a project property (repeat option to set multiple properties)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/project.py:253
+msgid "Project to display (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/project.py:320
+msgid "Unset a project property (repeat option to unset multiple properties)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/role.py:41
+msgid "Role to add to <project>:<user> (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/role.py:47
+#: openstackclient/identity/v2_0/role.py:309
+msgid "Include <project> (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/role.py:53
+#: openstackclient/identity/v2_0/role.py:315
+msgid "Include <user> (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/role.py:87
+msgid "New role name"
+msgstr ""
+
+#: openstackclient/identity/v2_0/role.py:92
+#: openstackclient/identity/v3/role.py:165
+msgid "Return existing role"
+msgstr ""
+
+#: openstackclient/identity/v2_0/role.py:127
+msgid "Role(s) to delete (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/role.py:194
+#: openstackclient/identity/v2_0/role.py:257
+msgid "Project must be specified"
+msgstr ""
+
+#: openstackclient/identity/v2_0/role.py:208
+#: openstackclient/identity/v2_0/role.py:263
+msgid "User must be specified"
+msgstr ""
+
+#: openstackclient/identity/v2_0/role.py:236
+msgid "User to list (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/role.py:241
+msgid "Filter users by <project> (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/role.py:303
+msgid "Role to remove (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/role.py:344
+msgid "Role to display (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/service.py:42
+msgid "New service type (compute, image, identity, volume, etc)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/service.py:53
+msgid "New service name"
+msgstr ""
+
+#: openstackclient/identity/v2_0/service.py:58
+msgid "New service description"
+msgstr ""
+
+#: openstackclient/identity/v2_0/service.py:78
+msgid ""
+"The argument --type is deprecated, use service create --name <service-"
+"name> type instead."
+msgstr ""
+
+#: openstackclient/identity/v2_0/service.py:105
+msgid "Service to delete (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/service.py:156
+msgid "Service to display (type, name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/service.py:162
+msgid "Show service catalog information"
+msgstr ""
+
+#: openstackclient/identity/v2_0/service.py:180
+#, python-format
+msgid "No service catalog with a type, name or ID of '%s' exists."
+msgstr ""
+
+#: openstackclient/identity/v2_0/token.py:55
+msgid "Token to be deleted"
+msgstr ""
+
+#: openstackclient/identity/v2_0/user.py:40
+msgid "New user name"
+msgstr ""
+
+#: openstackclient/identity/v2_0/user.py:45
+msgid "Default project (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/user.py:50
+#: openstackclient/identity/v2_0/user.py:273
+msgid "Set user password"
+msgstr ""
+
+#: openstackclient/identity/v2_0/user.py:56
+#: openstackclient/identity/v2_0/user.py:279
+msgid "Prompt interactively for password"
+msgstr ""
+
+#: openstackclient/identity/v2_0/user.py:61
+#: openstackclient/identity/v2_0/user.py:284
+msgid "Set user email address"
+msgstr ""
+
+#: openstackclient/identity/v2_0/user.py:67
+#: openstackclient/identity/v2_0/user.py:290
+msgid "Enable user (default)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/user.py:72
+#: openstackclient/identity/v2_0/user.py:295
+msgid "Disable user"
+msgstr ""
+
+#: openstackclient/identity/v2_0/user.py:77
+#: openstackclient/identity/v3/user.py:90
+msgid "Return existing user"
+msgstr ""
+
+#: openstackclient/identity/v2_0/user.py:141
+msgid "User(s) to delete (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/user.py:168
+msgid "Filter users by project (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/user.py:258
+msgid "User to change (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/user.py:263
+msgid "Set user name"
+msgstr ""
+
+#: openstackclient/identity/v2_0/user.py:268
+msgid "Set default project (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v2_0/user.py:361
+msgid "User to display (name or ID)"
+msgstr ""
+
+#: openstackclient/identity/v3/domain.py:62
+msgid "Return existing domain"
+msgstr ""
+
+#: openstackclient/identity/v3/group.py:141
+msgid "Return existing group"
+msgstr ""
+
+#: openstackclient/identity/v3/region.py:39
+msgid "New region ID"
+msgstr ""
+
+#: openstackclient/identity/v3/region.py:44
+msgid "Parent region ID"
+msgstr ""
+
+#: openstackclient/identity/v3/region.py:49
+#: openstackclient/identity/v3/region.py:144
+msgid "New region description"
+msgstr ""
+
+#: openstackclient/identity/v3/region.py:79
+msgid "Region ID to delete"
+msgstr ""
+
+#: openstackclient/identity/v3/region.py:101
+msgid "Filter by parent region ID"
+msgstr ""
+
+#: openstackclient/identity/v3/region.py:134
+msgid "Region to modify"
+msgstr ""
+
+#: openstackclient/identity/v3/region.py:139
+msgid "New parent region ID"
+msgstr ""
+
+#: openstackclient/identity/v3/region.py:175
+msgid "Region to display"
+msgstr ""
+
diff --git a/openstackclient/locale/zh_TW/LC_MESSAGES/openstackclient.po b/openstackclient/locale/zh_TW/LC_MESSAGES/openstackclient.po
new file mode 100644
index 00000000..26032666
--- /dev/null
+++ b/openstackclient/locale/zh_TW/LC_MESSAGES/openstackclient.po
@@ -0,0 +1,495 @@
+# Translations template for python-openstackclient.
+# Copyright (C) 2015 ORGANIZATION
+# This file is distributed under the same license as the
+# python-openstackclient project.
+#
+# Translators:
+# OpenStack Infra <zanata@openstack.org>, 2015. #zanata
+msgid ""
+msgstr ""
+"Project-Id-Version: python-openstackclient 2.0.1.dev168\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2016-01-19 02:20+0000\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"PO-Revision-Date: 2015-06-14 06:41+0000\n"
+"Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
+"Language: zh-TW\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"Generated-By: Babel 2.0\n"
+"X-Generator: Zanata 3.7.3\n"
+"Language-Team: Chinese (Taiwan)\n"
+
+msgid ""
+"\n"
+"Complete\n"
+msgstr ""
+"\n"
+"完成\n"
+
+msgid ""
+"\n"
+"Error creating server"
+msgstr ""
+"\n"
+"新增雲實例時出錯"
+
+msgid ""
+"\n"
+"Error creating server snapshot"
+msgstr ""
+"\n"
+"新增雲實例即時存檔時出錯"
+
+msgid ""
+"\n"
+"Error migrating server"
+msgstr ""
+"\n"
+"轉移雲實例出錯"
+
+msgid ""
+"\n"
+"Error rebooting server\n"
+msgstr ""
+"\n"
+"重開雲實例出錯\n"
+
+msgid ""
+"\n"
+"Error rebuilding server"
+msgstr ""
+"\n"
+"重建雲實例出錯"
+
+msgid ""
+"\n"
+"Error resizing server"
+msgstr ""
+"\n"
+"調整雲實例容量時出錯"
+
+msgid ""
+"\n"
+"Reboot complete\n"
+msgstr ""
+"\n"
+"重開機完成\n"
+
+msgid "Add a property to <name> (repeat option to set multiple properties)"
+msgstr "加入屬性到 <name>(重復這選項來設定多個屬性)"
+
+msgid "Allow disk over-commit on the destination host"
+msgstr "允許目標主機過量使用"
+
+msgid "Complete\n"
+msgstr "完成\n"
+
+msgid "Confirm server resize is complete"
+msgstr "確認調整雲實例容量完成"
+
+msgid "Credentials access key"
+msgstr "憑鑰存取密鑰"
+
+msgid "Default project (name or ID)"
+msgstr "預設專案(名稱或識別號)"
+
+msgid "Destination port (ssh -p option)"
+msgstr "目標埠口(ssh -p 選項)"
+
+msgid "Disable project"
+msgstr "關閉專案"
+
+msgid "Disable user"
+msgstr "關閉用戶"
+
+msgid "Display server diagnostics information"
+msgstr "顯示雲實例診斷資訊"
+
+msgid "Do not over-commit disk on the destination host (default)"
+msgstr "不準目標主機過量使用(預設)"
+
+msgid "Enable project"
+msgstr "啟用專案"
+
+msgid "Enable project (default)"
+msgstr "啟用專案(預設)"
+
+msgid "Enable user (default)"
+msgstr "啟用用戶(預設)"
+
+msgid "Endpoint ID to delete"
+msgstr "要刪除的端點識別號"
+
+msgid "Endpoint ID to display"
+msgstr "要顯示的端點識別號"
+
+#, python-format
+msgid "Error creating server snapshot: %s"
+msgstr "新增雲實例即時存檔時出錯:%s"
+
+#, python-format
+msgid "Error creating server: %s"
+msgstr "新增雲實例時出錯:%s"
+
+msgid "Error retrieving diagnostics data"
+msgstr "獲得診斷資料時出錯"
+
+msgid "File to inject into image before boot (repeat for multiple files)"
+msgstr "在開機前要注入映像檔的檔案(為多個檔案重復指定)"
+
+msgid "Filter by parent region ID"
+msgstr "以父地區識別號來篩選"
+
+msgid "Filter users by <project> (name or ID)"
+msgstr "以 <project> 來篩選用戶(名稱或識別號)"
+
+msgid "Filter users by project (name or ID)"
+msgstr "以專案篩選用戶(名稱或識別號)"
+
+msgid "Hints for the scheduler (optional extension)"
+msgstr "給排程器的提示(選用)"
+
+msgid "Include <project> (name or ID)"
+msgstr "包括 <project>(名稱或識別號)"
+
+msgid "Include <user> (name or ID)"
+msgstr "包括 <user>(名稱或識別號)"
+
+msgid "Include all projects (admin only)"
+msgstr "包括所有的專案(管理員專用)"
+
+msgid "Keypair to inject into this server (optional extension)"
+msgstr "要注入到此伺服器的密鑰對(選用)"
+
+msgid "List additional fields in output"
+msgstr "列出額外的欄位"
+
+msgid "Login name (ssh -l option)"
+msgstr "登入名稱(ssh -l 選項)"
+
+msgid ""
+"Map block devices; map is <id>:<type>:<size(GB)>:<delete_on_terminate> "
+"(optional extension)"
+msgstr ""
+"映射區塊裝置;映射是 <id>:<type>:<size(GB)>:<delete_on_terminate>(選用)"
+
+msgid "Maximum number of servers to launch (default=1)"
+msgstr "最多要發動的雲實例(預設為 1)"
+
+msgid "Minimum number of servers to launch (default=1)"
+msgstr "最少要發動的雲實例(預設為 1)"
+
+msgid "Name of new image (default is server name)"
+msgstr "新映像檔的名稱(預設為雲實例名稱)"
+
+msgid "Name or ID of security group to remove from server"
+msgstr "要從雲實例移除的安全性群組名稱或識別號"
+
+msgid "Name or ID of server to use"
+msgstr "要用的雲實例名稱或識別號"
+
+msgid "New endpoint admin URL"
+msgstr "新端點管理員網址"
+
+msgid "New endpoint internal URL"
+msgstr "新端點內部網址"
+
+msgid "New endpoint public URL (required)"
+msgstr "新端點公開網址(需要)"
+
+msgid "New endpoint region ID"
+msgstr "新端點地區識別號"
+
+msgid "New endpoint service (name or ID)"
+msgstr "新端點伺服器(名稱或識別號)"
+
+msgid "New parent region ID"
+msgstr "新父地區識別號"
+
+msgid "New password: "
+msgstr "新密碼:"
+
+msgid "New project name"
+msgstr "新專案名稱"
+
+msgid "New region ID"
+msgstr "新地區識別號"
+
+msgid "New region description"
+msgstr "新地區描述"
+
+msgid "New role name"
+msgstr "新角色名稱"
+
+msgid "New server name"
+msgstr "新雲實例名稱"
+
+msgid "New service description"
+msgstr "新伺服器描述"
+
+msgid "New service name"
+msgstr "新伺服器名稱"
+
+msgid "New service type (compute, image, identity, volume, etc)"
+msgstr "新伺服器類型(compute、image、identity 或 volume 等等)"
+
+msgid "New user name"
+msgstr "新用戶名稱"
+
+#, python-format
+msgid "No service catalog with a type, name or ID of '%s' exists."
+msgstr "沒有相似「%s」類型、名稱或識別號的伺服器分類。"
+
+msgid "Only return instances that match the reservation"
+msgstr "只回傳要保留的雲實例"
+
+msgid "Options in ssh_config(5) format (ssh -o option)"
+msgstr "ssh_config(5) 格式的選項(ssh -o 選項)"
+
+msgid "Parent region ID"
+msgstr "父地區識別號"
+
+msgid "Passwords do not match, password unchanged"
+msgstr "密碼不一樣,未更換密碼"
+
+msgid "Perform a block live migration"
+msgstr "覆行區塊的即時轉移"
+
+msgid "Perform a hard reboot"
+msgstr "履行強制重開機"
+
+msgid "Perform a shared live migration (default)"
+msgstr "覆行已分享的即時轉移(預設)"
+
+msgid "Perform a soft reboot"
+msgstr "履行重開機"
+
+msgid "Private key file (ssh -i option)"
+msgstr "私鑰檔案(ssh -i 選項)"
+
+msgid "Project description"
+msgstr "專案描述"
+
+msgid "Project must be specified"
+msgstr "必須指定專案"
+
+msgid "Project to display (name or ID)"
+msgstr "要顯示的專案(名稱或識別號)"
+
+msgid "Project to modify (name or ID)"
+msgstr "要更改的專案(名稱或識別號)"
+
+msgid "Project(s) to delete (name or ID)"
+msgstr "要刪除的專案(名稱或識別號)"
+
+msgid "Prompt interactively for password"
+msgstr "為密碼互動提示"
+
+msgid "Property key to remove from server (repeat to unset multiple values)"
+msgstr "要從雲實例上移除的屬性鍵(重復來取消選擇多個值)"
+
+msgid ""
+"Property to add/change for this server (repeat option to set multiple "
+"properties)"
+msgstr "要加入這個雲實例的屬性(重復這選項來設定多個屬性)"
+
+msgid "Region ID to delete"
+msgstr "要刪除的地區識別號"
+
+msgid "Region to display"
+msgstr "要顯示的地區"
+
+msgid "Region to modify"
+msgstr "要更改的地區"
+
+msgid "Regular expression to match IP addresses"
+msgstr "以正規式來匹配 IP 位址"
+
+msgid "Regular expression to match IPv6 addresses"
+msgstr "以正規式來匹配 IPv6 位址"
+
+msgid "Regular expression to match instance name (admin only)"
+msgstr "以正規式來匹配雲實例名稱(管理員專用)"
+
+msgid "Regular expression to match names"
+msgstr "以正規式來匹配名稱"
+
+msgid "Resize server to specified flavor"
+msgstr "調整雲實例容量來符合指定的虛擬硬體樣板"
+
+msgid "Restore server state before resize"
+msgstr "恢復雲實例狀態到未調整容量前"
+
+msgid "Return existing domain"
+msgstr "回傳存在的地域"
+
+msgid "Return existing group"
+msgstr "回傳存在的群組"
+
+msgid "Return existing project"
+msgstr "回傳存在的專案"
+
+msgid "Return existing role"
+msgstr "回傳存在的角色"
+
+msgid "Return existing user"
+msgstr "回傳存在的用戶"
+
+msgid "Retype new password: "
+msgstr "重新輸入新密碼:"
+
+msgid "Role to add to <project>:<user> (name or ID)"
+msgstr "加入角色到 <project>:<user>(名稱或識別號)"
+
+msgid "Role to display (name or ID)"
+msgstr "要顯示的角色(名稱或識別號)"
+
+msgid "Role to remove (name or ID)"
+msgstr "要移除的角色(名稱或識別號)"
+
+msgid "Role(s) to delete (name or ID)"
+msgstr "要刪除的角色(名稱或識別號)"
+
+msgid "Search by hostname"
+msgstr "以主機名稱來尋找"
+
+msgid "Search by server status"
+msgstr "以雲實例狀態來尋找"
+
+msgid "Security group to add (name or ID)"
+msgstr "要加入的安全性群組(名稱或識別號)"
+
+msgid "Select an availability zone for the server"
+msgstr "為雲實例選擇可用的區域。"
+
+msgid "Server (name or ID)"
+msgstr "伺服器(名稱或識別號)"
+
+msgid "Server internal device name for volume"
+msgstr "雲硬碟在雲實例內的裝置名稱"
+
+msgid "Server(s) to delete (name or ID)"
+msgstr "要刪除的雲實例(名稱或識別號)"
+
+msgid "Service to delete (name or ID)"
+msgstr "要刪除的伺服器(名稱或識別號)"
+
+msgid "Service to display (type or name)"
+msgstr "要顯示的伺服器(類型或名稱)"
+
+msgid "Service to display (type, name or ID)"
+msgstr "要顯示的伺服器(類型、名稱或識別號)"
+
+msgid "Set a project property (repeat option to set multiple properties)"
+msgstr "設定專案屬性(重復這選項來設定多個屬性)"
+
+msgid "Set a property on this server (repeat for multiple values)"
+msgstr "為此伺服器設定屬性(為多個值重複設定)"
+
+msgid "Set default project (name or ID)"
+msgstr "設定預設專案(名稱或識別號)"
+
+msgid "Set new root password (interactive only)"
+msgstr "設定新密碼(只限互動)"
+
+msgid "Set project description"
+msgstr "設定專案描述"
+
+msgid "Set project name"
+msgstr "設定專案名稱"
+
+msgid "Set user email address"
+msgstr "設定用戶電子信箱位址"
+
+msgid "Set user name"
+msgstr "設定用戶名稱"
+
+msgid "Set user password"
+msgstr "設定用戶密碼"
+
+msgid "Show service catalog information"
+msgstr "顯示伺服器分類資訊"
+
+msgid "Target hostname"
+msgstr "目標主機名稱"
+
+msgid ""
+"The argument --type is deprecated, use service create --name <service-name> "
+"type instead."
+msgstr ""
+"已經淘汰 --type 參數,請用 service create --name <service-name> 來代替。"
+
+msgid "Token to be deleted"
+msgstr "要刪除的記號"
+
+msgid "Use only IPv4 addresses"
+msgstr "只使用 IPv4 位址"
+
+msgid "Use only IPv6 addresses"
+msgstr "只使用 IPv6 位址"
+
+msgid "Use other IP address (public, private, etc)"
+msgstr "使用其他 IP 位址(公開、私人等等)"
+
+msgid "Use private IP address"
+msgstr "使用私人 IP 位址"
+
+msgid "Use public IP address"
+msgstr "使用公開 IP 位址"
+
+msgid ""
+"Use specified volume as the config drive, or 'True' to use an ephemeral drive"
+msgstr "使用指定的雲硬碟為設定檔硬碟,或「True」來使用暫時性硬碟"
+
+msgid "User data file to serve from the metadata server"
+msgstr "來自詮釋資料伺服器要服務的用戶資料檔案"
+
+msgid "User must be specified"
+msgstr "必須指定用戶"
+
+msgid "User to change (name or ID)"
+msgstr "要更換的用戶(名稱或識別號)"
+
+msgid "User to display (name or ID)"
+msgstr "要顯示的用戶(名稱或識別號)"
+
+msgid "User to list (name or ID)"
+msgstr "要列出的用戶(名稱或識別號)"
+
+msgid "User(s) to delete (name or ID)"
+msgstr "要刪除的用戶(名稱或識別號)"
+
+msgid "Volume to add (name or ID)"
+msgstr "要加入的雲硬碟(名稱或識別號)"
+
+msgid "Volume to remove (name or ID)"
+msgstr "要移除的雲硬碟(名稱或識別號)"
+
+msgid "Wait for build to complete"
+msgstr "等待完成建立"
+
+msgid "Wait for image create to complete"
+msgstr "等待映像檔新增完成"
+
+msgid "Wait for reboot to complete"
+msgstr "等待重開機完成"
+
+msgid "Wait for rebuild to complete"
+msgstr "等待重建完成"
+
+msgid "Wait for resize to complete"
+msgstr "等待調整容量完成"
+
+msgid "either net-id or port-id should be specified but not both"
+msgstr "任選網路識別號或接口識別號,但不能兩者都指定"
+
+msgid "max instances should be > 0"
+msgstr "雲實例發動的最大值要大於 0"
+
+msgid "min instances should be <= max instances"
+msgstr "雲實例發動的最少值不應大於最大值"
+
+msgid "min instances should be > 0"
+msgstr "雲實例發動的最少值要大於 0"
diff --git a/openstackclient/network/v2/subnet.py b/openstackclient/network/v2/subnet.py
new file mode 100644
index 00000000..62747125
--- /dev/null
+++ b/openstackclient/network/v2/subnet.py
@@ -0,0 +1,70 @@
+# 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.
+#
+
+"""Subnet action implementations"""
+
+import logging
+
+from cliff import lister
+
+from openstackclient.common import utils
+
+
+def _format_allocation_pools(data):
+ pool_formatted = ['%s-%s' % (pool.get('start', ''), pool.get('end', ''))
+ for pool in data]
+ return ','.join(pool_formatted)
+
+
+_formatters = {
+ 'allocation_pools': _format_allocation_pools,
+ 'dns_nameservers': utils.format_list,
+ 'host_routes': utils.format_list,
+}
+
+
+class ListSubnet(lister.Lister):
+ """List subnets"""
+
+ log = logging.getLogger(__name__ + '.ListSubnet')
+
+ def get_parser(self, prog_name):
+ parser = super(ListSubnet, 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)
+
+ data = self.app.client_manager.network.subnets()
+
+ headers = ('ID', 'Name', 'Network', 'Subnet')
+ columns = ('id', 'name', 'network_id', 'cidr')
+ if parsed_args.long:
+ headers += ('Project', 'DHCP', 'Name Servers',
+ 'Allocation Pools', 'Host Routes', 'IP Version',
+ 'Gateway')
+ columns += ('tenant_id', 'enable_dhcp', 'dns_nameservers',
+ 'allocation_pools', 'host_routes', 'ip_version',
+ 'gateway_ip')
+
+ return (headers,
+ (utils.get_item_properties(
+ s, columns,
+ formatters=_formatters,
+ ) for s in data))
diff --git a/openstackclient/tests/common/test_availability_zone.py b/openstackclient/tests/common/test_availability_zone.py
new file mode 100644
index 00000000..232b56c9
--- /dev/null
+++ b/openstackclient/tests/common/test_availability_zone.py
@@ -0,0 +1,192 @@
+# 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.
+#
+
+import six
+
+from openstackclient.common import availability_zone
+from openstackclient.tests.compute.v2 import fakes as compute_fakes
+from openstackclient.tests import fakes
+from openstackclient.tests import utils
+from openstackclient.tests.volume.v2 import fakes as volume_fakes
+
+
+def _build_compute_az_datalist(compute_az, long_datalist=False):
+ datalist = ()
+ if not long_datalist:
+ datalist = (
+ compute_az.zoneName,
+ 'available',
+ )
+ else:
+ for host, services in six.iteritems(compute_az.hosts):
+ for service, state in six.iteritems(services):
+ datalist += (
+ compute_az.zoneName,
+ 'available',
+ host,
+ service,
+ 'enabled :-) ' + state['updated_at'],
+ )
+ return (datalist,)
+
+
+def _build_volume_az_datalist(volume_az, long_datalist=False):
+ datalist = ()
+ if not long_datalist:
+ datalist = (
+ volume_az.zoneName,
+ 'available',
+ )
+ else:
+ datalist = (
+ volume_az.zoneName,
+ 'available',
+ '', '', '',
+ )
+ return (datalist,)
+
+
+class TestAvailabilityZone(utils.TestCommand):
+
+ def setUp(self):
+ super(TestAvailabilityZone, self).setUp()
+
+ compute_client = compute_fakes.FakeComputev2Client(
+ endpoint=fakes.AUTH_URL,
+ token=fakes.AUTH_TOKEN,
+ )
+ self.app.client_manager.compute = compute_client
+
+ self.compute_azs_mock = compute_client.availability_zones
+ self.compute_azs_mock.reset_mock()
+
+ volume_client = volume_fakes.FakeVolumeClient(
+ endpoint=fakes.AUTH_URL,
+ token=fakes.AUTH_TOKEN,
+ )
+ self.app.client_manager.volume = volume_client
+
+ self.volume_azs_mock = volume_client.availability_zones
+ self.volume_azs_mock.reset_mock()
+
+
+class TestAvailabilityZoneList(TestAvailabilityZone):
+
+ compute_azs = \
+ compute_fakes.FakeAvailabilityZone.create_availability_zones()
+ volume_azs = \
+ volume_fakes.FakeAvailabilityZone.create_availability_zones(count=1)
+
+ short_columnslist = ('Zone Name', 'Zone Status')
+ long_columnslist = (
+ 'Zone Name',
+ 'Zone Status',
+ 'Host Name',
+ 'Service Name',
+ 'Service Status',
+ )
+
+ def setUp(self):
+ super(TestAvailabilityZoneList, self).setUp()
+
+ self.compute_azs_mock.list.return_value = self.compute_azs
+ self.volume_azs_mock.list.return_value = self.volume_azs
+
+ # Get the command object to test
+ self.cmd = availability_zone.ListAvailabilityZone(self.app, None)
+
+ def test_availability_zone_list_no_options(self):
+ arglist = []
+ verifylist = []
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.compute_azs_mock.list.assert_called_with()
+ self.volume_azs_mock.list.assert_called_with()
+
+ self.assertEqual(self.short_columnslist, columns)
+ datalist = ()
+ for compute_az in self.compute_azs:
+ datalist += _build_compute_az_datalist(compute_az)
+ for volume_az in self.volume_azs:
+ datalist += _build_volume_az_datalist(volume_az)
+ self.assertEqual(datalist, tuple(data))
+
+ def test_availability_zone_list_long(self):
+ arglist = [
+ '--long',
+ ]
+ verifylist = [
+ ('long', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.compute_azs_mock.list.assert_called_with()
+ self.volume_azs_mock.list.assert_called_with()
+
+ self.assertEqual(self.long_columnslist, columns)
+ datalist = ()
+ for compute_az in self.compute_azs:
+ datalist += _build_compute_az_datalist(compute_az,
+ long_datalist=True)
+ for volume_az in self.volume_azs:
+ datalist += _build_volume_az_datalist(volume_az,
+ long_datalist=True)
+ self.assertEqual(datalist, tuple(data))
+
+ def test_availability_zone_list_compute(self):
+ arglist = [
+ '--compute',
+ ]
+ verifylist = [
+ ('compute', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.compute_azs_mock.list.assert_called_with()
+ self.volume_azs_mock.list.assert_not_called()
+
+ self.assertEqual(self.short_columnslist, columns)
+ datalist = ()
+ for compute_az in self.compute_azs:
+ datalist += _build_compute_az_datalist(compute_az)
+ self.assertEqual(datalist, tuple(data))
+
+ def test_availability_zone_list_volume(self):
+ arglist = [
+ '--volume',
+ ]
+ verifylist = [
+ ('volume', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.compute_azs_mock.list.assert_not_called()
+ self.volume_azs_mock.list.assert_called_with()
+
+ self.assertEqual(self.short_columnslist, columns)
+ datalist = ()
+ for volume_az in self.volume_azs:
+ datalist += _build_volume_az_datalist(volume_az)
+ self.assertEqual(datalist, tuple(data))
diff --git a/openstackclient/tests/compute/v2/fakes.py b/openstackclient/tests/compute/v2/fakes.py
index ecf7f599..a90c9ee7 100644
--- a/openstackclient/tests/compute/v2/fakes.py
+++ b/openstackclient/tests/compute/v2/fakes.py
@@ -88,6 +88,8 @@ SERVICE = {
class FakeComputev2Client(object):
def __init__(self, **kwargs):
+ self.availability_zones = mock.Mock()
+ self.availability_zones.resource_class = fakes.FakeResource(None, {})
self.images = mock.Mock()
self.images.resource_class = fakes.FakeResource(None, {})
self.servers = mock.Mock()
@@ -289,3 +291,63 @@ class FakeFlavor(object):
if flavors is None:
flavors = FakeServer.create_flavors(count)
return mock.MagicMock(side_effect=flavors)
+
+
+class FakeAvailabilityZone(object):
+ """Fake one or more compute availability zones (AZs)."""
+
+ @staticmethod
+ def create_one_availability_zone(attrs={}, methods={}):
+ """Create a fake AZ.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :return:
+ A FakeResource object with zoneName, zoneState, etc.
+ """
+ # Set default attributes.
+ host_name = uuid.uuid4().hex
+ service_name = uuid.uuid4().hex
+ service_updated_at = uuid.uuid4().hex
+ availability_zone = {
+ 'zoneName': uuid.uuid4().hex,
+ 'zoneState': {'available': True},
+ 'hosts': {host_name: {service_name: {
+ 'available': True,
+ 'active': True,
+ 'updated_at': service_updated_at,
+ }}},
+ }
+
+ # Overwrite default attributes.
+ availability_zone.update(attrs)
+
+ availability_zone = fakes.FakeResource(
+ info=copy.deepcopy(availability_zone),
+ methods=methods,
+ loaded=True)
+ return availability_zone
+
+ @staticmethod
+ def create_availability_zones(attrs={}, methods={}, count=2):
+ """Create multiple fake AZs.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :param int count:
+ The number of AZs to fake
+ :return:
+ A list of FakeResource objects faking the AZs
+ """
+ availability_zones = []
+ for i in range(0, count):
+ availability_zone = \
+ FakeAvailabilityZone.create_one_availability_zone(
+ attrs, methods)
+ availability_zones.append(availability_zone)
+
+ return availability_zones
diff --git a/openstackclient/tests/image/v1/test_image.py b/openstackclient/tests/image/v1/test_image.py
index 4d964bdb..1e0b29aa 100644
--- a/openstackclient/tests/image/v1/test_image.py
+++ b/openstackclient/tests/image/v1/test_image.py
@@ -103,6 +103,7 @@ class TestImageCreate(TestImage):
'--min-ram', '4',
'--protected',
'--private',
+ '--project', 'q',
image_fakes.image_name,
]
verifylist = [
@@ -114,6 +115,7 @@ class TestImageCreate(TestImage):
('unprotected', False),
('public', False),
('private', True),
+ ('project', 'q'),
('name', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -130,6 +132,7 @@ class TestImageCreate(TestImage):
min_ram=4,
protected=True,
is_public=False,
+ owner='q',
data=mock.ANY,
)
@@ -237,6 +240,19 @@ class TestImageDelete(TestImage):
class TestImageList(TestImage):
+ columns = (
+ 'ID',
+ 'Name',
+ 'Status',
+ )
+ datalist = (
+ (
+ image_fakes.image_id,
+ image_fakes.image_name,
+ '',
+ ),
+ )
+
def setUp(self):
super(TestImageList, self).setUp()
@@ -265,15 +281,8 @@ class TestImageList(TestImage):
marker=image_fakes.image_id,
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(collist, columns)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_image_list_public_option(self):
arglist = [
@@ -294,15 +303,8 @@ class TestImageList(TestImage):
marker=image_fakes.image_id,
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(collist, columns)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_image_list_private_option(self):
arglist = [
@@ -323,15 +325,8 @@ class TestImageList(TestImage):
marker=image_fakes.image_id,
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(collist, columns)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_image_list_long_option(self):
arglist = [
@@ -358,7 +353,7 @@ class TestImageList(TestImage):
'Status',
'Visibility',
'Protected',
- 'Owner',
+ 'Project',
'Properties',
)
@@ -404,15 +399,8 @@ class TestImageList(TestImage):
property_field='properties',
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(columns, collist)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
@mock.patch('openstackclient.common.utils.sort_items')
def test_image_list_sort_option(self, si_mock):
@@ -435,15 +423,8 @@ class TestImageList(TestImage):
'name:asc'
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(collist, columns)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
class TestImageSet(TestImage):
@@ -484,22 +465,22 @@ class TestImageSet(TestImage):
def test_image_set_options(self):
arglist = [
'--name', 'new-name',
- '--owner', 'new-owner',
'--min-disk', '2',
'--min-ram', '4',
'--container-format', 'ovf',
'--disk-format', 'vmdk',
'--size', '35165824',
+ '--project', 'new-owner',
image_fakes.image_name,
]
verifylist = [
('name', 'new-name'),
- ('owner', 'new-owner'),
('min_disk', 2),
('min_ram', 4),
('container_format', 'ovf'),
('disk_format', 'vmdk'),
('size', 35165824),
+ ('project', 'new-owner'),
('image', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/image/v2/test_image.py b/openstackclient/tests/image/v2/test_image.py
index 02182413..488eab20 100644
--- a/openstackclient/tests/image/v2/test_image.py
+++ b/openstackclient/tests/image/v2/test_image.py
@@ -131,11 +131,11 @@ class TestImageCreate(TestImage):
'--disk-format', 'fs',
'--min-disk', '10',
'--min-ram', '4',
- '--owner', self.new_image.owner,
('--protected'
if self.new_image.protected else '--unprotected'),
('--private'
if self.new_image.visibility == 'private' else '--public'),
+ '--project', self.new_image.owner,
'--project-domain', identity_fakes.domain_id,
self.new_image.name,
]
@@ -144,11 +144,11 @@ class TestImageCreate(TestImage):
('disk_format', 'fs'),
('min_disk', 10),
('min_ram', 4),
- ('owner', self.new_image.owner),
('protected', self.new_image.protected),
('unprotected', not self.new_image.protected),
('public', self.new_image.visibility == 'public'),
('private', self.new_image.visibility == 'private'),
+ ('project', self.new_image.owner),
('project_domain', identity_fakes.domain_id),
('name', self.new_image.name),
]
@@ -217,6 +217,40 @@ class TestImageCreate(TestImage):
parsed_args,
)
+ def test_image_create_with_unexist_project(self):
+ self.project_mock.get.side_effect = exceptions.NotFound(None)
+ self.project_mock.find.side_effect = exceptions.NotFound(None)
+
+ arglist = [
+ '--container-format', 'ovf',
+ '--disk-format', 'fs',
+ '--min-disk', '10',
+ '--min-ram', '4',
+ '--protected',
+ '--private',
+ '--project', 'unexist_owner',
+ image_fakes.image_name,
+ ]
+ verifylist = [
+ ('container_format', 'ovf'),
+ ('disk_format', 'fs'),
+ ('min_disk', 10),
+ ('min_ram', 4),
+ ('protected', True),
+ ('unprotected', False),
+ ('public', False),
+ ('private', True),
+ ('project', 'unexist_owner'),
+ ('name', image_fakes.image_name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args,
+ )
+
@mock.patch('glanceclient.common.utils.get_data_file', name='Open')
def test_image_create_file(self, mock_open):
mock_file = mock.MagicMock(name='File')
@@ -299,6 +333,17 @@ class TestImageCreate(TestImage):
class TestAddProjectToImage(TestImage):
+ columns = (
+ 'image_id',
+ 'member_id',
+ 'status',
+ )
+ datalist = (
+ image_fakes.image_id,
+ identity_fakes.project_id,
+ image_fakes.member_status,
+ )
+
def setUp(self):
super(TestAddProjectToImage, self).setUp()
@@ -341,14 +386,8 @@ class TestAddProjectToImage(TestImage):
image_fakes.image_id,
identity_fakes.project_id
)
- collist = ('image_id', 'member_id', 'status')
- self.assertEqual(collist, columns)
- datalist = (
- image_fakes.image_id,
- identity_fakes.project_id,
- image_fakes.member_status
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_add_project_to_image_with_option(self):
arglist = [
@@ -369,14 +408,8 @@ class TestAddProjectToImage(TestImage):
image_fakes.image_id,
identity_fakes.project_id
)
- collist = ('image_id', 'member_id', 'status')
- self.assertEqual(collist, columns)
- datalist = (
- image_fakes.image_id,
- identity_fakes.project_id,
- image_fakes.member_status
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
class TestImageDelete(TestImage):
@@ -426,6 +459,19 @@ class TestImageDelete(TestImage):
class TestImageList(TestImage):
+ columns = (
+ 'ID',
+ 'Name',
+ 'Status',
+ )
+ datalist = (
+ (
+ image_fakes.image_id,
+ image_fakes.image_name,
+ '',
+ ),
+ )
+
def setUp(self):
super(TestImageList, self).setUp()
@@ -454,15 +500,8 @@ class TestImageList(TestImage):
marker=image_fakes.image_id,
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(collist, columns)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_image_list_public_option(self):
arglist = [
@@ -483,15 +522,8 @@ class TestImageList(TestImage):
marker=image_fakes.image_id,
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(collist, columns)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_image_list_private_option(self):
arglist = [
@@ -512,15 +544,8 @@ class TestImageList(TestImage):
marker=image_fakes.image_id,
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(collist, columns)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_image_list_shared_option(self):
arglist = [
@@ -541,15 +566,8 @@ class TestImageList(TestImage):
marker=image_fakes.image_id,
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(columns, collist)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_image_list_long_option(self):
arglist = [
@@ -575,7 +593,7 @@ class TestImageList(TestImage):
'Status',
'Visibility',
'Protected',
- 'Owner',
+ 'Project',
'Tags',
)
@@ -620,15 +638,8 @@ class TestImageList(TestImage):
property_field='properties',
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(columns, collist)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
@mock.patch('openstackclient.common.utils.sort_items')
def test_image_list_sort_option(self, si_mock):
@@ -650,15 +661,8 @@ class TestImageList(TestImage):
'name:asc'
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(collist, columns)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
class TestRemoveProjectImage(TestImage):
@@ -755,21 +759,21 @@ class TestImageSet(TestImage):
def test_image_set_options(self):
arglist = [
'--name', 'new-name',
- '--owner', identity_fakes.project_name,
'--min-disk', '2',
'--min-ram', '4',
'--container-format', 'ovf',
'--disk-format', 'vmdk',
+ '--project', identity_fakes.project_name,
'--project-domain', identity_fakes.domain_id,
image_fakes.image_id,
]
verifylist = [
('name', 'new-name'),
- ('owner', identity_fakes.project_name),
('min_disk', 2),
('min_ram', 4),
('container_format', 'ovf'),
('disk_format', 'vmdk'),
+ ('project', identity_fakes.project_name),
('project_domain', identity_fakes.domain_id),
('image', image_fakes.image_id),
]
@@ -809,6 +813,25 @@ class TestImageSet(TestImage):
exceptions.CommandError,
self.cmd.take_action, parsed_args)
+ def test_image_set_with_unexist_project(self):
+ self.project_mock.get.side_effect = exceptions.NotFound(None)
+ self.project_mock.find.side_effect = exceptions.NotFound(None)
+
+ arglist = [
+ '--project', 'unexist_owner',
+ image_fakes.image_id,
+ ]
+ verifylist = [
+ ('project', 'unexist_owner'),
+ ('image', image_fakes.image_id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action, parsed_args)
+
def test_image_set_bools1(self):
arglist = [
'--protected',
diff --git a/openstackclient/tests/network/v2/fakes.py b/openstackclient/tests/network/v2/fakes.py
index 146ba616..88370feb 100644
--- a/openstackclient/tests/network/v2/fakes.py
+++ b/openstackclient/tests/network/v2/fakes.py
@@ -307,3 +307,71 @@ class FakeRouter(object):
if routers is None:
routers = FakeRouter.create_routers(count)
return mock.MagicMock(side_effect=routers)
+
+
+class FakeSubnet(object):
+ """Fake one or more subnets."""
+
+ @staticmethod
+ def create_one_subnet(attrs={}, methods={}):
+ """Create a fake subnet.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :return:
+ A FakeResource object faking the subnet
+ """
+ # Set default attributes.
+ subnet_attrs = {
+ 'id': 'subnet-id-' + uuid.uuid4().hex,
+ 'name': 'subnet-name-' + uuid.uuid4().hex,
+ 'network_id': 'network-id-' + uuid.uuid4().hex,
+ 'cidr': '10.10.10.0/24',
+ 'tenant_id': 'project-id-' + uuid.uuid4().hex,
+ 'enable_dhcp': True,
+ 'dns_nameservers': [],
+ 'allocation_pools': [],
+ 'host_routes': [],
+ 'ip_version': '4',
+ 'gateway_ip': '10.10.10.1',
+ }
+
+ # Overwrite default attributes.
+ subnet_attrs.update(attrs)
+
+ # Set default methods.
+ subnet_methods = {
+ 'keys': ['id', 'name', 'network_id', 'cidr', 'enable_dhcp',
+ 'allocation_pools', 'dns_nameservers', 'gateway_ip',
+ 'host_routes', 'ip_version', 'tenant_id']
+ }
+
+ # Overwrite default methods.
+ subnet_methods.update(methods)
+
+ subnet = fakes.FakeResource(info=copy.deepcopy(subnet_attrs),
+ methods=copy.deepcopy(subnet_methods),
+ loaded=True)
+
+ return subnet
+
+ @staticmethod
+ def create_subnets(attrs={}, methods={}, count=2):
+ """Create multiple fake subnets.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :param int count:
+ The number of subnets to fake
+ :return:
+ A list of FakeResource objects faking the subnets
+ """
+ subnets = []
+ for i in range(0, count):
+ subnets.append(FakeSubnet.create_one_subnet(attrs, methods))
+
+ return subnets
diff --git a/openstackclient/tests/network/v2/test_subnet.py b/openstackclient/tests/network/v2/test_subnet.py
new file mode 100644
index 00000000..5fca5edd
--- /dev/null
+++ b/openstackclient/tests/network/v2/test_subnet.py
@@ -0,0 +1,108 @@
+# 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.
+#
+
+import mock
+
+from openstackclient.common import utils
+from openstackclient.network.v2 import subnet as subnet_v2
+from openstackclient.tests.network.v2 import fakes as network_fakes
+
+
+class TestSubnet(network_fakes.TestNetworkV2):
+ def setUp(self):
+ super(TestSubnet, self).setUp()
+
+ # Get a shortcut to the network client
+ self.network = self.app.client_manager.network
+
+
+class TestListSubnet(TestSubnet):
+ # The subnets going to be listed up.
+ _subnet = network_fakes.FakeSubnet.create_subnets(count=3)
+
+ columns = (
+ 'ID',
+ 'Name',
+ 'Network',
+ 'Subnet'
+ )
+ columns_long = columns + (
+ 'Project',
+ 'DHCP',
+ 'Name Servers',
+ 'Allocation Pools',
+ 'Host Routes',
+ 'IP Version',
+ 'Gateway'
+ )
+
+ data = []
+ for subnet in _subnet:
+ data.append((
+ subnet.id,
+ subnet.name,
+ subnet.network_id,
+ subnet.cidr,
+ ))
+
+ data_long = []
+ for subnet in _subnet:
+ data_long.append((
+ subnet.id,
+ subnet.name,
+ subnet.network_id,
+ subnet.cidr,
+ subnet.tenant_id,
+ subnet.enable_dhcp,
+ utils.format_list(subnet.dns_nameservers),
+ subnet_v2._format_allocation_pools(subnet.allocation_pools),
+ utils.format_list(subnet.host_routes),
+ subnet.ip_version,
+ subnet.gateway_ip
+ ))
+
+ def setUp(self):
+ super(TestListSubnet, self).setUp()
+
+ # Get the command object to test
+ self.cmd = subnet_v2.ListSubnet(self.app, self.namespace)
+
+ self.network.subnets = mock.Mock(return_value=self._subnet)
+
+ def test_subnet_list_no_options(self):
+ arglist = []
+ verifylist = [
+ ('long', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.subnets.assert_called_with()
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_subnet_list_long(self):
+ arglist = [
+ '--long',
+ ]
+ verifylist = [
+ ('long', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.subnets.assert_called_with()
+ self.assertEqual(self.columns_long, columns)
+ self.assertEqual(self.data_long, list(data))
diff --git a/openstackclient/tests/object/v1/test_container.py b/openstackclient/tests/object/v1/test_container.py
index 2ef2f7b5..afcb3386 100644
--- a/openstackclient/tests/object/v1/test_container.py
+++ b/openstackclient/tests/object/v1/test_container.py
@@ -32,6 +32,9 @@ class FakeClient(object):
class TestContainer(object_fakes.TestObjectv1):
+
+ columns = ('Name',)
+
def setUp(self):
super(TestContainer, self).setUp()
self.app.client_manager.object_store = object_store.APIv1(
@@ -73,8 +76,7 @@ class TestContainerList(TestContainer):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(object_fakes.container_name, ),
(object_fakes.container_name_3, ),
@@ -107,8 +109,7 @@ class TestContainerList(TestContainer):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(object_fakes.container_name, ),
(object_fakes.container_name_3, ),
@@ -143,8 +144,7 @@ class TestContainerList(TestContainer):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(object_fakes.container_name, ),
(object_fakes.container_name_3, ),
@@ -176,8 +176,7 @@ class TestContainerList(TestContainer):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(object_fakes.container_name, ),
(object_fakes.container_name_3, ),
@@ -250,8 +249,7 @@ class TestContainerList(TestContainer):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(object_fakes.container_name, ),
(object_fakes.container_name_2, ),
diff --git a/openstackclient/tests/object/v1/test_container_all.py b/openstackclient/tests/object/v1/test_container_all.py
index 69fc0f39..c2dd02a5 100644
--- a/openstackclient/tests/object/v1/test_container_all.py
+++ b/openstackclient/tests/object/v1/test_container_all.py
@@ -29,6 +29,12 @@ class TestContainerAll(object_fakes.TestObjectv1):
class TestContainerCreate(TestContainerAll):
+ columns = (
+ 'account',
+ 'container',
+ 'x-trans-id',
+ )
+
def setUp(self):
super(TestContainerCreate, self).setUp()
@@ -54,8 +60,7 @@ class TestContainerCreate(TestContainerAll):
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- collist = ('account', 'container', 'x-trans-id')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = [(
object_fakes.ACCOUNT_ID,
'ernie',
@@ -89,8 +94,7 @@ class TestContainerCreate(TestContainerAll):
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- collist = ('account', 'container', 'x-trans-id')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = [
(
object_fakes.ACCOUNT_ID,
@@ -161,6 +165,8 @@ class TestContainerDelete(TestContainerAll):
class TestContainerList(TestContainerAll):
+ columns = ('Name',)
+
def setUp(self):
super(TestContainerList, self).setUp()
@@ -187,8 +193,7 @@ class TestContainerList(TestContainerAll):
# Lister.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = [
(object_fakes.container_name, ),
(object_fakes.container_name_3, ),
@@ -219,8 +224,7 @@ class TestContainerList(TestContainerAll):
# Lister.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = [
(object_fakes.container_name, ),
(object_fakes.container_name_3, ),
diff --git a/openstackclient/tests/object/v1/test_object.py b/openstackclient/tests/object/v1/test_object.py
index 305fe8f8..f0d62f6e 100644
--- a/openstackclient/tests/object/v1/test_object.py
+++ b/openstackclient/tests/object/v1/test_object.py
@@ -40,6 +40,13 @@ class TestObject(object_fakes.TestObjectv1):
)
class TestObjectList(TestObject):
+ columns = ('Name',)
+ datalist = (
+ (
+ object_fakes.object_name_2,
+ ),
+ )
+
def setUp(self):
super(TestObjectList, self).setUp()
@@ -67,8 +74,7 @@ class TestObjectList(TestObject):
container=object_fakes.container_name,
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(object_fakes.object_name_1, ),
(object_fakes.object_name_2, ),
@@ -102,12 +108,8 @@ class TestObjectList(TestObject):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
- datalist = (
- (object_fakes.object_name_2, ),
- )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_object_list_objects_delimiter(self, o_mock):
o_mock.return_value = [
@@ -136,12 +138,8 @@ class TestObjectList(TestObject):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
- datalist = (
- (object_fakes.object_name_2, ),
- )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_object_list_objects_marker(self, o_mock):
o_mock.return_value = [
@@ -170,12 +168,8 @@ class TestObjectList(TestObject):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
- datalist = (
- (object_fakes.object_name_2, ),
- )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_object_list_objects_end_marker(self, o_mock):
o_mock.return_value = [
@@ -204,12 +198,8 @@ class TestObjectList(TestObject):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
- datalist = (
- (object_fakes.object_name_2, ),
- )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_object_list_objects_limit(self, o_mock):
o_mock.return_value = [
@@ -238,12 +228,8 @@ class TestObjectList(TestObject):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
- datalist = (
- (object_fakes.object_name_2, ),
- )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_object_list_objects_long(self, o_mock):
o_mock.return_value = [
@@ -320,8 +306,7 @@ class TestObjectList(TestObject):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(object_fakes.object_name_1, ),
(object_fakes.object_name_2, ),
diff --git a/openstackclient/tests/object/v1/test_object_all.py b/openstackclient/tests/object/v1/test_object_all.py
index 7a76ab76..a90e5b65 100644
--- a/openstackclient/tests/object/v1/test_object_all.py
+++ b/openstackclient/tests/object/v1/test_object_all.py
@@ -37,6 +37,8 @@ class TestObjectCreate(TestObjectAll):
class TestObjectList(TestObjectAll):
+ columns = ('Name',)
+
def setUp(self):
super(TestObjectList, self).setUp()
@@ -69,8 +71,7 @@ class TestObjectList(TestObjectAll):
# Lister.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = [
(object_fakes.object_name_1, ),
(object_fakes.object_name_2, ),
@@ -104,8 +105,7 @@ class TestObjectList(TestObjectAll):
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(object_fakes.object_name_2, ),
)
diff --git a/openstackclient/tests/volume/v1/test_qos_specs.py b/openstackclient/tests/volume/v1/test_qos_specs.py
index c2e6c0af..7ecc8ee8 100644
--- a/openstackclient/tests/volume/v1/test_qos_specs.py
+++ b/openstackclient/tests/volume/v1/test_qos_specs.py
@@ -69,6 +69,18 @@ class TestQosAssociate(TestQos):
class TestQosCreate(TestQos):
+
+ columns = (
+ 'consumer',
+ 'id',
+ 'name',
+ )
+ datalist = (
+ volume_fakes.qos_consumer,
+ volume_fakes.qos_id,
+ volume_fakes.qos_name
+ )
+
def setUp(self):
super(TestQosCreate, self).setUp()
@@ -97,12 +109,7 @@ class TestQosCreate(TestQos):
{'consumer': volume_fakes.qos_default_consumer}
)
- collist = (
- 'consumer',
- 'id',
- 'name'
- )
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
volume_fakes.qos_default_consumer,
volume_fakes.qos_id,
@@ -133,19 +140,8 @@ class TestQosCreate(TestQos):
volume_fakes.qos_name,
{'consumer': volume_fakes.qos_consumer}
)
-
- collist = (
- 'consumer',
- 'id',
- 'name'
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.qos_consumer,
- volume_fakes.qos_id,
- volume_fakes.qos_name
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_qos_create_with_properties(self):
self.qos_mock.create.return_value = fakes.FakeResource(
@@ -176,17 +172,11 @@ class TestQosCreate(TestQos):
specs
)
- collist = (
- 'consumer',
- 'id',
- 'name',
+ columns = self.columns + (
'specs',
)
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.qos_consumer,
- volume_fakes.qos_id,
- volume_fakes.qos_name,
+ self.assertEqual(columns, columns)
+ datalist = self.datalist + (
volume_fakes.qos_specs,
)
self.assertEqual(datalist, data)
diff --git a/openstackclient/tests/volume/v1/test_volume.py b/openstackclient/tests/volume/v1/test_volume.py
index 70ff50de..33255aac 100644
--- a/openstackclient/tests/volume/v1/test_volume.py
+++ b/openstackclient/tests/volume/v1/test_volume.py
@@ -49,6 +49,29 @@ class TestVolume(volume_fakes.TestVolumev1):
class TestVolumeCreate(TestVolume):
+ columns = (
+ 'attach_status',
+ 'availability_zone',
+ 'display_description',
+ 'display_name',
+ 'id',
+ 'properties',
+ 'size',
+ 'status',
+ 'type',
+ )
+ datalist = (
+ 'detached',
+ volume_fakes.volume_zone,
+ volume_fakes.volume_description,
+ volume_fakes.volume_name,
+ volume_fakes.volume_id,
+ volume_fakes.volume_metadata_str,
+ volume_fakes.volume_size,
+ volume_fakes.volume_status,
+ volume_fakes.volume_type,
+ )
+
def setUp(self):
super(TestVolumeCreate, self).setUp()
@@ -93,31 +116,8 @@ class TestVolumeCreate(TestVolume):
None,
None,
)
-
- collist = (
- 'attach_status',
- 'availability_zone',
- 'display_description',
- 'display_name',
- 'id',
- 'properties',
- 'size',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- 'detached',
- volume_fakes.volume_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_name,
- volume_fakes.volume_id,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_options(self):
arglist = [
@@ -158,30 +158,8 @@ class TestVolumeCreate(TestVolume):
None,
)
- collist = (
- 'attach_status',
- 'availability_zone',
- 'display_description',
- 'display_name',
- 'id',
- 'properties',
- 'size',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- 'detached',
- volume_fakes.volume_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_name,
- volume_fakes.volume_id,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_user_project_id(self):
# Return a project
@@ -233,30 +211,8 @@ class TestVolumeCreate(TestVolume):
None,
)
- collist = (
- 'attach_status',
- 'availability_zone',
- 'display_description',
- 'display_name',
- 'id',
- 'properties',
- 'size',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- 'detached',
- volume_fakes.volume_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_name,
- volume_fakes.volume_id,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_user_project_name(self):
# Return a project
@@ -308,30 +264,8 @@ class TestVolumeCreate(TestVolume):
None,
)
- collist = (
- 'attach_status',
- 'availability_zone',
- 'display_description',
- 'display_name',
- 'id',
- 'properties',
- 'size',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- 'detached',
- volume_fakes.volume_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_name,
- volume_fakes.volume_id,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_properties(self):
arglist = [
@@ -369,30 +303,8 @@ class TestVolumeCreate(TestVolume):
None,
)
- collist = (
- 'attach_status',
- 'availability_zone',
- 'display_description',
- 'display_name',
- 'id',
- 'properties',
- 'size',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- 'detached',
- volume_fakes.volume_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_name,
- volume_fakes.volume_id,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_image_id(self):
self.images_mock.get.return_value = fakes.FakeResource(
@@ -435,30 +347,8 @@ class TestVolumeCreate(TestVolume):
volume_fakes.image_id,
)
- collist = (
- 'attach_status',
- 'availability_zone',
- 'display_description',
- 'display_name',
- 'id',
- 'properties',
- 'size',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- 'detached',
- volume_fakes.volume_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_name,
- volume_fakes.volume_id,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_image_name(self):
self.images_mock.get.return_value = fakes.FakeResource(
@@ -501,34 +391,29 @@ class TestVolumeCreate(TestVolume):
volume_fakes.image_id,
)
- collist = (
- 'attach_status',
- 'availability_zone',
- 'display_description',
- 'display_name',
- 'id',
- 'properties',
- 'size',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- 'detached',
- volume_fakes.volume_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_name,
- volume_fakes.volume_id,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
class TestVolumeList(TestVolume):
+ columns = (
+ 'ID',
+ 'Display Name',
+ 'Status',
+ 'Size',
+ 'Attached to',
+ )
+ datalist = (
+ (
+ volume_fakes.volume_id,
+ volume_fakes.volume_name,
+ volume_fakes.volume_status,
+ volume_fakes.volume_size,
+ '',
+ ),
+ )
+
def setUp(self):
super(TestVolumeList, self).setUp()
@@ -555,23 +440,8 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, columns)
-
- datalist = ((
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_status,
- volume_fakes.volume_size,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_volume_list_name(self):
arglist = [
@@ -586,24 +456,8 @@ class TestVolumeList(TestVolume):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
-
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, tuple(columns))
-
- datalist = ((
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_status,
- volume_fakes.volume_size,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, tuple(columns))
+ self.assertEqual(self.datalist, tuple(data))
def test_volume_list_status(self):
arglist = [
@@ -618,24 +472,8 @@ class TestVolumeList(TestVolume):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
-
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, tuple(columns))
-
- datalist = ((
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_status,
- volume_fakes.volume_size,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, tuple(columns))
+ self.assertEqual(self.datalist, tuple(data))
def test_volume_list_all_projects(self):
arglist = [
@@ -650,24 +488,8 @@ class TestVolumeList(TestVolume):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
-
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, columns)
-
- datalist = ((
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_status,
- volume_fakes.volume_size,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, tuple(columns))
+ self.assertEqual(self.datalist, tuple(data))
def test_volume_list_long(self):
arglist = [
diff --git a/openstackclient/tests/volume/v2/fakes.py b/openstackclient/tests/volume/v2/fakes.py
index 60cec335..2e58e58d 100644
--- a/openstackclient/tests/volume/v2/fakes.py
+++ b/openstackclient/tests/volume/v2/fakes.py
@@ -202,6 +202,8 @@ class FakeVolumeClient(object):
self.restores.resource_class = fakes.FakeResource(None, {})
self.qos_specs = mock.Mock()
self.qos_specs.resource_class = fakes.FakeResource(None, {})
+ self.availability_zones = mock.Mock()
+ self.availability_zones.resource_class = fakes.FakeResource(None, {})
self.auth_token = kwargs['token']
self.management_url = kwargs['endpoint']
@@ -304,3 +306,55 @@ class FakeVolume(object):
volumes = FakeVolume.create_volumes(count)
return mock.MagicMock(side_effect=volumes)
+
+
+class FakeAvailabilityZone(object):
+ """Fake one or more volume availability zones (AZs)."""
+
+ @staticmethod
+ def create_one_availability_zone(attrs={}, methods={}):
+ """Create a fake AZ.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :return:
+ A FakeResource object with zoneName, zoneState, etc.
+ """
+ # Set default attributes.
+ availability_zone = {
+ 'zoneName': uuid.uuid4().hex,
+ 'zoneState': {'available': True},
+ }
+
+ # Overwrite default attributes.
+ availability_zone.update(attrs)
+
+ availability_zone = fakes.FakeResource(
+ info=copy.deepcopy(availability_zone),
+ methods=methods,
+ loaded=True)
+ return availability_zone
+
+ @staticmethod
+ def create_availability_zones(attrs={}, methods={}, count=2):
+ """Create multiple fake AZs.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :param int count:
+ The number of AZs to fake
+ :return:
+ A list of FakeResource objects faking the AZs
+ """
+ availability_zones = []
+ for i in range(0, count):
+ availability_zone = \
+ FakeAvailabilityZone.create_one_availability_zone(
+ attrs, methods)
+ availability_zones.append(availability_zone)
+
+ return availability_zones
diff --git a/openstackclient/tests/volume/v2/test_backup.py b/openstackclient/tests/volume/v2/test_backup.py
index 7af22e8a..dc1d7877 100644
--- a/openstackclient/tests/volume/v2/test_backup.py
+++ b/openstackclient/tests/volume/v2/test_backup.py
@@ -166,6 +166,24 @@ class TestBackupRestore(TestBackup):
class TestBackupList(TestBackup):
+
+ columns = [
+ 'ID',
+ 'Name',
+ 'Description',
+ 'Status',
+ 'Size',
+ ]
+ datalist = (
+ (
+ volume_fakes.backup_id,
+ volume_fakes.backup_name,
+ volume_fakes.backup_description,
+ volume_fakes.backup_status,
+ volume_fakes.backup_size
+ ),
+ )
+
def setUp(self):
super(TestBackupList, self).setUp()
@@ -193,17 +211,8 @@ class TestBackupList(TestBackup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- collist = ['ID', 'Name', 'Description', 'Status', 'Size']
- self.assertEqual(collist, columns)
-
- datalist = ((
- volume_fakes.backup_id,
- volume_fakes.backup_name,
- volume_fakes.backup_description,
- volume_fakes.backup_status,
- volume_fakes.backup_size
- ),)
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_backup_list_with_options(self):
arglist = ["--long"]
@@ -212,9 +221,13 @@ class TestBackupList(TestBackup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- collist = ['ID', 'Name', 'Description', 'Status', 'Size',
- 'Availability Zone', 'Volume', 'Container']
- self.assertEqual(collist, columns)
+ columns = self.columns + [
+ 'Availability Zone',
+ 'Volume',
+ 'Container',
+ ]
+
+ self.assertEqual(columns, columns)
datalist = ((
volume_fakes.backup_id,
diff --git a/openstackclient/tests/volume/v2/test_qos_specs.py b/openstackclient/tests/volume/v2/test_qos_specs.py
index 4222ed07..403634a3 100644
--- a/openstackclient/tests/volume/v2/test_qos_specs.py
+++ b/openstackclient/tests/volume/v2/test_qos_specs.py
@@ -69,6 +69,18 @@ class TestQosAssociate(TestQos):
class TestQosCreate(TestQos):
+
+ columns = (
+ 'consumer',
+ 'id',
+ 'name'
+ )
+ datalist = (
+ volume_fakes.qos_consumer,
+ volume_fakes.qos_id,
+ volume_fakes.qos_name
+ )
+
def setUp(self):
super(TestQosCreate, self).setUp()
@@ -97,12 +109,7 @@ class TestQosCreate(TestQos):
{'consumer': volume_fakes.qos_default_consumer}
)
- collist = (
- 'consumer',
- 'id',
- 'name'
- )
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
volume_fakes.qos_default_consumer,
volume_fakes.qos_id,
@@ -134,18 +141,8 @@ class TestQosCreate(TestQos):
{'consumer': volume_fakes.qos_consumer}
)
- collist = (
- 'consumer',
- 'id',
- 'name'
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.qos_consumer,
- volume_fakes.qos_id,
- volume_fakes.qos_name
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_qos_create_with_properties(self):
self.qos_mock.create.return_value = fakes.FakeResource(
@@ -176,17 +173,11 @@ class TestQosCreate(TestQos):
specs
)
- collist = (
- 'consumer',
- 'id',
- 'name',
+ columns = self.columns + (
'specs',
)
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.qos_consumer,
- volume_fakes.qos_id,
- volume_fakes.qos_name,
+ self.assertEqual(columns, columns)
+ datalist = self.datalist + (
volume_fakes.qos_specs,
)
self.assertEqual(datalist, data)
diff --git a/openstackclient/tests/volume/v2/test_snapshot.py b/openstackclient/tests/volume/v2/test_snapshot.py
index 3b30d4ef..1c1dd437 100644
--- a/openstackclient/tests/volume/v2/test_snapshot.py
+++ b/openstackclient/tests/volume/v2/test_snapshot.py
@@ -202,6 +202,15 @@ class TestSnapshotUnset(TestSnapshot):
class TestSnapshotList(TestSnapshot):
+
+ columns = [
+ "ID",
+ "Name",
+ "Description",
+ "Status",
+ "Size"
+ ]
+
def setUp(self):
super(TestSnapshotList, self).setUp()
@@ -231,8 +240,7 @@ class TestSnapshotList(TestSnapshot):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- collist = ["ID", "Name", "Description", "Status", "Size"]
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = ((
volume_fakes.snapshot_id,
volume_fakes.snapshot_name,
@@ -249,9 +257,12 @@ class TestSnapshotList(TestSnapshot):
columns, data = self.cmd.take_action(parsed_args)
- collist = ["ID", "Name", "Description", "Status", "Size", "Created At",
- "Volume", "Properties"]
- self.assertEqual(collist, columns)
+ columns = self.columns + [
+ "Created At",
+ "Volume",
+ "Properties"
+ ]
+ self.assertEqual(columns, columns)
datalist = ((
volume_fakes.snapshot_id,
@@ -277,14 +288,7 @@ class TestSnapshotList(TestSnapshot):
columns, data = self.cmd.take_action(parsed_args)
- collist = [
- "ID",
- "Name",
- "Description",
- "Status",
- "Size"
- ]
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = ((
volume_fakes.snapshot_id,
diff --git a/openstackclient/tests/volume/v2/test_type.py b/openstackclient/tests/volume/v2/test_type.py
index c63cd1fa..9bf60363 100644
--- a/openstackclient/tests/volume/v2/test_type.py
+++ b/openstackclient/tests/volume/v2/test_type.py
@@ -44,6 +44,17 @@ class TestType(volume_fakes.TestVolume):
class TestTypeCreate(TestType):
+ columns = (
+ 'description',
+ 'id',
+ 'name',
+ )
+ datalist = (
+ volume_fakes.type_description,
+ volume_fakes.type_id,
+ volume_fakes.type_name,
+ )
+
def setUp(self):
super(TestTypeCreate, self).setUp()
@@ -76,18 +87,8 @@ class TestTypeCreate(TestType):
is_public=True,
)
- collist = (
- 'description',
- 'id',
- 'name',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.type_description,
- volume_fakes.type_id,
- volume_fakes.type_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_type_create_private(self):
arglist = [
@@ -110,21 +111,17 @@ class TestTypeCreate(TestType):
is_public=False,
)
- collist = (
- 'description',
- 'id',
- 'name',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.type_description,
- volume_fakes.type_id,
- volume_fakes.type_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
class TestTypeList(TestType):
+
+ columns = [
+ "ID",
+ "Name"
+ ]
+
def setUp(self):
super(TestTypeList, self).setUp()
@@ -146,8 +143,7 @@ class TestTypeList(TestType):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- collist = ["ID", "Name"]
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = ((
volume_fakes.type_id,
volume_fakes.type_name,
@@ -160,8 +156,11 @@ class TestTypeList(TestType):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- collist = ["ID", "Name", "Description", "Properties"]
- self.assertEqual(collist, columns)
+ columns = self.columns + [
+ "Description",
+ "Properties"
+ ]
+ self.assertEqual(columns, columns)
datalist = ((
volume_fakes.type_id,
volume_fakes.type_name,
diff --git a/openstackclient/tests/volume/v2/test_volume.py b/openstackclient/tests/volume/v2/test_volume.py
index 50826c31..d61a6c15 100644
--- a/openstackclient/tests/volume/v2/test_volume.py
+++ b/openstackclient/tests/volume/v2/test_volume.py
@@ -48,6 +48,32 @@ class TestVolume(volume_fakes.TestVolume):
class TestVolumeCreate(TestVolume):
+
+ columns = (
+ 'attachments',
+ 'availability_zone',
+ 'description',
+ 'id',
+ 'name',
+ 'properties',
+ 'size',
+ 'snapshot_id',
+ 'status',
+ 'type',
+ )
+ datalist = (
+ volume_fakes.volume_attachments,
+ volume_fakes.volume_availability_zone,
+ volume_fakes.volume_description,
+ volume_fakes.volume_id,
+ volume_fakes.volume_name,
+ volume_fakes.volume_metadata_str,
+ volume_fakes.volume_size,
+ volume_fakes.volume_snapshot_id,
+ volume_fakes.volume_status,
+ volume_fakes.volume_type,
+ )
+
def setUp(self):
super(TestVolumeCreate, self).setUp()
@@ -88,32 +114,8 @@ class TestVolumeCreate(TestVolume):
source_volid=None
)
- collist = (
- 'attachments',
- 'availability_zone',
- 'description',
- 'id',
- 'name',
- 'properties',
- 'size',
- 'snapshot_id',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.volume_attachments,
- volume_fakes.volume_availability_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_snapshot_id,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_options(self):
arglist = [
@@ -149,32 +151,8 @@ class TestVolumeCreate(TestVolume):
source_volid=None
)
- collist = (
- 'attachments',
- 'availability_zone',
- 'description',
- 'id',
- 'name',
- 'properties',
- 'size',
- 'snapshot_id',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.volume_attachments,
- volume_fakes.volume_availability_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_snapshot_id,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_user_project_id(self):
# Return a project
@@ -221,32 +199,8 @@ class TestVolumeCreate(TestVolume):
source_volid=None
)
- collist = (
- 'attachments',
- 'availability_zone',
- 'description',
- 'id',
- 'name',
- 'properties',
- 'size',
- 'snapshot_id',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.volume_attachments,
- volume_fakes.volume_availability_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_snapshot_id,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_user_project_name(self):
# Return a project
@@ -293,32 +247,8 @@ class TestVolumeCreate(TestVolume):
source_volid=None
)
- collist = (
- 'attachments',
- 'availability_zone',
- 'description',
- 'id',
- 'name',
- 'properties',
- 'size',
- 'snapshot_id',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.volume_attachments,
- volume_fakes.volume_availability_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_snapshot_id,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_properties(self):
arglist = [
@@ -351,32 +281,8 @@ class TestVolumeCreate(TestVolume):
source_volid=None
)
- collist = (
- 'attachments',
- 'availability_zone',
- 'description',
- 'id',
- 'name',
- 'properties',
- 'size',
- 'snapshot_id',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.volume_attachments,
- volume_fakes.volume_availability_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_snapshot_id,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_image_id(self):
self.images_mock.get.return_value = fakes.FakeResource(
@@ -411,35 +317,11 @@ class TestVolumeCreate(TestVolume):
availability_zone=None,
metadata=None,
imageRef=volume_fakes.image_id,
- source_volid=None
+ source_volid=None,
)
- collist = (
- 'attachments',
- 'availability_zone',
- 'description',
- 'id',
- 'name',
- 'properties',
- 'size',
- 'snapshot_id',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.volume_attachments,
- volume_fakes.volume_availability_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_snapshot_id,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_image_name(self):
self.images_mock.get.return_value = fakes.FakeResource(
@@ -477,36 +359,20 @@ class TestVolumeCreate(TestVolume):
source_volid=None
)
- collist = (
- 'attachments',
- 'availability_zone',
- 'description',
- 'id',
- 'name',
- 'properties',
- 'size',
- 'snapshot_id',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.volume_attachments,
- volume_fakes.volume_availability_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_snapshot_id,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
class TestVolumeList(TestVolume):
+ columns = [
+ 'ID',
+ 'Display Name',
+ 'Status',
+ 'Size',
+ 'Attached to',
+ ]
+
def setUp(self):
super(TestVolumeList, self).setUp()
@@ -549,14 +415,7 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = [
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- ]
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
@@ -584,19 +443,11 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, tuple(columns))
+ self.assertEqual(self.columns, columns)
server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
-
datalist = ((
volume_fakes.volume_id,
volume_fakes.volume_name,
@@ -622,19 +473,11 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, tuple(columns))
+ self.assertEqual(self.columns, columns)
server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
-
datalist = ((
volume_fakes.volume_id,
volume_fakes.volume_name,
@@ -658,19 +501,10 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, tuple(columns))
-
+ self.assertEqual(self.columns, columns)
server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
-
datalist = ((
volume_fakes.volume_id,
volume_fakes.volume_name,
@@ -696,19 +530,11 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, tuple(columns))
+ self.assertEqual(self.columns, columns)
server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
-
datalist = ((
volume_fakes.volume_id,
volume_fakes.volume_name,
@@ -732,19 +558,11 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, tuple(columns))
+ self.assertEqual(self.columns, columns)
server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
-
datalist = ((
volume_fakes.volume_id,
volume_fakes.volume_name,
@@ -768,14 +586,7 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, tuple(columns))
+ self.assertEqual(self.columns, columns)
server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
@@ -803,14 +614,7 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = [
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- ]
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']