summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Goirand <zigo@debian.org>2015-09-26 19:37:25 +0000
committergit-ubuntu importer <ubuntu-devel-discuss@lists.ubuntu.com>2015-09-27 04:10:17 +0000
commitebeeea8f7893f20d811b5ac6cf1137787419cccd (patch)
tree77b1268ef539955f427306a909080847578d20cf
parent3b23dabb641692af41b4988583a0c80698ea94c1 (diff)
Imported using git-ubuntu import.
Notes
Notes: * New upstream release. * Fixed (build-)depends for this release.
-rw-r--r--.coveragerc2
-rw-r--r--debian/changelog7
-rw-r--r--debian/control18
-rw-r--r--doc/source/command-objects/image.rst21
-rw-r--r--doc/source/command-objects/role.rst18
-rw-r--r--doc/source/command-objects/server.rst19
-rw-r--r--doc/source/configuration.rst71
-rw-r--r--doc/source/developing.rst27
-rw-r--r--doc/source/man/openstack.rst21
-rw-r--r--doc/source/plugins.rst2
-rw-r--r--doc/source/releases.rst42
-rw-r--r--functional/tests/compute/v2/test_server.py38
-rw-r--r--functional/tests/identity/v3/test_identity.py3
-rw-r--r--functional/tests/identity/v3/test_idp.py34
-rw-r--r--functional/tests/image/v1/test_image.py2
-rw-r--r--openstackclient/api/auth.py2
-rw-r--r--openstackclient/common/configuration.py4
-rw-r--r--openstackclient/common/context.py170
-rw-r--r--openstackclient/common/limits.py4
-rw-r--r--openstackclient/common/module.py6
-rw-r--r--openstackclient/common/quota.py9
-rw-r--r--openstackclient/common/utils.py23
-rw-r--r--openstackclient/compute/client.py59
-rw-r--r--openstackclient/compute/v2/aggregate.py6
-rw-r--r--openstackclient/compute/v2/availability_zone.py2
-rw-r--r--openstackclient/compute/v2/console.py4
-rw-r--r--openstackclient/compute/v2/floatingip.py6
-rw-r--r--openstackclient/compute/v2/floatingippool.py2
-rw-r--r--openstackclient/compute/v2/keypair.py6
-rw-r--r--openstackclient/compute/v2/security_group.py19
-rw-r--r--openstackclient/compute/v2/server.py87
-rw-r--r--openstackclient/identity/v2_0/catalog.py4
-rw-r--r--openstackclient/identity/v2_0/ec2creds.py8
-rw-r--r--openstackclient/identity/v2_0/endpoint.py8
-rw-r--r--openstackclient/identity/v2_0/project.py10
-rw-r--r--openstackclient/identity/v2_0/role.py14
-rw-r--r--openstackclient/identity/v2_0/service.py8
-rw-r--r--openstackclient/identity/v2_0/token.py3
-rw-r--r--openstackclient/identity/v2_0/user.py10
-rw-r--r--openstackclient/identity/v3/catalog.py4
-rw-r--r--openstackclient/identity/v3/consumer.py10
-rw-r--r--openstackclient/identity/v3/credential.py10
-rw-r--r--openstackclient/identity/v3/domain.py10
-rw-r--r--openstackclient/identity/v3/ec2creds.py8
-rw-r--r--openstackclient/identity/v3/endpoint.py10
-rw-r--r--openstackclient/identity/v3/federation_protocol.py4
-rw-r--r--openstackclient/identity/v3/group.py16
-rw-r--r--openstackclient/identity/v3/identity_provider.py10
-rw-r--r--openstackclient/identity/v3/policy.py10
-rw-r--r--openstackclient/identity/v3/project.py10
-rw-r--r--openstackclient/identity/v3/region.py10
-rw-r--r--openstackclient/identity/v3/role.py14
-rw-r--r--openstackclient/identity/v3/service.py10
-rw-r--r--openstackclient/identity/v3/service_provider.py10
-rw-r--r--openstackclient/identity/v3/token.py2
-rw-r--r--openstackclient/identity/v3/unscoped_saml.py4
-rw-r--r--openstackclient/identity/v3/user.py22
-rw-r--r--openstackclient/image/v2/image.py225
-rw-r--r--openstackclient/object/v1/container.py8
-rw-r--r--openstackclient/object/v1/object.py8
-rw-r--r--openstackclient/shell.py106
-rw-r--r--openstackclient/tests/common/test_context.py202
-rw-r--r--openstackclient/tests/common/test_quota.py45
-rw-r--r--openstackclient/tests/compute/v2/test_security_group_rule.py338
-rw-r--r--openstackclient/tests/image/v2/test_image.py186
-rw-r--r--openstackclient/tests/test_shell.py2
-rw-r--r--openstackclient/tests/volume/v2/fakes.py7
-rw-r--r--openstackclient/tests/volume/v2/test_volume.py10
-rw-r--r--openstackclient/volume/client.py2
-rw-r--r--openstackclient/volume/v1/backup.py10
-rw-r--r--openstackclient/volume/v1/qos_specs.py16
-rw-r--r--openstackclient/volume/v1/snapshot.py12
-rw-r--r--openstackclient/volume/v1/volume.py12
-rw-r--r--openstackclient/volume/v1/volume_type.py10
-rw-r--r--openstackclient/volume/v2/qos_specs.py16
-rw-r--r--openstackclient/volume/v2/snapshot.py4
-rw-r--r--openstackclient/volume/v2/volume.py10
-rw-r--r--openstackclient/volume/v2/volume_type.py8
-rw-r--r--python-openstackclient/locale/de/LC_MESSAGES/python-openstackclient.po23
-rw-r--r--python-openstackclient/locale/python-openstackclient.pot230
-rw-r--r--requirements.txt12
-rw-r--r--setup.cfg1
-rw-r--r--setup.py2
-rw-r--r--test-requirements.txt2
84 files changed, 2011 insertions, 469 deletions
diff --git a/.coveragerc b/.coveragerc
index 9c8f046..2651b2f 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -4,4 +4,4 @@ source = openstackclient
omit = openstackclient/openstack/*
[report]
-ignore-errors = True
+ignore_errors = True
diff --git a/debian/changelog b/debian/changelog
index 01ae560..5e2465d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+python-openstackclient (1.7.0-1) experimental; urgency=medium
+
+ * New upstream release.
+ * Fixed (build-)depends for this release.
+
+ -- Thomas Goirand <zigo@debian.org> Sat, 26 Sep 2015 19:37:25 +0000
+
python-openstackclient (1.6.0-1) experimental; urgency=medium
[ gustavo panizzo ]
diff --git a/debian/control b/debian/control
index 67c3fb4..7ae2058 100644
--- a/debian/control
+++ b/debian/control
@@ -8,7 +8,7 @@ Build-Depends: debhelper (>= 9),
dh-python,
openstack-pkg-tools,
python-all,
- python-pbr (>= 1.6),
+ python-pbr (>= 1.8),
python-setuptools,
python-sphinx,
Build-Depends-Indep: cliff-tablib,
@@ -24,20 +24,20 @@ Build-Depends-Indep: cliff-tablib,
python-keystoneclient (>= 1:1.6.0),
python-mock (>= 1.3),
python-neutronclient (>= 1:2.6.0),
- python-novaclient (>= 2:2.26.0),
+ python-novaclient (>= 2:2.28.1),
python-os-client-config (>= 1.4.0),
python-os-testr,
- python-oslo.config (>= 1:1.11.0),
+ python-oslo.config (>= 1:2.3.0),
python-oslo.i18n (>= 1.5.0),
python-oslo.serialization (>= 1.2.0),
- python-oslo.utils (>= 1.9.0),
+ python-oslo.utils (>= 2.0.0),
python-oslosphinx (>= 2.5.0),
python-oslotest (>= 1.10.0),
python-requests (>= 2.5.2),
python-requests-mock (>= 0.6.0),
python-six (>= 1.9.0),
python-stevedore (>= 1.5.0),
- python-tempest-lib (>= 0.6.1),
+ python-tempest-lib (>= 0.8.0),
python-testtools (>= 1.4.0),
python-webob,
subunit,
@@ -58,13 +58,13 @@ Depends: cliff-tablib,
python-keyring,
python-keystoneclient (>= 1:1.6.0),
python-neutronclient (>= 1:2.6.0),
- python-novaclient (>= 2:2.26.0),
+ python-novaclient (>= 2:2.28.1),
python-os-client-config (>= 1.4.0),
- python-oslo.config (>= 1:1.11.0),
+ python-oslo.config (>= 1:2.3.0),
python-oslo.i18n (>= 1.5.0),
python-oslo.serialization (>= 1.2.0),
- python-oslo.utils (>= 1.9.0),
- python-pbr (>= 1.6),
+ python-oslo.utils (>= 2.0.0),
+ python-pbr (>= 1.8),
python-requests (>= 2.5.2),
python-six (>= 1.9.0),
python-stevedore (>= 1.5.0),
diff --git a/doc/source/command-objects/image.rst b/doc/source/command-objects/image.rst
index 2574142..8e44f51 100644
--- a/doc/source/command-objects/image.rst
+++ b/doc/source/command-objects/image.rst
@@ -7,7 +7,7 @@ Image v1, v2
image create
------------
-*Only supported for Image v1*
+*Image v1, v2*
Create/upload an image
@@ -32,6 +32,7 @@ Create/upload an image
[--protected | --unprotected]
[--public | --private]
[--property <key=value> [...] ]
+ [--tag <tag> [...] ]
<image-name>
.. option:: --id <id>
@@ -42,6 +43,8 @@ Create/upload an image
Upload image to this store
+ *Image version 1 only.*
+
.. option:: --container-format <container-format>
Image container format (default: bare)
@@ -54,10 +57,14 @@ Create/upload an image
Image owner project name or ID
+ *Image version 1 only.*
+
.. option:: --size <size>
Image size, in bytes (only used with --location and --copy-from)
+ *Image version 1 only.*
+
.. option:: --min-disk <disk-gb>
Minimum disk size needed to boot image, in gigabytes
@@ -70,10 +77,14 @@ Create/upload an image
Download image from an existing URL
+ *Image version 1 only.*
+
.. option:: --copy-from <image-url>
Copy image from the data store (similar to --location)
+ *Image version 1 only.*
+
.. option:: --file <file>
Upload image from local file
@@ -90,6 +101,8 @@ Create/upload an image
Image hash used for verification
+ *Image version 1 only.*
+
.. option:: --protected
Prevent image from being deleted
@@ -110,6 +123,12 @@ Create/upload an image
Set a property on this image (repeat for multiple values)
+.. option:: --tag <tag>
+
+ Set a tag on this image (repeat for multiple values)
+
+ .. versionadded:: 2
+
.. describe:: <image-name>
New image name
diff --git a/doc/source/command-objects/role.rst b/doc/source/command-objects/role.rst
index 9ba149e..48751ed 100644
--- a/doc/source/command-objects/role.rst
+++ b/doc/source/command-objects/role.rst
@@ -20,21 +20,21 @@ Add role to a user or group in a project or domain
.. option:: --domain <domain>
- Include `<domain>` (name or ID)
+ Include <domain> (name or ID)
.. versionadded:: 3
.. option:: --project <project>
- Include `<project>` (name or ID)
+ Include <project> (name or ID)
.. option:: --user <user>
- Include `<user>` (name or ID)
+ Include <user> (name or ID)
.. option:: --group <group>
- Include `<group>` (name or ID)
+ Include <group> (name or ID)
.. versionadded:: 3
@@ -67,7 +67,7 @@ Add role to a user or group in a project or domain
.. describe:: <role>
- Role to add to `<project>`:`<user>` (name or ID)
+ Role to add to <project>:<user> (name or ID)
role create
-----------
@@ -186,21 +186,21 @@ Remove role from domain/project : user/group
.. option:: --domain <domain>
- Include `<domain>` (name or ID)
+ Include <domain> (name or ID)
.. versionadded:: 3
.. option:: --project <project>
- Include `<project>` (name or ID)
+ Include <project> (name or ID)
.. option:: --user <user>
- Include `<user>` (name or ID)
+ Include <user> (name or ID)
.. option:: --group <group>
- Include `<group>` (name or ID)
+ Include <group> (name or ID)
.. versionadded:: 3
diff --git a/doc/source/command-objects/server.rst b/doc/source/command-objects/server.rst
index eb61bab..9ff4843 100644
--- a/doc/source/command-objects/server.rst
+++ b/doc/source/command-objects/server.rst
@@ -185,6 +185,7 @@ List servers
[--image <image>]
[--host <hostname>]
[--all-projects]
+ [--project <project> [--project-domain <project-domain>]]
[--long]
.. option:: --reservation-id <reservation-id>
@@ -227,6 +228,24 @@ List servers
Include all projects (admin only)
+.. option:: --project <project>
+
+ Search by project (admin only) (name or ID)
+
+.. option:: --project-domain <project-domain>
+
+ Domain the project belongs to (name or ID).
+ This can be used in case collisions between project names exist.
+
+.. option:: --user <user>
+
+ Search by user (admin only) (name or ID)
+
+.. option:: --user-domain <user-domain>
+
+ Domain the user belongs to (name or ID).
+ This can be used in case collisions between user names exist.
+
.. option:: --long
List additional fields in output
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 563a719..c770014 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -143,3 +143,74 @@ Debugging
You may find the :doc:`config show <command-objects/config>`
helpful to debug configuration issues. It will display your current
configuration.
+
+Logging Settings
+----------------
+
+By setting `log_level` or `log_file` in the configuration
+:file:`clouds.yaml`, a user may enable additional logging::
+
+ clouds:
+ devstack:
+ auth:
+ auth_url: http://192.168.122.10:35357/
+ project_name: demo
+ username: demo
+ password: 0penstack
+ region_name: RegionOne
+ operation_log:
+ logging: TRUE
+ file: /tmp/openstackclient_demo.log
+ level: info
+ ds-admin:
+ auth:
+ auth_url: http://192.168.122.10:35357/
+ project_name: admin
+ username: admin
+ password: 0penstack
+ region_name: RegionOne
+ log_file: /tmp/openstackclient_admin.log
+ log_level: debug
+
+:dfn:`log_file`: ``</path/file-name>``
+ Full path to logging file.
+:dfn:`log_level`: ``error`` | ``info`` | ``debug``
+ If log level is not set, ``warning`` will be used.
+
+If log level is ``info``, the following information is recorded:
+
+* cloud name
+* user name
+* project name
+* CLI start time (logging start time)
+* CLI end time
+* CLI arguments
+* CLI return value
+* and any ``info`` messages.
+
+If log level is ``debug``, the following information is recorded:
+
+* cloud name
+* user name
+* project name
+* CLI start time (logging start time)
+* CLI end time
+* CLI arguments
+* CLI return value
+* API request header/body
+* API response header/body
+* and any ``debug`` messages.
+
+When a command is executed, these logs are saved every time. Recording the user
+operations can help to identify resource changes and provide useful information
+for troubleshooting.
+
+If saving the output of a single command use the `--log-file` option instead.
+
+* `--log-file <LOG_FILE>`
+
+The logging level for `--log-file` can be set by using following options.
+
+* `-v, --verbose`
+* `-q, --quiet`
+* `--debug`
diff --git a/doc/source/developing.rst b/doc/source/developing.rst
index f13241f..90f0900 100644
--- a/doc/source/developing.rst
+++ b/doc/source/developing.rst
@@ -2,6 +2,16 @@
Developing with OpenStackClient
===============================
+Communication
+-------------
+
+Meetings
+=========
+The OpenStackClient team meets regularly on every Thursday. For details
+please refer to the `wiki`_.
+
+.. _`wiki`: https://wiki.openstack.org/wiki/Meetings/OpenStackClient
+
Testing
-------
@@ -87,3 +97,20 @@ create HTML docs, run the following:
$ tox -e docs
The resultant HTML will be the ``doc/build/html`` directory.
+
+Testing new code
+----------------
+
+If a developer wants to test new code (feature, command or option) that
+they have written, OpenStackClient may be installed from source by running
+the following commands in the base directory of the project:
+
+.. code-block:: bash
+
+ $ python setup.py develop
+
+or
+
+.. code-block:: bash
+
+ $ pip install -e
diff --git a/doc/source/man/openstack.rst b/doc/source/man/openstack.rst
index 53bf362..3e47635 100644
--- a/doc/source/man/openstack.rst
+++ b/doc/source/man/openstack.rst
@@ -123,6 +123,18 @@ OPTIONS
:option:`--os-interface` <interface>
Interface type. Valid options are `public`, `admin` and `internal`.
+:option:`--log-file` <LOGFILE>
+ Specify a file to log output. Disabled by default.
+
+:option:`-v, --verbose`
+ Increase verbosity of output. Can be repeated.
+
+:option:`-q, --quiet`
+ suppress output except warnings and errors
+
+:option:`--debug`
+ show tracebacks on errors and set verbosity to debug
+
COMMANDS
========
@@ -240,6 +252,15 @@ When :option:`--os-token` and :option:`--os-url` are both present the
:option:`--os-auth-url` and :option:`--os-username` are present ``password``
auth type is selected.
+Logging Settings
+----------------
+
+:program:`openstack` can record the operation history by logging settings
+in configuration file. Recording the user operation, it can identify the
+change of the resource and it becomes useful information for troubleshooting.
+
+See :doc:`../configuration` about Logging Settings for more details.
+
NOTES
=====
diff --git a/doc/source/plugins.rst b/doc/source/plugins.rst
index 8102c97..469742d 100644
--- a/doc/source/plugins.rst
+++ b/doc/source/plugins.rst
@@ -28,7 +28,7 @@ python-barbicanclient patch in progress (https://review.openstack.org/#
python-ceilometerclient using argparse
python-congressclient using OpenStackClient
python-cueclient using OpenStackClient
-python-designateclient uses cliff, but not OpenStackClient
+python-designateclient patch in progress (https://review.openstack.org/#/c/133676/)
python-heatclient patch in progress (https://review.openstack.org/#/c/195867/)
python-ironicclient patch in progress (https://review.openstack.org/#/c/171672/)
python-magnumclient using argparse
diff --git a/doc/source/releases.rst b/doc/source/releases.rst
index 5dd6771..526b163 100644
--- a/doc/source/releases.rst
+++ b/doc/source/releases.rst
@@ -2,6 +2,48 @@
Release Notes
=============
+1.7.0 (22 Sep 2015)
+===================
+
+* Add support for v2 image create/update commands
+ Bug `1405562 <https://bugs.launchpad.net/bugs/1405562>`_
+
+* ICMP secgroup rule must have ``--dst-port -1`` to actually allow ICMP
+ Bug `1477629 <https://bugs.launchpad.net/bugs/1477629>`_
+
+* Add a blurb about ``pip install -e .`` to the developer docs
+ Bug `1483384 <https://bugs.launchpad.net/bugs/1483384>`_
+
+* Add filtering by user for command 'openstack server list'
+ Bug `1483974 <https://bugs.launchpad.net/bugs/1483974>`_
+
+* No support for listing servers of other project with openstack server list
+ Bug `1488486 <https://bugs.launchpad.net/bugs/1488486>`_
+
+* Missing image causes confusing 'server show' response
+ Bug `1489901 <https://bugs.launchpad.net/bugs/1489901>`_
+
+* Volume Attached to is incorrect
+ Bug `1489954 <https://bugs.launchpad.net/bugs/1489954>`_
+
+* novaclient 2.27.0 breaks version handling
+ Bug `1492467 <https://bugs.launchpad.net/bugs/1492467>`_
+
+* Support listing users in a non-default domain scoped group
+ Bug `1492916 <https://bugs.launchpad.net/bugs/1492916>`_
+
+* ERROR: InvocationError:
+ '/opt/stack/new/python-openstackclient/.tox/functional/bin/ostestr'
+ in gate-osc-dsvm-functional
+ Bug `1496337 <https://bugs.launchpad.net/bugs/1496337>`_
+
+* image list --long is broken with v2
+ Bug `1498150 <https://bugs.launchpad.net/bugs/1498150>`_
+
+* Add ``--log-file`` option support
+
+* Set default Volume API version to ``2``
+
1.6.0 (10 Aug 2015)
===================
diff --git a/functional/tests/compute/v2/test_server.py b/functional/tests/compute/v2/test_server.py
index aa1c120..a6cc98e 100644
--- a/functional/tests/compute/v2/test_server.py
+++ b/functional/tests/compute/v2/test_server.py
@@ -15,6 +15,7 @@ import uuid
import testtools
+from functional.common import exceptions
from functional.common import test
@@ -28,18 +29,37 @@ class ServerTests(test.TestCase):
IP_POOL = 'public'
@classmethod
+ def get_flavor(cls):
+ raw_output = cls.openstack('flavor list -f value -c ID')
+ ray = raw_output.split('\n')
+ idx = len(ray)/2
+ return ray[idx]
+
+ @classmethod
+ def get_image(cls):
+ raw_output = cls.openstack('image list -f value -c ID')
+ ray = raw_output.split('\n')
+ idx = len(ray)/2
+ return ray[idx]
+
+ @classmethod
+ def get_network(cls):
+ try:
+ raw_output = cls.openstack('network list -f value -c ID')
+ except exceptions.CommandFailed:
+ return ''
+ ray = raw_output.split('\n')
+ idx = len(ray)/2
+ return ' --nic net-id=' + ray[idx]
+
+ @classmethod
def setUpClass(cls):
opts = cls.get_show_opts(cls.FIELDS)
- # TODO(thowe): pull these values from clouds.yaml
- flavor = '4'
- image = 'cirros-0.3.4-x86_64-uec'
- netid = ''
- if netid:
- nicargs = ' --nic net-id=' + netid
- else:
- nicargs = ''
+ flavor = cls.get_flavor()
+ image = cls.get_image()
+ network = cls.get_network()
raw_output = cls.openstack('server create --flavor ' + flavor +
- ' --image ' + image + nicargs + ' ' +
+ ' --image ' + image + network + ' ' +
cls.NAME + opts)
expected = cls.NAME + '\n'
cls.assertOutput(expected, raw_output)
diff --git a/functional/tests/identity/v3/test_identity.py b/functional/tests/identity/v3/test_identity.py
index bf3da16..dd5f2f4 100644
--- a/functional/tests/identity/v3/test_identity.py
+++ b/functional/tests/identity/v3/test_identity.py
@@ -28,7 +28,7 @@ class IdentityTests(test.TestCase):
TOKEN_FIELDS = ['expires', 'id', 'project_id', 'user_id']
USER_FIELDS = ['email', 'enabled', 'id', 'name', 'name',
'domain_id', 'default_project_id', 'description']
- PROJECT_FIELDS = ['description', 'id', 'domain_id',
+ PROJECT_FIELDS = ['description', 'id', 'domain_id', 'is_domain',
'enabled', 'name', 'parent_id', 'links']
ROLE_FIELDS = ['id', 'name', 'links']
SERVICE_FIELDS = ['id', 'enabled', 'name', 'type', 'description']
@@ -43,6 +43,7 @@ class IdentityTests(test.TestCase):
'Enabled', 'Interface', 'URL']
IDENTITY_PROVIDER_FIELDS = ['description', 'enabled', 'id', 'remote_ids']
+ IDENTITY_PROVIDER_LIST_HEADERS = ['ID', 'Enabled', 'Description']
@classmethod
def setUpClass(cls):
diff --git a/functional/tests/identity/v3/test_idp.py b/functional/tests/identity/v3/test_idp.py
index 6a07f15..3d6739d 100644
--- a/functional/tests/identity/v3/test_idp.py
+++ b/functional/tests/identity/v3/test_idp.py
@@ -11,6 +11,7 @@
# under the License.
from functional.tests.identity.v3 import test_identity
+from tempest_lib.common.utils import data_utils
class IdentityProviderTests(test_identity.IdentityTests):
@@ -18,3 +19,36 @@ class IdentityProviderTests(test_identity.IdentityTests):
def test_idp_create(self):
self._create_dummy_idp()
+
+ def test_idp_delete(self):
+ identity_provider = self._create_dummy_idp(add_clean_up=False)
+ raw_output = self.openstack('identity provider delete %s'
+ % identity_provider)
+ self.assertEqual(0, len(raw_output))
+
+ def test_idp_show(self):
+ identity_provider = self._create_dummy_idp(add_clean_up=True)
+ raw_output = self.openstack('identity provider show %s'
+ % identity_provider)
+ items = self.parse_show(raw_output)
+ self.assert_show_fields(items, self.IDENTITY_PROVIDER_FIELDS)
+
+ def test_idp_list(self):
+ self._create_dummy_idp(add_clean_up=True)
+ raw_output = self.openstack('identity provider list')
+ items = self.parse_listing(raw_output)
+ self.assert_table_structure(items, self.IDENTITY_PROVIDER_LIST_HEADERS)
+
+ def test_idp_set(self):
+ identity_provider = self._create_dummy_idp(add_clean_up=True)
+ new_remoteid = data_utils.rand_name('newRemoteId')
+ raw_output = self.openstack('identity provider set '
+ '%(identity-provider)s '
+ '--remote-id %(remote-id)s '
+ % {'identity-provider': identity_provider,
+ 'remote-id': new_remoteid})
+ self.assertEqual(0, len(raw_output))
+ raw_output = self.openstack('identity provider show %s'
+ % identity_provider)
+ updated_value = self.parse_show_as_object(raw_output)
+ self.assertIn(new_remoteid, updated_value['remote_ids'])
diff --git a/functional/tests/image/v1/test_image.py b/functional/tests/image/v1/test_image.py
index 9f6ddcc..17c0c3d 100644
--- a/functional/tests/image/v1/test_image.py
+++ b/functional/tests/image/v1/test_image.py
@@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import os
import uuid
from functional.common import test
@@ -25,6 +26,7 @@ class ImageTests(test.TestCase):
@classmethod
def setUpClass(cls):
+ os.environ['OS_IMAGE_API_VERSION'] = '1'
opts = cls.get_show_opts(cls.FIELDS)
raw_output = cls.openstack('image create ' + cls.NAME + opts)
expected = cls.NAME + '\n'
diff --git a/openstackclient/api/auth.py b/openstackclient/api/auth.py
index 820b4ec..66272e4 100644
--- a/openstackclient/api/auth.py
+++ b/openstackclient/api/auth.py
@@ -185,7 +185,7 @@ def build_auth_plugins_option_parser(parser):
metavar='<auth-type>',
dest='auth_type',
default=utils.env('OS_AUTH_TYPE'),
- help='Select an auhentication type. Available types: ' +
+ help='Select an authentication type. Available types: ' +
', '.join(available_plugins) +
'. Default: selected based on --os-username/--os-token' +
' (Env: OS_AUTH_TYPE)',
diff --git a/openstackclient/common/configuration.py b/openstackclient/common/configuration.py
index 83df73e..ac2792d 100644
--- a/openstackclient/common/configuration.py
+++ b/openstackclient/common/configuration.py
@@ -18,6 +18,8 @@ import logging
from cliff import show
import six
+from openstackclient.common import utils
+
REDACTED = "<redacted>"
@@ -44,8 +46,8 @@ class ShowConfiguration(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
info = self.app.client_manager.get_configuration()
for key, value in six.iteritems(info.pop('auth', {})):
diff --git a/openstackclient/common/context.py b/openstackclient/common/context.py
new file mode 100644
index 0000000..6d1aec1
--- /dev/null
+++ b/openstackclient/common/context.py
@@ -0,0 +1,170 @@
+# 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.
+#
+
+"""Application logging"""
+
+import logging
+import sys
+import warnings
+
+
+def log_level_from_options(options):
+ # if --debug, --quiet or --verbose is not specified,
+ # the default logging level is warning
+ log_level = logging.WARNING
+ if options.verbose_level == 0:
+ # --quiet
+ log_level = logging.ERROR
+ elif options.verbose_level == 2:
+ # One --verbose
+ log_level = logging.INFO
+ elif options.verbose_level >= 3:
+ # Two or more --verbose
+ log_level = logging.DEBUG
+ return log_level
+
+
+def log_level_from_config(config):
+ # Check the command line option
+ verbose_level = config.get('verbose_level')
+ if config.get('debug', False):
+ verbose_level = 3
+ if verbose_level == 0:
+ verbose_level = 'error'
+ elif verbose_level == 1:
+ # If a command line option has not been specified, check the
+ # configuration file
+ verbose_level = config.get('log_level', 'warning')
+ elif verbose_level == 2:
+ verbose_level = 'info'
+ else:
+ verbose_level = 'debug'
+
+ log_level = {
+ 'critical': logging.CRITICAL,
+ 'error': logging.ERROR,
+ 'warning': logging.WARNING,
+ 'info': logging.INFO,
+ 'debug': logging.DEBUG,
+ }.get(verbose_level, logging.WARNING)
+ return log_level
+
+
+def set_warning_filter(log_level):
+ if log_level == logging.ERROR:
+ warnings.simplefilter("ignore")
+ elif log_level == logging.WARNING:
+ warnings.simplefilter("ignore")
+ elif log_level == logging.INFO:
+ warnings.simplefilter("once")
+
+
+class _FileFormatter(logging.Formatter):
+ """Customize the logging format for logging handler"""
+ _LOG_MESSAGE_BEGIN = (
+ '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s ')
+ _LOG_MESSAGE_CONTEXT = '[%(cloud)s %(username)s %(project)s] '
+ _LOG_MESSAGE_END = '%(message)s'
+ _LOG_DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
+
+ def __init__(self, options=None, config=None, **kwargs):
+ context = {}
+ if options:
+ context = {
+ 'cloud': getattr(options, 'cloud', ''),
+ 'project': getattr(options, 'os_project_name', ''),
+ 'username': getattr(options, 'username', ''),
+ }
+ elif config:
+ context = {
+ 'cloud': config.config.get('cloud', ''),
+ 'project': config.auth.get('project_name', ''),
+ 'username': config.auth.get('username', ''),
+ }
+ if context:
+ self.fmt = (self._LOG_MESSAGE_BEGIN +
+ (self._LOG_MESSAGE_CONTEXT % context) +
+ self._LOG_MESSAGE_END)
+ else:
+ self.fmt = self._LOG_MESSAGE_BEGIN + self._LOG_MESSAGE_END
+ logging.Formatter.__init__(self, self.fmt, self._LOG_DATE_FORMAT)
+
+
+class LogConfigurator(object):
+
+ _CONSOLE_MESSAGE_FORMAT = '%(message)s'
+
+ def __init__(self, options):
+ self.root_logger = logging.getLogger('')
+ self.root_logger.setLevel(logging.DEBUG)
+
+ # Force verbose_level 3 on --debug
+ self.dump_trace = False
+ if options.debug:
+ options.verbose_level = 3
+ self.dump_trace = True
+
+ # Always send higher-level messages to the console via stderr
+ self.console_logger = logging.StreamHandler(sys.stderr)
+ log_level = log_level_from_options(options)
+ self.console_logger.setLevel(log_level)
+ formatter = logging.Formatter(self._CONSOLE_MESSAGE_FORMAT)
+ self.console_logger.setFormatter(formatter)
+ self.root_logger.addHandler(self.console_logger)
+
+ # Set the warning filter now
+ set_warning_filter(log_level)
+
+ # Set up logging to a file
+ self.file_logger = None
+ log_file = options.log_file
+ if log_file:
+ self.file_logger = logging.FileHandler(filename=log_file)
+ self.file_logger.setFormatter(_FileFormatter(options=options))
+ self.file_logger.setLevel(log_level)
+ self.root_logger.addHandler(self.file_logger)
+
+ # Requests logs some stuff at INFO that we don't want
+ # unless we have DEBUG
+ requests_log = logging.getLogger("requests")
+
+ # Other modules we don't want DEBUG output for
+ cliff_log = logging.getLogger('cliff')
+ stevedore_log = logging.getLogger('stevedore')
+ iso8601_log = logging.getLogger("iso8601")
+
+ if options.debug:
+ # --debug forces traceback
+ requests_log.setLevel(logging.DEBUG)
+ else:
+ requests_log.setLevel(logging.ERROR)
+
+ cliff_log.setLevel(logging.ERROR)
+ stevedore_log.setLevel(logging.ERROR)
+ iso8601_log.setLevel(logging.ERROR)
+
+ def configure(self, cloud_config):
+ log_level = log_level_from_config(cloud_config.config)
+ set_warning_filter(log_level)
+ self.dump_trace = cloud_config.config.get('debug', self.dump_trace)
+ self.console_logger.setLevel(log_level)
+
+ log_file = cloud_config.config.get('log_file', None)
+ if log_file:
+ if not self.file_logger:
+ self.file_logger = logging.FileHandler(filename=log_file)
+ formatter = _FileFormatter(cloud_config=cloud_config)
+ self.file_logger.setFormatter(formatter)
+ self.file_logger.setFormatter(_FileFormatter(config=cloud_config))
+ self.file_logger.setLevel(log_level)
+ self.root_logger.addHandler(self.file_logger)
diff --git a/openstackclient/common/limits.py b/openstackclient/common/limits.py
index 4abcf16..582f70c 100644
--- a/openstackclient/common/limits.py
+++ b/openstackclient/common/limits.py
@@ -31,7 +31,7 @@ class ShowLimits(lister.Lister):
def get_parser(self, prog_name):
parser = super(ShowLimits, self).get_parser(prog_name)
- type_group = parser.add_mutually_exclusive_group()
+ type_group = parser.add_mutually_exclusive_group(required=True)
type_group.add_argument(
"--absolute",
dest="is_absolute",
@@ -64,8 +64,8 @@ class ShowLimits(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
volume_client = self.app.client_manager.volume
diff --git a/openstackclient/common/module.py b/openstackclient/common/module.py
index 356cdca..f0ed23b 100644
--- a/openstackclient/common/module.py
+++ b/openstackclient/common/module.py
@@ -22,6 +22,8 @@ import sys
from cliff import lister
from cliff import show
+from openstackclient.common import utils
+
class ListCommand(lister.Lister):
"""List recognized commands by group"""
@@ -29,8 +31,8 @@ class ListCommand(lister.Lister):
auth_required = False
log = logging.getLogger(__name__ + '.ListCommand')
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
cm = self.app.command_manager
groups = cm.get_command_groups()
@@ -54,8 +56,8 @@ class ListModule(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
data = {}
# Get module versions
diff --git a/openstackclient/common/quota.py b/openstackclient/common/quota.py
index e79fd7e..e092fef 100644
--- a/openstackclient/common/quota.py
+++ b/openstackclient/common/quota.py
@@ -23,6 +23,8 @@ import sys
from cliff import command
from cliff import show
+from openstackclient.common import utils
+
# List the quota items, map the internal argument name to the option
# name that the user sees.
@@ -89,8 +91,8 @@ class SetQuota(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
volume_client = self.app.client_manager.volume
@@ -103,8 +105,7 @@ class SetQuota(command.Command):
volume_kwargs = {}
for k, v in VOLUME_QUOTAS.items():
- # TODO(jiaxi): Should use k or v needs discuss
- value = getattr(parsed_args, v, None)
+ value = getattr(parsed_args, k, None)
if value is not None:
if parsed_args.volume_type:
k = k + '_%s' % parsed_args.volume_type
@@ -188,8 +189,8 @@ class ShowQuota(show.ShowOne):
else:
return {}
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
volume_client = self.app.client_manager.volume
diff --git a/openstackclient/common/utils.py b/openstackclient/common/utils.py
index 2f8419f..b6726bf 100644
--- a/openstackclient/common/utils.py
+++ b/openstackclient/common/utils.py
@@ -26,6 +26,29 @@ from oslo_utils import importutils
from openstackclient.common import exceptions
+def log_method(log, level=logging.DEBUG):
+ """Logs a method and its arguments when entered."""
+
+ def decorator(func):
+ func_name = func.__name__
+
+ @six.wraps(func)
+ def wrapper(self, *args, **kwargs):
+ if log.isEnabledFor(level):
+ pretty_args = []
+ if args:
+ pretty_args.extend(str(a) for a in args)
+ if kwargs:
+ pretty_args.extend(
+ "%s=%s" % (k, v) for k, v in six.iteritems(kwargs))
+ log.log(level, "%s(%s)", func_name, ", ".join(pretty_args))
+ return func(self, *args, **kwargs)
+
+ return wrapper
+
+ return decorator
+
+
def find_resource(manager, name_or_id, **kwargs):
"""Helper for the _find_* methods.
diff --git a/openstackclient/compute/client.py b/openstackclient/compute/client.py
index 9dda32d..8ac5f32 100644
--- a/openstackclient/compute/client.py
+++ b/openstackclient/compute/client.py
@@ -15,6 +15,7 @@
import logging
+from openstackclient.common import exceptions
from openstackclient.common import utils
LOG = logging.getLogger(__name__)
@@ -26,6 +27,9 @@ API_VERSIONS = {
"2": "novaclient.client",
}
+# Save the microversion if in use
+_compute_api_version = None
+
def make_client(instance):
"""Returns a compute service client."""
@@ -38,10 +42,12 @@ def make_client(instance):
except ImportError:
from novaclient.v1_1.contrib import list_extensions
- compute_client = nova_client.get_client_class(
- instance._api_version[API_NAME],
- )
- LOG.debug('Instantiating compute client: %s', compute_client)
+ if _compute_api_version is not None:
+ version = _compute_api_version
+ else:
+ version = instance._api_version[API_NAME]
+
+ LOG.debug('Instantiating compute client for V%s' % version)
# Set client http_log_debug to True if verbosity level is high enough
http_log_debug = utils.get_effective_log_level() <= logging.DEBUG
@@ -51,7 +57,8 @@ def make_client(instance):
# Remember interface only if it is set
kwargs = utils.build_kwargs_dict('endpoint_type', instance._interface)
- client = compute_client(
+ client = nova_client.Client(
+ version,
session=instance.session,
extensions=extensions,
http_log_debug=http_log_debug,
@@ -73,3 +80,45 @@ def build_option_parser(parser):
DEFAULT_API_VERSION +
' (Env: OS_COMPUTE_API_VERSION)')
return parser
+
+
+def check_api_version(check_version):
+ """Validate version supplied by user
+
+ Returns:
+ * True if version is OK
+ * False if the version has not been checked and the previous plugin
+ check should be performed
+ * throws an exception if the version is no good
+
+ TODO(dtroyer): make the exception thrown a version-related one
+ """
+
+ # Defer client imports until we actually need them
+ try:
+ from novaclient import api_versions
+ except ImportError:
+ # Retain previous behaviour
+ return False
+
+ import novaclient
+
+ global _compute_api_version
+
+ # Copy some logic from novaclient 2.27.0 for basic version detection
+ # NOTE(dtroyer): This is only enough to resume operations using API
+ # version 2.0 or any valid version supplied by the user.
+ _compute_api_version = api_versions.get_api_version(check_version)
+
+ if _compute_api_version > api_versions.APIVersion("2.0"):
+ if not _compute_api_version.matches(
+ novaclient.API_MIN_VERSION,
+ novaclient.API_MAX_VERSION,
+ ):
+ raise exceptions.CommandError(
+ "versions supported by client: %s - %s" % (
+ novaclient.API_MIN_VERSION.get_string(),
+ novaclient.API_MAX_VERSION.get_string(),
+ ),
+ )
+ return True
diff --git a/openstackclient/compute/v2/aggregate.py b/openstackclient/compute/v2/aggregate.py
index 84ed5c7..a1ba618 100644
--- a/openstackclient/compute/v2/aggregate.py
+++ b/openstackclient/compute/v2/aggregate.py
@@ -123,8 +123,8 @@ class DeleteAggregate(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
data = utils.find_resource(
@@ -256,8 +256,8 @@ class SetAggregate(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
aggregate = utils.find_resource(
@@ -303,8 +303,8 @@ class ShowAggregate(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
data = utils.find_resource(
diff --git a/openstackclient/compute/v2/availability_zone.py b/openstackclient/compute/v2/availability_zone.py
index 648c0ee..0fe6c73 100644
--- a/openstackclient/compute/v2/availability_zone.py
+++ b/openstackclient/compute/v2/availability_zone.py
@@ -73,8 +73,8 @@ class ListAvailabilityZone(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
if parsed_args.long:
columns = ('Zone Name', 'Zone Status',
diff --git a/openstackclient/compute/v2/console.py b/openstackclient/compute/v2/console.py
index 082a3a0..bb0747b 100644
--- a/openstackclient/compute/v2/console.py
+++ b/openstackclient/compute/v2/console.py
@@ -47,8 +47,8 @@ class ShowConsoleLog(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
server = utils.find_resource(
@@ -103,8 +103,8 @@ class ShowConsoleURL(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
server = utils.find_resource(
compute_client.servers,
diff --git a/openstackclient/compute/v2/floatingip.py b/openstackclient/compute/v2/floatingip.py
index 658f0d5..c557c24 100644
--- a/openstackclient/compute/v2/floatingip.py
+++ b/openstackclient/compute/v2/floatingip.py
@@ -69,8 +69,8 @@ class CreateFloatingIP(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
floating_ip = compute_client.floating_ips.create(parsed_args.pool)
@@ -93,8 +93,8 @@ class DeleteFloatingIP(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
floating_ip = utils.find_resource(
@@ -111,8 +111,8 @@ class ListFloatingIP(lister.Lister):
log = logging.getLogger(__name__ + '.ListFloatingIP')
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
columns = ('ID', 'Pool', 'IP', 'Fixed IP', 'Instance ID')
diff --git a/openstackclient/compute/v2/floatingippool.py b/openstackclient/compute/v2/floatingippool.py
index db1c9f0..cc48555 100644
--- a/openstackclient/compute/v2/floatingippool.py
+++ b/openstackclient/compute/v2/floatingippool.py
@@ -27,8 +27,8 @@ class ListFloatingIPPool(lister.Lister):
log = logging.getLogger(__name__ + '.ListFloatingIPPool')
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
columns = ('Name',)
diff --git a/openstackclient/compute/v2/keypair.py b/openstackclient/compute/v2/keypair.py
index edf25f8..5c627c5 100644
--- a/openstackclient/compute/v2/keypair.py
+++ b/openstackclient/compute/v2/keypair.py
@@ -47,8 +47,8 @@ class CreateKeypair(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
public_key = parsed_args.public_key
@@ -93,8 +93,8 @@ class DeleteKeypair(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
compute_client.keypairs.delete(parsed_args.name)
return
@@ -140,8 +140,8 @@ class ShowKeypair(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
keypair = utils.find_resource(compute_client.keypairs,
parsed_args.name)
diff --git a/openstackclient/compute/v2/security_group.py b/openstackclient/compute/v2/security_group.py
index 3dc9bae..3dd0c49 100644
--- a/openstackclient/compute/v2/security_group.py
+++ b/openstackclient/compute/v2/security_group.py
@@ -50,10 +50,10 @@ def _xform_security_group_rule(sgroup):
info['ip_range'] = info['ip_range']['cidr']
else:
info['ip_range'] = ''
- if info['ip_protocol'] == 'icmp':
- info['port_range'] = ''
- elif info['ip_protocol'] is None:
+ if info['ip_protocol'] is None:
info['ip_protocol'] = ''
+ elif info['ip_protocol'].lower() == 'icmp':
+ info['port_range'] = ''
return info
@@ -107,8 +107,8 @@ class DeleteSecurityGroup(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
data = utils.find_resource(
@@ -199,8 +199,8 @@ class SetSecurityGroup(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
data = utils.find_resource(
@@ -240,8 +240,8 @@ class ShowSecurityGroup(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
info = {}
@@ -307,7 +307,10 @@ class CreateSecurityGroupRule(show.ShowOne):
compute_client.security_groups,
parsed_args.group,
)
- from_port, to_port = parsed_args.dst_port
+ if parsed_args.proto.lower() == 'icmp':
+ from_port, to_port = -1, -1
+ else:
+ from_port, to_port = parsed_args.dst_port
data = compute_client.security_group_rules.create(
group.id,
parsed_args.proto,
@@ -334,8 +337,8 @@ class DeleteSecurityGroupRule(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
compute_client.security_group_rules.delete(parsed_args.rule)
diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index 4efef97..661ce84 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -36,6 +36,7 @@ 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 as identity_common
from openstackclient.network import common
@@ -107,14 +108,20 @@ def _prep_server_detail(compute_client, server):
image_info = info.get('image', {})
if image_info:
image_id = image_info.get('id', '')
- image = utils.find_resource(compute_client.images, image_id)
- info['image'] = "%s (%s)" % (image.name, image_id)
+ try:
+ image = utils.find_resource(compute_client.images, image_id)
+ info['image'] = "%s (%s)" % (image.name, image_id)
+ except Exception:
+ info['image'] = image_id
# Convert the flavor blob to a name
flavor_info = info.get('flavor', {})
flavor_id = flavor_info.get('id', '')
- flavor = utils.find_resource(compute_client.flavors, flavor_id)
- info['flavor'] = "%s (%s)" % (flavor.name, flavor_id)
+ try:
+ flavor = utils.find_resource(compute_client.flavors, flavor_id)
+ info['flavor'] = "%s (%s)" % (flavor.name, flavor_id)
+ except Exception:
+ info['flavor'] = flavor_id
# NOTE(dtroyer): novaclient splits these into separate entries...
# Format addresses in a useful way
@@ -355,8 +362,8 @@ class CreateServer(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
volume_client = self.app.client_manager.volume
@@ -553,8 +560,8 @@ class CreateServerImage(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
image_client = self.app.client_manager.image
server = utils.find_resource(
@@ -612,8 +619,8 @@ class DeleteServer(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
for server in parsed_args.servers:
server_obj = utils.find_resource(
@@ -694,6 +701,17 @@ class ListServer(lister.Lister):
help=_('Include all projects (admin only)'),
)
parser.add_argument(
+ '--project',
+ metavar='<project>',
+ help="Search by project (admin only) (name or ID)")
+ identity_common.add_project_domain_option_to_parser(parser)
+ parser.add_argument(
+ '--user',
+ metavar='<user>',
+ help=_('Search by user (admin only) (name or ID)'),
+ )
+ identity_common.add_user_domain_option_to_parser(parser)
+ parser.add_argument(
'--long',
action='store_true',
default=False,
@@ -701,9 +719,28 @@ class ListServer(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
+ identity_client = self.app.client_manager.identity
+
+ project_id = None
+ if parsed_args.project:
+ project_id = identity_common.find_project(
+ identity_client,
+ parsed_args.project,
+ parsed_args.project_domain,
+ ).id
+ parsed_args.all_projects = True
+
+ user_id = None
+ if parsed_args.user:
+ user_id = identity_common.find_project(
+ identity_client,
+ parsed_args.user,
+ parsed_args.user_domain,
+ ).id
+
search_opts = {
'reservation_id': parsed_args.reservation_id,
'ip': parsed_args.ip,
@@ -714,7 +751,9 @@ class ListServer(lister.Lister):
'flavor': parsed_args.flavor,
'image': parsed_args.image,
'host': parsed_args.host,
+ 'tenant_id': project_id,
'all_tenants': parsed_args.all_projects,
+ 'user_id': user_id,
}
self.log.debug('search options: %s', search_opts)
@@ -772,8 +811,8 @@ class LockServer(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
utils.find_resource(
@@ -845,8 +884,8 @@ class MigrateServer(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
@@ -889,8 +928,8 @@ class PauseServer(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
utils.find_resource(
@@ -935,8 +974,8 @@ class RebootServer(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
server = utils.find_resource(
compute_client.servers, parsed_args.server)
@@ -984,8 +1023,8 @@ class RebuildServer(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
# Lookup parsed_args.image
@@ -1100,8 +1139,8 @@ class RescueServer(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
_, body = utils.find_resource(
@@ -1146,8 +1185,8 @@ class ResizeServer(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
server = utils.find_resource(
@@ -1191,8 +1230,8 @@ class ResumeServer(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
utils.find_resource(
@@ -1232,8 +1271,8 @@ class SetServer(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
server = utils.find_resource(
@@ -1280,8 +1319,8 @@ class ShowServer(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
server = utils.find_resource(compute_client.servers,
parsed_args.server)
@@ -1403,8 +1442,8 @@ class SshServer(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
server = utils.find_resource(
@@ -1458,8 +1497,8 @@ class SuspendServer(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
utils.find_resource(
@@ -1482,8 +1521,8 @@ class UnlockServer(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
utils.find_resource(
@@ -1506,8 +1545,8 @@ class UnpauseServer(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
utils.find_resource(
@@ -1530,8 +1569,8 @@ class UnrescueServer(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
utils.find_resource(
@@ -1562,8 +1601,8 @@ class UnsetServer(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
compute_client = self.app.client_manager.compute
server = utils.find_resource(
compute_client.servers,
diff --git a/openstackclient/identity/v2_0/catalog.py b/openstackclient/identity/v2_0/catalog.py
index e166c85..9bc2755 100644
--- a/openstackclient/identity/v2_0/catalog.py
+++ b/openstackclient/identity/v2_0/catalog.py
@@ -42,8 +42,8 @@ class ListCatalog(lister.Lister):
log = logging.getLogger(__name__ + '.ListCatalog')
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
# This is ugly because if auth hasn't happened yet we need
# to trigger it here.
@@ -76,8 +76,8 @@ class ShowCatalog(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
# This is ugly because if auth hasn't happened yet we need
# to trigger it here.
diff --git a/openstackclient/identity/v2_0/ec2creds.py b/openstackclient/identity/v2_0/ec2creds.py
index 348479a..a7730ce 100644
--- a/openstackclient/identity/v2_0/ec2creds.py
+++ b/openstackclient/identity/v2_0/ec2creds.py
@@ -52,8 +52,8 @@ class CreateEC2Creds(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if parsed_args.project:
@@ -105,8 +105,8 @@ class DeleteEC2Creds(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if parsed_args.user:
@@ -135,8 +135,8 @@ class ListEC2Creds(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if parsed_args.user:
@@ -178,8 +178,8 @@ class ShowEC2Creds(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if parsed_args.user:
diff --git a/openstackclient/identity/v2_0/endpoint.py b/openstackclient/identity/v2_0/endpoint.py
index 370a931..1744cc7 100644
--- a/openstackclient/identity/v2_0/endpoint.py
+++ b/openstackclient/identity/v2_0/endpoint.py
@@ -62,8 +62,8 @@ class CreateEndpoint(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
service = common.find_service(identity_client, parsed_args.service)
endpoint = identity_client.endpoints.create(
@@ -93,8 +93,8 @@ class DeleteEndpoint(command.Command):
help=_('Endpoint ID to delete'))
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
identity_client.endpoints.delete(parsed_args.endpoint)
return
@@ -115,8 +115,8 @@ class ListEndpoint(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if parsed_args.long:
columns = ('ID', 'Region', 'Service Name', 'Service Type',
@@ -150,8 +150,8 @@ class ShowEndpoint(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
data = identity_client.endpoints.list()
match = None
diff --git a/openstackclient/identity/v2_0/project.py b/openstackclient/identity/v2_0/project.py
index d01807a..97a95f2 100644
--- a/openstackclient/identity/v2_0/project.py
+++ b/openstackclient/identity/v2_0/project.py
@@ -70,8 +70,8 @@ class CreateProject(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
enabled = True
@@ -118,8 +118,8 @@ class DeleteProject(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
for project in parsed_args.projects:
@@ -146,8 +146,8 @@ class ListProject(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
if parsed_args.long:
columns = ('ID', 'Name', 'Description', 'Enabled')
else:
@@ -202,8 +202,8 @@ class SetProject(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if (not parsed_args.name
@@ -253,8 +253,8 @@ class ShowProject(show.ShowOne):
help=_('Project to display (name or ID)'))
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
info = {}
diff --git a/openstackclient/identity/v2_0/role.py b/openstackclient/identity/v2_0/role.py
index 3167f50..e98f8cb 100644
--- a/openstackclient/identity/v2_0/role.py
+++ b/openstackclient/identity/v2_0/role.py
@@ -54,8 +54,8 @@ class AddRole(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
role = utils.find_resource(identity_client.roles, parsed_args.role)
project = utils.find_resource(
@@ -93,8 +93,8 @@ class CreateRole(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
try:
role = identity_client.roles.create(parsed_args.role_name)
@@ -128,8 +128,8 @@ class DeleteRole(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
for role in parsed_args.roles:
@@ -160,8 +160,8 @@ class ListRole(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
auth_ref = self.app.client_manager.auth_ref
@@ -242,8 +242,8 @@ class ListUserRole(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
auth_ref = self.app.client_manager.auth_ref
@@ -316,8 +316,8 @@ class RemoveRole(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
role = utils.find_resource(identity_client.roles, parsed_args.role)
project = utils.find_resource(
@@ -345,8 +345,8 @@ class ShowRole(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
role = utils.find_resource(identity_client.roles, parsed_args.role)
diff --git a/openstackclient/identity/v2_0/service.py b/openstackclient/identity/v2_0/service.py
index f863023..c9d4844 100644
--- a/openstackclient/identity/v2_0/service.py
+++ b/openstackclient/identity/v2_0/service.py
@@ -59,8 +59,8 @@ class CreateService(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
type_or_name = parsed_args.type_or_name
@@ -106,8 +106,8 @@ class DeleteService(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
service = common.find_service(identity_client, parsed_args.service)
identity_client.services.delete(service.id)
@@ -129,8 +129,8 @@ class ListService(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
if parsed_args.long:
columns = ('ID', 'Name', 'Type', 'Description')
@@ -163,8 +163,8 @@ class ShowService(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
auth_ref = self.app.client_manager.auth_ref
diff --git a/openstackclient/identity/v2_0/token.py b/openstackclient/identity/v2_0/token.py
index c8b003e..5fed58e 100644
--- a/openstackclient/identity/v2_0/token.py
+++ b/openstackclient/identity/v2_0/token.py
@@ -21,6 +21,7 @@ import six
from cliff import command
from cliff import show
+from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
@@ -33,8 +34,8 @@ class IssueToken(show.ShowOne):
parser = super(IssueToken, self).get_parser(prog_name)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
token = self.app.client_manager.auth_ref.service_catalog.get_token()
token['project_id'] = token.pop('tenant_id')
diff --git a/openstackclient/identity/v2_0/user.py b/openstackclient/identity/v2_0/user.py
index 500aeec..76902e6 100644
--- a/openstackclient/identity/v2_0/user.py
+++ b/openstackclient/identity/v2_0/user.py
@@ -78,8 +78,8 @@ class CreateUser(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if parsed_args.project:
@@ -142,8 +142,8 @@ class DeleteUser(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
for user in parsed_args.users:
@@ -174,8 +174,8 @@ class ListUser(lister.Lister):
help=_('List additional fields in output'))
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
def _format_project(project):
@@ -296,8 +296,8 @@ class SetUser(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if parsed_args.password_prompt:
@@ -362,8 +362,8 @@ class ShowUser(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
info = {}
diff --git a/openstackclient/identity/v3/catalog.py b/openstackclient/identity/v3/catalog.py
index 1899f25..76f7da5 100644
--- a/openstackclient/identity/v3/catalog.py
+++ b/openstackclient/identity/v3/catalog.py
@@ -39,8 +39,8 @@ class ListCatalog(lister.Lister):
log = logging.getLogger(__name__ + '.ListCatalog')
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
# This is ugly because if auth hasn't happened yet we need
# to trigger it here.
@@ -73,8 +73,8 @@ class ShowCatalog(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
# This is ugly because if auth hasn't happened yet we need
# to trigger it here.
diff --git a/openstackclient/identity/v3/consumer.py b/openstackclient/identity/v3/consumer.py
index ffbd510..0a6ade6 100644
--- a/openstackclient/identity/v3/consumer.py
+++ b/openstackclient/identity/v3/consumer.py
@@ -40,8 +40,8 @@ class CreateConsumer(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
consumer = identity_client.oauth1.consumers.create(
parsed_args.description
@@ -64,8 +64,8 @@ class DeleteConsumer(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
consumer = utils.find_resource(
identity_client.oauth1.consumers, parsed_args.consumer)
@@ -78,8 +78,8 @@ class ListConsumer(lister.Lister):
log = logging.getLogger(__name__ + '.ListConsumer')
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
columns = ('ID', 'Description')
data = self.app.client_manager.identity.oauth1.consumers.list()
return (columns,
@@ -108,8 +108,8 @@ class SetConsumer(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
consumer = utils.find_resource(
identity_client.oauth1.consumers, parsed_args.consumer)
@@ -140,8 +140,8 @@ class ShowConsumer(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
consumer = utils.find_resource(
identity_client.oauth1.consumers, parsed_args.consumer)
diff --git a/openstackclient/identity/v3/credential.py b/openstackclient/identity/v3/credential.py
index dacbc9a..dbd73e2 100644
--- a/openstackclient/identity/v3/credential.py
+++ b/openstackclient/identity/v3/credential.py
@@ -57,8 +57,8 @@ class CreateCredential(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
user_id = utils.find_resource(identity_client.users,
parsed_args.user).id
@@ -91,8 +91,8 @@ class DeleteCredential(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
identity_client.credentials.delete(parsed_args.credential)
return
@@ -103,8 +103,8 @@ class ListCredential(lister.Lister):
log = logging.getLogger(__name__ + '.ListCredential')
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
columns = ('ID', 'Type', 'User ID', 'Blob', 'Project ID')
column_headers = ('ID', 'Type', 'User ID', 'Data', 'Project ID')
data = self.app.client_manager.identity.credentials.list()
@@ -150,8 +150,8 @@ class SetCredential(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
kwargs = {}
if parsed_args.user:
@@ -189,8 +189,8 @@ class ShowCredential(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
credential = utils.find_resource(identity_client.credentials,
parsed_args.credential)
diff --git a/openstackclient/identity/v3/domain.py b/openstackclient/identity/v3/domain.py
index 38f99a9..aec530a 100644
--- a/openstackclient/identity/v3/domain.py
+++ b/openstackclient/identity/v3/domain.py
@@ -63,8 +63,8 @@ class CreateDomain(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
enabled = True
@@ -103,8 +103,8 @@ class DeleteDomain(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
domain = utils.find_resource(identity_client.domains,
parsed_args.domain)
@@ -117,8 +117,8 @@ class ListDomain(lister.Lister):
log = logging.getLogger(__name__ + '.ListDomain')
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
columns = ('ID', 'Name', 'Enabled', 'Description')
data = self.app.client_manager.identity.domains.list()
return (columns,
@@ -163,8 +163,8 @@ class SetDomain(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
domain = utils.find_resource(identity_client.domains,
parsed_args.domain)
@@ -200,8 +200,8 @@ class ShowDomain(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
domain = utils.find_resource(identity_client.domains,
parsed_args.domain)
diff --git a/openstackclient/identity/v3/ec2creds.py b/openstackclient/identity/v3/ec2creds.py
index 0331463..a12ee25 100644
--- a/openstackclient/identity/v3/ec2creds.py
+++ b/openstackclient/identity/v3/ec2creds.py
@@ -79,8 +79,8 @@ class CreateEC2Creds(show.ShowOne):
common.add_project_domain_option_to_parser(parser)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
client_manager = self.app.client_manager
user = _determine_ec2_user(parsed_args, client_manager)
@@ -136,8 +136,8 @@ class DeleteEC2Creds(command.Command):
common.add_user_domain_option_to_parser(parser)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
client_manager = self.app.client_manager
user = _determine_ec2_user(parsed_args, client_manager)
client_manager.identity.ec2.delete(user, parsed_args.access_key)
@@ -158,8 +158,8 @@ class ListEC2Creds(lister.Lister):
common.add_user_domain_option_to_parser(parser)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
client_manager = self.app.client_manager
user = _determine_ec2_user(parsed_args, client_manager)
@@ -194,8 +194,8 @@ class ShowEC2Creds(show.ShowOne):
common.add_user_domain_option_to_parser(parser)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
client_manager = self.app.client_manager
user = _determine_ec2_user(parsed_args, client_manager)
creds = client_manager.identity.ec2.get(user, parsed_args.access_key)
diff --git a/openstackclient/identity/v3/endpoint.py b/openstackclient/identity/v3/endpoint.py
index 52db5ac..3d1c6f5 100644
--- a/openstackclient/identity/v3/endpoint.py
+++ b/openstackclient/identity/v3/endpoint.py
@@ -78,8 +78,8 @@ class CreateEndpoint(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
service = common.find_service(identity_client, parsed_args.service)
@@ -113,8 +113,8 @@ class DeleteEndpoint(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
endpoint_id = utils.find_resource(identity_client.endpoints,
parsed_args.endpoint).id
@@ -147,8 +147,8 @@ class ListEndpoint(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
columns = ('ID', 'Region', 'Service Name', 'Service Type',
'Enabled', 'Interface', 'URL')
@@ -221,8 +221,8 @@ class SetEndpoint(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
endpoint = utils.find_resource(identity_client.endpoints,
parsed_args.endpoint)
@@ -270,8 +270,8 @@ class ShowEndpoint(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
endpoint = utils.find_resource(identity_client.endpoints,
parsed_args.endpoint)
diff --git a/openstackclient/identity/v3/federation_protocol.py b/openstackclient/identity/v3/federation_protocol.py
index 57e8255..20877fc 100644
--- a/openstackclient/identity/v3/federation_protocol.py
+++ b/openstackclient/identity/v3/federation_protocol.py
@@ -50,8 +50,8 @@ class CreateProtocol(show.ShowOne):
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
protocol = identity_client.federation.protocols.create(
protocol_id=parsed_args.federation_protocol,
@@ -88,8 +88,8 @@ class DeleteProtocol(command.Command):
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
identity_client.federation.protocols.delete(
parsed_args.identity_provider, parsed_args.federation_protocol)
diff --git a/openstackclient/identity/v3/group.py b/openstackclient/identity/v3/group.py
index d659f71..8297506 100644
--- a/openstackclient/identity/v3/group.py
+++ b/openstackclient/identity/v3/group.py
@@ -50,8 +50,8 @@ class AddUserToGroup(command.Command):
common.add_user_domain_option_to_parser(parser)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
user_id = common.find_user(identity_client,
@@ -92,8 +92,8 @@ class CheckUserInGroup(command.Command):
common.add_user_domain_option_to_parser(parser)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
user_id = common.find_user(identity_client,
@@ -142,8 +142,8 @@ class CreateGroup(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
domain = None
@@ -188,8 +188,8 @@ class DeleteGroup(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
for group in parsed_args.groups:
@@ -226,8 +226,8 @@ class ListGroup(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
domain = None
@@ -284,8 +284,8 @@ class RemoveUserFromGroup(command.Command):
common.add_user_domain_option_to_parser(parser)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
user_id = common.find_user(identity_client,
@@ -331,8 +331,8 @@ class SetGroup(command.Command):
help='New group description')
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
group = common.find_group(identity_client, parsed_args.group,
parsed_args.domain)
@@ -368,8 +368,8 @@ class ShowGroup(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
group = common.find_group(identity_client,
diff --git a/openstackclient/identity/v3/identity_provider.py b/openstackclient/identity/v3/identity_provider.py
index 8096580..27982a9 100644
--- a/openstackclient/identity/v3/identity_provider.py
+++ b/openstackclient/identity/v3/identity_provider.py
@@ -70,8 +70,8 @@ class CreateIdentityProvider(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if parsed_args.remote_id_file:
file_content = utils.read_blob_file_contents(
@@ -105,8 +105,8 @@ class DeleteIdentityProvider(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
identity_client.federation.identity_providers.delete(
parsed_args.identity_provider)
@@ -118,8 +118,8 @@ class ListIdentityProvider(lister.Lister):
log = logging.getLogger(__name__ + '.ListIdentityProvider')
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
columns = ('ID', 'Enabled', 'Description')
identity_client = self.app.client_manager.identity
data = identity_client.federation.identity_providers.list()
@@ -169,8 +169,8 @@ class SetIdentityProvider(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
federation_client = self.app.client_manager.identity.federation
# Basic argument checking
@@ -218,8 +218,8 @@ class ShowIdentityProvider(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
identity_provider = utils.find_resource(
identity_client.federation.identity_providers,
diff --git a/openstackclient/identity/v3/policy.py b/openstackclient/identity/v3/policy.py
index 8293542..9da9486 100644
--- a/openstackclient/identity/v3/policy.py
+++ b/openstackclient/identity/v3/policy.py
@@ -47,8 +47,8 @@ class CreatePolicy(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
blob = utils.read_blob_file_contents(parsed_args.rules)
identity_client = self.app.client_manager.identity
@@ -75,8 +75,8 @@ class DeletePolicy(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
identity_client.policies.delete(parsed_args.policy)
return
@@ -97,8 +97,8 @@ class ListPolicy(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
if parsed_args.long:
columns = ('ID', 'Type', 'Blob')
column_headers = ('ID', 'Type', 'Rules')
@@ -137,8 +137,8 @@ class SetPolicy(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
blob = None
@@ -172,8 +172,8 @@ class ShowPolicy(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
policy = utils.find_resource(identity_client.policies,
parsed_args.policy)
diff --git a/openstackclient/identity/v3/project.py b/openstackclient/identity/v3/project.py
index 8185d65..96d7f97 100644
--- a/openstackclient/identity/v3/project.py
+++ b/openstackclient/identity/v3/project.py
@@ -81,8 +81,8 @@ class CreateProject(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
domain = None
@@ -146,8 +146,8 @@ class DeleteProject(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
domain = None
@@ -190,8 +190,8 @@ class ListProject(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if parsed_args.long:
columns = ('ID', 'Name', 'Domain ID', 'Description', 'Enabled')
@@ -271,8 +271,8 @@ class SetProject(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if (not parsed_args.name
@@ -337,8 +337,8 @@ class ShowProject(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if parsed_args.domain:
diff --git a/openstackclient/identity/v3/region.py b/openstackclient/identity/v3/region.py
index 5cb51fc..eb4c084 100644
--- a/openstackclient/identity/v3/region.py
+++ b/openstackclient/identity/v3/region.py
@@ -56,8 +56,8 @@ class CreateRegion(show.ShowOne):
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
region = identity_client.regions.create(
@@ -87,8 +87,8 @@ class DeleteRegion(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
identity_client.regions.delete(parsed_args.region)
@@ -109,8 +109,8 @@ class ListRegion(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
kwargs = {}
@@ -157,8 +157,8 @@ class SetRegion(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if (not parsed_args.url
@@ -192,8 +192,8 @@ class ShowRegion(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
region = utils.find_resource(identity_client.regions,
diff --git a/openstackclient/identity/v3/role.py b/openstackclient/identity/v3/role.py
index 9243639..c72de47 100644
--- a/openstackclient/identity/v3/role.py
+++ b/openstackclient/identity/v3/role.py
@@ -39,7 +39,7 @@ def _add_identity_and_resource_options_to_parser(parser):
domain_or_project.add_argument(
'--project',
metavar='<project>',
- help='Include `<project>` (name or ID)',
+ help='Include <project> (name or ID)',
)
user_or_group = parser.add_mutually_exclusive_group()
user_or_group.add_argument(
@@ -122,8 +122,8 @@ class AddRole(command.Command):
_add_identity_and_resource_options_to_parser(parser)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if (not parsed_args.user and not parsed_args.domain
@@ -166,8 +166,8 @@ class CreateRole(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
try:
@@ -199,8 +199,8 @@ class DeleteRole(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
for role in parsed_args.roles:
@@ -325,8 +325,8 @@ class RemoveRole(command.Command):
_add_identity_and_resource_options_to_parser(parser)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if (not parsed_args.user and not parsed_args.domain
@@ -368,8 +368,8 @@ class SetRole(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if not parsed_args.name:
@@ -398,8 +398,8 @@ class ShowRole(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
role = utils.find_resource(
diff --git a/openstackclient/identity/v3/service.py b/openstackclient/identity/v3/service.py
index d63a953..85081aa 100644
--- a/openstackclient/identity/v3/service.py
+++ b/openstackclient/identity/v3/service.py
@@ -61,8 +61,8 @@ class CreateService(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
enabled = True
@@ -94,8 +94,8 @@ class DeleteService(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
service = common.find_service(identity_client, parsed_args.service)
@@ -119,8 +119,8 @@ class ListService(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
if parsed_args.long:
columns = ('ID', 'Name', 'Type', 'Description', 'Enabled')
@@ -173,8 +173,8 @@ class SetService(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if (not parsed_args.name
@@ -219,8 +219,8 @@ class ShowService(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
service = common.find_service(identity_client, parsed_args.service)
diff --git a/openstackclient/identity/v3/service_provider.py b/openstackclient/identity/v3/service_provider.py
index 78f96b6..838ad4a 100644
--- a/openstackclient/identity/v3/service_provider.py
+++ b/openstackclient/identity/v3/service_provider.py
@@ -73,8 +73,8 @@ class CreateServiceProvider(show.ShowOne):
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
service_client = self.app.client_manager.identity
sp = service_client.federation.service_providers.create(
id=parsed_args.service_provider_id,
@@ -101,8 +101,8 @@ class DeleteServiceProvider(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
service_client = self.app.client_manager.identity
service_client.federation.service_providers.delete(
parsed_args.service_provider)
@@ -114,8 +114,8 @@ class ListServiceProvider(lister.Lister):
log = logging.getLogger(__name__ + '.ListServiceProvider')
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
service_client = self.app.client_manager.identity
data = service_client.federation.service_providers.list()
@@ -168,8 +168,8 @@ class SetServiceProvider(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
federation_client = self.app.client_manager.identity.federation
enabled = None
@@ -207,8 +207,8 @@ class ShowServiceProvider(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
service_client = self.app.client_manager.identity
service_provider = utils.find_resource(
service_client.federation.service_providers,
diff --git a/openstackclient/identity/v3/token.py b/openstackclient/identity/v3/token.py
index 7000b62..cd3dc79 100644
--- a/openstackclient/identity/v3/token.py
+++ b/openstackclient/identity/v3/token.py
@@ -182,8 +182,8 @@ class IssueToken(show.ShowOne):
parser = super(IssueToken, self).get_parser(prog_name)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
token = self.app.client_manager.auth_ref.service_catalog.get_token()
if 'tenant_id' in token:
token['project_id'] = token.pop('tenant_id')
diff --git a/openstackclient/identity/v3/unscoped_saml.py b/openstackclient/identity/v3/unscoped_saml.py
index fddac68..e659e75 100644
--- a/openstackclient/identity/v3/unscoped_saml.py
+++ b/openstackclient/identity/v3/unscoped_saml.py
@@ -49,8 +49,8 @@ class ListAccessibleDomains(lister.Lister):
log = logging.getLogger(__name__ + '.ListAccessibleDomains')
@auth_with_unscoped_saml
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
columns = ('ID', 'Enabled', 'Name', 'Description')
identity_client = self.app.client_manager.identity
data = identity_client.federation.domains.list()
@@ -67,8 +67,8 @@ class ListAccessibleProjects(lister.Lister):
log = logging.getLogger(__name__ + '.ListAccessibleProjects')
@auth_with_unscoped_saml
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
columns = ('ID', 'Domain ID', 'Enabled', 'Name')
identity_client = self.app.client_manager.identity
data = identity_client.federation.projects.list()
diff --git a/openstackclient/identity/v3/user.py b/openstackclient/identity/v3/user.py
index 459707d..0e89454 100644
--- a/openstackclient/identity/v3/user.py
+++ b/openstackclient/identity/v3/user.py
@@ -91,8 +91,8 @@ class CreateUser(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
project_id = None
@@ -155,8 +155,8 @@ class DeleteUser(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
domain = None
@@ -205,8 +205,8 @@ class ListUser(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
domain = None
@@ -214,13 +214,11 @@ class ListUser(lister.Lister):
domain = common.find_domain(identity_client,
parsed_args.domain).id
+ group = None
if parsed_args.group:
- group = utils.find_resource(
- identity_client.groups,
- parsed_args.group,
- ).id
- else:
- group = None
+ group = common.find_group(identity_client,
+ parsed_args.group,
+ parsed_args.domain).id
if parsed_args.project:
if domain is not None:
@@ -336,8 +334,8 @@ class SetUser(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if parsed_args.password_prompt:
@@ -396,8 +394,8 @@ class SetPasswordUser(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
current_password = utils.get_password(
@@ -430,8 +428,8 @@ class ShowUser(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
if parsed_args.domain:
diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py
index 4c019db..3e1c824 100644
--- a/openstackclient/image/v2/image.py
+++ b/openstackclient/image/v2/image.py
@@ -22,14 +22,51 @@ import six
from cliff import command
from cliff import lister
from cliff import show
-
from glanceclient.common import utils as gc_utils
+
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.identity import common
+DEFAULT_CONTAINER_FORMAT = 'bare'
+DEFAULT_DISK_FORMAT = 'raw'
+
+
+def _format_image(image):
+ """Format an image to make it more consistent with OSC operations. """
+
+ info = {}
+ properties = {}
+
+ # the only fields we're not including is "links", "tags" and the properties
+ fields_to_show = ['status', 'name', 'container_format', 'created_at',
+ 'size', 'disk_format', 'updated_at', 'visibility',
+ 'min_disk', 'protected', 'id', 'file', 'checksum',
+ 'owner', 'virtual_size', 'min_ram', 'schema']
+
+ # split out the usual key and the properties which are top-level
+ for key in six.iterkeys(image):
+ if key in fields_to_show:
+ info[key] = image.get(key)
+ elif key == 'tags':
+ continue # handle this later
+ else:
+ properties[key] = image.get(key)
+
+ # format the tags if they are there
+ if image.get('tags'):
+ info['tags'] = utils.format_list(image.get('tags'))
+
+ # add properties back into the dictionary as a top-level key
+ if properties:
+ info['properties'] = utils.format_dict(properties)
+
+ return info
+
+
class AddProjectToImage(show.ShowOne):
"""Associate project with image"""
@@ -72,6 +109,187 @@ class AddProjectToImage(show.ShowOne):
return zip(*sorted(six.iteritems(image_member._info)))
+class CreateImage(show.ShowOne):
+ """Create/upload an image"""
+
+ log = logging.getLogger(__name__ + ".CreateImage")
+ deadopts = ('owner', 'size', 'location', 'copy-from', 'checksum', 'store')
+
+ def get_parser(self, prog_name):
+ parser = super(CreateImage, self).get_parser(prog_name)
+ # TODO(mordred): add --volume and --force parameters and support
+ # TODO(bunting): There are additional arguments that v1 supported
+ # that v2 either doesn't support or supports weirdly.
+ # --checksum - could be faked clientside perhaps?
+ # --owner - could be set as an update after the put?
+ # --location - maybe location add?
+ # --size - passing image size is actually broken in python-glanceclient
+ # --copy-from - does not exist in v2
+ # --store - does not exits in v2
+ parser.add_argument(
+ "name",
+ metavar="<image-name>",
+ help="New image name",
+ )
+ parser.add_argument(
+ "--id",
+ metavar="<id>",
+ help="Image ID to reserve",
+ )
+ parser.add_argument(
+ "--container-format",
+ default=DEFAULT_CONTAINER_FORMAT,
+ metavar="<container-format>",
+ help="Image container format "
+ "(default: %s)" % DEFAULT_CONTAINER_FORMAT,
+ )
+ parser.add_argument(
+ "--disk-format",
+ default=DEFAULT_DISK_FORMAT,
+ metavar="<disk-format>",
+ help="Image disk format "
+ "(default: %s)" % DEFAULT_DISK_FORMAT,
+ )
+ parser.add_argument(
+ "--min-disk",
+ metavar="<disk-gb>",
+ type=int,
+ help="Minimum disk size needed to boot image, in gigabytes",
+ )
+ parser.add_argument(
+ "--min-ram",
+ metavar="<ram-mb>",
+ type=int,
+ help="Minimum RAM size needed to boot image, in megabytes",
+ )
+ parser.add_argument(
+ "--file",
+ metavar="<file>",
+ help="Upload image from local file",
+ )
+ protected_group = parser.add_mutually_exclusive_group()
+ protected_group.add_argument(
+ "--protected",
+ action="store_true",
+ help="Prevent image from being deleted",
+ )
+ protected_group.add_argument(
+ "--unprotected",
+ action="store_true",
+ help="Allow image to be deleted (default)",
+ )
+ public_group = parser.add_mutually_exclusive_group()
+ public_group.add_argument(
+ "--public",
+ action="store_true",
+ help="Image is accessible to the public",
+ )
+ public_group.add_argument(
+ "--private",
+ action="store_true",
+ help="Image is inaccessible to the public (default)",
+ )
+ parser.add_argument(
+ "--property",
+ dest="properties",
+ metavar="<key=value>",
+ action=parseractions.KeyValueAction,
+ help="Set a property on this image "
+ "(repeat option to set multiple properties)",
+ )
+ parser.add_argument(
+ "--tag",
+ dest="tags",
+ metavar="<tag>",
+ action='append',
+ help="Set a tag on this image "
+ "(repeat option to set multiple tags)",
+ )
+ for deadopt in self.deadopts:
+ parser.add_argument(
+ "--%s" % deadopt,
+ metavar="<%s>" % deadopt,
+ dest=deadopt.replace('-', '_'),
+ 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
+
+ for deadopt in self.deadopts:
+ if getattr(parsed_args, deadopt.replace('-', '_'), None):
+ raise exceptions.CommandError(
+ "ERROR: --%s was given, which is an Image v1 option"
+ " that is no longer supported in Image v2" % deadopt)
+
+ # Build an attribute dict from the parsed args, only include
+ # attributes that were actually set on the command line
+ kwargs = {}
+ copy_attrs = ('name', 'id',
+ 'container_format', 'disk_format',
+ 'min_disk', 'min_ram',
+ 'tags')
+ for attr in copy_attrs:
+ if attr in parsed_args:
+ val = getattr(parsed_args, attr, None)
+ if val:
+ # 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):
+ kwargs[k] = str(v)
+ # 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
+ # a single value for the pair of options because the default must be
+ # to do nothing when no options are present as opposed to always
+ # setting a default.
+ if parsed_args.protected:
+ kwargs['protected'] = True
+ if parsed_args.unprotected:
+ kwargs['protected'] = False
+ if parsed_args.public:
+ kwargs['visibility'] = 'public'
+ if parsed_args.private:
+ kwargs['visibility'] = 'private'
+
+ # open the file first to ensure any failures are handled before the
+ # image is created
+ fp = gc_utils.get_data_file(parsed_args)
+
+ if fp is None and parsed_args.file:
+ self.log.warning("Failed to get an image file.")
+ return {}, {}
+
+ image = image_client.images.create(**kwargs)
+
+ if fp is not None:
+ with fp:
+ try:
+ image_client.images.upload(image.id, fp)
+ except Exception as e:
+ # If the upload fails for some reason attempt to remove the
+ # dangling queued image made by the create() call above but
+ # only if the user did not specify an id which indicates
+ # the Image already exists and should be left alone.
+ try:
+ if 'id' not in kwargs:
+ image_client.images.delete(image.id)
+ except Exception:
+ pass # we don't care about this one
+ raise e # now, throw the upload exception again
+
+ # update the image after the data has been uploaded
+ image = image_client.images.get(image.id)
+
+ info = _format_image(image)
+ return zip(*sorted(six.iteritems(info)))
+
+
class DeleteImage(command.Command):
"""Delete image(s)"""
@@ -229,7 +447,7 @@ class ListImage(lister.Lister):
s,
columns,
formatters={
- 'tags': utils.format_dict,
+ 'tags': utils.format_list,
},
) for s in data)
)
@@ -327,8 +545,7 @@ class ShowImage(show.ShowOne):
parsed_args.image,
)
- info = {}
- info.update(image)
+ info = _format_image(image)
return zip(*sorted(six.iteritems(info)))
diff --git a/openstackclient/object/v1/container.py b/openstackclient/object/v1/container.py
index bc4fdec..49173de 100644
--- a/openstackclient/object/v1/container.py
+++ b/openstackclient/object/v1/container.py
@@ -41,8 +41,8 @@ class CreateContainer(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
results = []
for container in parsed_args.containers:
@@ -74,8 +74,8 @@ class DeleteContainer(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
for container in parsed_args.containers:
self.app.client_manager.object_store.container_delete(
@@ -125,8 +125,8 @@ class ListContainer(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
if parsed_args.long:
columns = ('Name', 'Bytes', 'Count')
@@ -192,8 +192,8 @@ class ShowContainer(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
data = self.app.client_manager.object_store.container_show(
container=parsed_args.container,
diff --git a/openstackclient/object/v1/object.py b/openstackclient/object/v1/object.py
index 752d784..c90f031 100644
--- a/openstackclient/object/v1/object.py
+++ b/openstackclient/object/v1/object.py
@@ -46,8 +46,8 @@ class CreateObject(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
results = []
for obj in parsed_args.objects:
@@ -85,8 +85,8 @@ class DeleteObject(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
for obj in parsed_args.objects:
self.app.client_manager.object_store.object_delete(
@@ -147,8 +147,8 @@ class ListObject(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
if parsed_args.long:
columns = (
@@ -240,8 +240,8 @@ class ShowObject(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
data = self.app.client_manager.object_store.object_show(
container=parsed_args.container,
diff --git a/openstackclient/shell.py b/openstackclient/shell.py
index a8b5ac4..d3a7d8a 100644
--- a/openstackclient/shell.py
+++ b/openstackclient/shell.py
@@ -20,7 +20,6 @@ import getpass
import logging
import sys
import traceback
-import warnings
from cliff import app
from cliff import command
@@ -30,6 +29,7 @@ from cliff import help
import openstackclient
from openstackclient.common import clientmanager
from openstackclient.common import commandmanager
+from openstackclient.common import context
from openstackclient.common import exceptions as exc
from openstackclient.common import timing
from openstackclient.common import utils
@@ -94,62 +94,19 @@ class OpenStackShell(app.App):
self.verify = True
self.client_manager = None
+ self.command_options = None
def configure_logging(self):
- """Configure logging for the app
-
- Cliff sets some defaults we don't want so re-work it a bit
- """
-
- if self.options.debug:
- # --debug forces verbose_level 3
- # Set this here so cliff.app.configure_logging() can work
- self.options.verbose_level = 3
-
- super(OpenStackShell, self).configure_logging()
- root_logger = logging.getLogger('')
-
- # Set logging to the requested level
- if self.options.verbose_level == 0:
- # --quiet
- root_logger.setLevel(logging.ERROR)
- warnings.simplefilter("ignore")
- elif self.options.verbose_level == 1:
- # This is the default case, no --debug, --verbose or --quiet
- root_logger.setLevel(logging.WARNING)
- warnings.simplefilter("ignore")
- elif self.options.verbose_level == 2:
- # One --verbose
- root_logger.setLevel(logging.INFO)
- warnings.simplefilter("once")
- elif self.options.verbose_level >= 3:
- # Two or more --verbose
- root_logger.setLevel(logging.DEBUG)
-
- # Requests logs some stuff at INFO that we don't want
- # unless we have DEBUG
- requests_log = logging.getLogger("requests")
-
- # Other modules we don't want DEBUG output for
- cliff_log = logging.getLogger('cliff')
- stevedore_log = logging.getLogger('stevedore')
- iso8601_log = logging.getLogger("iso8601")
-
- if self.options.debug:
- # --debug forces traceback
- self.dump_stack_trace = True
- requests_log.setLevel(logging.DEBUG)
- else:
- self.dump_stack_trace = False
- requests_log.setLevel(logging.ERROR)
-
- cliff_log.setLevel(logging.ERROR)
- stevedore_log.setLevel(logging.ERROR)
- iso8601_log.setLevel(logging.ERROR)
+ """Configure logging for the app."""
+ self.log_configurator = context.LogConfigurator(self.options)
+ self.dump_stack_trace = self.log_configurator.dump_trace
def run(self, argv):
+ ret_val = 1
+ self.command_options = argv
try:
- return super(OpenStackShell, self).run(argv)
+ ret_val = super(OpenStackShell, self).run(argv)
+ return ret_val
except Exception as e:
if not logging.getLogger('').handlers:
logging.basicConfig()
@@ -157,7 +114,11 @@ class OpenStackShell(app.App):
self.log.error(traceback.format_exc(e))
else:
self.log.error('Exception raised: ' + str(e))
- return 1
+
+ return ret_val
+
+ finally:
+ self.log.info("END return value: %s", ret_val)
def build_option_parser(self, description, version):
parser = super(OpenStackShell, self).build_option_parser(
@@ -236,14 +197,15 @@ class OpenStackShell(app.App):
# Parent __init__ parses argv into self.options
super(OpenStackShell, self).initialize_app(argv)
+ self.log.info("START with options: %s", self.command_options)
+ self.log.debug("options: %s", self.options)
# Set the default plugin to token_endpoint if url and token are given
if (self.options.url and self.options.token):
# Use service token authentication
auth_type = 'token_endpoint'
else:
- auth_type = 'osc_password'
- self.log.debug("options: %s", self.options)
+ auth_type = 'password'
project_id = getattr(self.options, 'project_id', None)
project_name = getattr(self.options, 'project_name', None)
@@ -266,14 +228,20 @@ class OpenStackShell(app.App):
# Ignore the default value of interface. Only if it is set later
# will it be used.
cc = cloud_config.OpenStackConfig(
- override_defaults={'interface': None,
- 'auth_type': auth_type, })
- self.log.debug("defaults: %s", cc.defaults)
+ override_defaults={
+ 'interface': None,
+ 'auth_type': auth_type,
+ },
+ )
self.cloud = cc.get_one_cloud(
cloud=self.options.cloud,
argparse=self.options,
)
+
+ self.log_configurator.configure(self.cloud)
+ self.dump_stack_trace = self.log_configurator.dump_trace
+ self.log.debug("defaults: %s", cc.defaults)
self.log.debug("cloud cfg: %s", self.cloud.config)
# Set up client TLS
@@ -304,11 +272,23 @@ class OpenStackShell(app.App):
if version_opt:
api = mod.API_NAME
self.api_version[api] = version_opt
- if version_opt not in mod.API_VERSIONS:
- self.log.warning(
- "The %s version <%s> is not in supported versions <%s>"
- % (api, version_opt,
- ', '.join(mod.API_VERSIONS.keys())))
+
+ # Add a plugin interface to let the module validate the version
+ # requested by the user
+ skip_old_check = False
+ mod_check_api_version = getattr(mod, 'check_api_version', None)
+ if mod_check_api_version:
+ # this throws an exception if invalid
+ skip_old_check = mod_check_api_version(version_opt)
+
+ mod_versions = getattr(mod, 'API_VERSIONS', None)
+ if not skip_old_check and mod_versions:
+ if version_opt not in mod_versions:
+ self.log.warning(
+ "%s version %s is not in supported versions %s"
+ % (api, version_opt,
+ ', '.join(mod.API_VERSIONS.keys())))
+
# Command groups deal only with major versions
version = '.v' + version_opt.replace('.', '_').split('_')[0]
cmd_group = 'openstack.' + api.replace('-', '_') + version
diff --git a/openstackclient/tests/common/test_context.py b/openstackclient/tests/common/test_context.py
new file mode 100644
index 0000000..55e4285
--- /dev/null
+++ b/openstackclient/tests/common/test_context.py
@@ -0,0 +1,202 @@
+# 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 logging
+import mock
+
+from openstackclient.common import context
+from openstackclient.tests import utils
+
+
+class TestContext(utils.TestCase):
+
+ def test_log_level_from_options(self):
+ opts = mock.Mock()
+ opts.verbose_level = 0
+ self.assertEqual(logging.ERROR, context.log_level_from_options(opts))
+ opts.verbose_level = 1
+ self.assertEqual(logging.WARNING, context.log_level_from_options(opts))
+ opts.verbose_level = 2
+ self.assertEqual(logging.INFO, context.log_level_from_options(opts))
+ opts.verbose_level = 3
+ self.assertEqual(logging.DEBUG, context.log_level_from_options(opts))
+
+ def test_log_level_from_config(self):
+ cfg = {'verbose_level': 0}
+ self.assertEqual(logging.ERROR, context.log_level_from_config(cfg))
+ cfg = {'verbose_level': 1}
+ self.assertEqual(logging.WARNING, context.log_level_from_config(cfg))
+ cfg = {'verbose_level': 2}
+ self.assertEqual(logging.INFO, context.log_level_from_config(cfg))
+ cfg = {'verbose_level': 3}
+ self.assertEqual(logging.DEBUG, context.log_level_from_config(cfg))
+ cfg = {'verbose_level': 1, 'log_level': 'critical'}
+ self.assertEqual(logging.CRITICAL, context.log_level_from_config(cfg))
+ cfg = {'verbose_level': 1, 'log_level': 'error'}
+ self.assertEqual(logging.ERROR, context.log_level_from_config(cfg))
+ cfg = {'verbose_level': 1, 'log_level': 'warning'}
+ self.assertEqual(logging.WARNING, context.log_level_from_config(cfg))
+ cfg = {'verbose_level': 1, 'log_level': 'info'}
+ self.assertEqual(logging.INFO, context.log_level_from_config(cfg))
+ cfg = {'verbose_level': 1, 'log_level': 'debug'}
+ self.assertEqual(logging.DEBUG, context.log_level_from_config(cfg))
+ cfg = {'verbose_level': 1, 'log_level': 'bogus'}
+ self.assertEqual(logging.WARNING, context.log_level_from_config(cfg))
+ cfg = {'verbose_level': 1, 'log_level': 'info', 'debug': True}
+ self.assertEqual(logging.DEBUG, context.log_level_from_config(cfg))
+
+ @mock.patch('warnings.simplefilter')
+ def test_set_warning_filter(self, simplefilter):
+ context.set_warning_filter(logging.ERROR)
+ simplefilter.assert_called_with("ignore")
+ context.set_warning_filter(logging.WARNING)
+ simplefilter.assert_called_with("ignore")
+ context.set_warning_filter(logging.INFO)
+ simplefilter.assert_called_with("once")
+
+
+class TestFileFormatter(utils.TestCase):
+ def test_nothing(self):
+ formatter = context._FileFormatter()
+ self.assertEqual(('%(asctime)s.%(msecs)03d %(process)d %(levelname)s '
+ '%(name)s %(message)s'), formatter.fmt)
+
+ def test_options(self):
+ class Opts(object):
+ cloud = 'cloudy'
+ os_project_name = 'projecty'
+ username = 'usernamey'
+ options = Opts()
+ formatter = context._FileFormatter(options=options)
+ self.assertEqual(('%(asctime)s.%(msecs)03d %(process)d %(levelname)s '
+ '%(name)s [cloudy usernamey projecty] %(message)s'),
+ formatter.fmt)
+
+ def test_config(self):
+ config = mock.Mock()
+ config.config = {'cloud': 'cloudy'}
+ config.auth = {'project_name': 'projecty', 'username': 'usernamey'}
+ formatter = context._FileFormatter(config=config)
+ self.assertEqual(('%(asctime)s.%(msecs)03d %(process)d %(levelname)s '
+ '%(name)s [cloudy usernamey projecty] %(message)s'),
+ formatter.fmt)
+
+
+class TestLogConfigurator(utils.TestCase):
+ def setUp(self):
+ super(TestLogConfigurator, self).setUp()
+ self.options = mock.Mock()
+ self.options.verbose_level = 1
+ self.options.log_file = None
+ self.options.debug = False
+ self.root_logger = mock.Mock()
+ self.root_logger.setLevel = mock.Mock()
+ self.root_logger.addHandler = mock.Mock()
+ self.requests_log = mock.Mock()
+ self.requests_log.setLevel = mock.Mock()
+ self.cliff_log = mock.Mock()
+ self.cliff_log.setLevel = mock.Mock()
+ self.stevedore_log = mock.Mock()
+ self.stevedore_log.setLevel = mock.Mock()
+ self.iso8601_log = mock.Mock()
+ self.iso8601_log.setLevel = mock.Mock()
+ self.loggers = [
+ self.root_logger,
+ self.requests_log,
+ self.cliff_log,
+ self.stevedore_log,
+ self.iso8601_log]
+
+ @mock.patch('logging.StreamHandler')
+ @mock.patch('logging.getLogger')
+ @mock.patch('openstackclient.common.context.set_warning_filter')
+ def test_init(self, warning_filter, getLogger, handle):
+ getLogger.side_effect = self.loggers
+ console_logger = mock.Mock()
+ console_logger.setFormatter = mock.Mock()
+ console_logger.setLevel = mock.Mock()
+ handle.return_value = console_logger
+
+ configurator = context.LogConfigurator(self.options)
+
+ getLogger.assert_called_with('iso8601') # last call
+ warning_filter.assert_called_with(logging.WARNING)
+ self.root_logger.setLevel.assert_called_with(logging.DEBUG)
+ self.root_logger.addHandler.assert_called_with(console_logger)
+ self.requests_log.setLevel.assert_called_with(logging.ERROR)
+ self.cliff_log.setLevel.assert_called_with(logging.ERROR)
+ self.stevedore_log.setLevel.assert_called_with(logging.ERROR)
+ self.iso8601_log.setLevel.assert_called_with(logging.ERROR)
+ self.assertEqual(False, configurator.dump_trace)
+
+ @mock.patch('logging.getLogger')
+ @mock.patch('openstackclient.common.context.set_warning_filter')
+ def test_init_no_debug(self, warning_filter, getLogger):
+ getLogger.side_effect = self.loggers
+ self.options.debug = True
+
+ configurator = context.LogConfigurator(self.options)
+
+ warning_filter.assert_called_with(logging.DEBUG)
+ self.requests_log.setLevel.assert_called_with(logging.DEBUG)
+ self.assertEqual(True, configurator.dump_trace)
+
+ @mock.patch('logging.FileHandler')
+ @mock.patch('logging.getLogger')
+ @mock.patch('openstackclient.common.context.set_warning_filter')
+ @mock.patch('openstackclient.common.context._FileFormatter')
+ def test_init_log_file(self, formatter, warning_filter, getLogger, handle):
+ getLogger.side_effect = self.loggers
+ self.options.log_file = '/tmp/log_file'
+ file_logger = mock.Mock()
+ file_logger.setFormatter = mock.Mock()
+ file_logger.setLevel = mock.Mock()
+ handle.return_value = file_logger
+ mock_formatter = mock.Mock()
+ formatter.return_value = mock_formatter
+
+ context.LogConfigurator(self.options)
+
+ handle.assert_called_with(filename=self.options.log_file)
+ self.root_logger.addHandler.assert_called_with(file_logger)
+ file_logger.setFormatter.assert_called_with(mock_formatter)
+ file_logger.setLevel.assert_called_with(logging.WARNING)
+
+ @mock.patch('logging.FileHandler')
+ @mock.patch('logging.getLogger')
+ @mock.patch('openstackclient.common.context.set_warning_filter')
+ @mock.patch('openstackclient.common.context._FileFormatter')
+ def test_configure(self, formatter, warning_filter, getLogger, handle):
+ getLogger.side_effect = self.loggers
+ configurator = context.LogConfigurator(self.options)
+ cloud_config = mock.Mock()
+ config_log = '/tmp/config_log'
+ cloud_config.config = {
+ 'log_file': config_log,
+ 'verbose_level': 1,
+ 'log_level': 'info'}
+ file_logger = mock.Mock()
+ file_logger.setFormatter = mock.Mock()
+ file_logger.setLevel = mock.Mock()
+ handle.return_value = file_logger
+ mock_formatter = mock.Mock()
+ formatter.return_value = mock_formatter
+
+ configurator.configure(cloud_config)
+
+ warning_filter.assert_called_with(logging.INFO)
+ handle.assert_called_with(filename=config_log)
+ self.root_logger.addHandler.assert_called_with(file_logger)
+ file_logger.setFormatter.assert_called_with(mock_formatter)
+ file_logger.setLevel.assert_called_with(logging.INFO)
+ self.assertEqual(False, configurator.dump_trace)
diff --git a/openstackclient/tests/common/test_quota.py b/openstackclient/tests/common/test_quota.py
index f0013e4..b6ad156 100644
--- a/openstackclient/tests/common/test_quota.py
+++ b/openstackclient/tests/common/test_quota.py
@@ -12,6 +12,8 @@
import copy
+import mock
+
from openstackclient.common import quota
from openstackclient.tests.compute.v2 import fakes as compute_fakes
from openstackclient.tests import fakes
@@ -38,6 +40,11 @@ class TestQuota(compute_fakes.TestComputev2):
super(TestQuota, self).setUp()
self.quotas_mock = self.app.client_manager.compute.quotas
self.quotas_mock.reset_mock()
+ volume_mock = mock.Mock()
+ volume_mock.quotas = mock.Mock()
+ self.app.client_manager.volume = volume_mock
+ self.volume_quotas_mock = volume_mock.quotas
+ self.volume_quotas_mock.reset_mock()
class TestQuotaSet(TestQuota):
@@ -57,6 +64,18 @@ class TestQuotaSet(TestQuota):
loaded=True,
)
+ self.volume_quotas_mock.find.return_value = FakeQuotaResource(
+ None,
+ copy.deepcopy(compute_fakes.QUOTA),
+ loaded=True,
+ )
+
+ self.volume_quotas_mock.update.return_value = FakeQuotaResource(
+ None,
+ copy.deepcopy(compute_fakes.QUOTA),
+ loaded=True,
+ )
+
self.cmd = quota.SetQuota(self.app, None)
def test_quota_set(self):
@@ -87,3 +106,29 @@ class TestQuotaSet(TestQuota):
}
self.quotas_mock.update.assert_called_with('project_test', **kwargs)
+
+ def test_quota_set_volume(self):
+ arglist = [
+ '--gigabytes', str(compute_fakes.floating_ip_num),
+ '--snapshots', str(compute_fakes.fix_ip_num),
+ '--volumes', str(compute_fakes.injected_file_num),
+ compute_fakes.project_name,
+ ]
+ verifylist = [
+ ('gigabytes', compute_fakes.floating_ip_num),
+ ('snapshots', compute_fakes.fix_ip_num),
+ ('volumes', compute_fakes.injected_file_num),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.cmd.take_action(parsed_args)
+
+ kwargs = {
+ 'gigabytes': compute_fakes.floating_ip_num,
+ 'snapshots': compute_fakes.fix_ip_num,
+ 'volumes': compute_fakes.injected_file_num,
+ }
+
+ self.volume_quotas_mock.update.assert_called_with('project_test',
+ **kwargs)
diff --git a/openstackclient/tests/compute/v2/test_security_group_rule.py b/openstackclient/tests/compute/v2/test_security_group_rule.py
new file mode 100644
index 0000000..9516f8d
--- /dev/null
+++ b/openstackclient/tests/compute/v2/test_security_group_rule.py
@@ -0,0 +1,338 @@
+# 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 copy
+import mock
+
+from openstackclient.compute.v2 import security_group
+from openstackclient.tests.compute.v2 import fakes as compute_fakes
+from openstackclient.tests import fakes
+from openstackclient.tests.identity.v2_0 import fakes as identity_fakes
+
+
+security_group_id = '11'
+security_group_name = 'wide-open'
+security_group_description = 'nothing but net'
+
+security_group_rule_id = '1'
+
+SECURITY_GROUP = {
+ 'id': security_group_id,
+ 'name': security_group_name,
+ 'description': security_group_description,
+ 'tenant_id': identity_fakes.project_id,
+}
+
+SECURITY_GROUP_RULE = {
+ 'id': security_group_rule_id,
+ 'group': {},
+ 'ip_protocol': 'tcp',
+ 'ip_range': '0.0.0.0/0',
+ 'parent_group_id': security_group_id,
+ 'from_port': 0,
+ 'to_port': 0,
+}
+
+SECURITY_GROUP_RULE_ICMP = {
+ 'id': security_group_rule_id,
+ 'group': {},
+ 'ip_protocol': 'icmp',
+ 'ip_range': '0.0.0.0/0',
+ 'parent_group_id': security_group_id,
+ 'from_port': -1,
+ 'to_port': -1,
+}
+
+
+class FakeSecurityGroupRuleResource(fakes.FakeResource):
+
+ def get_keys(self):
+ return {'property': 'value'}
+
+
+class TestSecurityGroupRule(compute_fakes.TestComputev2):
+
+ def setUp(self):
+ super(TestSecurityGroupRule, self).setUp()
+
+ self.secgroups_mock = mock.Mock()
+ self.secgroups_mock.resource_class = fakes.FakeResource(None, {})
+ self.app.client_manager.compute.security_groups = self.secgroups_mock
+ self.secgroups_mock.reset_mock()
+
+ self.sg_rules_mock = mock.Mock()
+ self.sg_rules_mock.resource_class = fakes.FakeResource(None, {})
+ self.app.client_manager.compute.security_group_rules = \
+ self.sg_rules_mock
+ self.sg_rules_mock.reset_mock()
+
+
+class TestSecurityGroupRuleCreate(TestSecurityGroupRule):
+
+ def setUp(self):
+ super(TestSecurityGroupRuleCreate, self).setUp()
+
+ self.secgroups_mock.get.return_value = FakeSecurityGroupRuleResource(
+ None,
+ copy.deepcopy(SECURITY_GROUP),
+ loaded=True,
+ )
+
+ # Get the command object to test
+ self.cmd = security_group.CreateSecurityGroupRule(self.app, None)
+
+ def test_security_group_rule_create_no_options(self):
+ self.sg_rules_mock.create.return_value = FakeSecurityGroupRuleResource(
+ None,
+ copy.deepcopy(SECURITY_GROUP_RULE),
+ loaded=True,
+ )
+
+ arglist = [
+ security_group_name,
+ ]
+ verifylist = [
+ ('group', security_group_name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # SecurityGroupManager.create(name, description)
+ self.sg_rules_mock.create.assert_called_with(
+ security_group_id,
+ 'tcp',
+ 0,
+ 0,
+ '0.0.0.0/0',
+ )
+
+ collist = (
+ 'group',
+ 'id',
+ 'ip_protocol',
+ 'ip_range',
+ 'parent_group_id',
+ 'port_range',
+ )
+ self.assertEqual(collist, columns)
+ datalist = (
+ {},
+ security_group_rule_id,
+ 'tcp',
+ '',
+ security_group_id,
+ '0:0',
+ )
+ self.assertEqual(datalist, data)
+
+ def test_security_group_rule_create_ftp(self):
+ sg_rule = copy.deepcopy(SECURITY_GROUP_RULE)
+ sg_rule['from_port'] = 20
+ sg_rule['to_port'] = 21
+ self.sg_rules_mock.create.return_value = FakeSecurityGroupRuleResource(
+ None,
+ sg_rule,
+ loaded=True,
+ )
+
+ arglist = [
+ security_group_name,
+ '--dst-port', '20:21',
+ ]
+ verifylist = [
+ ('group', security_group_name),
+ ('dst_port', (20, 21)),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # SecurityGroupManager.create(name, description)
+ self.sg_rules_mock.create.assert_called_with(
+ security_group_id,
+ 'tcp',
+ 20,
+ 21,
+ '0.0.0.0/0',
+ )
+
+ collist = (
+ 'group',
+ 'id',
+ 'ip_protocol',
+ 'ip_range',
+ 'parent_group_id',
+ 'port_range',
+ )
+ self.assertEqual(collist, columns)
+ datalist = (
+ {},
+ security_group_rule_id,
+ 'tcp',
+ '',
+ security_group_id,
+ '20:21',
+ )
+ self.assertEqual(datalist, data)
+
+ def test_security_group_rule_create_ssh(self):
+ sg_rule = copy.deepcopy(SECURITY_GROUP_RULE)
+ sg_rule['from_port'] = 22
+ sg_rule['to_port'] = 22
+ self.sg_rules_mock.create.return_value = FakeSecurityGroupRuleResource(
+ None,
+ sg_rule,
+ loaded=True,
+ )
+
+ arglist = [
+ security_group_name,
+ '--dst-port', '22',
+ ]
+ verifylist = [
+ ('group', security_group_name),
+ ('dst_port', (22, 22)),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # SecurityGroupManager.create(name, description)
+ self.sg_rules_mock.create.assert_called_with(
+ security_group_id,
+ 'tcp',
+ 22,
+ 22,
+ '0.0.0.0/0',
+ )
+
+ collist = (
+ 'group',
+ 'id',
+ 'ip_protocol',
+ 'ip_range',
+ 'parent_group_id',
+ 'port_range',
+ )
+ self.assertEqual(collist, columns)
+ datalist = (
+ {},
+ security_group_rule_id,
+ 'tcp',
+ '',
+ security_group_id,
+ '22:22',
+ )
+ self.assertEqual(datalist, data)
+
+ def test_security_group_rule_create_udp(self):
+ sg_rule = copy.deepcopy(SECURITY_GROUP_RULE)
+ sg_rule['ip_protocol'] = 'udp'
+ self.sg_rules_mock.create.return_value = FakeSecurityGroupRuleResource(
+ None,
+ sg_rule,
+ loaded=True,
+ )
+
+ arglist = [
+ security_group_name,
+ '--proto', 'udp',
+ ]
+ verifylist = [
+ ('group', security_group_name),
+ ('proto', 'udp'),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # SecurityGroupManager.create(name, description)
+ self.sg_rules_mock.create.assert_called_with(
+ security_group_id,
+ 'udp',
+ 0,
+ 0,
+ '0.0.0.0/0',
+ )
+
+ collist = (
+ 'group',
+ 'id',
+ 'ip_protocol',
+ 'ip_range',
+ 'parent_group_id',
+ 'port_range',
+ )
+ self.assertEqual(collist, columns)
+ datalist = (
+ {},
+ security_group_rule_id,
+ 'udp',
+ '',
+ security_group_id,
+ '0:0',
+ )
+ self.assertEqual(datalist, data)
+
+ def test_security_group_rule_create_icmp(self):
+ self.sg_rules_mock.create.return_value = FakeSecurityGroupRuleResource(
+ None,
+ copy.deepcopy(SECURITY_GROUP_RULE_ICMP),
+ loaded=True,
+ )
+
+ arglist = [
+ security_group_name,
+ '--proto', 'ICMP',
+ ]
+ verifylist = [
+ ('group', security_group_name),
+ ('proto', 'ICMP'),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # SecurityGroupManager.create(name, description)
+ self.sg_rules_mock.create.assert_called_with(
+ security_group_id,
+ 'ICMP',
+ -1,
+ -1,
+ '0.0.0.0/0',
+ )
+
+ collist = (
+ 'group',
+ 'id',
+ 'ip_protocol',
+ 'ip_range',
+ 'parent_group_id',
+ 'port_range',
+ )
+ self.assertEqual(collist, columns)
+ datalist = (
+ {},
+ security_group_rule_id,
+ 'icmp',
+ '',
+ security_group_id,
+ '',
+ )
+ self.assertEqual(datalist, data)
diff --git a/openstackclient/tests/image/v2/test_image.py b/openstackclient/tests/image/v2/test_image.py
index bfb9476..bb720d7 100644
--- a/openstackclient/tests/image/v2/test_image.py
+++ b/openstackclient/tests/image/v2/test_image.py
@@ -19,6 +19,7 @@ import mock
import warlock
from glanceclient.v2 import schemas
+from openstackclient.common import exceptions
from openstackclient.image.v2 import image
from openstackclient.tests import fakes
from openstackclient.tests.identity.v3 import fakes as identity_fakes
@@ -41,6 +42,191 @@ class TestImage(image_fakes.TestImagev2):
self.domain_mock.reset_mock()
+class TestImageCreate(TestImage):
+
+ def setUp(self):
+ super(TestImageCreate, self).setUp()
+
+ self.images_mock.create.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(image_fakes.IMAGE),
+ loaded=True,
+ )
+ # This is the return value for utils.find_resource()
+ self.images_mock.get.return_value = copy.deepcopy(image_fakes.IMAGE)
+ self.images_mock.update.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(image_fakes.IMAGE),
+ loaded=True,
+ )
+
+ # Get the command object to test
+ self.cmd = image.CreateImage(self.app, None)
+
+ def test_image_reserve_no_options(self):
+ mock_exception = {
+ 'find.side_effect': exceptions.CommandError('x'),
+ }
+ self.images_mock.configure_mock(**mock_exception)
+ arglist = [
+ image_fakes.image_name,
+ ]
+ verifylist = [
+ ('container_format', image.DEFAULT_CONTAINER_FORMAT),
+ ('disk_format', image.DEFAULT_DISK_FORMAT),
+ ('name', image_fakes.image_name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # ImageManager.create(name=, **)
+ self.images_mock.create.assert_called_with(
+ name=image_fakes.image_name,
+ container_format=image.DEFAULT_CONTAINER_FORMAT,
+ disk_format=image.DEFAULT_DISK_FORMAT,
+ )
+
+ # Verify update() was not called, if it was show the args
+ self.assertEqual(self.images_mock.update.call_args_list, [])
+
+ self.images_mock.upload.assert_called_with(
+ mock.ANY, mock.ANY,
+ )
+
+ self.assertEqual(image_fakes.IMAGE_columns, columns)
+ self.assertEqual(image_fakes.IMAGE_data, data)
+
+ @mock.patch('glanceclient.common.utils.get_data_file', name='Open')
+ def test_image_reserve_options(self, mock_open):
+ mock_file = mock.MagicMock(name='File')
+ mock_open.return_value = mock_file
+ mock_open.read.return_value = None
+ mock_exception = {
+ 'find.side_effect': exceptions.CommandError('x'),
+ }
+ self.images_mock.configure_mock(**mock_exception)
+ arglist = [
+ '--container-format', 'ovf',
+ '--disk-format', 'fs',
+ '--min-disk', '10',
+ '--min-ram', '4',
+ '--protected',
+ '--private',
+ 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),
+ ('name', image_fakes.image_name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # ImageManager.create(name=, **)
+ self.images_mock.create.assert_called_with(
+ name=image_fakes.image_name,
+ container_format='ovf',
+ disk_format='fs',
+ min_disk=10,
+ min_ram=4,
+ protected=True,
+ visibility='private',
+ )
+
+ # Verify update() was not called, if it was show the args
+ self.assertEqual(self.images_mock.update.call_args_list, [])
+
+ self.images_mock.upload.assert_called_with(
+ mock.ANY, mock.ANY,
+ )
+
+ self.assertEqual(image_fakes.IMAGE_columns, columns)
+ self.assertEqual(image_fakes.IMAGE_data, data)
+
+ @mock.patch('glanceclient.common.utils.get_data_file', name='Open')
+ def test_image_create_file(self, mock_open):
+ mock_file = mock.MagicMock(name='File')
+ mock_open.return_value = mock_file
+ mock_open.read.return_value = image_fakes.IMAGE_data
+ mock_exception = {
+ 'find.side_effect': exceptions.CommandError('x'),
+ }
+ self.images_mock.configure_mock(**mock_exception)
+
+ arglist = [
+ '--file', 'filer',
+ '--unprotected',
+ '--public',
+ '--property', 'Alpha=1',
+ '--property', 'Beta=2',
+ '--tag', 'awesome',
+ '--tag', 'better',
+ image_fakes.image_name,
+ ]
+ verifylist = [
+ ('file', 'filer'),
+ ('protected', False),
+ ('unprotected', True),
+ ('public', True),
+ ('private', False),
+ ('properties', {'Alpha': '1', 'Beta': '2'}),
+ ('tags', ['awesome', 'better']),
+ ('name', image_fakes.image_name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # ImageManager.create(name=, **)
+ self.images_mock.create.assert_called_with(
+ name=image_fakes.image_name,
+ container_format=image.DEFAULT_CONTAINER_FORMAT,
+ disk_format=image.DEFAULT_DISK_FORMAT,
+ protected=False,
+ visibility='public',
+ Alpha='1',
+ Beta='2',
+ tags=['awesome', 'better'],
+ )
+
+ # Verify update() was not called, if it was show the args
+ self.assertEqual(self.images_mock.update.call_args_list, [])
+
+ self.images_mock.upload.assert_called_with(
+ mock.ANY, mock.ANY,
+ )
+
+ self.assertEqual(image_fakes.IMAGE_columns, columns)
+ self.assertEqual(image_fakes.IMAGE_data, data)
+
+ def test_image_dead_options(self):
+
+ arglist = [
+ '--owner', 'nobody',
+ image_fakes.image_name,
+ ]
+ verifylist = [
+ ('owner', 'nobody'),
+ ('name', image_fakes.image_name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action, parsed_args)
+
+
class TestAddProjectToImage(TestImage):
def setUp(self):
diff --git a/openstackclient/tests/test_shell.py b/openstackclient/tests/test_shell.py
index 0e0cc50..c548d89 100644
--- a/openstackclient/tests/test_shell.py
+++ b/openstackclient/tests/test_shell.py
@@ -77,6 +77,8 @@ CLOUD_2 = {
'username': 'zaphod',
},
'region_name': 'occ-cloud',
+ 'log_file': '/tmp/test_log_file',
+ 'log_level': 'debug',
}
}
}
diff --git a/openstackclient/tests/volume/v2/fakes.py b/openstackclient/tests/volume/v2/fakes.py
index 0d8c202..7b7758a 100644
--- a/openstackclient/tests/volume/v2/fakes.py
+++ b/openstackclient/tests/volume/v2/fakes.py
@@ -15,14 +15,15 @@
import copy
import mock
-from openstackclient.tests.compute.v2 import fakes as compute_fakes
from openstackclient.tests import fakes
from openstackclient.tests.identity.v2_0 import fakes as identity_fakes
from openstackclient.tests.image.v2 import fakes as image_fakes
from openstackclient.tests import utils
-volume_attachment_server = copy.deepcopy(compute_fakes.SERVER)
-volume_attachment_server['device'] = 'device'
+volume_attachment_server = {
+ 'device': '/dev/ice',
+ 'server_id': '1233',
+}
volume_id = "ce26708d-a7f8-4b4b-9861-4a80256615a6"
volume_name = "fake_volume"
diff --git a/openstackclient/tests/volume/v2/test_volume.py b/openstackclient/tests/volume/v2/test_volume.py
index 348ae37..b15fd02 100644
--- a/openstackclient/tests/volume/v2/test_volume.py
+++ b/openstackclient/tests/volume/v2/test_volume.py
@@ -548,7 +548,7 @@ class TestVolumeList(TestVolume):
]
self.assertEqual(collist, columns)
- server = volume_fakes.volume_attachment_server['id']
+ server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
datalist = ((
@@ -583,7 +583,7 @@ class TestVolumeList(TestVolume):
]
self.assertEqual(collist, columns)
- server = volume_fakes.volume_attachment_server['id']
+ server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
datalist = ((
@@ -618,7 +618,7 @@ class TestVolumeList(TestVolume):
)
self.assertEqual(collist, tuple(columns))
- server = volume_fakes.volume_attachment_server['id']
+ server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
@@ -654,7 +654,7 @@ class TestVolumeList(TestVolume):
)
self.assertEqual(collist, tuple(columns))
- server = volume_fakes.volume_attachment_server['id']
+ server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
datalist = ((
@@ -693,7 +693,7 @@ class TestVolumeList(TestVolume):
]
self.assertEqual(collist, columns)
- server = volume_fakes.volume_attachment_server['id']
+ server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
datalist = ((
diff --git a/openstackclient/volume/client.py b/openstackclient/volume/client.py
index d4800b8..0973868 100644
--- a/openstackclient/volume/client.py
+++ b/openstackclient/volume/client.py
@@ -19,7 +19,7 @@ from openstackclient.common import utils
LOG = logging.getLogger(__name__)
-DEFAULT_API_VERSION = '1'
+DEFAULT_API_VERSION = '2'
API_VERSION_OPTION = 'os_volume_api_version'
API_NAME = "volume"
API_VERSIONS = {
diff --git a/openstackclient/volume/v1/backup.py b/openstackclient/volume/v1/backup.py
index 03c63a0..c668e36 100644
--- a/openstackclient/volume/v1/backup.py
+++ b/openstackclient/volume/v1/backup.py
@@ -57,8 +57,8 @@ class CreateBackup(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
volume_id = utils.find_resource(volume_client.volumes,
parsed_args.volume).id
@@ -88,8 +88,8 @@ class DeleteBackup(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
for backup in parsed_args.backups:
backup_id = utils.find_resource(volume_client.backups,
@@ -113,8 +113,8 @@ class ListBackup(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
def _format_volume_id(volume_id):
"""Return a volume name if available
@@ -172,8 +172,8 @@ class RestoreBackup(command.Command):
help='Volume to restore to (name or ID)')
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
backup = utils.find_resource(volume_client.backups,
parsed_args.backup)
@@ -196,8 +196,8 @@ class ShowBackup(show.ShowOne):
help='Backup to display (ID only)')
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
backup = utils.find_resource(volume_client.backups,
parsed_args.backup)
diff --git a/openstackclient/volume/v1/qos_specs.py b/openstackclient/volume/v1/qos_specs.py
index 8e909e3..d1c7011 100644
--- a/openstackclient/volume/v1/qos_specs.py
+++ b/openstackclient/volume/v1/qos_specs.py
@@ -45,8 +45,8 @@ class AssociateQos(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
parsed_args.qos_spec)
@@ -88,8 +88,8 @@ class CreateQos(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
specs = {}
specs.update({'consumer': parsed_args.consumer})
@@ -117,8 +117,8 @@ class DeleteQos(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
for qos in parsed_args.qos_specs:
qos_spec = utils.find_resource(volume_client.qos_specs, qos)
@@ -153,8 +153,8 @@ class DisassociateQos(command.Command):
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
parsed_args.qos_spec)
@@ -174,8 +174,8 @@ class ListQos(lister.Lister):
log = logging.getLogger(__name__ + '.ListQos')
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
qos_specs_list = volume_client.qos_specs.list()
@@ -218,8 +218,8 @@ class SetQos(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
parsed_args.qos_spec)
@@ -247,8 +247,8 @@ class ShowQos(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
parsed_args.qos_spec)
@@ -287,8 +287,8 @@ class UnsetQos(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
parsed_args.qos_spec)
diff --git a/openstackclient/volume/v1/snapshot.py b/openstackclient/volume/v1/snapshot.py
index e81efb5..de7bb5b 100644
--- a/openstackclient/volume/v1/snapshot.py
+++ b/openstackclient/volume/v1/snapshot.py
@@ -59,8 +59,8 @@ class CreateSnapshot(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
volume_id = utils.find_resource(volume_client.volumes,
parsed_args.volume).id
@@ -93,8 +93,8 @@ class DeleteSnapshot(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
for snapshot in parsed_args.snapshots:
snapshot_id = utils.find_resource(volume_client.volume_snapshots,
@@ -118,8 +118,8 @@ class ListSnapshot(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
def _format_volume_id(volume_id):
"""Return a volume name if available
@@ -194,8 +194,8 @@ class SetSnapshot(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
snapshot = utils.find_resource(volume_client.volume_snapshots,
parsed_args.snapshot)
@@ -231,8 +231,8 @@ class ShowSnapshot(show.ShowOne):
help='Snapshot to display (name or ID)')
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
snapshot = utils.find_resource(volume_client.volume_snapshots,
parsed_args.snapshot)
@@ -267,8 +267,8 @@ class UnsetSnapshot(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
snapshot = utils.find_resource(
volume_client.volume_snapshots, parsed_args.snapshot)
diff --git a/openstackclient/volume/v1/volume.py b/openstackclient/volume/v1/volume.py
index 884611e..52b0eb2 100644
--- a/openstackclient/volume/v1/volume.py
+++ b/openstackclient/volume/v1/volume.py
@@ -102,8 +102,8 @@ class CreateVolume(show.ShowOne):
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
image_client = self.app.client_manager.image
@@ -186,8 +186,8 @@ class DeleteVolume(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
for volume in parsed_args.volumes:
volume_obj = utils.find_resource(
@@ -230,8 +230,8 @@ class ListVolume(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
compute_client = self.app.client_manager.compute
@@ -351,8 +351,8 @@ class SetVolume(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
@@ -399,8 +399,8 @@ class ShowVolume(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
# Map 'metadata' column to 'properties'
@@ -441,8 +441,8 @@ class UnsetVolume(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
volume = utils.find_resource(
volume_client.volumes, parsed_args.volume)
diff --git a/openstackclient/volume/v1/volume_type.py b/openstackclient/volume/v1/volume_type.py
index d5c617b..d7765c7 100644
--- a/openstackclient/volume/v1/volume_type.py
+++ b/openstackclient/volume/v1/volume_type.py
@@ -47,8 +47,8 @@ class CreateVolumeType(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
volume_type = volume_client.volume_types.create(parsed_args.name)
volume_type._info.pop('extra_specs')
@@ -75,8 +75,8 @@ class DeleteVolumeType(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
volume_type_id = utils.find_resource(
volume_client.volume_types, parsed_args.volume_type).id
@@ -98,8 +98,8 @@ class ListVolumeType(lister.Lister):
help='List additional fields in output')
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
if parsed_args.long:
columns = ('ID', 'Name', 'Extra Specs')
column_headers = ('ID', 'Name', 'Properties')
@@ -135,8 +135,8 @@ class SetVolumeType(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
volume_type = utils.find_resource(
volume_client.volume_types, parsed_args.volume_type)
@@ -170,8 +170,8 @@ class UnsetVolumeType(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
volume_type = utils.find_resource(
volume_client.volume_types,
diff --git a/openstackclient/volume/v2/qos_specs.py b/openstackclient/volume/v2/qos_specs.py
index ac78ca1..b3a34ca 100644
--- a/openstackclient/volume/v2/qos_specs.py
+++ b/openstackclient/volume/v2/qos_specs.py
@@ -45,8 +45,8 @@ class AssociateQos(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
parsed_args.qos_spec)
@@ -88,8 +88,8 @@ class CreateQos(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
specs = {}
specs.update({'consumer': parsed_args.consumer})
@@ -117,8 +117,8 @@ class DeleteQos(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
for qos in parsed_args.qos_specs:
qos_spec = utils.find_resource(volume_client.qos_specs, qos)
@@ -153,8 +153,8 @@ class DisassociateQos(command.Command):
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
parsed_args.qos_spec)
@@ -174,8 +174,8 @@ class ListQos(lister.Lister):
log = logging.getLogger(__name__ + '.ListQos')
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
qos_specs_list = volume_client.qos_specs.list()
@@ -218,8 +218,8 @@ class SetQos(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
parsed_args.qos_spec)
@@ -247,8 +247,8 @@ class ShowQos(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
parsed_args.qos_spec)
@@ -287,8 +287,8 @@ class UnsetQos(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
parsed_args.qos_spec)
diff --git a/openstackclient/volume/v2/snapshot.py b/openstackclient/volume/v2/snapshot.py
index 4370cde..bbc92c4 100644
--- a/openstackclient/volume/v2/snapshot.py
+++ b/openstackclient/volume/v2/snapshot.py
@@ -186,8 +186,8 @@ class SetSnapshot(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
snapshot = utils.find_resource(volume_client.volume_snapshots,
parsed_args.snapshot)
@@ -256,8 +256,8 @@ class UnsetSnapshot(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
snapshot = utils.find_resource(
volume_client.volume_snapshots, parsed_args.snapshot)
diff --git a/openstackclient/volume/v2/volume.py b/openstackclient/volume/v2/volume.py
index fe4a3ff..ad6215e 100644
--- a/openstackclient/volume/v2/volume.py
+++ b/openstackclient/volume/v2/volume.py
@@ -223,8 +223,8 @@ class ListVolume(lister.Lister):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
compute_client = self.app.client_manager.compute
@@ -238,7 +238,7 @@ class ListVolume(lister.Lister):
msg = ''
for attachment in attachments:
- server = attachment['id']
+ server = attachment['server_id']
if server in server_cache:
server = server_cache[server].name
device = attachment['device']
@@ -335,8 +335,8 @@ class SetVolume(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
@@ -383,8 +383,8 @@ class ShowVolume(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
@@ -416,8 +416,8 @@ class UnsetVolume(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
volume = utils.find_resource(
volume_client.volumes, parsed_args.volume)
diff --git a/openstackclient/volume/v2/volume_type.py b/openstackclient/volume/v2/volume_type.py
index fb0342c..8cca86f 100644
--- a/openstackclient/volume/v2/volume_type.py
+++ b/openstackclient/volume/v2/volume_type.py
@@ -66,8 +66,8 @@ class CreateVolumeType(show.ShowOne):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
@@ -127,8 +127,8 @@ class ListVolumeType(lister.Lister):
help='List additional fields in output')
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
if parsed_args.long:
columns = ['ID', 'Name', 'Description', 'Extra Specs']
column_headers = ['ID', 'Name', 'Description', 'Properties']
@@ -174,8 +174,8 @@ class SetVolumeType(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
volume_type = utils.find_resource(
volume_client.volume_types, parsed_args.volume_type)
@@ -250,8 +250,8 @@ class UnsetVolumeType(command.Command):
)
return parser
+ @utils.log_method(log)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
volume_type = utils.find_resource(
volume_client.volume_types,
diff --git a/python-openstackclient/locale/de/LC_MESSAGES/python-openstackclient.po b/python-openstackclient/locale/de/LC_MESSAGES/python-openstackclient.po
index 6c838a4..6758943 100644
--- a/python-openstackclient/locale/de/LC_MESSAGES/python-openstackclient.po
+++ b/python-openstackclient/locale/de/LC_MESSAGES/python-openstackclient.po
@@ -5,13 +5,15 @@
#
# 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\n"
+"Project-Id-Version: python-openstackclient 1.6.1.dev56\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2015-08-04 06:26+0000\n"
-"PO-Revision-Date: 2015-06-14 18:41+0000\n"
-"Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
+"POT-Creation-Date: 2015-09-21 06:09+0000\n"
+"PO-Revision-Date: 2015-09-19 07:10+0000\n"
+"Last-Translator: Andreas Jaeger <jaegerandi@gmail.com>\n"
"Language-Team: German (http://www.transifex.com/openstack/python-"
"openstackclient/language/de/)\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
@@ -432,6 +434,9 @@ msgstr "Nach Bild 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)"
@@ -472,6 +477,16 @@ msgstr ""
"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."
diff --git a/python-openstackclient/locale/python-openstackclient.pot b/python-openstackclient/locale/python-openstackclient.pot
index e53b824..f613a5a 100644
--- a/python-openstackclient/locale/python-openstackclient.pot
+++ b/python-openstackclient/locale/python-openstackclient.pot
@@ -7,9 +7,9 @@
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: python-openstackclient 1.5.1.dev136\n"
+"Project-Id-Version: python-openstackclient 1.6.1.dev43\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2015-07-29 06:32+0000\n"
+"POT-Creation-Date: 2015-09-11 06:10+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"
@@ -48,7 +48,7 @@ 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:700
+#: openstackclient/compute/v2/server.py:718
#: openstackclient/identity/v2_0/endpoint.py:114
#: openstackclient/identity/v2_0/project.py:145
#: openstackclient/identity/v2_0/service.py:128
@@ -56,89 +56,89 @@ msgstr ""
msgid "List additional fields in output"
msgstr ""
-#: openstackclient/compute/v2/server.py:154
-#: openstackclient/compute/v2/server.py:191
-#: openstackclient/compute/v2/server.py:542
-#: openstackclient/compute/v2/server.py:771
-#: openstackclient/compute/v2/server.py:805
-#: openstackclient/compute/v2/server.py:888
-#: openstackclient/compute/v2/server.py:912
-#: openstackclient/compute/v2/server.py:967
-#: openstackclient/compute/v2/server.py:1059
-#: openstackclient/compute/v2/server.py:1099
-#: openstackclient/compute/v2/server.py:1125
-#: openstackclient/compute/v2/server.py:1190
-#: openstackclient/compute/v2/server.py:1214
-#: openstackclient/compute/v2/server.py:1273
-#: openstackclient/compute/v2/server.py:1310
-#: openstackclient/compute/v2/server.py:1457
-#: openstackclient/compute/v2/server.py:1481
-#: openstackclient/compute/v2/server.py:1505
-#: openstackclient/compute/v2/server.py:1529
-#: openstackclient/compute/v2/server.py:1553
+#: openstackclient/compute/v2/server.py:161
+#: openstackclient/compute/v2/server.py:198
+#: openstackclient/compute/v2/server.py:549
+#: openstackclient/compute/v2/server.py:810
+#: openstackclient/compute/v2/server.py:844
+#: openstackclient/compute/v2/server.py:927
+#: openstackclient/compute/v2/server.py:951
+#: openstackclient/compute/v2/server.py:1006
+#: openstackclient/compute/v2/server.py:1098
+#: openstackclient/compute/v2/server.py:1138
+#: openstackclient/compute/v2/server.py:1164
+#: openstackclient/compute/v2/server.py:1229
+#: openstackclient/compute/v2/server.py:1253
+#: openstackclient/compute/v2/server.py:1312
+#: openstackclient/compute/v2/server.py:1349
+#: openstackclient/compute/v2/server.py:1496
+#: openstackclient/compute/v2/server.py:1520
+#: openstackclient/compute/v2/server.py:1544
+#: openstackclient/compute/v2/server.py:1568
+#: openstackclient/compute/v2/server.py:1592
msgid "Server (name or ID)"
msgstr ""
-#: openstackclient/compute/v2/server.py:159
+#: openstackclient/compute/v2/server.py:166
msgid "Security group to add (name or ID)"
msgstr ""
-#: openstackclient/compute/v2/server.py:196
+#: openstackclient/compute/v2/server.py:203
msgid "Volume to add (name or ID)"
msgstr ""
-#: openstackclient/compute/v2/server.py:201
+#: openstackclient/compute/v2/server.py:208
msgid "Server internal device name for volume"
msgstr ""
-#: openstackclient/compute/v2/server.py:241
-#: openstackclient/compute/v2/server.py:1219
+#: openstackclient/compute/v2/server.py:248
+#: openstackclient/compute/v2/server.py:1258
msgid "New server name"
msgstr ""
-#: openstackclient/compute/v2/server.py:249
+#: openstackclient/compute/v2/server.py:256
msgid "Create server from this image"
msgstr ""
-#: openstackclient/compute/v2/server.py:254
+#: openstackclient/compute/v2/server.py:261
msgid "Create server from this volume"
msgstr ""
-#: openstackclient/compute/v2/server.py:260
+#: openstackclient/compute/v2/server.py:267
msgid "Create server with this flavor"
msgstr ""
-#: openstackclient/compute/v2/server.py:267
+#: openstackclient/compute/v2/server.py:274
msgid "Security group to assign to this server (repeat for multiple groups)"
msgstr ""
-#: openstackclient/compute/v2/server.py:273
+#: openstackclient/compute/v2/server.py:280
msgid "Keypair to inject into this server (optional extension)"
msgstr ""
-#: openstackclient/compute/v2/server.py:279
+#: openstackclient/compute/v2/server.py:286
msgid "Set a property on this server (repeat for multiple values)"
msgstr ""
-#: openstackclient/compute/v2/server.py:287
+#: openstackclient/compute/v2/server.py:294
msgid "File to inject into image before boot (repeat for multiple files)"
msgstr ""
-#: openstackclient/compute/v2/server.py:293
+#: openstackclient/compute/v2/server.py:300
msgid "User data file to serve from the metadata server"
msgstr ""
-#: openstackclient/compute/v2/server.py:298
+#: openstackclient/compute/v2/server.py:305
msgid "Select an availability zone for the server"
msgstr ""
-#: openstackclient/compute/v2/server.py:305
+#: openstackclient/compute/v2/server.py:312
msgid ""
"Map block devices; map is <id>:<type>:<size(GB)>:<delete_on_terminate> "
"(optional extension)"
msgstr ""
-#: openstackclient/compute/v2/server.py:315
+#: openstackclient/compute/v2/server.py:322
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. "
@@ -147,314 +147,318 @@ msgid ""
"-fixed-ip: IPv6 fixed address for NIC (optional)."
msgstr ""
-#: openstackclient/compute/v2/server.py:328
+#: openstackclient/compute/v2/server.py:335
msgid "Hints for the scheduler (optional extension)"
msgstr ""
-#: openstackclient/compute/v2/server.py:334
+#: openstackclient/compute/v2/server.py:341
msgid ""
"Use specified volume as the config drive, or 'True' to use an ephemeral "
"drive"
msgstr ""
-#: openstackclient/compute/v2/server.py:342
+#: openstackclient/compute/v2/server.py:349
msgid "Minimum number of servers to launch (default=1)"
msgstr ""
-#: openstackclient/compute/v2/server.py:349
+#: openstackclient/compute/v2/server.py:356
msgid "Maximum number of servers to launch (default=1)"
msgstr ""
-#: openstackclient/compute/v2/server.py:354
+#: openstackclient/compute/v2/server.py:361
msgid "Wait for build to complete"
msgstr ""
-#: openstackclient/compute/v2/server.py:394
+#: openstackclient/compute/v2/server.py:401
msgid "min instances should be <= max instances"
msgstr ""
-#: openstackclient/compute/v2/server.py:397
+#: openstackclient/compute/v2/server.py:404
msgid "min instances should be > 0"
msgstr ""
-#: openstackclient/compute/v2/server.py:400
+#: openstackclient/compute/v2/server.py:407
msgid "max instances should be > 0"
msgstr ""
-#: openstackclient/compute/v2/server.py:436
+#: openstackclient/compute/v2/server.py:443
msgid "either net-id or port-id should be specified but not both"
msgstr ""
-#: openstackclient/compute/v2/server.py:458
+#: openstackclient/compute/v2/server.py:465
msgid "can't create server with port specified since neutron not enabled"
msgstr ""
-#: openstackclient/compute/v2/server.py:523
+#: openstackclient/compute/v2/server.py:530
#, python-format
msgid "Error creating server: %s"
msgstr ""
-#: openstackclient/compute/v2/server.py:525
+#: openstackclient/compute/v2/server.py:532
msgid ""
"\n"
"Error creating server"
msgstr ""
-#: openstackclient/compute/v2/server.py:547
+#: openstackclient/compute/v2/server.py:554
msgid "Name of new image (default is server name)"
msgstr ""
-#: openstackclient/compute/v2/server.py:552
+#: openstackclient/compute/v2/server.py:559
msgid "Wait for image create to complete"
msgstr ""
-#: openstackclient/compute/v2/server.py:582
+#: openstackclient/compute/v2/server.py:589
#, python-format
msgid "Error creating server snapshot: %s"
msgstr ""
-#: openstackclient/compute/v2/server.py:584
+#: openstackclient/compute/v2/server.py:591
msgid ""
"\n"
"Error creating server snapshot"
msgstr ""
-#: openstackclient/compute/v2/server.py:606
+#: openstackclient/compute/v2/server.py:613
msgid "Server(s) to delete (name or ID)"
msgstr ""
-#: openstackclient/compute/v2/server.py:611
+#: openstackclient/compute/v2/server.py:618
msgid "Wait for delete to complete"
msgstr ""
-#: openstackclient/compute/v2/server.py:630
+#: openstackclient/compute/v2/server.py:637
#, python-format
msgid "Error deleting server: %s"
msgstr ""
-#: openstackclient/compute/v2/server.py:632
+#: openstackclient/compute/v2/server.py:639
msgid ""
"\n"
"Error deleting server"
msgstr ""
-#: openstackclient/compute/v2/server.py:647
+#: openstackclient/compute/v2/server.py:654
msgid "Only return instances that match the reservation"
msgstr ""
-#: openstackclient/compute/v2/server.py:652
+#: openstackclient/compute/v2/server.py:659
msgid "Regular expression to match IP addresses"
msgstr ""
-#: openstackclient/compute/v2/server.py:657
+#: openstackclient/compute/v2/server.py:664
msgid "Regular expression to match IPv6 addresses"
msgstr ""
-#: openstackclient/compute/v2/server.py:662
+#: openstackclient/compute/v2/server.py:669
msgid "Regular expression to match names"
msgstr ""
-#: openstackclient/compute/v2/server.py:667
+#: openstackclient/compute/v2/server.py:674
msgid "Regular expression to match instance name (admin only)"
msgstr ""
-#: openstackclient/compute/v2/server.py:673
+#: openstackclient/compute/v2/server.py:680
msgid "Search by server status"
msgstr ""
-#: openstackclient/compute/v2/server.py:678
+#: openstackclient/compute/v2/server.py:685
msgid "Search by flavor"
msgstr ""
-#: openstackclient/compute/v2/server.py:683
+#: openstackclient/compute/v2/server.py:690
msgid "Search by image"
msgstr ""
-#: openstackclient/compute/v2/server.py:688
+#: openstackclient/compute/v2/server.py:695
msgid "Search by hostname"
msgstr ""
-#: openstackclient/compute/v2/server.py:694
+#: openstackclient/compute/v2/server.py:701
msgid "Include all projects (admin only)"
msgstr ""
-#: openstackclient/compute/v2/server.py:810
+#: openstackclient/compute/v2/server.py:711
+msgid "Search by user (admin only) (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:849
msgid "Target hostname"
msgstr ""
-#: openstackclient/compute/v2/server.py:818
+#: openstackclient/compute/v2/server.py:857
msgid "Perform a shared live migration (default)"
msgstr ""
-#: openstackclient/compute/v2/server.py:824
+#: openstackclient/compute/v2/server.py:863
msgid "Perform a block live migration"
msgstr ""
-#: openstackclient/compute/v2/server.py:831
+#: openstackclient/compute/v2/server.py:870
msgid "Allow disk over-commit on the destination host"
msgstr ""
-#: openstackclient/compute/v2/server.py:838
+#: openstackclient/compute/v2/server.py:877
msgid "Do not over-commit disk on the destination host (default)"
msgstr ""
-#: openstackclient/compute/v2/server.py:844
-#: openstackclient/compute/v2/server.py:1145
+#: openstackclient/compute/v2/server.py:883
+#: openstackclient/compute/v2/server.py:1184
msgid "Wait for resize to complete"
msgstr ""
-#: openstackclient/compute/v2/server.py:872
-#: openstackclient/compute/v2/server.py:1170
+#: openstackclient/compute/v2/server.py:911
+#: openstackclient/compute/v2/server.py:1209
msgid "Complete\n"
msgstr ""
-#: openstackclient/compute/v2/server.py:874
+#: openstackclient/compute/v2/server.py:913
msgid ""
"\n"
"Error migrating server"
msgstr ""
-#: openstackclient/compute/v2/server.py:921
+#: openstackclient/compute/v2/server.py:960
msgid "Perform a hard reboot"
msgstr ""
-#: openstackclient/compute/v2/server.py:929
+#: openstackclient/compute/v2/server.py:968
msgid "Perform a soft reboot"
msgstr ""
-#: openstackclient/compute/v2/server.py:934
+#: openstackclient/compute/v2/server.py:973
msgid "Wait for reboot to complete"
msgstr ""
-#: openstackclient/compute/v2/server.py:951
+#: openstackclient/compute/v2/server.py:990
msgid ""
"\n"
"Reboot complete\n"
msgstr ""
-#: openstackclient/compute/v2/server.py:953
+#: openstackclient/compute/v2/server.py:992
msgid ""
"\n"
"Error rebooting server\n"
msgstr ""
-#: openstackclient/compute/v2/server.py:973
+#: openstackclient/compute/v2/server.py:1012
msgid "Recreate server from this image"
msgstr ""
-#: openstackclient/compute/v2/server.py:983
+#: openstackclient/compute/v2/server.py:1022
msgid "Wait for rebuild to complete"
msgstr ""
-#: openstackclient/compute/v2/server.py:1004
+#: openstackclient/compute/v2/server.py:1043
msgid ""
"\n"
"Complete\n"
msgstr ""
-#: openstackclient/compute/v2/server.py:1006
+#: openstackclient/compute/v2/server.py:1045
msgid ""
"\n"
"Error rebuilding server"
msgstr ""
-#: openstackclient/compute/v2/server.py:1023
+#: openstackclient/compute/v2/server.py:1062
msgid "Name or ID of server to use"
msgstr ""
-#: openstackclient/compute/v2/server.py:1028
+#: openstackclient/compute/v2/server.py:1067
msgid "Name or ID of security group to remove from server"
msgstr ""
-#: openstackclient/compute/v2/server.py:1064
+#: openstackclient/compute/v2/server.py:1103
msgid "Volume to remove (name or ID)"
msgstr ""
-#: openstackclient/compute/v2/server.py:1130
+#: openstackclient/compute/v2/server.py:1169
msgid "Resize server to specified flavor"
msgstr ""
-#: openstackclient/compute/v2/server.py:1135
+#: openstackclient/compute/v2/server.py:1174
msgid "Confirm server resize is complete"
msgstr ""
-#: openstackclient/compute/v2/server.py:1140
+#: openstackclient/compute/v2/server.py:1179
msgid "Restore server state before resize"
msgstr ""
-#: openstackclient/compute/v2/server.py:1172
+#: openstackclient/compute/v2/server.py:1211
msgid ""
"\n"
"Error resizing server"
msgstr ""
-#: openstackclient/compute/v2/server.py:1224
+#: openstackclient/compute/v2/server.py:1263
msgid "Set new root password (interactive only)"
msgstr ""
-#: openstackclient/compute/v2/server.py:1230
+#: openstackclient/compute/v2/server.py:1269
msgid ""
"Property to add/change for this server (repeat option to set multiple "
"properties)"
msgstr ""
-#: openstackclient/compute/v2/server.py:1254
+#: openstackclient/compute/v2/server.py:1293
msgid "New password: "
msgstr ""
-#: openstackclient/compute/v2/server.py:1255
+#: openstackclient/compute/v2/server.py:1294
msgid "Retype new password: "
msgstr ""
-#: openstackclient/compute/v2/server.py:1259
+#: openstackclient/compute/v2/server.py:1298
msgid "Passwords do not match, password unchanged"
msgstr ""
-#: openstackclient/compute/v2/server.py:1279
+#: openstackclient/compute/v2/server.py:1318
msgid "Display server diagnostics information"
msgstr ""
-#: openstackclient/compute/v2/server.py:1292
+#: openstackclient/compute/v2/server.py:1331
msgid "Error retrieving diagnostics data"
msgstr ""
-#: openstackclient/compute/v2/server.py:1315
+#: openstackclient/compute/v2/server.py:1354
msgid "Login name (ssh -l option)"
msgstr ""
-#: openstackclient/compute/v2/server.py:1327
+#: openstackclient/compute/v2/server.py:1366
msgid "Destination port (ssh -p option)"
msgstr ""
-#: openstackclient/compute/v2/server.py:1339
+#: openstackclient/compute/v2/server.py:1378
msgid "Private key file (ssh -i option)"
msgstr ""
-#: openstackclient/compute/v2/server.py:1350
+#: openstackclient/compute/v2/server.py:1389
msgid "Options in ssh_config(5) format (ssh -o option)"
msgstr ""
-#: openstackclient/compute/v2/server.py:1364
+#: openstackclient/compute/v2/server.py:1403
msgid "Use only IPv4 addresses"
msgstr ""
-#: openstackclient/compute/v2/server.py:1371
+#: openstackclient/compute/v2/server.py:1410
msgid "Use only IPv6 addresses"
msgstr ""
-#: openstackclient/compute/v2/server.py:1380
+#: openstackclient/compute/v2/server.py:1419
msgid "Use public IP address"
msgstr ""
-#: openstackclient/compute/v2/server.py:1388
+#: openstackclient/compute/v2/server.py:1427
msgid "Use private IP address"
msgstr ""
-#: openstackclient/compute/v2/server.py:1395
+#: openstackclient/compute/v2/server.py:1434
msgid "Use other IP address (public, private, etc)"
msgstr ""
-#: openstackclient/compute/v2/server.py:1560
+#: openstackclient/compute/v2/server.py:1599
msgid "Property key to remove from server (repeat to unset multiple values)"
msgstr ""
@@ -669,7 +673,7 @@ msgstr ""
msgid "No service catalog with a type, name or ID of '%s' exists."
msgstr ""
-#: openstackclient/identity/v2_0/token.py:54
+#: openstackclient/identity/v2_0/token.py:55
msgid "Token to be deleted"
msgstr ""
diff --git a/requirements.txt b/requirements.txt
index b575125..c638ed1 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,20 +1,20 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
-pbr<2.0,>=1.4
+pbr>=1.6
six>=1.9.0
Babel>=1.3
cliff>=1.14.0 # Apache-2.0
cliff-tablib>=1.0
-os-client-config>=1.4.0
-oslo.config>=1.11.0 # Apache-2.0
+os-client-config!=1.6.2,>=1.4.0
+oslo.config>=2.3.0 # Apache-2.0
oslo.i18n>=1.5.0 # Apache-2.0
-oslo.utils>=1.9.0 # Apache-2.0
+oslo.utils>=2.0.0 # Apache-2.0
python-glanceclient>=0.18.0
python-keystoneclient>=1.6.0
-python-novaclient>=2.26.0
+python-novaclient>=2.28.1
python-cinderclient>=1.3.1
-python-neutronclient<3,>=2.6.0
+python-neutronclient>=2.6.0
requests>=2.5.2
stevedore>=1.5.0 # Apache-2.0
diff --git a/setup.cfg b/setup.cfg
index f2f4833..0b93682 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -316,6 +316,7 @@ openstack.image.v1 =
openstack.image.v2 =
image_add_project = openstackclient.image.v2.image:AddProjectToImage
+ image_create = openstackclient.image.v2.image:CreateImage
image_delete = openstackclient.image.v2.image:DeleteImage
image_list = openstackclient.image.v2.image:ListImage
image_remove_project = openstackclient.image.v2.image:RemoveProjectImage
diff --git a/setup.py b/setup.py
index d8080d0..782bb21 100644
--- a/setup.py
+++ b/setup.py
@@ -25,5 +25,5 @@ except ImportError:
pass
setuptools.setup(
- setup_requires=['pbr>=1.3'],
+ setup_requires=['pbr>=1.8'],
pbr=True)
diff --git a/test-requirements.txt b/test-requirements.txt
index 23edc37..25d0628 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -15,4 +15,4 @@ os-testr>=0.1.0
testrepository>=0.0.18
testtools>=1.4.0
WebOb>=1.2.3
-tempest-lib>=0.6.1
+tempest-lib>=0.8.0