summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorey Bryant <corey.bryant@canonical.com>2016-03-01 14:20:39 -0500
committergit-ubuntu importer <ubuntu-devel-discuss@lists.ubuntu.com>2016-03-01 19:45:09 +0000
commitba815ad57e1f5a7b71261c4a7b8bee142c75b5db (patch)
tree1def0d24a7ba397c9e4538a3c4ee9a6a65c364ef
parent52574c696d01ea4b4eb469dce0b01dcb7e7ca8c2 (diff)
parent1fed399182555cb88ec582a864a480e278ecc52f (diff)
2.1.0-0ubuntu1 (patches applied)applied/2.1.0-0ubuntu1
Imported using git-ubuntu import.
-rw-r--r--MANIFEST.in14
-rw-r--r--README.rst4
-rw-r--r--debian/changelog7
-rw-r--r--debian/control60
-rw-r--r--doc/source/command-objects/availability-zone.rst17
-rw-r--r--doc/source/command-objects/backup.rst2
-rw-r--r--doc/source/command-objects/compute-service.rst2
-rw-r--r--doc/source/command-objects/extension.rst2
-rw-r--r--doc/source/command-objects/image.rst60
-rw-r--r--doc/source/command-objects/limits.rst6
-rw-r--r--doc/source/command-objects/network.rst19
-rw-r--r--doc/source/command-objects/port.rst37
-rw-r--r--doc/source/command-objects/project.rst24
-rw-r--r--doc/source/command-objects/quota.rst8
-rw-r--r--doc/source/command-objects/router.rst137
-rw-r--r--doc/source/command-objects/security-group-rule.rst12
-rw-r--r--doc/source/command-objects/security-group.rst2
-rw-r--r--doc/source/command-objects/server.rst18
-rw-r--r--doc/source/command-objects/snapshot.rst2
-rw-r--r--doc/source/command-objects/subnet.rst20
-rw-r--r--doc/source/command-objects/volume-qos.rst2
-rw-r--r--doc/source/command-objects/volume-type.rst2
-rw-r--r--doc/source/command-objects/volume.rst2
-rw-r--r--doc/source/command-options.rst2
-rw-r--r--doc/source/commands.rst16
-rw-r--r--doc/source/index.rst5
-rw-r--r--doc/source/man/openstack.rst2
-rw-r--r--doc/source/plugins.rst8
-rw-r--r--doc/source/releases.rst4
-rw-r--r--functional/tests/common/test_availability_zone.py25
-rw-r--r--functional/tests/compute/v2/test_security_group_rule.py59
-rw-r--r--functional/tests/identity/v2/test_project.py8
-rw-r--r--functional/tests/network/v2/test_network.py4
-rw-r--r--functional/tests/network/v2/test_router.py50
-rw-r--r--openstackclient/api/network_v2.py59
-rw-r--r--openstackclient/api/object_store_v1.py2
-rw-r--r--openstackclient/api/utils.py4
-rw-r--r--openstackclient/common/availability_zone.py191
-rw-r--r--openstackclient/common/clientmanager.py20
-rw-r--r--openstackclient/common/command.py45
-rw-r--r--openstackclient/common/commandmanager.py4
-rw-r--r--openstackclient/common/configuration.py10
-rw-r--r--openstackclient/common/extension.py18
-rw-r--r--openstackclient/common/limits.py11
-rw-r--r--openstackclient/common/module.py14
-rw-r--r--openstackclient/common/quota.py24
-rw-r--r--openstackclient/common/timing.py10
-rw-r--r--openstackclient/common/utils.py52
-rw-r--r--openstackclient/compute/v2/agent.py25
-rw-r--r--openstackclient/compute/v2/aggregate.py44
-rw-r--r--openstackclient/compute/v2/availability_zone.py102
-rw-r--r--openstackclient/compute/v2/console.py14
-rw-r--r--openstackclient/compute/v2/fixedip.py13
-rw-r--r--openstackclient/compute/v2/flavor.py35
-rw-r--r--openstackclient/compute/v2/floatingip.py28
-rw-r--r--openstackclient/compute/v2/floatingippool.py10
-rw-r--r--openstackclient/compute/v2/host.py15
-rw-r--r--openstackclient/compute/v2/hypervisor.py15
-rw-r--r--openstackclient/compute/v2/hypervisor_stats.py8
-rw-r--r--openstackclient/compute/v2/keypair.py25
-rw-r--r--openstackclient/compute/v2/security_group.py140
-rw-r--r--openstackclient/compute/v2/server.py173
-rw-r--r--openstackclient/compute/v2/service.py33
-rw-r--r--openstackclient/compute/v2/usage.py15
-rw-r--r--openstackclient/i18n.py2
-rw-r--r--openstackclient/identity/common.py5
-rw-r--r--openstackclient/identity/v2_0/catalog.py15
-rw-r--r--openstackclient/identity/v2_0/ec2creds.py24
-rw-r--r--openstackclient/identity/v2_0/endpoint.py24
-rw-r--r--openstackclient/identity/v2_0/project.py79
-rw-r--r--openstackclient/identity/v2_0/role.py36
-rw-r--r--openstackclient/identity/v2_0/service.py24
-rw-r--r--openstackclient/identity/v2_0/token.py14
-rw-r--r--openstackclient/identity/v2_0/user.py26
-rw-r--r--openstackclient/identity/v3/catalog.py15
-rw-r--r--openstackclient/identity/v3/consumer.py27
-rw-r--r--openstackclient/identity/v3/credential.py27
-rw-r--r--openstackclient/identity/v3/domain.py26
-rw-r--r--openstackclient/identity/v3/ec2creds.py24
-rw-r--r--openstackclient/identity/v3/endpoint.py27
-rw-r--r--openstackclient/identity/v3/federation_protocol.py24
-rw-r--r--openstackclient/identity/v3/group.py35
-rw-r--r--openstackclient/identity/v3/identity_provider.py27
-rw-r--r--openstackclient/identity/v3/mapping.py25
-rw-r--r--openstackclient/identity/v3/policy.py27
-rw-r--r--openstackclient/identity/v3/project.py34
-rw-r--r--openstackclient/identity/v3/region.py27
-rw-r--r--openstackclient/identity/v3/role.py32
-rw-r--r--openstackclient/identity/v3/role_assignment.py11
-rw-r--r--openstackclient/identity/v3/service.py27
-rw-r--r--openstackclient/identity/v3/service_provider.py27
-rw-r--r--openstackclient/identity/v3/token.py25
-rw-r--r--openstackclient/identity/v3/trust.py24
-rw-r--r--openstackclient/identity/v3/unscoped_saml.py15
-rw-r--r--openstackclient/identity/v3/user.py60
-rw-r--r--openstackclient/image/v1/image.py101
-rw-r--r--openstackclient/image/v2/image.py238
-rw-r--r--openstackclient/locale/de/LC_MESSAGES/openstackclient.po (renamed from python-openstackclient/locale/de/LC_MESSAGES/python-openstackclient.po)45
-rw-r--r--openstackclient/locale/openstackclient.pot (renamed from python-openstackclient/locale/python-openstackclient.pot)295
-rw-r--r--openstackclient/locale/zh_TW/LC_MESSAGES/openstackclient.po (renamed from python-openstackclient/locale/zh_TW/LC_MESSAGES/python-openstackclient.po)43
-rw-r--r--openstackclient/network/client.py62
-rw-r--r--openstackclient/network/common.py83
-rw-r--r--openstackclient/network/v2/network.py225
-rw-r--r--openstackclient/network/v2/port.py93
-rw-r--r--openstackclient/network/v2/router.py295
-rw-r--r--openstackclient/network/v2/security_group.py40
-rw-r--r--openstackclient/network/v2/subnet.py63
-rw-r--r--openstackclient/object/client.py4
-rw-r--r--openstackclient/object/v1/account.py16
-rw-r--r--openstackclient/object/v1/container.py34
-rw-r--r--openstackclient/object/v1/object.py34
-rw-r--r--openstackclient/shell.py2
-rw-r--r--openstackclient/tests/api/test_network_v2.py52
-rw-r--r--openstackclient/tests/api/test_object_store_v1.py5
-rw-r--r--openstackclient/tests/common/test_availability_zone.py257
-rw-r--r--openstackclient/tests/common/test_clientmanager.py33
-rw-r--r--openstackclient/tests/common/test_command.py (renamed from openstackclient/tests/network/common.py)29
-rw-r--r--openstackclient/tests/common/test_configuration.py47
-rw-r--r--openstackclient/tests/common/test_extension.py17
-rw-r--r--openstackclient/tests/common/test_logs.py6
-rw-r--r--openstackclient/tests/common/test_parseractions.py97
-rw-r--r--openstackclient/tests/common/test_quota.py25
-rw-r--r--openstackclient/tests/common/test_timing.py12
-rw-r--r--openstackclient/tests/common/test_utils.py38
-rw-r--r--openstackclient/tests/compute/v2/fakes.py64
-rw-r--r--openstackclient/tests/compute/v2/test_flavor.py8
-rw-r--r--openstackclient/tests/compute/v2/test_security_group.py45
-rw-r--r--openstackclient/tests/compute/v2/test_security_group_rule.py282
-rw-r--r--openstackclient/tests/compute/v2/test_server.py437
-rw-r--r--openstackclient/tests/fakes.py14
-rw-r--r--openstackclient/tests/identity/v2_0/test_catalog.py12
-rw-r--r--openstackclient/tests/identity/v2_0/test_project.py139
-rw-r--r--openstackclient/tests/identity/v2_0/test_role.py46
-rw-r--r--openstackclient/tests/identity/v2_0/test_service.py57
-rw-r--r--openstackclient/tests/identity/v2_0/test_user.py145
-rw-r--r--openstackclient/tests/identity/v3/test_domain.py57
-rw-r--r--openstackclient/tests/identity/v3/test_endpoint.py145
-rw-r--r--openstackclient/tests/identity/v3/test_group.py44
-rw-r--r--openstackclient/tests/identity/v3/test_identity_provider.py115
-rw-r--r--openstackclient/tests/identity/v3/test_project.py130
-rw-r--r--openstackclient/tests/identity/v3/test_region.py75
-rw-r--r--openstackclient/tests/identity/v3/test_role.py38
-rw-r--r--openstackclient/tests/identity/v3/test_role_assignment.py30
-rw-r--r--openstackclient/tests/identity/v3/test_service.py63
-rw-r--r--openstackclient/tests/identity/v3/test_service_provider.py79
-rw-r--r--openstackclient/tests/identity/v3/test_user.py211
-rw-r--r--openstackclient/tests/image/v1/test_image.py77
-rw-r--r--openstackclient/tests/image/v2/fakes.py133
-rw-r--r--openstackclient/tests/image/v2/test_image.py513
-rw-r--r--openstackclient/tests/network/test_common.py135
-rw-r--r--openstackclient/tests/network/v2/fakes.py536
-rw-r--r--openstackclient/tests/network/v2/test_network.py655
-rw-r--r--openstackclient/tests/network/v2/test_port.py140
-rw-r--r--openstackclient/tests/network/v2/test_router.py372
-rw-r--r--openstackclient/tests/network/v2/test_security_group.py99
-rw-r--r--openstackclient/tests/network/v2/test_subnet.py108
-rw-r--r--openstackclient/tests/object/v1/test_container.py18
-rw-r--r--openstackclient/tests/object/v1/test_container_all.py20
-rw-r--r--openstackclient/tests/object/v1/test_object.py53
-rw-r--r--openstackclient/tests/object/v1/test_object_all.py8
-rw-r--r--openstackclient/tests/test_shell.py2
-rw-r--r--openstackclient/tests/volume/v1/test_qos_specs.py46
-rw-r--r--openstackclient/tests/volume/v1/test_volume.py302
-rw-r--r--openstackclient/tests/volume/v2/fakes.py59
-rw-r--r--openstackclient/tests/volume/v2/test_backup.py41
-rw-r--r--openstackclient/tests/volume/v2/test_qos_specs.py45
-rw-r--r--openstackclient/tests/volume/v2/test_snapshot.py30
-rw-r--r--openstackclient/tests/volume/v2/test_type.py55
-rw-r--r--openstackclient/tests/volume/v2/test_volume.py497
-rw-r--r--openstackclient/volume/v1/backup.py28
-rw-r--r--openstackclient/volume/v1/qos_specs.py45
-rw-r--r--openstackclient/volume/v1/snapshot.py33
-rw-r--r--openstackclient/volume/v1/volume.py34
-rw-r--r--openstackclient/volume/v1/volume_type.py34
-rw-r--r--openstackclient/volume/v2/backup.py29
-rw-r--r--openstackclient/volume/v2/qos_specs.py45
-rw-r--r--openstackclient/volume/v2/snapshot.py32
-rw-r--r--openstackclient/volume/v2/volume.py36
-rw-r--r--openstackclient/volume/v2/volume_type.py34
-rw-r--r--releasenotes/notes/add-port-delete-command-4789d3881b186cfc.yaml5
-rw-r--r--releasenotes/notes/add-port-show-command-de0a599017189a21.yaml5
-rw-r--r--releasenotes/notes/add-subnet-list-command-970f4b397469bdc6.yaml5
-rw-r--r--releasenotes/notes/bug-1486597-857e20262c038514.yaml5
-rw-r--r--releasenotes/notes/bug-1516661-757ef629f899cca3.yaml5
-rw-r--r--releasenotes/notes/bug-1517134-9efecb257910989c.yaml6
-rw-r--r--releasenotes/notes/bug-1519503-978a68a54819dbbc.yaml5
-rw-r--r--releasenotes/notes/bug-1519512-d20f44aca1f9e9b9.yaml6
-rw-r--r--releasenotes/notes/bug-1520003-505af921c8afffc9.yaml5
-rw-r--r--releasenotes/notes/bug-1521492-89b972c6362940a5.yaml5
-rw-r--r--releasenotes/notes/bug-1521492-8cde2601591a8c78.yaml5
-rw-r--r--releasenotes/notes/bug-1522969-63abf273c6e71a07.yaml6
-rw-r--r--releasenotes/notes/bug-1524456-9967fac653c91cb2.yaml6
-rw-r--r--releasenotes/notes/bug-1525805-122e6ce0c3cd4945.yaml5
-rw-r--r--releasenotes/notes/bug-1527833-42cde11d28b09ac3.yaml7
-rw-r--r--releasenotes/notes/bug-1531360-0f5c62d18088e5b5.yaml5
-rw-r--r--releasenotes/notes/bug-1532945-1a5485b8d0ebddb8.yaml8
-rw-r--r--releasenotes/notes/bug-1534202-1ba78f0bb744961f.yaml7
-rw-r--r--releasenotes/notes/bug-1540988-17841cfd5accf7f5.yaml9
-rw-r--r--requirements.txt28
-rw-r--r--setup.cfg26
-rw-r--r--test-requirements.txt41
-rw-r--r--tox.ini3
202 files changed, 6780 insertions, 4865 deletions
diff --git a/MANIFEST.in b/MANIFEST.in
deleted file mode 100644
index aeabc0d..0000000
--- a/MANIFEST.in
+++ /dev/null
@@ -1,14 +0,0 @@
-include AUTHORS
-include babel.cfg
-include ChangeLog
-include LICENSE
-include README.rst
-
-recursive-include doc *
-recursive-include tests *
-recursive-include python-openstackclient *.po *.pot
-
-exclude .gitignore
-exclude .gitreview
-
-global-exclude *.pyc
diff --git a/README.rst b/README.rst
index 7a92b1c..53b42a7 100644
--- a/README.rst
+++ b/README.rst
@@ -11,8 +11,8 @@ OpenStackClient
:alt: Downloads
OpenStackClient (aka OSC) is a command-line client for OpenStack that brings
-the command set for Compute, Identity, Image, Object Store and Volume APIs
-together in a single shell with a uniform command structure.
+the command set for Compute, Identity, Image, Object Store and Block Storage
+APIs together in a single shell with a uniform command structure.
The primary goal is to provide a unified shell command structure and a common
language to describe operations in OpenStack.
diff --git a/debian/changelog b/debian/changelog
index 6932dbf..46771e7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+python-openstackclient (2.1.0-0ubuntu1) xenial; urgency=medium
+
+ * New upstream release.
+ * Align (Build-)Depends with upstream.
+
+ -- Corey Bryant <corey.bryant@canonical.com> Tue, 01 Mar 2016 14:20:39 -0500
+
python-openstackclient (2.0.0-3) experimental; urgency=medium
* Blacklist 3 failed unit tests in Jessie (works in Sid):
diff --git a/debian/control b/debian/control
index 40d806e..a9cd36e 100644
--- a/debian/control
+++ b/debian/control
@@ -1,7 +1,8 @@
Source: python-openstackclient
Section: python
Priority: optional
-Maintainer: PKG OpenStack <openstack-devel@lists.alioth.debian.org>
+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
+XSBC-Original-Maintainer: PKG OpenStack <openstack-devel@lists.alioth.debian.org>
Uploaders: gustavo panizzo <gfa@zumbi.com.ar>,
Thomas Goirand <zigo@debian.org>,
Build-Depends: debhelper (>= 9),
@@ -23,10 +24,10 @@ Build-Depends-Indep: python-babel,
python-crypto,
python-designateclient (>= 1.5.0),
python-fixtures (>= 1.3.1),
- python-glanceclient (>= 1:0.18.0),
+ python-glanceclient (>= 1:1.2.0),
python-hacking (>= 0.10.0),
python-heatclient (>= 0.6.0),
- python-ironicclient (>= 0.8.0),
+ python-ironicclient (>= 1.1.0),
python-keyring,
python-keystoneauth1 (>= 2.1.0),
python-keystoneclient (>= 1:1.6.0),
@@ -34,20 +35,21 @@ Build-Depends-Indep: python-babel,
python-mock (>= 1.3),
python-neutronclient (>= 1:2.6.0),
python-novaclient (>= 2:2.30.0),
- python-os-client-config (>= 1.4.0),
+ python-openstacksdk (>= 0.7.4),
+ python-os-client-config (>= 1.13.1),
python-os-testr (>= 0.4.2),
- python-oslo.config (>= 1:3.2.0),
- python-oslo.i18n (>= 1.5.0),
+ python-oslo.config (>= 1:3.4.0),
+ python-oslo.i18n (>= 2.1.0),
python-oslo.serialization (>= 1.2.0),
- python-oslo.utils (>= 3.3.0),
+ python-oslo.utils (>= 3.4.0),
python-oslosphinx (>= 2.5.0),
python-oslotest (>= 1.10.0),
python-requests (>= 2.8.1),
- python-requests-mock (>= 0.6.0),
+ python-requests-mock (>= 0.7.0),
python-saharaclient (>= 0.10.0),
python-six (>= 1.9.0),
python-stevedore (>= 1.5.0),
- python-tempest-lib (>= 0.11.0),
+ python-tempest-lib (>= 0.13.0),
python-testtools (>= 1.4.0),
python-webob,
python-zaqarclient (>= 0.3.0),
@@ -57,26 +59,30 @@ Build-Depends-Indep: python-babel,
python3-coverage,
python3-crypto,
python3-fixtures (>= 1.3.1),
- python3-glanceclient (>= 1:0.18.0),
+ python3-glanceclient (>= 1:1.2.0),
+ python3-ironicclient (>= 1.1.0),
python3-keyring,
python3-keystoneauth1 (>= 2.1.0),
python3-keystoneclient (>= 1:1.6.0),
+ python3-mistralclient (>= 1.0.0),
python3-mock (>= 1.3),
python3-neutronclient (>= 1:2.6.0),
python3-novaclient (>= 2:2.30.0),
- python3-os-client-config (>= 1.4.0),
+ python3-openstacksdk (>= 0.7.4),
+ python3-os-client-config (>= 1.13.1),
python3-os-testr (>= 0.4.2),
- python3-oslo.config (>= 1:3.2.0),
- python3-oslo.i18n (>= 1.5.0),
+ python3-oslo.config (>= 1:3.4.0),
+ python3-oslo.i18n (>= 2.1.0),
python3-oslo.serialization (>= 1.2.0),
- python3-oslo.utils (>= 3.3.0),
+ python3-oslo.utils (>= 3.4.0),
python3-oslotest (>= 1.10.0),
python3-requests (>= 2.8.1),
- python3-requests-mock (>= 0.6.0),
+ python3-requests-mock (>= 0.7.0),
+ python3-saharaclient (>= 0.10.0),
python3-six (>= 1.9.0),
python3-stevedore (>= 1.5.0),
python3-subunit,
- python3-tempest-lib (>= 0.11.0),
+ python3-tempest-lib (>= 0.13.0),
python3-testtools (>= 1.4.0),
python3-webob,
subunit,
@@ -92,17 +98,18 @@ Depends: python-babel,
python-cinderclient (>= 1:1.3.1),
python-cliff (>= 1.15.0),
python-crypto,
- python-glanceclient (>= 1:0.18.0),
+ python-glanceclient (>= 1:1.2.0),
python-keyring,
python-keystoneauth1 (>= 2.1.0),
python-keystoneclient (>= 1:1.6.0),
python-neutronclient (>= 1:2.6.0),
python-novaclient (>= 2:2.30.0),
- python-os-client-config (>= 1.4.0),
- python-oslo.config (>= 1:3.2.0),
- python-oslo.i18n (>= 1.5.0),
+ python-openstacksdk (>= 0.7.4),
+ python-os-client-config (>= 1.13.1),
+ python-oslo.config (>= 1:3.4.0),
+ python-oslo.i18n (>= 2.1.0),
python-oslo.serialization (>= 1.2.0),
- python-oslo.utils (>= 3.3.0),
+ python-oslo.utils (>= 3.4.0),
python-pbr (>= 1.8),
python-requests (>= 2.8.1),
python-six (>= 1.9.0),
@@ -129,17 +136,18 @@ Depends: python3-babel,
python3-cinderclient (>= 1:1.3.1),
python3-cliff (>= 1.15.0),
python3-crypto,
- python3-glanceclient (>= 1:0.18.0),
+ python3-glanceclient (>= 1:1.2.0),
python3-keyring,
python3-keystoneauth1 (>= 2.1.0),
python3-keystoneclient (>= 1:1.6.0),
python3-neutronclient (>= 1:2.6.0),
python3-novaclient (>= 2:2.30.0),
- python3-os-client-config (>= 1.4.0),
- python3-oslo.config (>= 1:3.2.0),
- python3-oslo.i18n (>= 1.5.0),
+ python3-openstacksdk (>= 0.7.4),
+ python3-os-client-config (>= 1.13.1),
+ python3-oslo.config (>= 1:3.4.0),
+ python3-oslo.i18n (>= 2.1.0),
python3-oslo.serialization (>= 1.2.0),
- python3-oslo.utils (>= 3.3.0),
+ python3-oslo.utils (>= 3.4.0),
python3-pbr (>= 1.8),
python3-requests (>= 2.8.1),
python3-six (>= 1.9.0),
diff --git a/doc/source/command-objects/availability-zone.rst b/doc/source/command-objects/availability-zone.rst
index 3743523..1f56843 100644
--- a/doc/source/command-objects/availability-zone.rst
+++ b/doc/source/command-objects/availability-zone.rst
@@ -2,7 +2,7 @@
availability zone
=================
-Compute v2
+Block Storage v2, Compute v2, Network v2
availability zone list
----------------------
@@ -13,8 +13,23 @@ List availability zones and their status
.. code:: bash
os availability zone list
+ [--compute]
+ [--network]
+ [--volume]
[--long]
+.. option:: --compute
+
+ List compute availability zones
+
+.. option:: --network
+
+ List network availability zones
+
+.. option:: --volume
+
+ List volume availability zones
+
.. option:: --long
List additional fields in output
diff --git a/doc/source/command-objects/backup.rst b/doc/source/command-objects/backup.rst
index ec201aa..9d7fb95 100644
--- a/doc/source/command-objects/backup.rst
+++ b/doc/source/command-objects/backup.rst
@@ -2,7 +2,7 @@
backup
======
-Volume v1
+Block Storage v1
backup create
-------------
diff --git a/doc/source/command-objects/compute-service.rst b/doc/source/command-objects/compute-service.rst
index 95a77bd..7bcab4d 100644
--- a/doc/source/command-objects/compute-service.rst
+++ b/doc/source/command-objects/compute-service.rst
@@ -57,7 +57,7 @@ Set service command
.. _compute-service-set:
.. describe:: --enable
- Enable service
+ Enable service (default)
.. describe:: --disable
diff --git a/doc/source/command-objects/extension.rst b/doc/source/command-objects/extension.rst
index 8f39a62..dff30fa 100644
--- a/doc/source/command-objects/extension.rst
+++ b/doc/source/command-objects/extension.rst
@@ -34,7 +34,7 @@ List API extensions
.. option:: --volume
- List extensions for the Volume API
+ List extensions for the Block Storage API
.. option:: --long
diff --git a/doc/source/command-objects/image.rst b/doc/source/command-objects/image.rst
index d4b9916..61872ec 100644
--- a/doc/source/command-objects/image.rst
+++ b/doc/source/command-objects/image.rst
@@ -19,7 +19,6 @@ Create/upload an image
[--store <store>]
[--container-format <container-format>]
[--disk-format <disk-format>]
- [--owner <project>]
[--size <size>]
[--min-disk <disk-gb>]
[--min-ram <ram-mb>]
@@ -33,6 +32,7 @@ Create/upload an image
[--public | --private]
[--property <key=value> [...] ]
[--tag <tag> [...] ]
+ [--project <project> [--project-domain <project-domain>]]
<image-name>
.. option:: --id <id>
@@ -53,10 +53,6 @@ Create/upload an image
Image disk format (default: raw)
-.. option:: --owner <project>
-
- Image owner project name or ID
-
.. option:: --size <size>
Image size, in bytes (only used with --location and --copy-from)
@@ -127,6 +123,18 @@ Create/upload an image
.. versionadded:: 2
+.. option:: --project <project>
+
+ Set an alternate project on this image (name or ID).
+ Previously known as `--owner`.
+
+.. option:: --project-domain <project-domain>
+
+ Domain the project belongs to (name or ID).
+ This can be used in case collisions between project names exist.
+
+ .. versionadded:: 2
+
.. describe:: <image-name>
New image name
@@ -159,6 +167,8 @@ List available images
[--property <key=value>]
[--long]
[--sort <key>[:<direction>]]
+ [--limit <limit>]
+ [--marker <marker>]
.. option:: --public
@@ -187,6 +197,15 @@ List available images
Sort output by selected keys and directions(asc or desc) (default: asc),
multiple keys and directions can be specified separated by comma
+.. option:: --limit <limit>
+
+ Maximum number of images to display.
+
+.. option:: --marker <marker>
+
+ The last image (name or ID) of the previous page. Display list of images
+ after marker. Display all images if not specified.
+
image save
----------
@@ -219,7 +238,6 @@ Set image properties
os image set
[--name <name>]
- [--owner <project>]
[--min-disk <disk-gb>]
[--min-ram <disk-ram>]
[--container-format <container-format>]
@@ -243,16 +261,14 @@ Set image properties
[--os-distro <os-distro>]
[--os-version <os-version>]
[--ramdisk-id <ramdisk-id>]
+ [--activate|--deactivate]
+ [--project <project> [--project-domain <project-domain>]]
<image>
.. option:: --name <name>
New image name
-.. option:: --owner <project>
-
- New image owner project (name or ID)
-
.. option:: --min-disk <disk-gb>
Minimum disk size needed to boot image, in gigabytes
@@ -387,6 +403,30 @@ Set image properties
.. versionadded:: 2
+.. option:: --activate
+
+ Activate the image.
+
+ .. versionadded:: 2
+
+.. option:: --deactivate
+
+ Deactivate the image.
+
+ .. versionadded:: 2
+
+.. option:: --project <project>
+
+ Set an alternate project on this image (name or ID).
+ Previously known as `--owner`.
+
+.. option:: --project-domain <project-domain>
+
+ Domain the project belongs to (name or ID).
+ This can be used in case collisions between project names exist.
+
+ .. versionadded:: 2
+
.. describe:: <image>
Image to modify (name or ID)
diff --git a/doc/source/command-objects/limits.rst b/doc/source/command-objects/limits.rst
index 0d466af..6a7509f 100644
--- a/doc/source/command-objects/limits.rst
+++ b/doc/source/command-objects/limits.rst
@@ -2,14 +2,14 @@
limits
======
-The Compute and Volume APIs have resource usage limits.
+The Compute and Block Storage APIs have resource usage limits.
-Compute v2, Volume v1
+Compute v2, Block Storage v1
limits show
-----------
-Show compute and volume limits
+Show compute and block storage limits
.. program:: limits show
.. code:: bash
diff --git a/doc/source/command-objects/network.rst b/doc/source/command-objects/network.rst
index 6b63c35..bb36667 100644
--- a/doc/source/command-objects/network.rst
+++ b/doc/source/command-objects/network.rst
@@ -16,6 +16,7 @@ Create new network
[--project <project> [--project-domain <project-domain>]]
[--enable | --disable]
[--share | --no-share]
+ [--availability-zone-hint <availability-zone>]
<name>
.. option:: --project <project>
@@ -43,6 +44,11 @@ Create new network
Do not share the network between projects
+.. option:: --availability-zone-hint <availability-zone>
+
+ Availability Zone in which to create this network (requires the Network
+ Availability Zone extension, this option can be repeated).
+
.. _network_create-name:
.. describe:: <name>
@@ -59,10 +65,10 @@ Delete network(s)
os network delete
<network> [<network> ...]
-.. _network_delete-project:
+.. _network_delete-network:
.. describe:: <network>
- Network to delete (name or ID)
+ Network(s) to delete (name or ID)
network list
------------
@@ -74,17 +80,12 @@ List networks
os network list
[--external]
- [--dhcp <dhcp-id>]
[--long]
.. option:: --external
List external networks
-.. option:: --dhcp <dhcp-id>
-
- DHCP agent ID
-
.. option:: --long
List additional fields in output
@@ -123,7 +124,7 @@ Set network properties
Do not share the network between projects
-.. _network_set-name:
+.. _network_set-network:
.. describe:: <network>
Network to modify (name or ID)
@@ -139,7 +140,7 @@ Display network details
os network show
<network>
-.. _network_show-name:
+.. _network_show-network:
.. describe:: <network>
Network to display (name or ID)
diff --git a/doc/source/command-objects/port.rst b/doc/source/command-objects/port.rst
new file mode 100644
index 0000000..414b743
--- /dev/null
+++ b/doc/source/command-objects/port.rst
@@ -0,0 +1,37 @@
+====
+port
+====
+
+Network v2
+
+port delete
+-----------
+
+Delete port(s)
+
+.. program:: port delete
+.. code:: bash
+
+ os port delete
+ <port> [<port> ...]
+
+.. _port_delete-port:
+.. describe:: <port>
+
+ Port(s) to delete (name or ID)
+
+port show
+---------
+
+Display port details
+
+.. program:: port show
+.. code:: bash
+
+ os port show
+ <port>
+
+.. _port_show-port:
+.. describe:: <port>
+
+ Port to display (name or ID)
diff --git a/doc/source/command-objects/project.rst b/doc/source/command-objects/project.rst
index a342115..f76f79f 100644
--- a/doc/source/command-objects/project.rst
+++ b/doc/source/command-objects/project.rst
@@ -156,6 +156,8 @@ Set project properties
Set a property on :ref:`\<project\> <project_set-project>`
(repeat option to set multiple properties)
+ *Identity version 2 only*
+
.. _project_set-project:
.. describe:: <project>
@@ -195,3 +197,25 @@ Display project details
.. describe:: <project>
Project to display (name or ID)
+
+project unset
+-------------
+
+Unset project properties
+
+*Identity version 2 only*
+
+.. program:: project unset
+.. code:: bash
+
+ os project unset
+ --property <key> [--property <key> ...]
+ <project>
+
+.. option:: --property <key>
+
+ Property key to remove from project (repeat option to remove multiple properties)
+
+.. describe:: <project>
+
+ Project to modify (name or ID)
diff --git a/doc/source/command-objects/quota.rst b/doc/source/command-objects/quota.rst
index 5ea49f8..98e6df3 100644
--- a/doc/source/command-objects/quota.rst
+++ b/doc/source/command-objects/quota.rst
@@ -4,7 +4,7 @@ quota
Resource quotas appear in multiple APIs, OpenStackClient presents them as a single object with multiple properties.
-Compute v2, Volume v1
+Compute v2, Block Storage v1
quota set
---------
@@ -26,7 +26,7 @@ Set quotas for project
[--properties <num-properties>]
[--ram <ram-mb>]
- # Volume settings
+ # Block Storage settings
[--gigabytes <new-gigabytes>]
[--snapshots <new-snapshots>]
[--volumes <new-volumes>]
@@ -51,7 +51,7 @@ Set quotas for class
[--properties <num-properties>]
[--ram <ram-mb>]
- # Volume settings
+ # Block Storage settings
[--gigabytes <new-gigabytes>]
[--snapshots <new-snapshots>]
[--volumes <new-volumes>]
@@ -161,4 +161,4 @@ Show quotas for project
.. _quota_show-class:
.. describe:: <class>
- Class to show \ No newline at end of file
+ Class to show
diff --git a/doc/source/command-objects/router.rst b/doc/source/command-objects/router.rst
new file mode 100644
index 0000000..2a5bf05
--- /dev/null
+++ b/doc/source/command-objects/router.rst
@@ -0,0 +1,137 @@
+======
+router
+======
+
+Network v2
+
+router create
+-------------
+
+Create new router
+
+.. program:: router create
+.. code:: bash
+
+ os router create
+ [--project <project> [--project-domain <project-domain>]]
+ [--enable | --disable]
+ [--distributed]
+ [--availability-zone-hint <availability-zone>]
+ <name>
+
+.. option:: --project <project>
+
+ Owner's project (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:: --enable
+
+ Enable router (default)
+
+.. option:: --disable
+
+ Disable router
+
+.. option:: --distributed
+
+ Create a distributed router
+
+.. option:: --availability-zone-hint <availability-zone>
+
+ Availability Zone in which to create this router (requires the Router
+ Availability Zone extension, this option can be repeated).
+
+.. _router_create-name:
+.. describe:: <name>
+
+ New router name
+
+router delete
+-------------
+
+Delete router(s)
+
+.. program:: router delete
+.. code:: bash
+
+ os router delete
+ <router> [<router> ...]
+
+.. _router_delete-router:
+.. describe:: <router>
+
+ Router(s) to delete (name or ID)
+
+router list
+-----------
+
+List routers
+
+.. program:: router list
+.. code:: bash
+
+ os router list
+ [--long]
+
+.. option:: --long
+
+ List additional fields in output
+
+router set
+----------
+
+Set router properties
+
+.. program:: router set
+.. code:: bash
+
+ os router set
+ [--name <name>]
+ [--enable | --disable]
+ [--distributed | --centralized]
+ <router>
+
+.. option:: --name <name>
+
+ Set router name
+
+.. option:: --enable
+
+ Enable router
+
+.. option:: --disable
+
+ Disable router
+
+.. option:: --distributed
+
+ Set router to distributed mode (disabled router only)
+
+.. option:: --centralized
+
+ Set router to centralized mode (disabled router only)
+
+.. _router_set-router:
+.. describe:: <router>
+
+ Router to modify (name or ID)
+
+router show
+-----------
+
+Display router details
+
+.. program:: router show
+.. code:: bash
+
+ os router show
+ <router>
+
+.. _router_show-router:
+.. describe:: <router>
+
+ Router to display (name or ID)
diff --git a/doc/source/command-objects/security-group-rule.rst b/doc/source/command-objects/security-group-rule.rst
index 8bd0d06..50bc64a 100644
--- a/doc/source/command-objects/security-group-rule.rst
+++ b/doc/source/command-objects/security-group-rule.rst
@@ -2,7 +2,7 @@
security group rule
===================
-Compute v2
+Compute v2, Network v2
security group rule create
--------------------------
@@ -14,7 +14,7 @@ Create a new security group rule
os security group rule create
[--proto <proto>]
- [--src-ip <ip-address>]
+ [--src-ip <ip-address> | --src-group <group>]
[--dst-port <port-range>]
<group>
@@ -24,7 +24,11 @@ Create a new security group rule
.. option:: --src-ip <ip-address>
- Source IP (may use CIDR notation; default: 0.0.0.0/0)
+ Source IP address block (may use CIDR notation; default: 0.0.0.0/0)
+
+.. option:: --src-group <group>
+
+ Source security group (ID only)
.. option:: --dst-port <port-range>
@@ -58,7 +62,7 @@ List security group rules
.. code:: bash
os security group rule list
- <group>
+ [<group>]
.. describe:: <group>
diff --git a/doc/source/command-objects/security-group.rst b/doc/source/command-objects/security-group.rst
index 60de41d..cf86bda 100644
--- a/doc/source/command-objects/security-group.rst
+++ b/doc/source/command-objects/security-group.rst
@@ -2,7 +2,7 @@
security group
==============
-Compute v2
+Compute v2, Network v2
security group create
---------------------
diff --git a/doc/source/command-objects/server.rst b/doc/source/command-objects/server.rst
index 506a82d..fc27597 100644
--- a/doc/source/command-objects/server.rst
+++ b/doc/source/command-objects/server.rst
@@ -77,19 +77,20 @@ Create a new server
.. option:: --image <image>
- Create server from this image
+ Create server from this image (name or ID)
.. option:: --volume <volume>
- Create server from this volume
+ Create server from this volume (name or ID)
.. option:: --flavor <flavor>
- Create server with this flavor
+ Create server with this flavor (name or ID)
.. option:: --security-group <security-group-name>
- Security group to assign to this server (repeat for multiple groups)
+ Security group to assign to this server (name or ID)
+ (repeat for multiple groups)
.. option:: --key-name <key-name>
@@ -216,11 +217,11 @@ List servers
.. option:: --flavor <flavor>
- Search by flavor ID
+ Search by flavor (name or ID)
.. option:: --image <image>
- Search by image ID
+ Search by image (name or ID)
.. option:: --host <hostname>
@@ -374,14 +375,15 @@ Rebuild server
.. code:: bash
os server rebuild
- --image <image>
+ [--image <image>]
[--password <password>]
[--wait]
<server>
.. option:: --image <image>
- Recreate server from this image
+ Recreate server from the specified image (name or ID). Defaults to the
+ currently used one.
.. option:: --password <password>
diff --git a/doc/source/command-objects/snapshot.rst b/doc/source/command-objects/snapshot.rst
index e05673b..b483868 100644
--- a/doc/source/command-objects/snapshot.rst
+++ b/doc/source/command-objects/snapshot.rst
@@ -2,7 +2,7 @@
snapshot
========
-Volume v1
+Block Storage v1
snapshot create
---------------
diff --git a/doc/source/command-objects/subnet.rst b/doc/source/command-objects/subnet.rst
new file mode 100644
index 0000000..70a0eed
--- /dev/null
+++ b/doc/source/command-objects/subnet.rst
@@ -0,0 +1,20 @@
+======
+subnet
+======
+
+Network v2
+
+subnet list
+-----------
+
+List subnets
+
+.. program:: subnet list
+.. code:: bash
+
+ os subnet list
+ [--long]
+
+.. option:: --long
+
+ List additional fields in output
diff --git a/doc/source/command-objects/volume-qos.rst b/doc/source/command-objects/volume-qos.rst
index d0fe36f..2d9d14a 100644
--- a/doc/source/command-objects/volume-qos.rst
+++ b/doc/source/command-objects/volume-qos.rst
@@ -2,7 +2,7 @@
volume qos
==========
-volume v1, v2
+Block Storage v1, v2
volume qos associate
--------------------
diff --git a/doc/source/command-objects/volume-type.rst b/doc/source/command-objects/volume-type.rst
index 0edd742..8a11384 100644
--- a/doc/source/command-objects/volume-type.rst
+++ b/doc/source/command-objects/volume-type.rst
@@ -2,7 +2,7 @@
volume type
===========
-Volume v1, v2
+Block Storage v1, v2
volume type create
------------------
diff --git a/doc/source/command-objects/volume.rst b/doc/source/command-objects/volume.rst
index cb52c56..bf89dc4 100644
--- a/doc/source/command-objects/volume.rst
+++ b/doc/source/command-objects/volume.rst
@@ -2,7 +2,7 @@
volume
======
-Volume v1, v2
+Block Storage v1, v2
volume create
-------------
diff --git a/doc/source/command-options.rst b/doc/source/command-options.rst
index edafb15..458c56b 100644
--- a/doc/source/command-options.rst
+++ b/doc/source/command-options.rst
@@ -19,7 +19,7 @@ Boolean Options
Boolean options for any command that sets a resource state, such as 'enabled'
or 'public', shall always have both positive and negative options defined.
-The names of those options shall either be a naturally occuring pair of
+The names of those options shall either be a naturally occurring pair of
words (in English) or a positive option and a negative option with `no-`
prepended (such as in the traditional GNU option usage) like `--share` and
`--no-share`.
diff --git a/doc/source/commands.rst b/doc/source/commands.rst
index 6069895..1c4f84b 100644
--- a/doc/source/commands.rst
+++ b/doc/source/commands.rst
@@ -70,7 +70,7 @@ the API resources will be merged, as in the ``quota`` object that has options
referring to both Compute and Volume quotas.
* ``access token``: (**Identity**) long-lived OAuth-based token
-* ``availability zone``: (**Compute**) a logical partition of hosts or volume services
+* ``availability zone``: (**Compute**, **Network**, **Volume**) a logical partition of hosts or block storage or network services
* ``aggregate``: (**Compute**) a grouping of servers
* ``backup``: (**Volume**) a volume copy
* ``catalog``: (**Identity**) service catalog
@@ -82,7 +82,7 @@ referring to both Compute and Volume quotas.
* ``domain``: (**Identity**) a grouping of projects
* ``ec2 credentials``: (**Identity**) AWS EC2-compatible credentials
* ``endpoint``: (**Identity**) the base URL used to contact a specific service
-* ``extension``: (**Compute**, **Identity**, **Volume**) OpenStack server API extensions
+* ``extension``: (**Compute**, **Identity**, **Network**, **Volume**) OpenStack server API extensions
* ``federation protocol``: (**Identity**) the underlying protocol used while federating identities
* ``flavor``: (**Compute**) predefined server configurations: ram, root disk, etc
* ``group``: (**Identity**) a grouping of users
@@ -101,12 +101,14 @@ referring to both Compute and Volume quotas.
* ``network``: (**Network**) - a virtual network for connecting servers and other resources
* ``object``: (**Object Storage**) a single file in the Object Storage
* ``policy``: (**Identity**) determines authorization
+* ``port``: (**Network**) - a virtual port for connecting servers and other resources to a network
* ``project``: (**Identity**) owns a group of resources
* ``quota``: (**Compute**, **Volume**) resource usage restrictions
* ``region``: (**Identity**) a subset of an OpenStack deployment
* ``request token``: (**Identity**) temporary OAuth-based token
* ``role``: (**Identity**) a policy object used to determine authorization
* ``role assignment``: (**Identity**) a relationship between roles, users or groups, and domains or projects
+* ``router``: (**Network**) - a virtual router
* ``security group``: (**Compute**, **Network**) - groups of network access rules
* ``security group rule``: (**Compute**, **Network**) - the individual rules that define protocol/IP/port access
* ``server``: (**Compute**) virtual machine instance
@@ -114,6 +116,7 @@ referring to both Compute and Volume quotas.
* ``service``: (**Identity**) a cloud service
* ``service provider``: (**Identity**) a resource that consumes assertions from an ``identity provider``
* ``snapshot``: (**Volume**) a point-in-time copy of a volume
+* ``subnet``: (**Network**) - a contiguous range of IP addresses assigned to a network
* ``token``: (**Identity**) a bearer token managed by Identity service
* ``usage``: (**Compute**) display host resources being consumed
* ``user``: (**Identity**) individual cloud resources users
@@ -129,17 +132,18 @@ The following are known `Objects` used by OpenStack :doc:`plugins`. These are
listed here to avoid name conflicts when creating new plugins. For a complete
list check out :doc:`plugin-commands`.
+* ``action definition``: (**Workflow Engine (Mistral)**)
+* ``action execution``: (**Workflow Engine (Mistral)**)
* ``baremetal``: (**Baremetal (Ironic)**)
* ``congress datasource``: (**Policy (Congress)**)
* ``congress driver``: (**Policy (Congress)**)
* ``congress policy``: (**Policy (Congress)**)
* ``congress policy rule``: (**Policy (Congress)**)
+* ``cron trigger``: (**Workflow Engine (Mistral)**)
* ``dataprocessing data source``: (**Data Processing (Sahara)**)
* ``dataprocessing image``: (**Data Processing (Sahara)**)
* ``dataprocessing image tags``: (**Data Processing (Sahara)**)
* ``dataprocessing plugin``: (**Data Processing (Sahara)**)
-* ``management plan``: (**Management (Tuskar)**)
-* ``management role``: (**Management (Tuskar)**)
* ``message-broker cluster``: (**Message Broker (Cue)**)
* ``message flavor``: (**Messaging (Zaqar)**)
* ``pool``: (**Messaging (Zaqar)**)
@@ -150,7 +154,11 @@ list check out :doc:`plugin-commands`.
* ``secret container``: (**Key Manager (Barbican)**)
* ``secret order``: (**Key Manager (Barbican)**)
* ``stack``: (**Orchestration (Heat)**)
+* ``task exeuction``: (**Workflow Engine (Mistral)**)
* ``tld``: (**DNS (Designate)**)
+* ``workbook``: (**Workflow Engine (Mistral)**)
+* ``workflow``: (**Workflow Engine (Mistral)**)
+* ``workflow execution``: (**Workflow Engine (Mistral)**)
* ``zone``: (**DNS (Designate)**)
* ``zone blacklist``: (**DNS (Designate)**)
* ``zone transfer``: (**DNS (Designate)**)
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 4992997..cb38d84 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -3,8 +3,9 @@ OpenStackClient
===============
OpenStackClient (aka OSC) is a command-line client for OpenStack that
-brings the command set for Compute, Identity, Image, Object Storage and Volume
-APIs together in a single shell with a uniform command structure.
+brings the command set for Compute, Identity, Image, Object Storage and
+Block Storage APIs together in a single shell with a uniform command
+structure.
User Documentation
------------------
diff --git a/doc/source/man/openstack.rst b/doc/source/man/openstack.rst
index 3e47635..a33b189 100644
--- a/doc/source/man/openstack.rst
+++ b/doc/source/man/openstack.rst
@@ -171,7 +171,7 @@ project support. The object names may consist of multiple words to compose a
unique name. Occasionally when multiple APIs have a common name with common
overlapping purposes there will be options to select which object to use, or
the API resources will be merged, as in the ``quota`` object that has options
-referring to both Compute and Volume quotas.
+referring to both Compute and Block Storage quotas.
Command Actions
---------------
diff --git a/doc/source/plugins.rst b/doc/source/plugins.rst
index 5f82cc6..0c838ec 100644
--- a/doc/source/plugins.rst
+++ b/doc/source/plugins.rst
@@ -11,8 +11,9 @@ Adoption
========
OpenStackClient promises to provide first class support for the following
-OpenStack services: Compute, Identity, Image, Storage, Volume and Network.
-These services are considered essential to any OpenStack deployment.
+OpenStack services: Compute, Identity, Image, Object Storage, Block Storage
+and Network. These services are considered essential to any OpenStack
+deployment.
Other OpenStack services, such as Orchestration or Telemetry may create an
OpenStackClient plugin. The source code will not be hosted by
@@ -33,11 +34,10 @@ python-heatclient patch in progress (https://review.openstack.org/#
python-ironicclient Using OpenStackClient
python-magnumclient using argparse
python-manilaclient using argparse
-python-mistralclient using cliff
+python-mistralclient using OpenStackClient
python-muranoclient using argparse
python-saharaclient using OpenStackClient
python-troveclient using argparse
-python-tuskarclient using OpenStackClient
python-zaqarclient using OpenStackClient
============================= ======================================
diff --git a/doc/source/releases.rst b/doc/source/releases.rst
index 853ef95..063066a 100644
--- a/doc/source/releases.rst
+++ b/doc/source/releases.rst
@@ -137,12 +137,12 @@ As of release 2.0 the release notes can be found on the OpenStack `Release Notes
* Add ``--log-file`` option support
-* Set default Volume API version to ``2``
+* Set default Block Storage API version to ``2``
1.6.0 (10 Aug 2015)
===================
-* Added support for Volume v2 APIs
+* Added support for Block Storage v2 APIs
Blueprint `volume-v2 <https://blueprints.launchpad.net/python-openstackclient/+spec/volume-v2>`_
* Backup
diff --git a/functional/tests/common/test_availability_zone.py b/functional/tests/common/test_availability_zone.py
new file mode 100644
index 0000000..9296db2
--- /dev/null
+++ b/functional/tests/common/test_availability_zone.py
@@ -0,0 +1,25 @@
+# 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.
+
+from functional.common import test
+
+
+class AvailabilityZoneTests(test.TestCase):
+ """Functional tests for availability zone. """
+ HEADERS = ["'Zone Name'"]
+ # So far, all components have the same default availability zone name.
+ DEFAULT_AZ_NAME = 'nova'
+
+ def test_availability_zone_list(self):
+ opts = self.get_list_opts(self.HEADERS)
+ raw_output = self.openstack('availability zone list' + opts)
+ self.assertIn(self.DEFAULT_AZ_NAME, raw_output)
diff --git a/functional/tests/compute/v2/test_security_group_rule.py b/functional/tests/compute/v2/test_security_group_rule.py
new file mode 100644
index 0000000..e864b08
--- /dev/null
+++ b/functional/tests/compute/v2/test_security_group_rule.py
@@ -0,0 +1,59 @@
+# 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 uuid
+
+from functional.common import test
+
+
+class SecurityGroupRuleTests(test.TestCase):
+ """Functional tests for security group rule. """
+ SECURITY_GROUP_NAME = uuid.uuid4().hex
+ SECURITY_GROUP_RULE_ID = None
+ NAME_FIELD = ['name']
+ ID_FIELD = ['id']
+ ID_HEADER = ['ID']
+
+ @classmethod
+ def setUpClass(cls):
+ # Create the security group to hold the rule.
+ opts = cls.get_show_opts(cls.NAME_FIELD)
+ raw_output = cls.openstack('security group create ' +
+ cls.SECURITY_GROUP_NAME +
+ opts)
+ expected = cls.SECURITY_GROUP_NAME + '\n'
+ cls.assertOutput(expected, raw_output)
+
+ # Create the security group rule.
+ opts = cls.get_show_opts(cls.ID_FIELD)
+ raw_output = cls.openstack('security group rule create ' +
+ cls.SECURITY_GROUP_NAME +
+ ' --proto tcp --dst-port 80:80' +
+ opts)
+ cls.SECURITY_GROUP_RULE_ID = raw_output.strip('\n')
+
+ @classmethod
+ def tearDownClass(cls):
+ raw_output = cls.openstack('security group rule delete ' +
+ cls.SECURITY_GROUP_RULE_ID)
+ cls.assertOutput('', raw_output)
+
+ raw_output = cls.openstack('security group delete ' +
+ cls.SECURITY_GROUP_NAME)
+ cls.assertOutput('', raw_output)
+
+ def test_security_group_rule_list(self):
+ opts = self.get_list_opts(self.ID_HEADER)
+ raw_output = self.openstack('security group rule list ' +
+ self.SECURITY_GROUP_NAME +
+ opts)
+ self.assertIn(self.SECURITY_GROUP_RULE_ID, raw_output)
diff --git a/functional/tests/identity/v2/test_project.py b/functional/tests/identity/v2/test_project.py
index 88b282e..3a5e8e8 100644
--- a/functional/tests/identity/v2/test_project.py
+++ b/functional/tests/identity/v2/test_project.py
@@ -68,12 +68,12 @@ class ProjectTests(test_identity.IdentityTests):
)
items = self.parse_show(raw_output)
fields = list(self.PROJECT_FIELDS)
- fields.extend(['k0'])
+ fields.extend(['properties'])
self.assert_show_fields(items, fields)
project = self.parse_show_as_object(raw_output)
self.assertEqual(new_project_name, project['name'])
self.assertEqual('False', project['enabled'])
- self.assertEqual('v0', project['k0'])
+ self.assertEqual("k0='v0'", project['properties'])
def test_project_show(self):
project_name = self._create_dummy_project()
@@ -81,4 +81,6 @@ class ProjectTests(test_identity.IdentityTests):
'project show %s' % project_name
)
items = self.parse_show(raw_output)
- self.assert_show_fields(items, self.PROJECT_FIELDS)
+ fields = list(self.PROJECT_FIELDS)
+ fields.extend(['properties'])
+ self.assert_show_fields(items, fields)
diff --git a/functional/tests/network/v2/test_network.py b/functional/tests/network/v2/test_network.py
index 0b2f35e..5cc461b 100644
--- a/functional/tests/network/v2/test_network.py
+++ b/functional/tests/network/v2/test_network.py
@@ -40,9 +40,9 @@ class NetworkTests(test.TestCase):
def test_network_set(self):
raw_output = self.openstack('network set --disable ' + self.NAME)
- opts = self.get_show_opts(['name', 'state'])
+ opts = self.get_show_opts(['name', 'admin_state_up'])
raw_output = self.openstack('network show ' + self.NAME + opts)
- self.assertEqual(self.NAME + "\nDOWN\n", raw_output)
+ self.assertEqual("DOWN\n" + self.NAME + "\n", raw_output)
def test_network_show(self):
opts = self.get_show_opts(self.FIELDS)
diff --git a/functional/tests/network/v2/test_router.py b/functional/tests/network/v2/test_router.py
new file mode 100644
index 0000000..ceb7625
--- /dev/null
+++ b/functional/tests/network/v2/test_router.py
@@ -0,0 +1,50 @@
+# 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 uuid
+
+from functional.common import test
+
+
+class RouterTests(test.TestCase):
+ """Functional tests for router. """
+ NAME = uuid.uuid4().hex
+ HEADERS = ['Name']
+ FIELDS = ['name']
+
+ @classmethod
+ def setUpClass(cls):
+ opts = cls.get_show_opts(cls.FIELDS)
+ raw_output = cls.openstack('router create ' + cls.NAME + opts)
+ expected = cls.NAME + '\n'
+ cls.assertOutput(expected, raw_output)
+
+ @classmethod
+ def tearDownClass(cls):
+ raw_output = cls.openstack('router delete ' + cls.NAME)
+ cls.assertOutput('', raw_output)
+
+ def test_router_list(self):
+ opts = self.get_list_opts(self.HEADERS)
+ raw_output = self.openstack('router list' + opts)
+ self.assertIn(self.NAME, raw_output)
+
+ def test_router_set(self):
+ self.openstack('router set --disable ' + self.NAME)
+ opts = self.get_show_opts(['name', 'admin_state_up'])
+ raw_output = self.openstack('router show ' + self.NAME + opts)
+ self.assertEqual("DOWN\n" + self.NAME + "\n", raw_output)
+
+ def test_router_show(self):
+ opts = self.get_show_opts(self.FIELDS)
+ raw_output = self.openstack('router show ' + self.NAME + opts)
+ self.assertEqual(self.NAME + "\n", raw_output)
diff --git a/openstackclient/api/network_v2.py b/openstackclient/api/network_v2.py
deleted file mode 100644
index 90be523..0000000
--- a/openstackclient/api/network_v2.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# 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.
-#
-
-"""Network v2 API Library"""
-
-from openstackclient.api import api
-
-
-class APIv2(api.BaseAPI):
- """Network v2 API"""
-
- def __init__(self, **kwargs):
- super(APIv2, self).__init__(**kwargs)
-
- def dhcp_agent_list(
- self,
- dhcp_id=None,
- **filter
- ):
- """List DHCP agents
-
- :param string dhcp_id:
- DHCP Agent ID
- :param filter:
- used to create the query string filters
- http://docs.openstack.org/api/openstack-network/2.0/content/filtering.html
- """
-
- return self.list('dhcp-networks', **filter)['dhcp-networks']
-
- def network_list(
- self,
- external=False,
- **filter
- ):
- """List external networks
-
- :param string dhcp_id:
- DHCP agent ID
- :param bool external:
- Return external networks if True
- :param filter:
- used to create the query string filters
- http://docs.openstack.org/api/openstack-network/2.0/content/filtering.html
- """
-
- if external:
- filter = {'router:external': True}
- return self.list('networks', **filter)['networks']
diff --git a/openstackclient/api/object_store_v1.py b/openstackclient/api/object_store_v1.py
index ab75a78..d9f130b 100644
--- a/openstackclient/api/object_store_v1.py
+++ b/openstackclient/api/object_store_v1.py
@@ -570,6 +570,6 @@ class APIv1(api.BaseAPI):
# OSC commands
properties = {}
for k, v in six.iteritems(headers):
- if k.startswith(header_tag):
+ if k.lower().startswith(header_tag):
properties[k[len(header_tag):]] = v
return properties
diff --git a/openstackclient/api/utils.py b/openstackclient/api/utils.py
index b7ff7f2..fa759cd 100644
--- a/openstackclient/api/utils.py
+++ b/openstackclient/api/utils.py
@@ -27,11 +27,11 @@ def simple_filter(
be changed if any filtering occurs.
:param string attr:
The name of the attribute to filter. If attr does not exist no
- match will succeed and no rows will be retrurned. If attr is
+ match will succeed and no rows will be returned. If attr is
None no filtering will be performed and all rows will be returned.
:param sring value:
The value to filter. None is considered to be a 'no filter' value.
- '' matches agains a Python empty string.
+ '' matches against a Python empty string.
:param string property_field:
The name of the data field containing a property dict to filter.
If property_field is None, attr is a field name. If property_field
diff --git a/openstackclient/common/availability_zone.py b/openstackclient/common/availability_zone.py
new file mode 100644
index 0000000..a941418
--- /dev/null
+++ b/openstackclient/common/availability_zone.py
@@ -0,0 +1,191 @@
+# 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.
+#
+
+"""Availability Zone action implementations"""
+
+import copy
+
+from novaclient import exceptions as nova_exceptions
+import six
+
+from openstackclient.common import command
+from openstackclient.common import utils
+from openstackclient.i18n import _ # noqa
+
+
+def _xform_common_availability_zone(az, zone_info):
+ if hasattr(az, 'zoneState'):
+ zone_info['zone_status'] = ('available' if az.zoneState['available']
+ else 'not available')
+ if hasattr(az, 'zoneName'):
+ zone_info['zone_name'] = az.zoneName
+
+ zone_info['zone_resource'] = ''
+
+
+def _xform_compute_availability_zone(az, include_extra):
+ result = []
+ zone_info = {}
+ _xform_common_availability_zone(az, zone_info)
+
+ if not include_extra:
+ result.append(zone_info)
+ return result
+
+ if hasattr(az, 'hosts') and az.hosts:
+ for host, services in six.iteritems(az.hosts):
+ host_info = copy.deepcopy(zone_info)
+ host_info['host_name'] = host
+
+ for svc, state in six.iteritems(services):
+ info = copy.deepcopy(host_info)
+ info['service_name'] = svc
+ info['service_status'] = '%s %s %s' % (
+ 'enabled' if state['active'] else 'disabled',
+ ':-)' if state['available'] else 'XXX',
+ state['updated_at'])
+ result.append(info)
+ else:
+ zone_info['host_name'] = ''
+ zone_info['service_name'] = ''
+ zone_info['service_status'] = ''
+ result.append(zone_info)
+ return result
+
+
+def _xform_volume_availability_zone(az):
+ result = []
+ zone_info = {}
+ _xform_common_availability_zone(az, zone_info)
+ result.append(zone_info)
+ return result
+
+
+def _xform_network_availability_zone(az):
+ result = []
+ zone_info = {}
+ zone_info['zone_name'] = getattr(az, 'name', '')
+ zone_info['zone_status'] = getattr(az, 'state', '')
+ if 'unavailable' == zone_info['zone_status']:
+ zone_info['zone_status'] = 'not available'
+ zone_info['zone_resource'] = getattr(az, 'resource', '')
+ result.append(zone_info)
+ return result
+
+
+class ListAvailabilityZone(command.Lister):
+ """List availability zones and their status"""
+
+ def get_parser(self, prog_name):
+ parser = super(ListAvailabilityZone, self).get_parser(prog_name)
+ parser.add_argument(
+ '--compute',
+ action='store_true',
+ default=False,
+ help='List compute availability zones')
+ parser.add_argument(
+ '--network',
+ action='store_true',
+ default=False,
+ help='List network availability zones')
+ parser.add_argument(
+ '--volume',
+ action='store_true',
+ default=False,
+ help='List volume availability zones')
+ parser.add_argument(
+ '--long',
+ action='store_true',
+ default=False,
+ help=_('List additional fields in output'),
+ )
+ return parser
+
+ def _get_compute_availability_zones(self, parsed_args):
+ compute_client = self.app.client_manager.compute
+ try:
+ data = compute_client.availability_zones.list()
+ except nova_exceptions.Forbidden as e: # policy doesn't allow
+ try:
+ data = compute_client.availability_zones.list(detailed=False)
+ except Exception:
+ raise e
+
+ # Argh, the availability zones are not iterable...
+ result = []
+ for zone in data:
+ result += _xform_compute_availability_zone(zone, parsed_args.long)
+ return result
+
+ def _get_volume_availability_zones(self, parsed_args):
+ volume_client = self.app.client_manager.volume
+ data = []
+ try:
+ data = volume_client.availability_zones.list()
+ except Exception as e:
+ self.log.debug('Volume availability zone exception: ' + str(e))
+ if parsed_args.volume:
+ message = "Availability zones list not supported by " \
+ "Block Storage API"
+ self.log.warning(message)
+
+ result = []
+ for zone in data:
+ result += _xform_volume_availability_zone(zone)
+ return result
+
+ def _get_network_availability_zones(self, parsed_args):
+ network_client = self.app.client_manager.network
+ data = []
+ try:
+ # Verify that the extension exists.
+ network_client.find_extension('Availability Zone',
+ ignore_missing=False)
+ data = network_client.availability_zones()
+ except Exception as e:
+ self.log.debug('Network availability zone exception: ' + str(e))
+ if parsed_args.network:
+ message = "Availability zones list not supported by " \
+ "Network API"
+ self.log.warning(message)
+
+ result = []
+ for zone in data:
+ result += _xform_network_availability_zone(zone)
+ return result
+
+ def take_action(self, parsed_args):
+
+ if parsed_args.long:
+ columns = ('Zone Name', 'Zone Status', 'Zone Resource',
+ 'Host Name', 'Service Name', 'Service Status')
+ else:
+ columns = ('Zone Name', 'Zone Status')
+
+ # Show everything by default.
+ show_all = (not parsed_args.compute and
+ not parsed_args.volume and
+ not parsed_args.network)
+
+ result = []
+ if parsed_args.compute or show_all:
+ result += self._get_compute_availability_zones(parsed_args)
+ if parsed_args.volume or show_all:
+ result += self._get_volume_availability_zones(parsed_args)
+ if parsed_args.network or show_all:
+ result += self._get_network_availability_zones(parsed_args)
+
+ return (columns,
+ (utils.get_dict_properties(
+ s, columns
+ ) for s in result))
diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py
index edabf65..dce1972 100644
--- a/openstackclient/common/clientmanager.py
+++ b/openstackclient/common/clientmanager.py
@@ -191,6 +191,26 @@ class ClientManager(object):
self._auth_ref = self.auth.get_auth_ref(self.session)
return self._auth_ref
+ def is_network_endpoint_enabled(self):
+ """Check if the network endpoint is enabled"""
+ # Trigger authentication necessary to determine if the network
+ # endpoint is enabled.
+ if self.auth_ref:
+ service_catalog = self.auth_ref.service_catalog
+ else:
+ service_catalog = None
+ # Assume that the network endpoint is enabled.
+ network_endpoint_enabled = True
+ if service_catalog:
+ if 'network' in service_catalog.get_endpoints():
+ LOG.debug("Network endpoint in service catalog")
+ else:
+ LOG.debug("No network endpoint in service catalog")
+ network_endpoint_enabled = False
+ else:
+ LOG.debug("No service catalog, assuming network endpoint enabled")
+ return network_endpoint_enabled
+
def get_endpoint_for_service_type(self, service_type, region_name=None,
interface='public'):
"""Return the endpoint URL for the service type."""
diff --git a/openstackclient/common/command.py b/openstackclient/common/command.py
new file mode 100644
index 0000000..13b0bcc
--- /dev/null
+++ b/openstackclient/common/command.py
@@ -0,0 +1,45 @@
+# Copyright 2016 NEC Corporation
+#
+# 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 abc
+import logging
+
+from cliff import command
+from cliff import lister
+from cliff import show
+import six
+
+
+class CommandMeta(abc.ABCMeta):
+ def __new__(mcs, name, bases, cls_dict):
+ if 'log' not in cls_dict:
+ cls_dict['log'] = logging.getLogger(
+ cls_dict['__module__'] + '.' + name)
+ return super(CommandMeta, mcs).__new__(mcs, name, bases, cls_dict)
+
+
+@six.add_metaclass(CommandMeta)
+class Command(command.Command):
+
+ def run(self, parsed_args):
+ self.log.debug('run(%s)', parsed_args)
+ return super(Command, self).run(parsed_args)
+
+
+class Lister(Command, lister.Lister):
+ pass
+
+
+class ShowOne(Command, show.ShowOne):
+ pass
diff --git a/openstackclient/common/commandmanager.py b/openstackclient/common/commandmanager.py
index b34bf7d..b809d63 100644
--- a/openstackclient/common/commandmanager.py
+++ b/openstackclient/common/commandmanager.py
@@ -15,15 +15,11 @@
"""Modify cliff.CommandManager"""
-import logging
import pkg_resources
import cliff.commandmanager
-LOG = logging.getLogger(__name__)
-
-
class CommandManager(cliff.commandmanager.CommandManager):
"""Add additional functionality to cliff.CommandManager
diff --git a/openstackclient/common/configuration.py b/openstackclient/common/configuration.py
index ac2792d..a70e4d1 100644
--- a/openstackclient/common/configuration.py
+++ b/openstackclient/common/configuration.py
@@ -13,21 +13,16 @@
"""Configuration action implementations"""
-import logging
-
-from cliff import show
import six
-from openstackclient.common import utils
+from openstackclient.common import command
REDACTED = "<redacted>"
-class ShowConfiguration(show.ShowOne):
+class ShowConfiguration(command.ShowOne):
"""Display configuration details"""
- log = logging.getLogger(__name__ + '.ShowConfiguration')
-
def get_parser(self, prog_name):
parser = super(ShowConfiguration, self).get_parser(prog_name)
mask_group = parser.add_mutually_exclusive_group()
@@ -46,7 +41,6 @@ class ShowConfiguration(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
info = self.app.client_manager.get_configuration()
diff --git a/openstackclient/common/extension.py b/openstackclient/common/extension.py
index dad7ed6..8b556b4 100644
--- a/openstackclient/common/extension.py
+++ b/openstackclient/common/extension.py
@@ -16,18 +16,14 @@
"""Extension action implementations"""
import itertools
-import logging
-
-from cliff import lister
+from openstackclient.common import command
from openstackclient.common import utils
-class ListExtension(lister.Lister):
+class ListExtension(command.Lister):
"""List API extensions"""
- log = logging.getLogger(__name__ + '.ListExtension')
-
def get_parser(self, prog_name):
parser = super(ListExtension, self).get_parser(prog_name)
parser.add_argument(
@@ -49,7 +45,7 @@ class ListExtension(lister.Lister):
'--volume',
action='store_true',
default=False,
- help='List extensions for the Volume API')
+ help='List extensions for the Block Storage API')
parser.add_argument(
'--long',
action='store_true',
@@ -58,8 +54,6 @@ class ListExtension(lister.Lister):
return parser
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
-
if parsed_args.long:
columns = ('Name', 'Namespace', 'Description',
'Alias', 'Updated', 'Links')
@@ -95,7 +89,7 @@ class ListExtension(lister.Lister):
try:
data += volume_client.list_extensions.show_all()
except Exception:
- message = "Extensions list not supported by Volume API"
+ message = "Extensions list not supported by Block Storage API"
self.log.warning(message)
# Resource classes for the above
@@ -111,9 +105,9 @@ class ListExtension(lister.Lister):
if parsed_args.network or show_all:
network_client = self.app.client_manager.network
try:
- data = network_client.list_extensions()['extensions']
+ data = network_client.extensions()
dict_tuples = (
- utils.get_dict_properties(
+ utils.get_item_properties(
s,
columns,
formatters={},
diff --git a/openstackclient/common/limits.py b/openstackclient/common/limits.py
index 582f70c..bd546c0 100644
--- a/openstackclient/common/limits.py
+++ b/openstackclient/common/limits.py
@@ -16,18 +16,14 @@
"""Limits Action Implementation"""
import itertools
-import logging
-
-from cliff import lister
+from openstackclient.common import command
from openstackclient.common import utils
from openstackclient.identity import common as identity_common
-class ShowLimits(lister.Lister):
- """Show compute and volume limits"""
-
- log = logging.getLogger(__name__ + '.ShowLimits')
+class ShowLimits(command.Lister):
+ """Show compute and block storage limits"""
def get_parser(self, prog_name):
parser = super(ShowLimits, self).get_parser(prog_name)
@@ -64,7 +60,6 @@ class ShowLimits(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
diff --git a/openstackclient/common/module.py b/openstackclient/common/module.py
index f0ed23b..a3dea5d 100644
--- a/openstackclient/common/module.py
+++ b/openstackclient/common/module.py
@@ -15,23 +15,17 @@
"""Module action implementation"""
-import logging
import six
import sys
-from cliff import lister
-from cliff import show
+from openstackclient.common import command
-from openstackclient.common import utils
-
-class ListCommand(lister.Lister):
+class ListCommand(command.Lister):
"""List recognized commands by group"""
auth_required = False
- log = logging.getLogger(__name__ + '.ListCommand')
- @utils.log_method(log)
def take_action(self, parsed_args):
cm = self.app.command_manager
groups = cm.get_command_groups()
@@ -40,11 +34,10 @@ class ListCommand(lister.Lister):
return (columns, ((c, cm.get_command_names(group=c)) for c in groups))
-class ListModule(show.ShowOne):
+class ListModule(command.ShowOne):
"""List module versions"""
auth_required = False
- log = logging.getLogger(__name__ + '.ListModule')
def get_parser(self, prog_name):
parser = super(ListModule, self).get_parser(prog_name)
@@ -56,7 +49,6 @@ class ListModule(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
data = {}
diff --git a/openstackclient/common/quota.py b/openstackclient/common/quota.py
index 8a9b910..f208948 100644
--- a/openstackclient/common/quota.py
+++ b/openstackclient/common/quota.py
@@ -16,13 +16,10 @@
"""Quota action implementations"""
import itertools
-import logging
import six
import sys
-from cliff import command
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
@@ -60,8 +57,6 @@ NETWORK_QUOTAS = {
class SetQuota(command.Command):
"""Set quotas for project or class"""
- log = logging.getLogger(__name__ + '.SetQuota')
-
def get_parser(self, prog_name):
parser = super(SetQuota, self).get_parser(prog_name)
parser.add_argument(
@@ -92,7 +87,6 @@ class SetQuota(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -143,11 +137,9 @@ class SetQuota(command.Command):
**volume_kwargs)
-class ShowQuota(show.ShowOne):
+class ShowQuota(command.ShowOne):
"""Show quotas for project or class"""
- log = logging.getLogger(__name__ + '.ShowQuota')
-
def get_parser(self, prog_name):
parser = super(ShowQuota, self).get_parser(prog_name)
parser.add_argument(
@@ -196,14 +188,16 @@ class ShowQuota(show.ShowOne):
def get_network_quota(self, parsed_args):
if parsed_args.quota_class or parsed_args.default:
return {}
- service_catalog = self.app.client_manager.auth_ref.service_catalog
- if 'network' in service_catalog.get_endpoints():
- network_client = self.app.client_manager.network
- return network_client.show_quota(parsed_args.project)['quota']
+ if self.app.client_manager.is_network_endpoint_enabled():
+ identity_client = self.app.client_manager.identity
+ project = utils.find_resource(
+ identity_client.projects,
+ parsed_args.project,
+ ).id
+ return self.app.client_manager.network.get_quota(project)
else:
return {}
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
diff --git a/openstackclient/common/timing.py b/openstackclient/common/timing.py
index d13c86e..5f62875 100644
--- a/openstackclient/common/timing.py
+++ b/openstackclient/common/timing.py
@@ -13,19 +13,13 @@
"""Timing Implementation"""
-import logging
+from openstackclient.common import command
-from cliff import lister
-
-class Timing(lister.Lister):
+class Timing(command.Lister):
"""Show timing data"""
- log = logging.getLogger(__name__ + '.Timing')
-
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
-
column_headers = (
'URL',
'Seconds',
diff --git a/openstackclient/common/utils.py b/openstackclient/common/utils.py
index 42630d9..4142f83 100644
--- a/openstackclient/common/utils.py
+++ b/openstackclient/common/utils.py
@@ -26,29 +26,6 @@ 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.
@@ -154,14 +131,25 @@ def format_dict(data):
return output[:-2]
-def format_list(data):
+def format_list(data, separator=', '):
"""Return a formatted strings
:param data: a list of strings
- :rtype: a string formatted to a,b,c
+ :param separator: the separator to use between strings (default: ', ')
+ :rtype: a string formatted based on separator
"""
- return ', '.join(sorted(data))
+ return separator.join(sorted(data))
+
+
+def format_list_of_dicts(data):
+ """Return a formatted string of key value pairs for each dict
+
+ :param data: a list of dicts
+ :rtype: a string formatted to key='value' with dicts separated by new line
+ """
+
+ return '\n'.join(format_dict(i) for i in data)
def get_field(item, field):
@@ -258,10 +246,6 @@ def sort_items(items, sort_str):
return items
-def string_to_bool(arg):
- return arg.strip().lower() in ('t', 'true', 'yes', '1')
-
-
def env(*vars, **kwargs):
"""Search for the first defined of possibly many env vars
@@ -330,6 +314,8 @@ def wait_for_status(status_f,
def wait_for_delete(manager,
res_id,
status_field='status',
+ error_status=['error'],
+ exception_name=['NotFound'],
sleep_time=5,
timeout=300,
callback=None):
@@ -340,6 +326,8 @@ def wait_for_delete(manager,
:param status_field: the status attribute in the returned resource object,
this is used to check for error states while the resource is being
deleted
+ :param error_status: a list of status strings for error
+ :param exception_name: a list of exception strings for deleted case
:param sleep_time: wait this long between checks (seconds)
:param timeout: check until this long (seconds)
:param callback: called per sleep cycle, useful to display progress; this
@@ -356,12 +344,12 @@ def wait_for_delete(manager,
# handle a NotFound exception here without parsing the message
res = manager.get(res_id)
except Exception as ex:
- if type(ex).__name__ == 'NotFound':
+ if type(ex).__name__ in exception_name:
return True
raise
status = getattr(res, status_field, '').lower()
- if status == 'error':
+ if status in error_status:
return False
if callback:
diff --git a/openstackclient/compute/v2/agent.py b/openstackclient/compute/v2/agent.py
index 14c4b2c..59d7dc6 100644
--- a/openstackclient/compute/v2/agent.py
+++ b/openstackclient/compute/v2/agent.py
@@ -15,21 +15,15 @@
"""Agent action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
-class CreateAgent(show.ShowOne):
+class CreateAgent(command.ShowOne):
"""Create compute agent command"""
- log = logging.getLogger(__name__ + ".CreateAgent")
-
def get_parser(self, prog_name):
parser = super(CreateAgent, self).get_parser(prog_name)
parser.add_argument(
@@ -60,7 +54,6 @@ class CreateAgent(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
args = (
parsed_args.os,
@@ -77,8 +70,6 @@ class CreateAgent(show.ShowOne):
class DeleteAgent(command.Command):
"""Delete compute agent command"""
- log = logging.getLogger(__name__ + ".DeleteAgent")
-
def get_parser(self, prog_name):
parser = super(DeleteAgent, self).get_parser(prog_name)
parser.add_argument(
@@ -88,17 +79,13 @@ class DeleteAgent(command.Command):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
compute_client.agents.delete(parsed_args.id)
- return
-class ListAgent(lister.Lister):
+class ListAgent(command.Lister):
"""List compute agent command"""
- log = logging.getLogger(__name__ + ".ListAgent")
-
def get_parser(self, prog_name):
parser = super(ListAgent, self).get_parser(prog_name)
parser.add_argument(
@@ -108,7 +95,6 @@ class ListAgent(lister.Lister):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
columns = (
"Agent ID",
@@ -126,11 +112,9 @@ class ListAgent(lister.Lister):
) for s in data))
-class SetAgent(show.ShowOne):
+class SetAgent(command.ShowOne):
"""Set compute agent command"""
- log = logging.getLogger(__name__ + ".SetAgent")
-
def get_parser(self, prog_name):
parser = super(SetAgent, self).get_parser(prog_name)
parser.add_argument(
@@ -152,7 +136,6 @@ class SetAgent(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
args = (
parsed_args.id,
diff --git a/openstackclient/compute/v2/aggregate.py b/openstackclient/compute/v2/aggregate.py
index a1ba618..5f29725 100644
--- a/openstackclient/compute/v2/aggregate.py
+++ b/openstackclient/compute/v2/aggregate.py
@@ -16,22 +16,16 @@
"""Compute v2 Aggregate action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import parseractions
from openstackclient.common import utils
-class AddAggregateHost(show.ShowOne):
+class AddAggregateHost(command.ShowOne):
"""Add host to aggregate"""
- log = logging.getLogger(__name__ + '.AddAggregateHost')
-
def get_parser(self, prog_name):
parser = super(AddAggregateHost, self).get_parser(prog_name)
parser.add_argument(
@@ -47,8 +41,6 @@ class AddAggregateHost(show.ShowOne):
return parser
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(
@@ -62,11 +54,9 @@ class AddAggregateHost(show.ShowOne):
return zip(*sorted(six.iteritems(info)))
-class CreateAggregate(show.ShowOne):
+class CreateAggregate(command.ShowOne):
"""Create a new aggregate"""
- log = logging.getLogger(__name__ + ".CreateAggregate")
-
def get_parser(self, prog_name):
parser = super(CreateAggregate, self).get_parser(prog_name)
parser.add_argument(
@@ -89,8 +79,6 @@ class CreateAggregate(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
compute_client = self.app.client_manager.compute
info = {}
@@ -112,8 +100,6 @@ class CreateAggregate(show.ShowOne):
class DeleteAggregate(command.Command):
"""Delete an existing aggregate"""
- log = logging.getLogger(__name__ + '.DeleteAggregate')
-
def get_parser(self, prog_name):
parser = super(DeleteAggregate, self).get_parser(prog_name)
parser.add_argument(
@@ -123,7 +109,6 @@ class DeleteAggregate(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -132,14 +117,11 @@ class DeleteAggregate(command.Command):
parsed_args.aggregate,
)
compute_client.aggregates.delete(data.id)
- return
-class ListAggregate(lister.Lister):
+class ListAggregate(command.Lister):
"""List all aggregates"""
- log = logging.getLogger(__name__ + ".ListAggregate")
-
def get_parser(self, prog_name):
parser = super(ListAggregate, self).get_parser(prog_name)
parser.add_argument(
@@ -150,8 +132,6 @@ class ListAggregate(lister.Lister):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
compute_client = self.app.client_manager.compute
data = compute_client.aggregates.list()
@@ -187,11 +167,9 @@ class ListAggregate(lister.Lister):
) for s in data))
-class RemoveAggregateHost(show.ShowOne):
+class RemoveAggregateHost(command.ShowOne):
"""Remove host from aggregate"""
- log = logging.getLogger(__name__ + '.RemoveAggregateHost')
-
def get_parser(self, prog_name):
parser = super(RemoveAggregateHost, self).get_parser(prog_name)
parser.add_argument(
@@ -207,8 +185,6 @@ class RemoveAggregateHost(show.ShowOne):
return parser
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(
@@ -225,11 +201,9 @@ class RemoveAggregateHost(show.ShowOne):
return zip(*sorted(six.iteritems(info)))
-class SetAggregate(show.ShowOne):
+class SetAggregate(command.ShowOne):
"""Set aggregate properties"""
- log = logging.getLogger(__name__ + '.SetAggregate')
-
def get_parser(self, prog_name):
parser = super(SetAggregate, self).get_parser(prog_name)
parser.add_argument(
@@ -256,7 +230,6 @@ class SetAggregate(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -289,11 +262,9 @@ class SetAggregate(show.ShowOne):
return ({}, {})
-class ShowAggregate(show.ShowOne):
+class ShowAggregate(command.ShowOne):
"""Display aggregate details"""
- log = logging.getLogger(__name__ + '.ShowAggregate')
-
def get_parser(self, prog_name):
parser = super(ShowAggregate, self).get_parser(prog_name)
parser.add_argument(
@@ -303,7 +274,6 @@ class ShowAggregate(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
diff --git a/openstackclient/compute/v2/availability_zone.py b/openstackclient/compute/v2/availability_zone.py
deleted file mode 100644
index 0fe6c73..0000000
--- a/openstackclient/compute/v2/availability_zone.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-#
-
-"""Compute v2 Availability Zone action implementations"""
-
-import copy
-import logging
-
-from cliff import lister
-from novaclient import exceptions as nova_exceptions
-import six
-
-from openstackclient.common import utils
-from openstackclient.i18n import _ # noqa
-
-
-def _xform_availability_zone(az, include_extra):
- result = []
- zone_info = {}
- if hasattr(az, 'zoneState'):
- zone_info['zone_status'] = ('available' if az.zoneState['available']
- else 'not available')
- if hasattr(az, 'zoneName'):
- zone_info['zone_name'] = az.zoneName
-
- if not include_extra:
- result.append(zone_info)
- return result
-
- if hasattr(az, 'hosts') and az.hosts:
- for host, services in six.iteritems(az.hosts):
- host_info = copy.deepcopy(zone_info)
- host_info['host_name'] = host
-
- for svc, state in six.iteritems(services):
- info = copy.deepcopy(host_info)
- info['service_name'] = svc
- info['service_status'] = '%s %s %s' % (
- 'enabled' if state['active'] else 'disabled',
- ':-)' if state['available'] else 'XXX',
- state['updated_at'])
- result.append(info)
- else:
- zone_info['host_name'] = ''
- zone_info['service_name'] = ''
- zone_info['service_status'] = ''
- result.append(zone_info)
- return result
-
-
-class ListAvailabilityZone(lister.Lister):
- """List availability zones and their status"""
-
- log = logging.getLogger(__name__ + '.ListAvailabilityZone')
-
- def get_parser(self, prog_name):
- parser = super(ListAvailabilityZone, self).get_parser(prog_name)
- parser.add_argument(
- '--long',
- action='store_true',
- default=False,
- help=_('List additional fields in output'),
- )
- return parser
-
- @utils.log_method(log)
- def take_action(self, parsed_args):
-
- if parsed_args.long:
- columns = ('Zone Name', 'Zone Status',
- 'Host Name', 'Service Name', 'Service Status')
- else:
- columns = ('Zone Name', 'Zone Status')
-
- compute_client = self.app.client_manager.compute
- try:
- data = compute_client.availability_zones.list()
- except nova_exceptions.Forbidden as e: # policy doesn't allow
- try:
- data = compute_client.availability_zones.list(detailed=False)
- except Exception:
- raise e
-
- # Argh, the availability zones are not iterable...
- result = []
- for zone in data:
- result += _xform_availability_zone(zone, parsed_args.long)
-
- return (columns,
- (utils.get_dict_properties(
- s, columns
- ) for s in result))
diff --git a/openstackclient/compute/v2/console.py b/openstackclient/compute/v2/console.py
index aafa5d4..6c0ec31 100644
--- a/openstackclient/compute/v2/console.py
+++ b/openstackclient/compute/v2/console.py
@@ -15,13 +15,10 @@
"""Compute v2 Console action implementations"""
-import logging
import six
import sys
-from cliff import command
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import parseractions
from openstackclient.common import utils
@@ -29,8 +26,6 @@ from openstackclient.common import utils
class ShowConsoleLog(command.Command):
"""Show server's console output"""
- log = logging.getLogger(__name__ + '.ShowConsoleLog')
-
def get_parser(self, prog_name):
parser = super(ShowConsoleLog, self).get_parser(prog_name)
parser.add_argument(
@@ -49,7 +44,6 @@ class ShowConsoleLog(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -65,14 +59,11 @@ class ShowConsoleLog(command.Command):
data = server.get_console_output(length=length)
sys.stdout.write(data)
- return
-class ShowConsoleURL(show.ShowOne):
+class ShowConsoleURL(command.ShowOne):
"""Show server's remote console URL"""
- log = logging.getLogger(__name__ + '.ShowConsoleURL')
-
def get_parser(self, prog_name):
parser = super(ShowConsoleURL, self).get_parser(prog_name)
parser.add_argument(
@@ -105,7 +96,6 @@ class ShowConsoleURL(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
server = utils.find_resource(
diff --git a/openstackclient/compute/v2/fixedip.py b/openstackclient/compute/v2/fixedip.py
index da9d85c..daac97d 100644
--- a/openstackclient/compute/v2/fixedip.py
+++ b/openstackclient/compute/v2/fixedip.py
@@ -15,18 +15,13 @@
"""Fixed IP action implementations"""
-import logging
-
-from cliff import command
-
+from openstackclient.common import command
from openstackclient.common import utils
class AddFixedIP(command.Command):
"""Add fixed IP address to server"""
- log = logging.getLogger(__name__ + ".AddFixedIP")
-
def get_parser(self, prog_name):
parser = super(AddFixedIP, self).get_parser(prog_name)
parser.add_argument(
@@ -42,7 +37,6 @@ class AddFixedIP(command.Command):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
network = utils.find_resource(
@@ -52,14 +46,11 @@ class AddFixedIP(command.Command):
compute_client.servers, parsed_args.server)
server.add_fixed_ip(network.id)
- return
class RemoveFixedIP(command.Command):
"""Remove fixed IP address from server"""
- log = logging.getLogger(__name__ + ".RemoveFixedIP")
-
def get_parser(self, prog_name):
parser = super(RemoveFixedIP, self).get_parser(prog_name)
parser.add_argument(
@@ -75,11 +66,9 @@ class RemoveFixedIP(command.Command):
return parser
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)
server.remove_fixed_ip(parsed_args.ip_address)
- return
diff --git a/openstackclient/compute/v2/flavor.py b/openstackclient/compute/v2/flavor.py
index 7474580..093592c 100644
--- a/openstackclient/compute/v2/flavor.py
+++ b/openstackclient/compute/v2/flavor.py
@@ -15,22 +15,16 @@
"""Flavor action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import parseractions
from openstackclient.common import utils
-class CreateFlavor(show.ShowOne):
+class CreateFlavor(command.ShowOne):
"""Create new flavor"""
- log = logging.getLogger(__name__ + ".CreateFlavor")
-
def get_parser(self, prog_name):
parser = super(CreateFlavor, self).get_parser(prog_name)
parser.add_argument(
@@ -104,7 +98,6 @@ class CreateFlavor(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
args = (
@@ -128,8 +121,6 @@ class CreateFlavor(show.ShowOne):
class DeleteFlavor(command.Command):
"""Delete flavor"""
- log = logging.getLogger(__name__ + ".DeleteFlavor")
-
def get_parser(self, prog_name):
parser = super(DeleteFlavor, self).get_parser(prog_name)
parser.add_argument(
@@ -140,19 +131,15 @@ class DeleteFlavor(command.Command):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
flavor = utils.find_resource(compute_client.flavors,
parsed_args.flavor)
compute_client.flavors.delete(flavor.id)
- return
-class ListFlavor(lister.Lister):
+class ListFlavor(command.Lister):
"""List flavors"""
- log = logging.getLogger(__name__ + ".ListFlavor")
-
def get_parser(self, prog_name):
parser = super(ListFlavor, self).get_parser(prog_name)
public_group = parser.add_mutually_exclusive_group()
@@ -193,7 +180,6 @@ class ListFlavor(lister.Lister):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
columns = (
"ID",
@@ -232,11 +218,9 @@ class ListFlavor(lister.Lister):
) for s in data))
-class ShowFlavor(show.ShowOne):
+class ShowFlavor(command.ShowOne):
"""Display flavor details"""
- log = logging.getLogger(__name__ + ".ShowFlavor")
-
def get_parser(self, prog_name):
parser = super(ShowFlavor, self).get_parser(prog_name)
parser.add_argument(
@@ -247,7 +231,6 @@ class ShowFlavor(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
resource_flavor = utils.find_resource(compute_client.flavors,
parsed_args.flavor)
@@ -259,11 +242,9 @@ class ShowFlavor(show.ShowOne):
return zip(*sorted(six.iteritems(flavor)))
-class SetFlavor(show.ShowOne):
+class SetFlavor(command.ShowOne):
"""Set flavor properties"""
- log = logging.getLogger(__name__ + ".SetFlavor")
-
def get_parser(self, prog_name):
parser = super(SetFlavor, self).get_parser(prog_name)
parser.add_argument(
@@ -281,7 +262,6 @@ class SetFlavor(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
resource_flavor = compute_client.flavors.find(name=parsed_args.flavor)
@@ -293,11 +273,9 @@ class SetFlavor(show.ShowOne):
return zip(*sorted(six.iteritems(flavor)))
-class UnsetFlavor(show.ShowOne):
+class UnsetFlavor(command.ShowOne):
"""Unset flavor properties"""
- log = logging.getLogger(__name__ + ".UnsetFlavor")
-
def get_parser(self, prog_name):
parser = super(UnsetFlavor, self).get_parser(prog_name)
parser.add_argument(
@@ -316,7 +294,6 @@ class UnsetFlavor(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
resource_flavor = compute_client.flavors.find(name=parsed_args.flavor)
diff --git a/openstackclient/compute/v2/floatingip.py b/openstackclient/compute/v2/floatingip.py
index 65fe591..29ecbc9 100644
--- a/openstackclient/compute/v2/floatingip.py
+++ b/openstackclient/compute/v2/floatingip.py
@@ -15,21 +15,15 @@
"""Floating IP action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
class AddFloatingIP(command.Command):
"""Add floating IP address to server"""
- log = logging.getLogger(__name__ + ".AddFloatingIP")
-
def get_parser(self, prog_name):
parser = super(AddFloatingIP, self).get_parser(prog_name)
parser.add_argument(
@@ -45,21 +39,17 @@ class AddFloatingIP(command.Command):
return parser
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)
server.add_floating_ip(parsed_args.ip_address)
- return
-class CreateFloatingIP(show.ShowOne):
+class CreateFloatingIP(command.ShowOne):
"""Create new floating IP address"""
- log = logging.getLogger(__name__ + '.CreateFloatingIP')
-
def get_parser(self, prog_name):
parser = super(CreateFloatingIP, self).get_parser(prog_name)
parser.add_argument(
@@ -69,7 +59,6 @@ class CreateFloatingIP(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
floating_ip = compute_client.floating_ips.create(parsed_args.pool)
@@ -82,8 +71,6 @@ class CreateFloatingIP(show.ShowOne):
class DeleteFloatingIP(command.Command):
"""Delete a floating IP address"""
- log = logging.getLogger(__name__ + '.DeleteFloatingIP')
-
def get_parser(self, prog_name):
parser = super(DeleteFloatingIP, self).get_parser(prog_name)
parser.add_argument(
@@ -93,7 +80,6 @@ class DeleteFloatingIP(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -103,15 +89,11 @@ class DeleteFloatingIP(command.Command):
)
compute_client.floating_ips.delete(floating_ip)
- return
-class ListFloatingIP(lister.Lister):
+class ListFloatingIP(command.Lister):
"""List floating IP addresses"""
- log = logging.getLogger(__name__ + '.ListFloatingIP')
-
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -129,8 +111,6 @@ class ListFloatingIP(lister.Lister):
class RemoveFloatingIP(command.Command):
"""Remove floating IP address from server"""
- log = logging.getLogger(__name__ + ".RemoveFloatingIP")
-
def get_parser(self, prog_name):
parser = super(RemoveFloatingIP, self).get_parser(prog_name)
parser.add_argument(
@@ -146,11 +126,9 @@ class RemoveFloatingIP(command.Command):
return parser
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)
server.remove_floating_ip(parsed_args.ip_address)
- return
diff --git a/openstackclient/compute/v2/floatingippool.py b/openstackclient/compute/v2/floatingippool.py
index 39a2d8f..997e032 100644
--- a/openstackclient/compute/v2/floatingippool.py
+++ b/openstackclient/compute/v2/floatingippool.py
@@ -15,19 +15,13 @@
"""Floating IP Pool action implementations"""
-import logging
-
-from cliff import lister
-
+from openstackclient.common import command
from openstackclient.common import utils
-class ListFloatingIPPool(lister.Lister):
+class ListFloatingIPPool(command.Lister):
"""List pools of floating IP addresses"""
- log = logging.getLogger(__name__ + '.ListFloatingIPPool')
-
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
diff --git a/openstackclient/compute/v2/host.py b/openstackclient/compute/v2/host.py
index 4f72738..f2257d1 100644
--- a/openstackclient/compute/v2/host.py
+++ b/openstackclient/compute/v2/host.py
@@ -15,18 +15,13 @@
"""Host action implementations"""
-import logging
-
-from cliff import lister
-
+from openstackclient.common import command
from openstackclient.common import utils
-class ListHost(lister.Lister):
+class ListHost(command.Lister):
"""List host command"""
- log = logging.getLogger(__name__ + ".ListHost")
-
def get_parser(self, prog_name):
parser = super(ListHost, self).get_parser(prog_name)
parser.add_argument(
@@ -36,7 +31,6 @@ class ListHost(lister.Lister):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
columns = (
"Host Name",
@@ -50,11 +44,9 @@ class ListHost(lister.Lister):
) for s in data))
-class ShowHost(lister.Lister):
+class ShowHost(command.Lister):
"""Show host command"""
- log = logging.getLogger(__name__ + ".ShowHost")
-
def get_parser(self, prog_name):
parser = super(ShowHost, self).get_parser(prog_name)
parser.add_argument(
@@ -64,7 +56,6 @@ class ShowHost(lister.Lister):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
columns = (
"Host",
diff --git a/openstackclient/compute/v2/hypervisor.py b/openstackclient/compute/v2/hypervisor.py
index f33beb0..f5288a3 100644
--- a/openstackclient/compute/v2/hypervisor.py
+++ b/openstackclient/compute/v2/hypervisor.py
@@ -15,21 +15,16 @@
"""Hypervisor action implementations"""
-import logging
import re
import six
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
-class ListHypervisor(lister.Lister):
+class ListHypervisor(command.Lister):
"""List hypervisors"""
- log = logging.getLogger(__name__ + ".ListHypervisor")
-
def get_parser(self, prog_name):
parser = super(ListHypervisor, self).get_parser(prog_name)
parser.add_argument(
@@ -40,7 +35,6 @@ class ListHypervisor(lister.Lister):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
columns = (
"ID",
@@ -58,11 +52,9 @@ class ListHypervisor(lister.Lister):
) for s in data))
-class ShowHypervisor(show.ShowOne):
+class ShowHypervisor(command.ShowOne):
"""Display hypervisor details"""
- log = logging.getLogger(__name__ + ".ShowHypervisor")
-
def get_parser(self, prog_name):
parser = super(ShowHypervisor, self).get_parser(prog_name)
parser.add_argument(
@@ -72,7 +64,6 @@ class ShowHypervisor(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
hypervisor = utils.find_resource(compute_client.hypervisors,
parsed_args.hypervisor)._info.copy()
diff --git a/openstackclient/compute/v2/hypervisor_stats.py b/openstackclient/compute/v2/hypervisor_stats.py
index 43ba9fc..290f541 100644
--- a/openstackclient/compute/v2/hypervisor_stats.py
+++ b/openstackclient/compute/v2/hypervisor_stats.py
@@ -14,19 +14,15 @@
"""Hypervisor Stats action implementations"""
-import logging
import six
-from cliff import show
+from openstackclient.common import command
-class ShowHypervisorStats(show.ShowOne):
+class ShowHypervisorStats(command.ShowOne):
"""Display hypervisor stats details"""
- log = logging.getLogger(__name__ + ".ShowHypervisorStats")
-
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
hypervisor_stats = compute_client.hypervisors.statistics().to_dict()
diff --git a/openstackclient/compute/v2/keypair.py b/openstackclient/compute/v2/keypair.py
index 5c627c5..71c9d67 100644
--- a/openstackclient/compute/v2/keypair.py
+++ b/openstackclient/compute/v2/keypair.py
@@ -15,24 +15,18 @@
"""Keypair action implementations"""
-import logging
import os
import six
import sys
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import exceptions
from openstackclient.common import utils
-class CreateKeypair(show.ShowOne):
+class CreateKeypair(command.ShowOne):
"""Create new public key"""
- log = logging.getLogger(__name__ + '.CreateKeypair')
-
def get_parser(self, prog_name):
parser = super(CreateKeypair, self).get_parser(prog_name)
parser.add_argument(
@@ -47,7 +41,6 @@ class CreateKeypair(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -82,8 +75,6 @@ class CreateKeypair(show.ShowOne):
class DeleteKeypair(command.Command):
"""Delete public key"""
- log = logging.getLogger(__name__ + '.DeleteKeypair')
-
def get_parser(self, prog_name):
parser = super(DeleteKeypair, self).get_parser(prog_name)
parser.add_argument(
@@ -93,20 +84,15 @@ class DeleteKeypair(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
compute_client.keypairs.delete(parsed_args.name)
- return
-class ListKeypair(lister.Lister):
+class ListKeypair(command.Lister):
"""List public key fingerprints"""
- log = logging.getLogger(__name__ + ".ListKeypair")
-
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
columns = (
"Name",
@@ -120,11 +106,9 @@ class ListKeypair(lister.Lister):
) for s in data))
-class ShowKeypair(show.ShowOne):
+class ShowKeypair(command.ShowOne):
"""Display public key details"""
- log = logging.getLogger(__name__ + '.ShowKeypair')
-
def get_parser(self, prog_name):
parser = super(ShowKeypair, self).get_parser(prog_name)
parser.add_argument(
@@ -140,7 +124,6 @@ class ShowKeypair(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
keypair = utils.find_resource(compute_client.keypairs,
diff --git a/openstackclient/compute/v2/security_group.py b/openstackclient/compute/v2/security_group.py
index 6d38195..2a8908d 100644
--- a/openstackclient/compute/v2/security_group.py
+++ b/openstackclient/compute/v2/security_group.py
@@ -16,13 +16,8 @@
"""Compute v2 Security Group action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
from keystoneauth1 import exceptions as ks_exc
try:
@@ -30,6 +25,7 @@ try:
except ImportError:
from novaclient.v1_1 import security_group_rules
+from openstackclient.common import command
from openstackclient.common import parseractions
from openstackclient.common import utils
@@ -54,13 +50,33 @@ def _xform_security_group_rule(sgroup):
info['ip_protocol'] = ''
elif info['ip_protocol'].lower() == 'icmp':
info['port_range'] = ''
+ group = info.pop('group')
+ if 'name' in group:
+ info['remote_security_group'] = group['name']
+ else:
+ info['remote_security_group'] = ''
return info
-class CreateSecurityGroup(show.ShowOne):
- """Create a new security group"""
+def _xform_and_trim_security_group_rule(sgroup):
+ info = _xform_security_group_rule(sgroup)
+ # Trim parent security group ID since caller has this information.
+ info.pop('parent_group_id', None)
+ # Trim keys with empty string values.
+ keys_to_trim = [
+ 'ip_protocol',
+ 'ip_range',
+ 'port_range',
+ 'remote_security_group',
+ ]
+ for key in keys_to_trim:
+ if key in info and not info[key]:
+ info.pop(key)
+ return info
- log = logging.getLogger(__name__ + ".CreateSecurityGroup")
+
+class CreateSecurityGroup(command.ShowOne):
+ """Create a new security group"""
def get_parser(self, prog_name):
parser = super(CreateSecurityGroup, self).get_parser(prog_name)
@@ -77,8 +93,6 @@ class CreateSecurityGroup(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
compute_client = self.app.client_manager.compute
description = parsed_args.description or parsed_args.name
@@ -93,11 +107,9 @@ class CreateSecurityGroup(show.ShowOne):
return zip(*sorted(six.iteritems(info)))
-class CreateSecurityGroupRule(show.ShowOne):
+class CreateSecurityGroupRule(command.ShowOne):
"""Create a new security group rule"""
- log = logging.getLogger(__name__ + ".CreateSecurityGroupRule")
-
def get_parser(self, prog_name):
parser = super(CreateSecurityGroupRule, self).get_parser(prog_name)
parser.add_argument(
@@ -111,11 +123,18 @@ class CreateSecurityGroupRule(show.ShowOne):
default="tcp",
help="IP protocol (icmp, tcp, udp; default: tcp)",
)
- parser.add_argument(
+ source_group = parser.add_mutually_exclusive_group()
+ source_group.add_argument(
"--src-ip",
metavar="<ip-address>",
default="0.0.0.0/0",
- help="Source IP (may use CIDR notation; default: 0.0.0.0/0)",
+ help="Source IP address block (may use CIDR notation; default: "
+ "0.0.0.0/0)",
+ )
+ source_group.add_argument(
+ "--src-group",
+ metavar="<group>",
+ help="Source security group (ID only)",
)
parser.add_argument(
"--dst-port",
@@ -128,8 +147,6 @@ class CreateSecurityGroupRule(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
compute_client = self.app.client_manager.compute
group = utils.find_resource(
compute_client.security_groups,
@@ -145,43 +162,16 @@ class CreateSecurityGroupRule(show.ShowOne):
from_port,
to_port,
parsed_args.src_ip,
+ parsed_args.src_group,
)
info = _xform_security_group_rule(data._info)
return zip(*sorted(six.iteritems(info)))
-class DeleteSecurityGroup(command.Command):
- """Delete a security group"""
-
- log = logging.getLogger(__name__ + '.DeleteSecurityGroup')
-
- def get_parser(self, prog_name):
- parser = super(DeleteSecurityGroup, self).get_parser(prog_name)
- parser.add_argument(
- 'group',
- metavar='<group>',
- help='Security group to delete (name or ID)',
- )
- return parser
-
- @utils.log_method(log)
- def take_action(self, parsed_args):
-
- compute_client = self.app.client_manager.compute
- data = utils.find_resource(
- compute_client.security_groups,
- parsed_args.group,
- )
- compute_client.security_groups.delete(data.id)
- return
-
-
class DeleteSecurityGroupRule(command.Command):
"""Delete a security group rule"""
- log = logging.getLogger(__name__ + '.DeleteSecurityGroupRule')
-
def get_parser(self, prog_name):
parser = super(DeleteSecurityGroupRule, self).get_parser(prog_name)
parser.add_argument(
@@ -191,19 +181,15 @@ class DeleteSecurityGroupRule(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
compute_client.security_group_rules.delete(parsed_args.rule)
- return
-class ListSecurityGroup(lister.Lister):
+class ListSecurityGroup(command.Lister):
"""List security groups"""
- log = logging.getLogger(__name__ + ".ListSecurityGroup")
-
def get_parser(self, prog_name):
parser = super(ListSecurityGroup, self).get_parser(prog_name)
parser.add_argument(
@@ -222,8 +208,6 @@ class ListSecurityGroup(lister.Lister):
except KeyError:
return project_id
- self.log.debug("take_action(%s)", parsed_args)
-
compute_client = self.app.client_manager.compute
columns = (
"ID",
@@ -255,54 +239,59 @@ class ListSecurityGroup(lister.Lister):
) for s in data))
-class ListSecurityGroupRule(lister.Lister):
+class ListSecurityGroupRule(command.Lister):
"""List security group rules"""
- log = logging.getLogger(__name__ + ".ListSecurityGroupRule")
-
def get_parser(self, prog_name):
parser = super(ListSecurityGroupRule, self).get_parser(prog_name)
parser.add_argument(
'group',
metavar='<group>',
+ nargs='?',
help='List all rules in this security group (name or ID)',
)
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
compute_client = self.app.client_manager.compute
- group = utils.find_resource(
- compute_client.security_groups,
- parsed_args.group,
+ columns = column_headers = (
+ "ID",
+ "IP Protocol",
+ "IP Range",
+ "Port Range",
+ "Remote Security Group",
)
+ rules_to_list = []
+ if parsed_args.group:
+ group = utils.find_resource(
+ compute_client.security_groups,
+ parsed_args.group,
+ )
+ rules_to_list = group.rules
+ else:
+ columns = columns + ('parent_group_id',)
+ column_headers = column_headers + ('Security Group',)
+ for group in compute_client.security_groups.list():
+ rules_to_list.extend(group.rules)
+
# Argh, the rules are not Resources...
rules = []
- for rule in group.rules:
+ for rule in rules_to_list:
rules.append(security_group_rules.SecurityGroupRule(
compute_client.security_group_rules,
_xform_security_group_rule(rule),
))
- columns = column_headers = (
- "ID",
- "IP Protocol",
- "IP Range",
- "Port Range",
- )
return (column_headers,
(utils.get_item_properties(
s, columns,
) for s in rules))
-class SetSecurityGroup(show.ShowOne):
+class SetSecurityGroup(command.ShowOne):
"""Set security group properties"""
- log = logging.getLogger(__name__ + '.SetSecurityGroup')
-
def get_parser(self, prog_name):
parser = super(SetSecurityGroup, self).get_parser(prog_name)
parser.add_argument(
@@ -322,7 +311,6 @@ class SetSecurityGroup(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -349,11 +337,9 @@ class SetSecurityGroup(show.ShowOne):
return ({}, {})
-class ShowSecurityGroup(show.ShowOne):
+class ShowSecurityGroup(command.ShowOne):
"""Display security group details"""
- log = logging.getLogger(__name__ + '.ShowSecurityGroup')
-
def get_parser(self, prog_name):
parser = super(ShowSecurityGroup, self).get_parser(prog_name)
parser.add_argument(
@@ -363,7 +349,6 @@ class ShowSecurityGroup(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -374,11 +359,12 @@ class ShowSecurityGroup(show.ShowOne):
)._info)
rules = []
for r in info['rules']:
- rules.append(utils.format_dict(_xform_security_group_rule(r)))
+ formatted_rule = _xform_and_trim_security_group_rule(r)
+ rules.append(utils.format_dict(formatted_rule))
# Format rules into a list of strings
info.update(
- {'rules': rules}
+ {'rules': utils.format_list(rules, separator='\n')}
)
# Map 'tenant_id' column to 'project_id'
info.update(
diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index 9dca784..dd7bc47 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -18,14 +18,11 @@
import argparse
import getpass
import io
-import logging
import os
import six
import sys
-from cliff import command
-from cliff import lister
-from cliff import show
+from openstackclient.common import command
try:
from novaclient.v2 import servers
@@ -37,7 +34,6 @@ 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
def _format_servers_list_networks(networks):
@@ -174,8 +170,6 @@ def _show_progress(progress):
class AddServerSecurityGroup(command.Command):
"""Add security group to server"""
- log = logging.getLogger(__name__ + '.AddServerSecurityGroup')
-
def get_parser(self, prog_name):
parser = super(AddServerSecurityGroup, self).get_parser(prog_name)
parser.add_argument(
@@ -191,8 +185,6 @@ class AddServerSecurityGroup(command.Command):
return parser
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(
@@ -205,14 +197,11 @@ class AddServerSecurityGroup(command.Command):
)
server.add_security_group(security_group.name)
- return
class AddServerVolume(command.Command):
"""Add volume to server"""
- log = logging.getLogger(__name__ + '.AddServerVolume')
-
def get_parser(self, prog_name):
parser = super(AddServerVolume, self).get_parser(prog_name)
parser.add_argument(
@@ -233,8 +222,6 @@ class AddServerVolume(command.Command):
return parser
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
@@ -254,15 +241,9 @@ class AddServerVolume(command.Command):
)
-class CreateServer(show.ShowOne):
+class CreateServer(command.ShowOne):
"""Create a new server"""
- log = logging.getLogger(__name__ + '.CreateServer')
-
- def _is_neutron_enabled(self):
- service_catalog = self.app.client_manager.auth_ref.service_catalog
- return 'network' in service_catalog.get_endpoints()
-
def get_parser(self, prog_name):
parser = super(CreateServer, self).get_parser(prog_name)
parser.add_argument(
@@ -276,25 +257,25 @@ class CreateServer(show.ShowOne):
disk_group.add_argument(
'--image',
metavar='<image>',
- help=_('Create server from this image'),
+ help=_('Create server from this image (name or ID)'),
)
disk_group.add_argument(
'--volume',
metavar='<volume>',
- help=_('Create server from this volume'),
+ help=_('Create server from this volume (name or ID)'),
)
parser.add_argument(
'--flavor',
metavar='<flavor>',
required=True,
- help=_('Create server with this flavor'),
+ help=_('Create server with this flavor (name or ID)'),
)
parser.add_argument(
'--security-group',
metavar='<security-group-name>',
action='append',
default=[],
- help=_('Security group to assign to this server '
+ help=_('Security group to assign to this server (name or ID) '
'(repeat for multiple groups)'),
)
parser.add_argument(
@@ -385,7 +366,6 @@ class CreateServer(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
volume_client = self.app.client_manager.volume
@@ -462,8 +442,6 @@ class CreateServer(show.ShowOne):
block_device_mapping.update({dev_key: block_volume})
nics = []
- if parsed_args.nic:
- neutron_enabled = self._is_neutron_enabled()
for nic_str in parsed_args.nic:
nic_info = {"net-id": "", "v4-fixed-ip": "",
"v6-fixed-ip": "", "port-id": ""}
@@ -473,18 +451,16 @@ class CreateServer(show.ShowOne):
msg = _("either net-id or port-id should be specified "
"but not both")
raise exceptions.CommandError(msg)
- if neutron_enabled:
+ if self.app.client_manager.is_network_endpoint_enabled():
network_client = self.app.client_manager.network
if nic_info["net-id"]:
- nic_info["net-id"] = common.find(network_client,
- 'network',
- 'networks',
- nic_info["net-id"])
+ net = network_client.find_network(
+ nic_info["net-id"], ignore_missing=False)
+ nic_info["net-id"] = net.id
if nic_info["port-id"]:
- nic_info["port-id"] = common.find(network_client,
- 'port',
- 'ports',
- nic_info["port-id"])
+ port = network_client.find_port(
+ nic_info["port-id"], ignore_missing=False)
+ nic_info["port-id"] = port.id
else:
if nic_info["net-id"]:
nic_info["net-id"] = utils.find_resource(
@@ -493,7 +469,7 @@ class CreateServer(show.ShowOne):
).id
if nic_info["port-id"]:
msg = _("can't create server with port specified "
- "since neutron not enabled")
+ "since network endpoint not enabled")
raise exceptions.CommandError(msg)
nics.append(nic_info)
@@ -566,11 +542,9 @@ class CreateServer(show.ShowOne):
return zip(*sorted(six.iteritems(details)))
-class CreateServerImage(show.ShowOne):
+class CreateServerImage(command.ShowOne):
"""Create a new disk image from a running server"""
- log = logging.getLogger(__name__ + '.CreateServerImage')
-
def get_parser(self, prog_name):
parser = super(CreateServerImage, self).get_parser(prog_name)
parser.add_argument(
@@ -590,7 +564,6 @@ class CreateServerImage(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
image_client = self.app.client_manager.image
@@ -632,8 +605,6 @@ class CreateServerImage(show.ShowOne):
class DeleteServer(command.Command):
"""Delete server(s)"""
- log = logging.getLogger(__name__ + '.DeleteServer')
-
def get_parser(self, prog_name):
parser = super(DeleteServer, self).get_parser(prog_name)
parser.add_argument(
@@ -649,7 +620,6 @@ class DeleteServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
for server in parsed_args.server:
@@ -668,14 +638,11 @@ class DeleteServer(command.Command):
server_obj.id)
sys.stdout.write(_('\nError deleting server'))
raise SystemExit
- return
-class ListServer(lister.Lister):
+class ListServer(command.Lister):
"""List servers"""
- log = logging.getLogger(__name__ + '.ListServer')
-
def get_parser(self, prog_name):
parser = super(ListServer, self).get_parser(prog_name)
parser.add_argument(
@@ -712,12 +679,12 @@ class ListServer(lister.Lister):
parser.add_argument(
'--flavor',
metavar='<flavor>',
- help=_('Search by flavor'),
+ help=_('Search by flavor (name or ID)'),
)
parser.add_argument(
'--image',
metavar='<image>',
- help=_('Search by image'),
+ help=_('Search by image (name or ID)'),
)
parser.add_argument(
'--host',
@@ -767,7 +734,6 @@ class ListServer(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
identity_client = self.app.client_manager.identity
@@ -789,6 +755,20 @@ class ListServer(lister.Lister):
parsed_args.user_domain,
).id
+ # Nova only supports list servers searching by flavor ID. So if a
+ # flavor name is given, map it to ID.
+ flavor_id = None
+ if parsed_args.flavor:
+ flavor_id = utils.find_resource(compute_client.flavors,
+ parsed_args.flavor).id
+
+ # Nova only supports list servers searching by image ID. So if a
+ # image name is given, map it to ID.
+ image_id = None
+ if parsed_args.image:
+ image_id = utils.find_resource(compute_client.images,
+ parsed_args.image).id
+
search_opts = {
'reservation_id': parsed_args.reservation_id,
'ip': parsed_args.ip,
@@ -796,8 +776,8 @@ class ListServer(lister.Lister):
'name': parsed_args.name,
'instance_name': parsed_args.instance_name,
'status': parsed_args.status,
- 'flavor': parsed_args.flavor,
- 'image': parsed_args.image,
+ 'flavor': flavor_id,
+ 'image': image_id,
'host': parsed_args.host,
'tenant_id': project_id,
'all_tenants': parsed_args.all_projects,
@@ -874,8 +854,6 @@ class LockServer(command.Command):
"""Lock server(s). A non-admin user will not be able to execute actions"""
- log = logging.getLogger(__name__ + '.LockServer')
-
def get_parser(self, prog_name):
parser = super(LockServer, self).get_parser(prog_name)
parser.add_argument(
@@ -886,7 +864,6 @@ class LockServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -910,8 +887,6 @@ class LockServer(command.Command):
class MigrateServer(command.Command):
"""Migrate server to different host"""
- log = logging.getLogger(__name__ + '.MigrateServer')
-
def get_parser(self, prog_name):
parser = super(MigrateServer, self).get_parser(prog_name)
parser.add_argument(
@@ -960,7 +935,6 @@ class MigrateServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -993,8 +967,6 @@ class MigrateServer(command.Command):
class PauseServer(command.Command):
"""Pause server(s)"""
- log = logging.getLogger(__name__ + '.PauseServer')
-
def get_parser(self, prog_name):
parser = super(PauseServer, self).get_parser(prog_name)
parser.add_argument(
@@ -1005,7 +977,6 @@ class PauseServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
for server in parsed_args.server:
@@ -1018,8 +989,6 @@ class PauseServer(command.Command):
class RebootServer(command.Command):
"""Perform a hard or soft server reboot"""
- log = logging.getLogger(__name__ + '.RebootServer')
-
def get_parser(self, prog_name):
parser = super(RebootServer, self).get_parser(prog_name)
parser.add_argument(
@@ -1051,7 +1020,6 @@ class RebootServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
server = utils.find_resource(
@@ -1070,11 +1038,9 @@ class RebootServer(command.Command):
raise SystemExit
-class RebuildServer(show.ShowOne):
+class RebuildServer(command.ShowOne):
"""Rebuild server"""
- log = logging.getLogger(__name__ + '.RebuildServer')
-
def get_parser(self, prog_name):
parser = super(RebuildServer, self).get_parser(prog_name)
parser.add_argument(
@@ -1085,8 +1051,8 @@ class RebuildServer(show.ShowOne):
parser.add_argument(
'--image',
metavar='<image>',
- required=True,
- help=_('Recreate server from this image'),
+ help=_('Recreate server from the specified image (name or ID).'
+ ' Defaults to the currently used one.'),
)
parser.add_argument(
'--password',
@@ -1100,16 +1066,16 @@ class RebuildServer(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
- # Lookup parsed_args.image
- image = utils.find_resource(compute_client.images, parsed_args.image)
-
server = utils.find_resource(
compute_client.servers, parsed_args.server)
+ # If parsed_args.image is not set, default to the currently used one.
+ image_id = parsed_args.image or server._info.get('image', {}).get('id')
+ image = utils.find_resource(compute_client.images, image_id)
+
server = server.rebuild(image, parsed_args.password)
if parsed_args.wait:
if utils.wait_for_status(
@@ -1129,8 +1095,6 @@ class RebuildServer(show.ShowOne):
class RemoveServerSecurityGroup(command.Command):
"""Remove security group from server"""
- log = logging.getLogger(__name__ + '.RemoveServerSecurityGroup')
-
def get_parser(self, prog_name):
parser = super(RemoveServerSecurityGroup, self).get_parser(prog_name)
parser.add_argument(
@@ -1146,8 +1110,6 @@ class RemoveServerSecurityGroup(command.Command):
return parser
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(
@@ -1165,8 +1127,6 @@ class RemoveServerSecurityGroup(command.Command):
class RemoveServerVolume(command.Command):
"""Remove volume from server"""
- log = logging.getLogger(__name__ + '.RemoveServerVolume')
-
def get_parser(self, prog_name):
parser = super(RemoveServerVolume, self).get_parser(prog_name)
parser.add_argument(
@@ -1182,8 +1142,6 @@ class RemoveServerVolume(command.Command):
return parser
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
@@ -1202,11 +1160,9 @@ class RemoveServerVolume(command.Command):
)
-class RescueServer(show.ShowOne):
+class RescueServer(command.ShowOne):
"""Put server in rescue mode"""
- log = logging.getLogger(__name__ + '.RescueServer')
-
def get_parser(self, prog_name):
parser = super(RescueServer, self).get_parser(prog_name)
parser.add_argument(
@@ -1216,7 +1172,6 @@ class RescueServer(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -1230,8 +1185,6 @@ class RescueServer(show.ShowOne):
class ResizeServer(command.Command):
"""Scale server to a new flavor"""
- log = logging.getLogger(__name__ + '.ResizeServer')
-
def get_parser(self, prog_name):
parser = super(ResizeServer, self).get_parser(prog_name)
phase_group = parser.add_mutually_exclusive_group()
@@ -1262,7 +1215,6 @@ class ResizeServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -1296,8 +1248,6 @@ class ResizeServer(command.Command):
class ResumeServer(command.Command):
"""Resume server(s)"""
- log = logging.getLogger(__name__ + '.ResumeServer')
-
def get_parser(self, prog_name):
parser = super(ResumeServer, self).get_parser(prog_name)
parser.add_argument(
@@ -1308,7 +1258,6 @@ class ResumeServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -1322,8 +1271,6 @@ class ResumeServer(command.Command):
class SetServer(command.Command):
"""Set server properties"""
- log = logging.getLogger(__name__ + '.SetServer')
-
def get_parser(self, prog_name):
parser = super(SetServer, self).get_parser(prog_name)
parser.add_argument(
@@ -1350,7 +1297,6 @@ class SetServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -1381,8 +1327,6 @@ class SetServer(command.Command):
class ShelveServer(command.Command):
"""Shelve server(s)"""
- log = logging.getLogger(__name__ + '.ShelveServer')
-
def get_parser(self, prog_name):
parser = super(ShelveServer, self).get_parser(prog_name)
parser.add_argument(
@@ -1393,7 +1337,6 @@ class ShelveServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
for server in parsed_args.server:
@@ -1403,11 +1346,9 @@ class ShelveServer(command.Command):
).shelve()
-class ShowServer(show.ShowOne):
+class ShowServer(command.ShowOne):
"""Show server details"""
- log = logging.getLogger(__name__ + '.ShowServer')
-
def get_parser(self, prog_name):
parser = super(ShowServer, self).get_parser(prog_name)
parser.add_argument(
@@ -1423,7 +1364,6 @@ class ShowServer(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
server = utils.find_resource(compute_client.servers,
@@ -1443,8 +1383,6 @@ class ShowServer(show.ShowOne):
class SshServer(command.Command):
"""Ssh to server"""
- log = logging.getLogger(__name__ + '.SshServer')
-
def get_parser(self, prog_name):
parser = super(SshServer, self).get_parser(prog_name)
parser.add_argument(
@@ -1546,7 +1484,6 @@ class SshServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -1590,8 +1527,6 @@ class SshServer(command.Command):
class StartServer(command.Command):
"""Start server(s)."""
- log = logging.getLogger(__name__ + '.StartServer')
-
def get_parser(self, prog_name):
parser = super(StartServer, self).get_parser(prog_name)
parser.add_argument(
@@ -1602,7 +1537,6 @@ class StartServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
for server in parsed_args.server:
@@ -1615,8 +1549,6 @@ class StartServer(command.Command):
class StopServer(command.Command):
"""Stop server(s)."""
- log = logging.getLogger(__name__ + '.StopServer')
-
def get_parser(self, prog_name):
parser = super(StopServer, self).get_parser(prog_name)
parser.add_argument(
@@ -1627,7 +1559,6 @@ class StopServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
for server in parsed_args.server:
@@ -1640,8 +1571,6 @@ class StopServer(command.Command):
class SuspendServer(command.Command):
"""Suspend server(s)"""
- log = logging.getLogger(__name__ + '.SuspendServer')
-
def get_parser(self, prog_name):
parser = super(SuspendServer, self).get_parser(prog_name)
parser.add_argument(
@@ -1652,7 +1581,6 @@ class SuspendServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -1666,8 +1594,6 @@ class SuspendServer(command.Command):
class UnlockServer(command.Command):
"""Unlock server(s)"""
- log = logging.getLogger(__name__ + '.UnlockServer')
-
def get_parser(self, prog_name):
parser = super(UnlockServer, self).get_parser(prog_name)
parser.add_argument(
@@ -1678,7 +1604,6 @@ class UnlockServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -1692,8 +1617,6 @@ class UnlockServer(command.Command):
class UnpauseServer(command.Command):
"""Unpause server(s)"""
- log = logging.getLogger(__name__ + '.UnpauseServer')
-
def get_parser(self, prog_name):
parser = super(UnpauseServer, self).get_parser(prog_name)
parser.add_argument(
@@ -1704,7 +1627,6 @@ class UnpauseServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -1718,8 +1640,6 @@ class UnpauseServer(command.Command):
class UnrescueServer(command.Command):
"""Restore server from rescue mode"""
- log = logging.getLogger(__name__ + '.UnrescueServer')
-
def get_parser(self, prog_name):
parser = super(UnrescueServer, self).get_parser(prog_name)
parser.add_argument(
@@ -1729,7 +1649,6 @@ class UnrescueServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
@@ -1742,8 +1661,6 @@ class UnrescueServer(command.Command):
class UnsetServer(command.Command):
"""Unset server properties"""
- log = logging.getLogger(__name__ + '.UnsetServer')
-
def get_parser(self, prog_name):
parser = super(UnsetServer, self).get_parser(prog_name)
parser.add_argument(
@@ -1761,7 +1678,6 @@ class UnsetServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
server = utils.find_resource(
@@ -1779,8 +1695,6 @@ class UnsetServer(command.Command):
class UnshelveServer(command.Command):
"""Unshelve server(s)"""
- log = logging.getLogger(__name__ + '.UnshelveServer')
-
def get_parser(self, prog_name):
parser = super(UnshelveServer, self).get_parser(prog_name)
parser.add_argument(
@@ -1791,7 +1705,6 @@ class UnshelveServer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
for server in parsed_args.server:
diff --git a/openstackclient/compute/v2/service.py b/openstackclient/compute/v2/service.py
index c2d51c2..3c06272 100644
--- a/openstackclient/compute/v2/service.py
+++ b/openstackclient/compute/v2/service.py
@@ -15,19 +15,13 @@
"""Service action implementations"""
-import logging
-
-from cliff import command
-from cliff import lister
-
+from openstackclient.common import command
from openstackclient.common import utils
class DeleteService(command.Command):
"""Delete service command"""
- log = logging.getLogger(__name__ + ".DeleteService")
-
def get_parser(self, prog_name):
parser = super(DeleteService, self).get_parser(prog_name)
parser.add_argument(
@@ -37,18 +31,14 @@ class DeleteService(command.Command):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
compute_client.services.delete(parsed_args.service)
- return
-class ListService(lister.Lister):
+class ListService(command.Lister):
"""List service command"""
- log = logging.getLogger(__name__ + ".ListService")
-
def get_parser(self, prog_name):
parser = super(ListService, self).get_parser(prog_name)
parser.add_argument(
@@ -62,7 +52,6 @@ class ListService(lister.Lister):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
columns = (
"Id",
@@ -81,11 +70,9 @@ class ListService(lister.Lister):
) for s in data))
-class SetService(lister.Lister):
+class SetService(command.Command):
"""Set service command"""
- log = logging.getLogger(__name__ + ".SetService")
-
def get_parser(self, prog_name):
parser = super(SetService, self).get_parser(prog_name)
parser.add_argument(
@@ -101,7 +88,7 @@ class SetService(lister.Lister):
"--enable",
dest="enabled",
default=True,
- help="Enable a service",
+ help="Enable a service (default)",
action="store_true")
enabled_group.add_argument(
"--disable",
@@ -111,21 +98,11 @@ class SetService(lister.Lister):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
- columns = (
- "Host",
- "Service",
- "Disabled"
- )
if parsed_args.enabled:
action = compute_client.services.enable
else:
action = compute_client.services.disable
- data = action(parsed_args.host, parsed_args.service)
- return (columns,
- (utils.get_item_properties(
- s, columns,
- ) for s in data))
+ action(parsed_args.host, parsed_args.service)
diff --git a/openstackclient/compute/v2/usage.py b/openstackclient/compute/v2/usage.py
index 4e7cf10..baa5017 100644
--- a/openstackclient/compute/v2/usage.py
+++ b/openstackclient/compute/v2/usage.py
@@ -16,21 +16,17 @@
"""Usage action implementations"""
import datetime
-import logging
import sys
-from cliff import lister
-from cliff import show
import six
+from openstackclient.common import command
from openstackclient.common import utils
-class ListUsage(lister.Lister):
+class ListUsage(command.Lister):
"""List resource usage per project"""
- log = logging.getLogger(__name__ + ".ListUsage")
-
def get_parser(self, prog_name):
parser = super(ListUsage, self).get_parser(prog_name)
parser.add_argument(
@@ -49,7 +45,6 @@ class ListUsage(lister.Lister):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
def _format_project(project):
if not project:
@@ -118,11 +113,9 @@ class ListUsage(lister.Lister):
) for s in usage_list))
-class ShowUsage(show.ShowOne):
+class ShowUsage(command.ShowOne):
"""Show resource usage for a single project"""
- log = logging.getLogger(__name__ + ".ShowUsage")
-
def get_parser(self, prog_name):
parser = super(ShowUsage, self).get_parser(prog_name)
parser.add_argument(
@@ -147,8 +140,6 @@ class ShowUsage(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
identity_client = self.app.client_manager.identity
compute_client = self.app.client_manager.compute
dateformat = "%Y-%m-%d"
diff --git a/openstackclient/i18n.py b/openstackclient/i18n.py
index 3a11c1d..1d09772 100644
--- a/openstackclient/i18n.py
+++ b/openstackclient/i18n.py
@@ -15,7 +15,7 @@
import oslo_i18n
-_translators = oslo_i18n.TranslatorFactory(domain='python-openstackclient')
+_translators = oslo_i18n.TranslatorFactory(domain='openstackclient')
# The primary translation function using the well-known name "_"
_ = _translators.primary
diff --git a/openstackclient/identity/common.py b/openstackclient/identity/common.py
index d0edb0b..2afa41f 100644
--- a/openstackclient/identity/common.py
+++ b/openstackclient/identity/common.py
@@ -41,6 +41,11 @@ def find_service(identity_client, name_type_or_id):
msg = ("No service with a type, name or ID of '%s' exists."
% name_type_or_id)
raise exceptions.CommandError(msg)
+ except identity_exc.NoUniqueMatch:
+ msg = ("Multiple service matches found for '%s', "
+ "use an ID to be more specific."
+ % name_type_or_id)
+ raise exceptions.CommandError(msg)
def _get_domain_id_if_requested(identity_client, domain_name_or_id):
diff --git a/openstackclient/identity/v2_0/catalog.py b/openstackclient/identity/v2_0/catalog.py
index 9bc2755..c927943 100644
--- a/openstackclient/identity/v2_0/catalog.py
+++ b/openstackclient/identity/v2_0/catalog.py
@@ -13,12 +13,9 @@
"""Identity v2 Service Catalog action implementations"""
-import logging
import six
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
@@ -37,12 +34,9 @@ def _format_endpoints(eps=None):
return ret
-class ListCatalog(lister.Lister):
+class ListCatalog(command.Lister):
"""List services in the service catalog"""
- log = logging.getLogger(__name__ + '.ListCatalog')
-
- @utils.log_method(log)
def take_action(self, parsed_args):
# This is ugly because if auth hasn't happened yet we need
@@ -62,11 +56,9 @@ class ListCatalog(lister.Lister):
) for s in data))
-class ShowCatalog(show.ShowOne):
+class ShowCatalog(command.ShowOne):
"""Display service catalog details"""
- log = logging.getLogger(__name__ + '.ShowCatalog')
-
def get_parser(self, prog_name):
parser = super(ShowCatalog, self).get_parser(prog_name)
parser.add_argument(
@@ -76,7 +68,6 @@ class ShowCatalog(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
# This is ugly because if auth hasn't happened yet we need
diff --git a/openstackclient/identity/v2_0/ec2creds.py b/openstackclient/identity/v2_0/ec2creds.py
index a7730ce..a16b3d9 100644
--- a/openstackclient/identity/v2_0/ec2creds.py
+++ b/openstackclient/identity/v2_0/ec2creds.py
@@ -16,22 +16,16 @@
"""Identity v2 EC2 Credentials action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
-class CreateEC2Creds(show.ShowOne):
+class CreateEC2Creds(command.ShowOne):
"""Create EC2 credentials"""
- log = logging.getLogger(__name__ + ".CreateEC2Creds")
-
def get_parser(self, prog_name):
parser = super(CreateEC2Creds, self).get_parser(prog_name)
parser.add_argument(
@@ -52,7 +46,6 @@ class CreateEC2Creds(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -89,8 +82,6 @@ class CreateEC2Creds(show.ShowOne):
class DeleteEC2Creds(command.Command):
"""Delete EC2 credentials"""
- log = logging.getLogger(__name__ + '.DeleteEC2Creds')
-
def get_parser(self, prog_name):
parser = super(DeleteEC2Creds, self).get_parser(prog_name)
parser.add_argument(
@@ -105,7 +96,6 @@ class DeleteEC2Creds(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -121,11 +111,9 @@ class DeleteEC2Creds(command.Command):
identity_client.ec2.delete(user, parsed_args.access_key)
-class ListEC2Creds(lister.Lister):
+class ListEC2Creds(command.Lister):
"""List EC2 credentials"""
- log = logging.getLogger(__name__ + '.ListEC2Creds')
-
def get_parser(self, prog_name):
parser = super(ListEC2Creds, self).get_parser(prog_name)
parser.add_argument(
@@ -135,7 +123,6 @@ class ListEC2Creds(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -159,11 +146,9 @@ class ListEC2Creds(lister.Lister):
) for s in data))
-class ShowEC2Creds(show.ShowOne):
+class ShowEC2Creds(command.ShowOne):
"""Display EC2 credentials details"""
- log = logging.getLogger(__name__ + '.ShowEC2Creds')
-
def get_parser(self, prog_name):
parser = super(ShowEC2Creds, self).get_parser(prog_name)
parser.add_argument(
@@ -178,7 +163,6 @@ class ShowEC2Creds(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
diff --git a/openstackclient/identity/v2_0/endpoint.py b/openstackclient/identity/v2_0/endpoint.py
index 1744cc7..08c0956 100644
--- a/openstackclient/identity/v2_0/endpoint.py
+++ b/openstackclient/identity/v2_0/endpoint.py
@@ -15,23 +15,17 @@
"""Endpoint action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
from openstackclient.identity import common
-class CreateEndpoint(show.ShowOne):
+class CreateEndpoint(command.ShowOne):
"""Create new endpoint"""
- log = logging.getLogger(__name__ + '.CreateEndpoint')
-
def get_parser(self, prog_name):
parser = super(CreateEndpoint, self).get_parser(prog_name)
parser.add_argument(
@@ -62,7 +56,6 @@ class CreateEndpoint(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
service = common.find_service(identity_client, parsed_args.service)
@@ -83,8 +76,6 @@ class CreateEndpoint(show.ShowOne):
class DeleteEndpoint(command.Command):
"""Delete endpoint"""
- log = logging.getLogger(__name__ + '.DeleteEndpoint')
-
def get_parser(self, prog_name):
parser = super(DeleteEndpoint, self).get_parser(prog_name)
parser.add_argument(
@@ -93,18 +84,15 @@ class DeleteEndpoint(command.Command):
help=_('Endpoint ID to delete'))
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
identity_client.endpoints.delete(parsed_args.endpoint)
return
-class ListEndpoint(lister.Lister):
+class ListEndpoint(command.Lister):
"""List endpoints"""
- log = logging.getLogger(__name__ + '.ListEndpoint')
-
def get_parser(self, prog_name):
parser = super(ListEndpoint, self).get_parser(prog_name)
parser.add_argument(
@@ -115,7 +103,6 @@ class ListEndpoint(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
if parsed_args.long:
@@ -136,11 +123,9 @@ class ListEndpoint(lister.Lister):
) for s in data))
-class ShowEndpoint(show.ShowOne):
+class ShowEndpoint(command.ShowOne):
"""Display endpoint details"""
- log = logging.getLogger(__name__ + '.ShowEndpoint')
-
def get_parser(self, prog_name):
parser = super(ShowEndpoint, self).get_parser(prog_name)
parser.add_argument(
@@ -150,7 +135,6 @@ class ShowEndpoint(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
data = identity_client.endpoints.list()
diff --git a/openstackclient/identity/v2_0/project.py b/openstackclient/identity/v2_0/project.py
index 065f0ad..9e26c30 100644
--- a/openstackclient/identity/v2_0/project.py
+++ b/openstackclient/identity/v2_0/project.py
@@ -15,24 +15,19 @@
"""Identity v2 Project action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
from keystoneauth1 import exceptions as ks_exc
+from openstackclient.common import command
from openstackclient.common import parseractions
from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
-class CreateProject(show.ShowOne):
+class CreateProject(command.ShowOne):
"""Create new project"""
- log = logging.getLogger(__name__ + '.CreateProject')
-
def get_parser(self, prog_name):
parser = super(CreateProject, self).get_parser(prog_name)
parser.add_argument(
@@ -70,7 +65,6 @@ class CreateProject(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -106,8 +100,6 @@ class CreateProject(show.ShowOne):
class DeleteProject(command.Command):
"""Delete project(s)"""
- log = logging.getLogger(__name__ + '.DeleteProject')
-
def get_parser(self, prog_name):
parser = super(DeleteProject, self).get_parser(prog_name)
parser.add_argument(
@@ -118,7 +110,6 @@ class DeleteProject(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -131,11 +122,9 @@ class DeleteProject(command.Command):
return
-class ListProject(lister.Lister):
+class ListProject(command.Lister):
"""List projects"""
- log = logging.getLogger(__name__ + '.ListProject')
-
def get_parser(self, prog_name):
parser = super(ListProject, self).get_parser(prog_name)
parser.add_argument(
@@ -146,7 +135,6 @@ class ListProject(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
if parsed_args.long:
columns = ('ID', 'Name', 'Description', 'Enabled')
@@ -163,8 +151,6 @@ class ListProject(lister.Lister):
class SetProject(command.Command):
"""Set project properties"""
- log = logging.getLogger(__name__ + '.SetProject')
-
def get_parser(self, prog_name):
parser = super(SetProject, self).get_parser(prog_name)
parser.add_argument(
@@ -202,7 +188,6 @@ class SetProject(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -240,11 +225,9 @@ class SetProject(command.Command):
return
-class ShowProject(show.ShowOne):
+class ShowProject(command.ShowOne):
"""Display project details"""
- log = logging.getLogger(__name__ + '.ShowProject')
-
def get_parser(self, prog_name):
parser = super(ShowProject, self).get_parser(prog_name)
parser.add_argument(
@@ -253,7 +236,6 @@ class ShowProject(show.ShowOne):
help=_('Project to display (name or ID)'))
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -282,4 +264,57 @@ class ShowProject(show.ShowOne):
# TODO(stevemar): Remove the line below when we support multitenancy
info.pop('parent_id', None)
+
+ # NOTE(stevemar): Property handling isn't really supported in Keystone
+ # and needs a lot of extra handling. Let's reserve the properties that
+ # the API has and handle the extra top level properties.
+ reserved = ('name', 'id', 'enabled', 'description')
+ properties = {}
+ for k, v in info.items():
+ if k not in reserved:
+ # If a key is not in `reserved` it's a property, pop it
+ info.pop(k)
+ # If a property has been "unset" it's `None`, so don't show it
+ if v is not None:
+ properties[k] = v
+
+ info['properties'] = utils.format_dict(properties)
return zip(*sorted(six.iteritems(info)))
+
+
+class UnsetProject(command.Command):
+ """Unset project properties"""
+
+ def get_parser(self, prog_name):
+ parser = super(UnsetProject, self).get_parser(prog_name)
+ parser.add_argument(
+ 'project',
+ metavar='<project>',
+ help=_('Project to modify (name or ID)'),
+ )
+ parser.add_argument(
+ '--property',
+ metavar='<key>',
+ action='append',
+ default=[],
+ help=_('Unset a project property '
+ '(repeat option to unset multiple properties)'),
+ required=True,
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ identity_client = self.app.client_manager.identity
+ project = utils.find_resource(
+ identity_client.tenants,
+ parsed_args.project,
+ )
+ if not parsed_args.property:
+ self.app.log.error("No changes requested\n")
+ else:
+ kwargs = project._info
+ for key in parsed_args.property:
+ if key in kwargs:
+ kwargs[key] = None
+ identity_client.tenants.update(project.id, **kwargs)
+ return
diff --git a/openstackclient/identity/v2_0/role.py b/openstackclient/identity/v2_0/role.py
index cab6b4a..892ce00 100644
--- a/openstackclient/identity/v2_0/role.py
+++ b/openstackclient/identity/v2_0/role.py
@@ -15,24 +15,19 @@
"""Identity v2 Role action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
from keystoneauth1 import exceptions as ks_exc
+from openstackclient.common import command
from openstackclient.common import exceptions
from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
-class AddRole(show.ShowOne):
+class AddRole(command.ShowOne):
"""Add role to project:user"""
- log = logging.getLogger(__name__ + '.AddRole')
-
def get_parser(self, prog_name):
parser = super(AddRole, self).get_parser(prog_name)
parser.add_argument(
@@ -54,7 +49,6 @@ class AddRole(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
role = utils.find_resource(identity_client.roles, parsed_args.role)
@@ -74,11 +68,9 @@ class AddRole(show.ShowOne):
return zip(*sorted(six.iteritems(info)))
-class CreateRole(show.ShowOne):
+class CreateRole(command.ShowOne):
"""Create new role"""
- log = logging.getLogger(__name__ + '.CreateRole')
-
def get_parser(self, prog_name):
parser = super(CreateRole, self).get_parser(prog_name)
parser.add_argument(
@@ -93,7 +85,6 @@ class CreateRole(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
try:
@@ -116,8 +107,6 @@ class CreateRole(show.ShowOne):
class DeleteRole(command.Command):
"""Delete role(s)"""
- log = logging.getLogger(__name__ + '.DeleteRole')
-
def get_parser(self, prog_name):
parser = super(DeleteRole, self).get_parser(prog_name)
parser.add_argument(
@@ -128,7 +117,6 @@ class DeleteRole(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -141,11 +129,9 @@ class DeleteRole(command.Command):
return
-class ListRole(lister.Lister):
+class ListRole(command.Lister):
"""List roles"""
- log = logging.getLogger(__name__ + '.ListRole')
-
def get_parser(self, prog_name):
parser = super(ListRole, self).get_parser(prog_name)
parser.add_argument(
@@ -160,7 +146,6 @@ class ListRole(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
auth_ref = self.app.client_manager.auth_ref
@@ -222,11 +207,9 @@ class ListRole(lister.Lister):
) for s in data))
-class ListUserRole(lister.Lister):
+class ListUserRole(command.Lister):
"""List user-role assignments"""
- log = logging.getLogger(__name__ + '.ListUserRole')
-
def get_parser(self, prog_name):
parser = super(ListUserRole, self).get_parser(prog_name)
parser.add_argument(
@@ -242,7 +225,6 @@ class ListUserRole(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
auth_ref = self.app.client_manager.auth_ref
@@ -293,8 +275,6 @@ class ListUserRole(lister.Lister):
class RemoveRole(command.Command):
"""Remove role from project : user"""
- log = logging.getLogger(__name__ + '.RemoveRole')
-
def get_parser(self, prog_name):
parser = super(RemoveRole, self).get_parser(prog_name)
parser.add_argument(
@@ -316,7 +296,6 @@ class RemoveRole(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
role = utils.find_resource(identity_client.roles, parsed_args.role)
@@ -331,11 +310,9 @@ class RemoveRole(command.Command):
project.id)
-class ShowRole(show.ShowOne):
+class ShowRole(command.ShowOne):
"""Display role details"""
- log = logging.getLogger(__name__ + '.ShowRole')
-
def get_parser(self, prog_name):
parser = super(ShowRole, self).get_parser(prog_name)
parser.add_argument(
@@ -345,7 +322,6 @@ class ShowRole(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, 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 c9d4844..3af85d7 100644
--- a/openstackclient/identity/v2_0/service.py
+++ b/openstackclient/identity/v2_0/service.py
@@ -16,24 +16,18 @@
"""Service action implementations"""
import argparse
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import exceptions
from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
from openstackclient.identity import common
-class CreateService(show.ShowOne):
+class CreateService(command.ShowOne):
"""Create new service"""
- log = logging.getLogger(__name__ + '.CreateService')
-
def get_parser(self, prog_name):
parser = super(CreateService, self).get_parser(prog_name)
parser.add_argument(
@@ -59,7 +53,6 @@ class CreateService(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -95,8 +88,6 @@ class CreateService(show.ShowOne):
class DeleteService(command.Command):
"""Delete service"""
- log = logging.getLogger(__name__ + '.DeleteService')
-
def get_parser(self, prog_name):
parser = super(DeleteService, self).get_parser(prog_name)
parser.add_argument(
@@ -106,7 +97,6 @@ class DeleteService(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
service = common.find_service(identity_client, parsed_args.service)
@@ -114,11 +104,9 @@ class DeleteService(command.Command):
return
-class ListService(lister.Lister):
+class ListService(command.Lister):
"""List services"""
- log = logging.getLogger(__name__ + '.ListService')
-
def get_parser(self, prog_name):
parser = super(ListService, self).get_parser(prog_name)
parser.add_argument(
@@ -129,7 +117,6 @@ class ListService(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
if parsed_args.long:
@@ -143,11 +130,9 @@ class ListService(lister.Lister):
)
-class ShowService(show.ShowOne):
+class ShowService(command.ShowOne):
"""Display service details"""
- log = logging.getLogger(__name__ + '.ShowService')
-
def get_parser(self, prog_name):
parser = super(ShowService, self).get_parser(prog_name)
parser.add_argument(
@@ -163,7 +148,6 @@ class ShowService(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, 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 5fed58e..db38fae 100644
--- a/openstackclient/identity/v2_0/token.py
+++ b/openstackclient/identity/v2_0/token.py
@@ -15,26 +15,19 @@
"""Identity v2 Token action implementations"""
-import logging
import six
-from cliff import command
-from cliff import show
-
-from openstackclient.common import utils
+from openstackclient.common import command
from openstackclient.i18n import _ # noqa
-class IssueToken(show.ShowOne):
+class IssueToken(command.ShowOne):
"""Issue new token"""
- log = logging.getLogger(__name__ + '.IssueToken')
-
def get_parser(self, prog_name):
parser = super(IssueToken, self).get_parser(prog_name)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
token = self.app.client_manager.auth_ref.service_catalog.get_token()
@@ -45,8 +38,6 @@ class IssueToken(show.ShowOne):
class RevokeToken(command.Command):
"""Revoke existing token"""
- log = logging.getLogger(__name__ + '.RevokeToken')
-
def get_parser(self, prog_name):
parser = super(RevokeToken, self).get_parser(prog_name)
parser.add_argument(
@@ -57,7 +48,6 @@ class RevokeToken(command.Command):
return parser
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
identity_client = self.app.client_manager.identity
identity_client.tokens.delete(parsed_args.token)
diff --git a/openstackclient/identity/v2_0/user.py b/openstackclient/identity/v2_0/user.py
index e2b285b..3d84873 100644
--- a/openstackclient/identity/v2_0/user.py
+++ b/openstackclient/identity/v2_0/user.py
@@ -15,23 +15,18 @@
"""Identity v2.0 User action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
from keystoneauth1 import exceptions as ks_exc
+from openstackclient.common import command
from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
-class CreateUser(show.ShowOne):
+class CreateUser(command.ShowOne):
"""Create new user"""
- log = logging.getLogger(__name__ + '.CreateUser')
-
def get_parser(self, prog_name):
parser = super(CreateUser, self).get_parser(prog_name)
parser.add_argument(
@@ -78,7 +73,6 @@ class CreateUser(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -130,8 +124,6 @@ class CreateUser(show.ShowOne):
class DeleteUser(command.Command):
"""Delete user(s)"""
- log = logging.getLogger(__name__ + '.DeleteUser')
-
def get_parser(self, prog_name):
parser = super(DeleteUser, self).get_parser(prog_name)
parser.add_argument(
@@ -142,7 +134,6 @@ class DeleteUser(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -155,11 +146,9 @@ class DeleteUser(command.Command):
return
-class ListUser(lister.Lister):
+class ListUser(command.Lister):
"""List users"""
- log = logging.getLogger(__name__ + '.ListUser')
-
def get_parser(self, prog_name):
parser = super(ListUser, self).get_parser(prog_name)
parser.add_argument(
@@ -174,7 +163,6 @@ class ListUser(lister.Lister):
help=_('List additional fields in output'))
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -248,8 +236,6 @@ class ListUser(lister.Lister):
class SetUser(command.Command):
"""Set user properties"""
- log = logging.getLogger(__name__ + '.SetUser')
-
def get_parser(self, prog_name):
parser = super(SetUser, self).get_parser(prog_name)
parser.add_argument(
@@ -296,7 +282,6 @@ class SetUser(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -348,11 +333,9 @@ class SetUser(command.Command):
return
-class ShowUser(show.ShowOne):
+class ShowUser(command.ShowOne):
"""Display user details"""
- log = logging.getLogger(__name__ + '.ShowUser')
-
def get_parser(self, prog_name):
parser = super(ShowUser, self).get_parser(prog_name)
parser.add_argument(
@@ -362,7 +345,6 @@ class ShowUser(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
diff --git a/openstackclient/identity/v3/catalog.py b/openstackclient/identity/v3/catalog.py
index 76f7da5..795f5d5 100644
--- a/openstackclient/identity/v3/catalog.py
+++ b/openstackclient/identity/v3/catalog.py
@@ -13,12 +13,9 @@
"""Identity v3 Service Catalog action implementations"""
-import logging
-
-from cliff import lister
-from cliff import show
import six
+from openstackclient.common import command
from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
@@ -34,12 +31,9 @@ def _format_endpoints(eps=None):
return ret
-class ListCatalog(lister.Lister):
+class ListCatalog(command.Lister):
"""List services in the service catalog"""
- log = logging.getLogger(__name__ + '.ListCatalog')
-
- @utils.log_method(log)
def take_action(self, parsed_args):
# This is ugly because if auth hasn't happened yet we need
@@ -59,11 +53,9 @@ class ListCatalog(lister.Lister):
) for s in data))
-class ShowCatalog(show.ShowOne):
+class ShowCatalog(command.ShowOne):
"""Display service catalog details"""
- log = logging.getLogger(__name__ + '.ShowCatalog')
-
def get_parser(self, prog_name):
parser = super(ShowCatalog, self).get_parser(prog_name)
parser.add_argument(
@@ -73,7 +65,6 @@ class ShowCatalog(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
# This is ugly because if auth hasn't happened yet we need
diff --git a/openstackclient/identity/v3/consumer.py b/openstackclient/identity/v3/consumer.py
index 0a6ade6..7298398 100644
--- a/openstackclient/identity/v3/consumer.py
+++ b/openstackclient/identity/v3/consumer.py
@@ -15,22 +15,16 @@
"""Identity v3 Consumer action implementations"""
-import logging
import six
import sys
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
-class CreateConsumer(show.ShowOne):
+class CreateConsumer(command.ShowOne):
"""Create new consumer"""
- log = logging.getLogger(__name__ + '.CreateConsumer')
-
def get_parser(self, prog_name):
parser = super(CreateConsumer, self).get_parser(prog_name)
parser.add_argument(
@@ -40,7 +34,6 @@ class CreateConsumer(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
consumer = identity_client.oauth1.consumers.create(
@@ -53,8 +46,6 @@ class CreateConsumer(show.ShowOne):
class DeleteConsumer(command.Command):
"""Delete consumer"""
- log = logging.getLogger(__name__ + '.DeleteConsumer')
-
def get_parser(self, prog_name):
parser = super(DeleteConsumer, self).get_parser(prog_name)
parser.add_argument(
@@ -64,7 +55,6 @@ class DeleteConsumer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
consumer = utils.find_resource(
@@ -73,12 +63,9 @@ class DeleteConsumer(command.Command):
return
-class ListConsumer(lister.Lister):
+class ListConsumer(command.Lister):
"""List consumers"""
- log = logging.getLogger(__name__ + '.ListConsumer')
-
- @utils.log_method(log)
def take_action(self, parsed_args):
columns = ('ID', 'Description')
data = self.app.client_manager.identity.oauth1.consumers.list()
@@ -92,8 +79,6 @@ class ListConsumer(lister.Lister):
class SetConsumer(command.Command):
"""Set consumer properties"""
- log = logging.getLogger(__name__ + '.SetConsumer')
-
def get_parser(self, prog_name):
parser = super(SetConsumer, self).get_parser(prog_name)
parser.add_argument(
@@ -108,7 +93,6 @@ class SetConsumer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
consumer = utils.find_resource(
@@ -126,11 +110,9 @@ class SetConsumer(command.Command):
return
-class ShowConsumer(show.ShowOne):
+class ShowConsumer(command.ShowOne):
"""Display consumer details"""
- log = logging.getLogger(__name__ + '.ShowConsumer')
-
def get_parser(self, prog_name):
parser = super(ShowConsumer, self).get_parser(prog_name)
parser.add_argument(
@@ -140,7 +122,6 @@ class ShowConsumer(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
consumer = utils.find_resource(
diff --git a/openstackclient/identity/v3/credential.py b/openstackclient/identity/v3/credential.py
index f22092d..6208b32 100644
--- a/openstackclient/identity/v3/credential.py
+++ b/openstackclient/identity/v3/credential.py
@@ -15,21 +15,15 @@
"""Identity v3 Credential action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
-class CreateCredential(show.ShowOne):
+class CreateCredential(command.ShowOne):
"""Create credential command"""
- log = logging.getLogger(__name__ + '.CreateCredential')
-
def get_parser(self, prog_name):
parser = super(CreateCredential, self).get_parser(prog_name)
parser.add_argument(
@@ -56,7 +50,6 @@ class CreateCredential(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
user_id = utils.find_resource(identity_client.users,
@@ -79,8 +72,6 @@ class CreateCredential(show.ShowOne):
class DeleteCredential(command.Command):
"""Delete credential command"""
- log = logging.getLogger(__name__ + '.DeleteCredential')
-
def get_parser(self, prog_name):
parser = super(DeleteCredential, self).get_parser(prog_name)
parser.add_argument(
@@ -90,19 +81,15 @@ class DeleteCredential(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
identity_client.credentials.delete(parsed_args.credential)
return
-class ListCredential(lister.Lister):
+class ListCredential(command.Lister):
"""List credential command"""
- log = logging.getLogger(__name__ + '.ListCredential')
-
- @utils.log_method(log)
def take_action(self, parsed_args):
columns = ('ID', 'Type', 'User ID', 'Blob', 'Project ID')
column_headers = ('ID', 'Type', 'User ID', 'Data', 'Project ID')
@@ -117,8 +104,6 @@ class ListCredential(lister.Lister):
class SetCredential(command.Command):
"""Set credential command"""
- log = logging.getLogger(__name__ + '.SetCredential')
-
def get_parser(self, prog_name):
parser = super(SetCredential, self).get_parser(prog_name)
parser.add_argument(
@@ -152,7 +137,6 @@ class SetCredential(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -174,11 +158,9 @@ class SetCredential(command.Command):
return
-class ShowCredential(show.ShowOne):
+class ShowCredential(command.ShowOne):
"""Show credential command"""
- log = logging.getLogger(__name__ + '.ShowCredential')
-
def get_parser(self, prog_name):
parser = super(ShowCredential, self).get_parser(prog_name)
parser.add_argument(
@@ -188,7 +170,6 @@ class ShowCredential(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
credential = utils.find_resource(identity_client.credentials,
diff --git a/openstackclient/identity/v3/domain.py b/openstackclient/identity/v3/domain.py
index 8278a30..cec967b 100644
--- a/openstackclient/identity/v3/domain.py
+++ b/openstackclient/identity/v3/domain.py
@@ -15,24 +15,19 @@
"""Identity v3 Domain action implementations"""
-import logging
import six
import sys
-from cliff import command
-from cliff import lister
-from cliff import show
from keystoneauth1 import exceptions as ks_exc
+from openstackclient.common import command
from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
-class CreateDomain(show.ShowOne):
+class CreateDomain(command.ShowOne):
"""Create new domain"""
- log = logging.getLogger(__name__ + '.CreateDomain')
-
def get_parser(self, prog_name):
parser = super(CreateDomain, self).get_parser(prog_name)
parser.add_argument(
@@ -63,7 +58,6 @@ class CreateDomain(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -92,8 +86,6 @@ class CreateDomain(show.ShowOne):
class DeleteDomain(command.Command):
"""Delete domain"""
- log = logging.getLogger(__name__ + '.DeleteDomain')
-
def get_parser(self, prog_name):
parser = super(DeleteDomain, self).get_parser(prog_name)
parser.add_argument(
@@ -103,7 +95,6 @@ class DeleteDomain(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
domain = utils.find_resource(identity_client.domains,
@@ -112,12 +103,9 @@ class DeleteDomain(command.Command):
return
-class ListDomain(lister.Lister):
+class ListDomain(command.Lister):
"""List domains"""
- log = logging.getLogger(__name__ + '.ListDomain')
-
- @utils.log_method(log)
def take_action(self, parsed_args):
columns = ('ID', 'Name', 'Enabled', 'Description')
data = self.app.client_manager.identity.domains.list()
@@ -131,8 +119,6 @@ class ListDomain(lister.Lister):
class SetDomain(command.Command):
"""Set domain properties"""
- log = logging.getLogger(__name__ + '.SetDomain')
-
def get_parser(self, prog_name):
parser = super(SetDomain, self).get_parser(prog_name)
parser.add_argument(
@@ -163,7 +149,6 @@ class SetDomain(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
domain = utils.find_resource(identity_client.domains,
@@ -186,11 +171,9 @@ class SetDomain(command.Command):
return
-class ShowDomain(show.ShowOne):
+class ShowDomain(command.ShowOne):
"""Display domain details"""
- log = logging.getLogger(__name__ + '.ShowDomain')
-
def get_parser(self, prog_name):
parser = super(ShowDomain, self).get_parser(prog_name)
parser.add_argument(
@@ -200,7 +183,6 @@ class ShowDomain(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
domain = utils.find_resource(identity_client.domains,
diff --git a/openstackclient/identity/v3/ec2creds.py b/openstackclient/identity/v3/ec2creds.py
index a12ee25..777c043 100644
--- a/openstackclient/identity/v3/ec2creds.py
+++ b/openstackclient/identity/v3/ec2creds.py
@@ -12,13 +12,9 @@
"""Identity v3 EC2 Credentials action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
from openstackclient.identity import common
@@ -52,11 +48,9 @@ def _determine_ec2_user(parsed_args, client_manager):
return user
-class CreateEC2Creds(show.ShowOne):
+class CreateEC2Creds(command.ShowOne):
"""Create EC2 credentials"""
- log = logging.getLogger(__name__ + ".CreateEC2Creds")
-
def get_parser(self, prog_name):
parser = super(CreateEC2Creds, self).get_parser(prog_name)
parser.add_argument(
@@ -79,7 +73,6 @@ class CreateEC2Creds(show.ShowOne):
common.add_project_domain_option_to_parser(parser)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
client_manager = self.app.client_manager
@@ -119,8 +112,6 @@ class CreateEC2Creds(show.ShowOne):
class DeleteEC2Creds(command.Command):
"""Delete EC2 credentials"""
- log = logging.getLogger(__name__ + '.DeleteEC2Creds')
-
def get_parser(self, prog_name):
parser = super(DeleteEC2Creds, self).get_parser(prog_name)
parser.add_argument(
@@ -136,18 +127,15 @@ class DeleteEC2Creds(command.Command):
common.add_user_domain_option_to_parser(parser)
return parser
- @utils.log_method(log)
def take_action(self, 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)
-class ListEC2Creds(lister.Lister):
+class ListEC2Creds(command.Lister):
"""List EC2 credentials"""
- log = logging.getLogger(__name__ + '.ListEC2Creds')
-
def get_parser(self, prog_name):
parser = super(ListEC2Creds, self).get_parser(prog_name)
parser.add_argument(
@@ -158,7 +146,6 @@ class ListEC2Creds(lister.Lister):
common.add_user_domain_option_to_parser(parser)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
client_manager = self.app.client_manager
user = _determine_ec2_user(parsed_args, client_manager)
@@ -174,11 +161,9 @@ class ListEC2Creds(lister.Lister):
) for s in data))
-class ShowEC2Creds(show.ShowOne):
+class ShowEC2Creds(command.ShowOne):
"""Display EC2 credentials details"""
- log = logging.getLogger(__name__ + '.ShowEC2Creds')
-
def get_parser(self, prog_name):
parser = super(ShowEC2Creds, self).get_parser(prog_name)
parser.add_argument(
@@ -194,7 +179,6 @@ class ShowEC2Creds(show.ShowOne):
common.add_user_domain_option_to_parser(parser)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
client_manager = self.app.client_manager
user = _determine_ec2_user(parsed_args, client_manager)
diff --git a/openstackclient/identity/v3/endpoint.py b/openstackclient/identity/v3/endpoint.py
index 3d1c6f5..1eff3b3 100644
--- a/openstackclient/identity/v3/endpoint.py
+++ b/openstackclient/identity/v3/endpoint.py
@@ -15,14 +15,10 @@
"""Identity v3 Endpoint action implementations"""
-import logging
import six
import sys
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
from openstackclient.identity import common
@@ -34,11 +30,9 @@ def get_service_name(service):
return ''
-class CreateEndpoint(show.ShowOne):
+class CreateEndpoint(command.ShowOne):
"""Create new endpoint"""
- log = logging.getLogger(__name__ + '.CreateEndpoint')
-
def get_parser(self, prog_name):
parser = super(CreateEndpoint, self).get_parser(prog_name)
parser.add_argument(
@@ -78,7 +72,6 @@ class CreateEndpoint(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
service = common.find_service(identity_client, parsed_args.service)
@@ -102,8 +95,6 @@ class CreateEndpoint(show.ShowOne):
class DeleteEndpoint(command.Command):
"""Delete endpoint"""
- log = logging.getLogger(__name__ + '.DeleteEndpoint')
-
def get_parser(self, prog_name):
parser = super(DeleteEndpoint, self).get_parser(prog_name)
parser.add_argument(
@@ -113,7 +104,6 @@ class DeleteEndpoint(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
endpoint_id = utils.find_resource(identity_client.endpoints,
@@ -122,11 +112,9 @@ class DeleteEndpoint(command.Command):
return
-class ListEndpoint(lister.Lister):
+class ListEndpoint(command.Lister):
"""List endpoints"""
- log = logging.getLogger(__name__ + '.ListEndpoint')
-
def get_parser(self, prog_name):
parser = super(ListEndpoint, self).get_parser(prog_name)
parser.add_argument(
@@ -147,7 +135,6 @@ class ListEndpoint(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
columns = ('ID', 'Region', 'Service Name', 'Service Type',
@@ -176,8 +163,6 @@ class ListEndpoint(lister.Lister):
class SetEndpoint(command.Command):
"""Set endpoint properties"""
- log = logging.getLogger(__name__ + '.SetEndpoint')
-
def get_parser(self, prog_name):
parser = super(SetEndpoint, self).get_parser(prog_name)
parser.add_argument(
@@ -221,7 +206,6 @@ class SetEndpoint(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
endpoint = utils.find_resource(identity_client.endpoints,
@@ -256,11 +240,9 @@ class SetEndpoint(command.Command):
return
-class ShowEndpoint(show.ShowOne):
+class ShowEndpoint(command.ShowOne):
"""Display endpoint details"""
- log = logging.getLogger(__name__ + '.ShowEndpoint')
-
def get_parser(self, prog_name):
parser = super(ShowEndpoint, self).get_parser(prog_name)
parser.add_argument(
@@ -270,7 +252,6 @@ class ShowEndpoint(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
endpoint = utils.find_resource(identity_client.endpoints,
diff --git a/openstackclient/identity/v3/federation_protocol.py b/openstackclient/identity/v3/federation_protocol.py
index 20877fc..2d7ab15 100644
--- a/openstackclient/identity/v3/federation_protocol.py
+++ b/openstackclient/identity/v3/federation_protocol.py
@@ -14,21 +14,15 @@
"""Identity v3 Protocols actions implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
-class CreateProtocol(show.ShowOne):
+class CreateProtocol(command.ShowOne):
"""Create new federation protocol"""
- log = logging.getLogger(__name__ + 'CreateProtocol')
-
def get_parser(self, prog_name):
parser = super(CreateProtocol, self).get_parser(prog_name)
parser.add_argument(
@@ -50,7 +44,6 @@ class CreateProtocol(show.ShowOne):
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
protocol = identity_client.federation.protocols.create(
@@ -71,8 +64,6 @@ class CreateProtocol(show.ShowOne):
class DeleteProtocol(command.Command):
"""Delete federation protocol"""
- log = logging.getLogger(__name__ + '.DeleteProtocol')
-
def get_parser(self, prog_name):
parser = super(DeleteProtocol, self).get_parser(prog_name)
parser.add_argument(
@@ -88,7 +79,6 @@ class DeleteProtocol(command.Command):
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
identity_client.federation.protocols.delete(
@@ -96,11 +86,9 @@ class DeleteProtocol(command.Command):
return
-class ListProtocols(lister.Lister):
+class ListProtocols(command.Lister):
"""List federation protocols"""
- log = logging.getLogger(__name__ + '.ListProtocols')
-
def get_parser(self, prog_name):
parser = super(ListProtocols, self).get_parser(prog_name)
parser.add_argument(
@@ -126,8 +114,6 @@ class ListProtocols(lister.Lister):
class SetProtocol(command.Command):
"""Set federation protocol properties"""
- log = logging.getLogger(__name__ + '.SetProtocol')
-
def get_parser(self, prog_name):
parser = super(SetProtocol, self).get_parser(prog_name)
parser.add_argument(
@@ -166,11 +152,9 @@ class SetProtocol(command.Command):
return zip(*sorted(six.iteritems(info)))
-class ShowProtocol(show.ShowOne):
+class ShowProtocol(command.ShowOne):
"""Display federation protocol details"""
- log = logging.getLogger(__name__ + '.ShowProtocol')
-
def get_parser(self, prog_name):
parser = super(ShowProtocol, self).get_parser(prog_name)
parser.add_argument(
diff --git a/openstackclient/identity/v3/group.py b/openstackclient/identity/v3/group.py
index d503a6b..b3d893c 100644
--- a/openstackclient/identity/v3/group.py
+++ b/openstackclient/identity/v3/group.py
@@ -15,15 +15,12 @@
"""Group action implementations"""
-import logging
import six
import sys
-from cliff import command
-from cliff import lister
-from cliff import show
from keystoneauth1 import exceptions as ks_exc
+from openstackclient.common import command
from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
from openstackclient.identity import common
@@ -32,8 +29,6 @@ from openstackclient.identity import common
class AddUserToGroup(command.Command):
"""Add user to group"""
- log = logging.getLogger(__name__ + '.AddUserToGroup')
-
def get_parser(self, prog_name):
parser = super(AddUserToGroup, self).get_parser(prog_name)
parser.add_argument(
@@ -50,7 +45,6 @@ class AddUserToGroup(command.Command):
common.add_user_domain_option_to_parser(parser)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -74,8 +68,6 @@ class AddUserToGroup(command.Command):
class CheckUserInGroup(command.Command):
"""Check user membership in group"""
- log = logging.getLogger(__name__ + '.CheckUserInGroup')
-
def get_parser(self, prog_name):
parser = super(CheckUserInGroup, self).get_parser(prog_name)
parser.add_argument(
@@ -92,7 +84,6 @@ class CheckUserInGroup(command.Command):
common.add_user_domain_option_to_parser(parser)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -113,11 +104,9 @@ class CheckUserInGroup(command.Command):
(parsed_args.user, parsed_args.group))
-class CreateGroup(show.ShowOne):
+class CreateGroup(command.ShowOne):
"""Create new group"""
- log = logging.getLogger(__name__ + '.CreateGroup')
-
def get_parser(self, prog_name):
parser = super(CreateGroup, self).get_parser(prog_name)
parser.add_argument(
@@ -142,7 +131,6 @@ class CreateGroup(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -172,8 +160,6 @@ class CreateGroup(show.ShowOne):
class DeleteGroup(command.Command):
"""Delete group(s)"""
- log = logging.getLogger(__name__ + '.DeleteGroup')
-
def get_parser(self, prog_name):
parser = super(DeleteGroup, self).get_parser(prog_name)
parser.add_argument(
@@ -188,7 +174,6 @@ class DeleteGroup(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -200,11 +185,9 @@ class DeleteGroup(command.Command):
return
-class ListGroup(lister.Lister):
+class ListGroup(command.Lister):
"""List groups"""
- log = logging.getLogger(__name__ + '.ListGroup')
-
def get_parser(self, prog_name):
parser = super(ListGroup, self).get_parser(prog_name)
parser.add_argument(
@@ -226,7 +209,6 @@ class ListGroup(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -266,8 +248,6 @@ class ListGroup(lister.Lister):
class RemoveUserFromGroup(command.Command):
"""Remove user from group"""
- log = logging.getLogger(__name__ + '.RemoveUserFromGroup')
-
def get_parser(self, prog_name):
parser = super(RemoveUserFromGroup, self).get_parser(prog_name)
parser.add_argument(
@@ -284,7 +264,6 @@ class RemoveUserFromGroup(command.Command):
common.add_user_domain_option_to_parser(parser)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -308,8 +287,6 @@ class RemoveUserFromGroup(command.Command):
class SetGroup(command.Command):
"""Set group properties"""
- log = logging.getLogger(__name__ + '.SetGroup')
-
def get_parser(self, prog_name):
parser = super(SetGroup, self).get_parser(prog_name)
parser.add_argument(
@@ -331,7 +308,6 @@ class SetGroup(command.Command):
help='New group description')
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
group = common.find_group(identity_client, parsed_args.group,
@@ -349,11 +325,9 @@ class SetGroup(command.Command):
return
-class ShowGroup(show.ShowOne):
+class ShowGroup(command.ShowOne):
"""Display group details"""
- log = logging.getLogger(__name__ + '.ShowGroup')
-
def get_parser(self, prog_name):
parser = super(ShowGroup, self).get_parser(prog_name)
parser.add_argument(
@@ -368,7 +342,6 @@ class ShowGroup(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
diff --git a/openstackclient/identity/v3/identity_provider.py b/openstackclient/identity/v3/identity_provider.py
index 4e086b6..0ff8acb 100644
--- a/openstackclient/identity/v3/identity_provider.py
+++ b/openstackclient/identity/v3/identity_provider.py
@@ -13,21 +13,15 @@
"""Identity v3 IdentityProvider action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
-class CreateIdentityProvider(show.ShowOne):
+class CreateIdentityProvider(command.ShowOne):
"""Create new identity provider"""
- log = logging.getLogger(__name__ + '.CreateIdentityProvider')
-
def get_parser(self, prog_name):
parser = super(CreateIdentityProvider, self).get_parser(prog_name)
parser.add_argument(
@@ -70,7 +64,6 @@ class CreateIdentityProvider(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
if parsed_args.remote_id_file:
@@ -96,8 +89,6 @@ class CreateIdentityProvider(show.ShowOne):
class DeleteIdentityProvider(command.Command):
"""Delete identity provider"""
- log = logging.getLogger(__name__ + '.DeleteIdentityProvider')
-
def get_parser(self, prog_name):
parser = super(DeleteIdentityProvider, self).get_parser(prog_name)
parser.add_argument(
@@ -107,7 +98,6 @@ class DeleteIdentityProvider(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
identity_client.federation.identity_providers.delete(
@@ -115,12 +105,9 @@ class DeleteIdentityProvider(command.Command):
return
-class ListIdentityProvider(lister.Lister):
+class ListIdentityProvider(command.Lister):
"""List identity providers"""
- log = logging.getLogger(__name__ + '.ListIdentityProvider')
-
- @utils.log_method(log)
def take_action(self, parsed_args):
columns = ('ID', 'Enabled', 'Description')
identity_client = self.app.client_manager.identity
@@ -135,8 +122,6 @@ class ListIdentityProvider(lister.Lister):
class SetIdentityProvider(command.Command):
"""Set identity provider properties"""
- log = logging.getLogger(__name__ + '.SetIdentityProvider')
-
def get_parser(self, prog_name):
parser = super(SetIdentityProvider, self).get_parser(prog_name)
parser.add_argument(
@@ -176,7 +161,6 @@ class SetIdentityProvider(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
federation_client = self.app.client_manager.identity.federation
@@ -215,11 +199,9 @@ class SetIdentityProvider(command.Command):
return zip(*sorted(six.iteritems(identity_provider._info)))
-class ShowIdentityProvider(show.ShowOne):
+class ShowIdentityProvider(command.ShowOne):
"""Display identity provider details"""
- log = logging.getLogger(__name__ + '.ShowIdentityProvider')
-
def get_parser(self, prog_name):
parser = super(ShowIdentityProvider, self).get_parser(prog_name)
parser.add_argument(
@@ -229,7 +211,6 @@ class ShowIdentityProvider(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
idp = utils.find_resource(
diff --git a/openstackclient/identity/v3/mapping.py b/openstackclient/identity/v3/mapping.py
index c79331e..422d66b 100644
--- a/openstackclient/identity/v3/mapping.py
+++ b/openstackclient/identity/v3/mapping.py
@@ -16,13 +16,10 @@
"""Identity v3 federation mapping action implementations"""
import json
-import logging
-from cliff import command
-from cliff import lister
-from cliff import show
import six
+from openstackclient.common import command
from openstackclient.common import exceptions
from openstackclient.common import utils
@@ -79,11 +76,9 @@ class _RulesReader(object):
return rules
-class CreateMapping(show.ShowOne, _RulesReader):
+class CreateMapping(command.ShowOne, _RulesReader):
"""Create new mapping"""
- log = logging.getLogger(__name__ + '.CreateMapping')
-
def get_parser(self, prog_name):
parser = super(CreateMapping, self).get_parser(prog_name)
parser.add_argument(
@@ -99,7 +94,6 @@ class CreateMapping(show.ShowOne, _RulesReader):
return parser
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
identity_client = self.app.client_manager.identity
rules = self._read_rules(parsed_args.rules)
@@ -114,8 +108,6 @@ class CreateMapping(show.ShowOne, _RulesReader):
class DeleteMapping(command.Command):
"""Delete mapping"""
- log = logging.getLogger(__name__ + '.DeleteMapping')
-
def get_parser(self, prog_name):
parser = super(DeleteMapping, self).get_parser(prog_name)
parser.add_argument(
@@ -126,19 +118,16 @@ class DeleteMapping(command.Command):
return parser
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
identity_client = self.app.client_manager.identity
identity_client.federation.mappings.delete(parsed_args.mapping)
return
-class ListMapping(lister.Lister):
+class ListMapping(command.Lister):
"""List mappings"""
- log = logging.getLogger(__name__ + '.ListMapping')
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
# NOTE(marek-denis): Since rules can be long and tedious I have decided
# to only list ids of the mappings. If somebody wants to check the
# rules, (s)he should show specific ones.
@@ -152,8 +141,6 @@ class ListMapping(lister.Lister):
class SetMapping(command.Command, _RulesReader):
"""Set mapping properties"""
- log = logging.getLogger(__name__ + '.SetMapping')
-
def get_parser(self, prog_name):
parser = super(SetMapping, self).get_parser(prog_name)
parser.add_argument(
@@ -169,7 +156,6 @@ class SetMapping(command.Command, _RulesReader):
return parser
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.rules:
@@ -186,11 +172,9 @@ class SetMapping(command.Command, _RulesReader):
return zip(*sorted(six.iteritems(mapping._info)))
-class ShowMapping(show.ShowOne):
+class ShowMapping(command.ShowOne):
"""Display mapping details"""
- log = logging.getLogger(__name__ + '.ShowMapping')
-
def get_parser(self, prog_name):
parser = super(ShowMapping, self).get_parser(prog_name)
parser.add_argument(
@@ -201,7 +185,6 @@ class ShowMapping(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
identity_client = self.app.client_manager.identity
mapping = identity_client.federation.mappings.get(parsed_args.mapping)
diff --git a/openstackclient/identity/v3/policy.py b/openstackclient/identity/v3/policy.py
index 9da9486..503df37 100644
--- a/openstackclient/identity/v3/policy.py
+++ b/openstackclient/identity/v3/policy.py
@@ -15,22 +15,16 @@
"""Identity v3 Policy action implementations"""
-import logging
import six
import sys
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
-class CreatePolicy(show.ShowOne):
+class CreatePolicy(command.ShowOne):
"""Create new policy"""
- log = logging.getLogger(__name__ + '.CreatePolicy')
-
def get_parser(self, prog_name):
parser = super(CreatePolicy, self).get_parser(prog_name)
parser.add_argument(
@@ -47,7 +41,6 @@ class CreatePolicy(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
blob = utils.read_blob_file_contents(parsed_args.rules)
@@ -64,8 +57,6 @@ class CreatePolicy(show.ShowOne):
class DeletePolicy(command.Command):
"""Delete policy"""
- log = logging.getLogger(__name__ + '.DeletePolicy')
-
def get_parser(self, prog_name):
parser = super(DeletePolicy, self).get_parser(prog_name)
parser.add_argument(
@@ -75,18 +66,15 @@ class DeletePolicy(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
identity_client.policies.delete(parsed_args.policy)
return
-class ListPolicy(lister.Lister):
+class ListPolicy(command.Lister):
"""List policies"""
- log = logging.getLogger(__name__ + '.ListPolicy')
-
def get_parser(self, prog_name):
parser = super(ListPolicy, self).get_parser(prog_name)
parser.add_argument(
@@ -97,7 +85,6 @@ class ListPolicy(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
if parsed_args.long:
columns = ('ID', 'Type', 'Blob')
@@ -116,8 +103,6 @@ class ListPolicy(lister.Lister):
class SetPolicy(command.Command):
"""Set policy properties"""
- log = logging.getLogger(__name__ + '.SetPolicy')
-
def get_parser(self, prog_name):
parser = super(SetPolicy, self).get_parser(prog_name)
parser.add_argument(
@@ -137,7 +122,6 @@ class SetPolicy(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
blob = None
@@ -158,11 +142,9 @@ class SetPolicy(command.Command):
return
-class ShowPolicy(show.ShowOne):
+class ShowPolicy(command.ShowOne):
"""Display policy details"""
- log = logging.getLogger(__name__ + '.ShowPolicy')
-
def get_parser(self, prog_name):
parser = super(ShowPolicy, self).get_parser(prog_name)
parser.add_argument(
@@ -172,7 +154,6 @@ class ShowPolicy(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
policy = utils.find_resource(identity_client.policies,
diff --git a/openstackclient/identity/v3/project.py b/openstackclient/identity/v3/project.py
index f87105d..61db861 100644
--- a/openstackclient/identity/v3/project.py
+++ b/openstackclient/identity/v3/project.py
@@ -15,25 +15,20 @@
"""Project action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
from keystoneauth1 import exceptions as ks_exc
+from openstackclient.common import command
from openstackclient.common import parseractions
from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
from openstackclient.identity import common
-class CreateProject(show.ShowOne):
+class CreateProject(command.ShowOne):
"""Create new project"""
- log = logging.getLogger(__name__ + '.CreateProject')
-
def get_parser(self, prog_name):
parser = super(CreateProject, self).get_parser(prog_name)
parser.add_argument(
@@ -81,7 +76,6 @@ class CreateProject(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -129,8 +123,6 @@ class CreateProject(show.ShowOne):
class DeleteProject(command.Command):
"""Delete project(s)"""
- log = logging.getLogger(__name__ + '.DeleteProject')
-
def get_parser(self, prog_name):
parser = super(DeleteProject, self).get_parser(prog_name)
parser.add_argument(
@@ -146,7 +138,6 @@ class DeleteProject(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -165,11 +156,9 @@ class DeleteProject(command.Command):
return
-class ListProject(lister.Lister):
+class ListProject(command.Lister):
"""List projects"""
- log = logging.getLogger(__name__ + '.ListProject')
-
def get_parser(self, prog_name):
parser = super(ListProject, self).get_parser(prog_name)
parser.add_argument(
@@ -190,7 +179,6 @@ class ListProject(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
if parsed_args.long:
@@ -227,8 +215,6 @@ class ListProject(lister.Lister):
class SetProject(command.Command):
"""Set project properties"""
- log = logging.getLogger(__name__ + '.SetProject')
-
def get_parser(self, prog_name):
parser = super(SetProject, self).get_parser(prog_name)
parser.add_argument(
@@ -271,7 +257,6 @@ class SetProject(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -283,16 +268,12 @@ class SetProject(command.Command):
and not parsed_args.disable):
return
- project = utils.find_resource(
- identity_client.projects,
- parsed_args.project,
- )
+ project = common.find_project(identity_client, parsed_args.project,
+ parsed_args.domain)
kwargs = {}
if parsed_args.name:
kwargs['name'] = parsed_args.name
- if parsed_args.domain:
- kwargs['domain'] = parsed_args.domain
if parsed_args.description:
kwargs['description'] = parsed_args.description
if parsed_args.enable:
@@ -306,11 +287,9 @@ class SetProject(command.Command):
return
-class ShowProject(show.ShowOne):
+class ShowProject(command.ShowOne):
"""Display project details"""
- log = logging.getLogger(__name__ + '.ShowProject')
-
def get_parser(self, prog_name):
parser = super(ShowProject, self).get_parser(prog_name)
parser.add_argument(
@@ -337,7 +316,6 @@ class ShowProject(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
diff --git a/openstackclient/identity/v3/region.py b/openstackclient/identity/v3/region.py
index 1ff0b8c..1e15fd2 100644
--- a/openstackclient/identity/v3/region.py
+++ b/openstackclient/identity/v3/region.py
@@ -13,22 +13,16 @@
"""Identity v3 Region action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
-class CreateRegion(show.ShowOne):
+class CreateRegion(command.ShowOne):
"""Create new region"""
- log = logging.getLogger(__name__ + '.CreateRegion')
-
def get_parser(self, prog_name):
parser = super(CreateRegion, self).get_parser(prog_name)
# NOTE(stevemar): The API supports an optional region ID, but that
@@ -50,7 +44,6 @@ class CreateRegion(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -69,8 +62,6 @@ class CreateRegion(show.ShowOne):
class DeleteRegion(command.Command):
"""Delete region"""
- log = logging.getLogger(__name__ + '.DeleteRegion')
-
def get_parser(self, prog_name):
parser = super(DeleteRegion, self).get_parser(prog_name)
parser.add_argument(
@@ -80,7 +71,6 @@ class DeleteRegion(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -88,11 +78,9 @@ class DeleteRegion(command.Command):
return
-class ListRegion(lister.Lister):
+class ListRegion(command.Lister):
"""List regions"""
- log = logging.getLogger(__name__ + '.ListRegion')
-
def get_parser(self, prog_name):
parser = super(ListRegion, self).get_parser(prog_name)
parser.add_argument(
@@ -102,7 +90,6 @@ class ListRegion(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -124,8 +111,6 @@ class ListRegion(lister.Lister):
class SetRegion(command.Command):
"""Set region properties"""
- log = logging.getLogger(__name__ + '.SetRegion')
-
def get_parser(self, prog_name):
parser = super(SetRegion, self).get_parser(prog_name)
parser.add_argument(
@@ -145,7 +130,6 @@ class SetRegion(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -162,11 +146,9 @@ class SetRegion(command.Command):
return
-class ShowRegion(show.ShowOne):
+class ShowRegion(command.ShowOne):
"""Display region details"""
- log = logging.getLogger(__name__ + '.ShowRegion')
-
def get_parser(self, prog_name):
parser = super(ShowRegion, self).get_parser(prog_name)
parser.add_argument(
@@ -176,7 +158,6 @@ class ShowRegion(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
diff --git a/openstackclient/identity/v3/role.py b/openstackclient/identity/v3/role.py
index 66f1896..4cced61 100644
--- a/openstackclient/identity/v3/role.py
+++ b/openstackclient/identity/v3/role.py
@@ -15,15 +15,12 @@
"""Identity v3 Role action implementations"""
-import logging
import six
import sys
-from cliff import command
-from cliff import lister
-from cliff import show
from keystoneauth1 import exceptions as ks_exc
+from openstackclient.common import command
from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
from openstackclient.identity import common
@@ -110,8 +107,6 @@ def _process_identity_and_resource_options(parsed_args,
class AddRole(command.Command):
"""Adds a role to a user or group on a domain or project"""
- log = logging.getLogger(__name__ + '.AddRole')
-
def get_parser(self, prog_name):
parser = super(AddRole, self).get_parser(prog_name)
parser.add_argument(
@@ -122,7 +117,6 @@ class AddRole(command.Command):
_add_identity_and_resource_options_to_parser(parser)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -147,11 +141,9 @@ class AddRole(command.Command):
return
-class CreateRole(show.ShowOne):
+class CreateRole(command.ShowOne):
"""Create new role"""
- log = logging.getLogger(__name__ + '.CreateRole')
-
def get_parser(self, prog_name):
parser = super(CreateRole, self).get_parser(prog_name)
parser.add_argument(
@@ -166,7 +158,6 @@ class CreateRole(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -187,8 +178,6 @@ class CreateRole(show.ShowOne):
class DeleteRole(command.Command):
"""Delete role(s)"""
- log = logging.getLogger(__name__ + '.DeleteRole')
-
def get_parser(self, prog_name):
parser = super(DeleteRole, self).get_parser(prog_name)
parser.add_argument(
@@ -199,7 +188,6 @@ class DeleteRole(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -212,18 +200,15 @@ class DeleteRole(command.Command):
return
-class ListRole(lister.Lister):
+class ListRole(command.Lister):
"""List roles"""
- log = logging.getLogger(__name__ + '.ListRole')
-
def get_parser(self, prog_name):
parser = super(ListRole, self).get_parser(prog_name)
_add_identity_and_resource_options_to_parser(parser)
return parser
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:
@@ -318,8 +303,6 @@ class ListRole(lister.Lister):
class RemoveRole(command.Command):
"""Remove role from domain/project : user/group"""
- log = logging.getLogger(__name__ + '.RemoveRole')
-
def get_parser(self, prog_name):
parser = super(RemoveRole, self).get_parser(prog_name)
parser.add_argument(
@@ -330,7 +313,6 @@ class RemoveRole(command.Command):
_add_identity_and_resource_options_to_parser(parser)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -357,8 +339,6 @@ class RemoveRole(command.Command):
class SetRole(command.Command):
"""Set role properties"""
- log = logging.getLogger(__name__ + '.SetRole')
-
def get_parser(self, prog_name):
parser = super(SetRole, self).get_parser(prog_name)
parser.add_argument(
@@ -373,7 +353,6 @@ class SetRole(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -389,11 +368,9 @@ class SetRole(command.Command):
return
-class ShowRole(show.ShowOne):
+class ShowRole(command.ShowOne):
"""Display role details"""
- log = logging.getLogger(__name__ + '.ShowRole')
-
def get_parser(self, prog_name):
parser = super(ShowRole, self).get_parser(prog_name)
parser.add_argument(
@@ -403,7 +380,6 @@ class ShowRole(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
diff --git a/openstackclient/identity/v3/role_assignment.py b/openstackclient/identity/v3/role_assignment.py
index 169c6cb..d766be6 100644
--- a/openstackclient/identity/v3/role_assignment.py
+++ b/openstackclient/identity/v3/role_assignment.py
@@ -13,19 +13,14 @@
"""Identity v3 Assignment action implementations """
-import logging
-
-from cliff import lister
-
+from openstackclient.common import command
from openstackclient.common import utils
from openstackclient.identity import common
-class ListRoleAssignment(lister.Lister):
+class ListRoleAssignment(command.Lister):
"""List role assignments"""
- log = logging.getLogger(__name__ + '.ListRoleAssignment')
-
def get_parser(self, prog_name):
parser = super(ListRoleAssignment, self).get_parser(prog_name)
parser.add_argument(
@@ -72,7 +67,6 @@ class ListRoleAssignment(lister.Lister):
assignment.project, assignment.domain, assignment.inherited)
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
identity_client = self.app.client_manager.identity
role = None
@@ -114,7 +108,6 @@ class ListRoleAssignment(lister.Lister):
)
effective = True if parsed_args.effective else False
- self.log.debug('take_action(%s)' % parsed_args)
columns = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited')
inherited_to = 'projects' if parsed_args.inherited else None
diff --git a/openstackclient/identity/v3/service.py b/openstackclient/identity/v3/service.py
index 85081aa..42117c8 100644
--- a/openstackclient/identity/v3/service.py
+++ b/openstackclient/identity/v3/service.py
@@ -15,22 +15,16 @@
"""Identity v3 Service action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
from openstackclient.identity import common
-class CreateService(show.ShowOne):
+class CreateService(command.ShowOne):
"""Create new service"""
- log = logging.getLogger(__name__ + '.CreateService')
-
def get_parser(self, prog_name):
parser = super(CreateService, self).get_parser(prog_name)
parser.add_argument(
@@ -61,7 +55,6 @@ class CreateService(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -83,8 +76,6 @@ class CreateService(show.ShowOne):
class DeleteService(command.Command):
"""Delete service"""
- log = logging.getLogger(__name__ + '.DeleteService')
-
def get_parser(self, prog_name):
parser = super(DeleteService, self).get_parser(prog_name)
parser.add_argument(
@@ -94,7 +85,6 @@ class DeleteService(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -104,11 +94,9 @@ class DeleteService(command.Command):
return
-class ListService(lister.Lister):
+class ListService(command.Lister):
"""List services"""
- log = logging.getLogger(__name__ + '.ListService')
-
def get_parser(self, prog_name):
parser = super(ListService, self).get_parser(prog_name)
parser.add_argument(
@@ -119,7 +107,6 @@ class ListService(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
if parsed_args.long:
@@ -136,8 +123,6 @@ class ListService(lister.Lister):
class SetService(command.Command):
"""Set service properties"""
- log = logging.getLogger(__name__ + '.SetService')
-
def get_parser(self, prog_name):
parser = super(SetService, self).get_parser(prog_name)
parser.add_argument(
@@ -173,7 +158,6 @@ class SetService(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -205,11 +189,9 @@ class SetService(command.Command):
return
-class ShowService(show.ShowOne):
+class ShowService(command.ShowOne):
"""Display service details"""
- log = logging.getLogger(__name__ + '.ShowService')
-
def get_parser(self, prog_name):
parser = super(ShowService, self).get_parser(prog_name)
parser.add_argument(
@@ -219,7 +201,6 @@ class ShowService(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
diff --git a/openstackclient/identity/v3/service_provider.py b/openstackclient/identity/v3/service_provider.py
index 838ad4a..6016928 100644
--- a/openstackclient/identity/v3/service_provider.py
+++ b/openstackclient/identity/v3/service_provider.py
@@ -13,22 +13,16 @@
"""Service Provider action implementations"""
-import logging
import six
import sys
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
-class CreateServiceProvider(show.ShowOne):
+class CreateServiceProvider(command.ShowOne):
"""Create new service provider"""
- log = logging.getLogger(__name__ + '.CreateServiceProvider')
-
def get_parser(self, prog_name):
parser = super(CreateServiceProvider, self).get_parser(prog_name)
parser.add_argument(
@@ -73,7 +67,6 @@ class CreateServiceProvider(show.ShowOne):
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
service_client = self.app.client_manager.identity
sp = service_client.federation.service_providers.create(
@@ -90,8 +83,6 @@ class CreateServiceProvider(show.ShowOne):
class DeleteServiceProvider(command.Command):
"""Delete service provider"""
- log = logging.getLogger(__name__ + '.DeleteServiceProvider')
-
def get_parser(self, prog_name):
parser = super(DeleteServiceProvider, self).get_parser(prog_name)
parser.add_argument(
@@ -101,7 +92,6 @@ class DeleteServiceProvider(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
service_client = self.app.client_manager.identity
service_client.federation.service_providers.delete(
@@ -109,12 +99,9 @@ class DeleteServiceProvider(command.Command):
return
-class ListServiceProvider(lister.Lister):
+class ListServiceProvider(command.Lister):
"""List service providers"""
- log = logging.getLogger(__name__ + '.ListServiceProvider')
-
- @utils.log_method(log)
def take_action(self, parsed_args):
service_client = self.app.client_manager.identity
data = service_client.federation.service_providers.list()
@@ -130,8 +117,6 @@ class ListServiceProvider(lister.Lister):
class SetServiceProvider(command.Command):
"""Set service provider properties"""
- log = logging.getLogger(__name__ + '.SetServiceProvider')
-
def get_parser(self, prog_name):
parser = super(SetServiceProvider, self).get_parser(prog_name)
parser.add_argument(
@@ -168,7 +153,6 @@ class SetServiceProvider(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
federation_client = self.app.client_manager.identity.federation
@@ -193,11 +177,9 @@ class SetServiceProvider(command.Command):
return zip(*sorted(six.iteritems(service_provider._info)))
-class ShowServiceProvider(show.ShowOne):
+class ShowServiceProvider(command.ShowOne):
"""Display service provider details"""
- log = logging.getLogger(__name__ + '.ShowServiceProvider')
-
def get_parser(self, prog_name):
parser = super(ShowServiceProvider, self).get_parser(prog_name)
parser.add_argument(
@@ -207,7 +189,6 @@ class ShowServiceProvider(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
service_client = self.app.client_manager.identity
service_provider = utils.find_resource(
diff --git a/openstackclient/identity/v3/token.py b/openstackclient/identity/v3/token.py
index cd3dc79..588c521 100644
--- a/openstackclient/identity/v3/token.py
+++ b/openstackclient/identity/v3/token.py
@@ -15,20 +15,16 @@
"""Identity v3 Token action implementations"""
-import logging
import six
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
from openstackclient.identity import common
-class AuthorizeRequestToken(show.ShowOne):
+class AuthorizeRequestToken(command.ShowOne):
"""Authorize a request token"""
- log = logging.getLogger(__name__ + '.AuthorizeRequestToken')
-
def get_parser(self, prog_name):
parser = super(AuthorizeRequestToken, self).get_parser(prog_name)
parser.add_argument(
@@ -49,7 +45,6 @@ class AuthorizeRequestToken(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
identity_client = self.app.client_manager.identity
# NOTE(stevemar): We want a list of role ids
@@ -68,11 +63,9 @@ class AuthorizeRequestToken(show.ShowOne):
return zip(*sorted(six.iteritems(verifier_pin._info)))
-class CreateAccessToken(show.ShowOne):
+class CreateAccessToken(command.ShowOne):
"""Create an access token"""
- log = logging.getLogger(__name__ + '.CreateAccessToken')
-
def get_parser(self, prog_name):
parser = super(CreateAccessToken, self).get_parser(prog_name)
parser.add_argument(
@@ -108,7 +101,6 @@ class CreateAccessToken(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
token_client = self.app.client_manager.identity.oauth1.access_tokens
access_token = token_client.create(
parsed_args.consumer_key, parsed_args.consumer_secret,
@@ -117,11 +109,9 @@ class CreateAccessToken(show.ShowOne):
return zip(*sorted(six.iteritems(access_token._info)))
-class CreateRequestToken(show.ShowOne):
+class CreateRequestToken(command.ShowOne):
"""Create a request token"""
- log = logging.getLogger(__name__ + '.CreateRequestToken')
-
def get_parser(self, prog_name):
parser = super(CreateRequestToken, self).get_parser(prog_name)
parser.add_argument(
@@ -151,8 +141,6 @@ class CreateRequestToken(show.ShowOne):
return parser
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:
@@ -173,16 +161,13 @@ class CreateRequestToken(show.ShowOne):
return zip(*sorted(six.iteritems(request_token._info)))
-class IssueToken(show.ShowOne):
+class IssueToken(command.ShowOne):
"""Issue new token"""
- log = logging.getLogger(__name__ + '.IssueToken')
-
def get_parser(self, prog_name):
parser = super(IssueToken, self).get_parser(prog_name)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
token = self.app.client_manager.auth_ref.service_catalog.get_token()
if 'tenant_id' in token:
diff --git a/openstackclient/identity/v3/trust.py b/openstackclient/identity/v3/trust.py
index 2c3cf53..26fb833 100644
--- a/openstackclient/identity/v3/trust.py
+++ b/openstackclient/identity/v3/trust.py
@@ -14,22 +14,16 @@
"""Identity v3 Trust action implementations"""
import datetime
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
from openstackclient.identity import common
-class CreateTrust(show.ShowOne):
+class CreateTrust(command.ShowOne):
"""Create new trust"""
- log = logging.getLogger(__name__ + '.CreateTrust')
-
def get_parser(self, prog_name):
parser = super(CreateTrust, self).get_parser(prog_name)
parser.add_argument(
@@ -85,7 +79,6 @@ class CreateTrust(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
identity_client = self.app.client_manager.identity
# NOTE(stevemar): Find the two users, project and roles that
@@ -138,8 +131,6 @@ class CreateTrust(show.ShowOne):
class DeleteTrust(command.Command):
"""Delete trust(s)"""
- log = logging.getLogger(__name__ + '.DeleteTrust')
-
def get_parser(self, prog_name):
parser = super(DeleteTrust, self).get_parser(prog_name)
parser.add_argument(
@@ -151,20 +142,16 @@ class DeleteTrust(command.Command):
return parser
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
identity_client = self.app.client_manager.identity
for t in parsed_args.trust:
trust_obj = utils.find_resource(identity_client.trusts, t)
identity_client.trusts.delete(trust_obj.id)
-class ListTrust(lister.Lister):
+class ListTrust(command.Lister):
"""List trusts"""
- log = logging.getLogger(__name__ + '.ListTrust')
-
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
columns = ('ID', 'Expires At', 'Impersonation', 'Project ID',
'Trustee User ID', 'Trustor User ID')
data = self.app.client_manager.identity.trusts.list()
@@ -175,11 +162,9 @@ class ListTrust(lister.Lister):
) for s in data))
-class ShowTrust(show.ShowOne):
+class ShowTrust(command.ShowOne):
"""Display trust details"""
- log = logging.getLogger(__name__ + '.ShowTrust')
-
def get_parser(self, prog_name):
parser = super(ShowTrust, self).get_parser(prog_name)
parser.add_argument(
@@ -190,7 +175,6 @@ class ShowTrust(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
identity_client = self.app.client_manager.identity
trust = utils.find_resource(identity_client.trusts,
parsed_args.trust)
diff --git a/openstackclient/identity/v3/unscoped_saml.py b/openstackclient/identity/v3/unscoped_saml.py
index e659e75..a42637d 100644
--- a/openstackclient/identity/v3/unscoped_saml.py
+++ b/openstackclient/identity/v3/unscoped_saml.py
@@ -17,10 +17,7 @@ The first step of federated auth is to fetch an unscoped token. From there,
the user can list domains and projects they are allowed to access, and request
a scoped token."""
-import logging
-
-from cliff import lister
-
+from openstackclient.common import command
from openstackclient.common import exceptions
from openstackclient.common import utils
@@ -43,13 +40,10 @@ def auth_with_unscoped_saml(func):
return _decorated
-class ListAccessibleDomains(lister.Lister):
+class ListAccessibleDomains(command.Lister):
"""List accessible domains"""
- log = logging.getLogger(__name__ + '.ListAccessibleDomains')
-
@auth_with_unscoped_saml
- @utils.log_method(log)
def take_action(self, parsed_args):
columns = ('ID', 'Enabled', 'Name', 'Description')
identity_client = self.app.client_manager.identity
@@ -61,13 +55,10 @@ class ListAccessibleDomains(lister.Lister):
) for s in data))
-class ListAccessibleProjects(lister.Lister):
+class ListAccessibleProjects(command.Lister):
"""List accessible projects"""
- log = logging.getLogger(__name__ + '.ListAccessibleProjects')
-
@auth_with_unscoped_saml
- @utils.log_method(log)
def take_action(self, parsed_args):
columns = ('ID', 'Domain ID', 'Enabled', 'Name')
identity_client = self.app.client_manager.identity
diff --git a/openstackclient/identity/v3/user.py b/openstackclient/identity/v3/user.py
index eaef8f0..c694c6a 100644
--- a/openstackclient/identity/v3/user.py
+++ b/openstackclient/identity/v3/user.py
@@ -16,24 +16,19 @@
"""Identity v3 User action implementations"""
import copy
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
from keystoneauth1 import exceptions as ks_exc
+from openstackclient.common import command
from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
from openstackclient.identity import common
-class CreateUser(show.ShowOne):
+class CreateUser(command.ShowOne):
"""Create new user"""
- log = logging.getLogger(__name__ + '.CreateUser')
-
def get_parser(self, prog_name):
parser = super(CreateUser, self).get_parser(prog_name)
parser.add_argument(
@@ -91,7 +86,6 @@ class CreateUser(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -138,8 +132,6 @@ class CreateUser(show.ShowOne):
class DeleteUser(command.Command):
"""Delete user(s)"""
- log = logging.getLogger(__name__ + '.DeleteUser')
-
def get_parser(self, prog_name):
parser = super(DeleteUser, self).get_parser(prog_name)
parser.add_argument(
@@ -155,7 +147,6 @@ class DeleteUser(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -174,11 +165,9 @@ class DeleteUser(command.Command):
return
-class ListUser(lister.Lister):
+class ListUser(command.Lister):
"""List users"""
- log = logging.getLogger(__name__ + '.ListUser')
-
def get_parser(self, prog_name):
parser = super(ListUser, self).get_parser(prog_name)
parser.add_argument(
@@ -205,7 +194,6 @@ class ListUser(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -280,8 +268,6 @@ class ListUser(lister.Lister):
class SetUser(command.Command):
"""Set user properties"""
- log = logging.getLogger(__name__ + '.SetUser')
-
def get_parser(self, prog_name):
parser = super(SetUser, self).get_parser(prog_name)
parser.add_argument(
@@ -334,7 +320,6 @@ class SetUser(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -383,8 +368,6 @@ class SetUser(command.Command):
class SetPasswordUser(command.Command):
"""Change current user password"""
- log = logging.getLogger(__name__ + '.SetPasswordUser')
-
def get_parser(self, prog_name):
parser = super(SetPasswordUser, self).get_parser(prog_name)
parser.add_argument(
@@ -392,14 +375,40 @@ class SetPasswordUser(command.Command):
metavar='<new-password>',
help='New user password'
)
+ parser.add_argument(
+ '--original-password',
+ metavar='<original-password>',
+ help='Original user password'
+ )
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
- current_password = utils.get_password(
- self.app.stdin, prompt="Current Password:", confirm=False)
+ # FIXME(gyee): there are two scenarios:
+ #
+ # 1. user update password for himself
+ # 2. admin update password on behalf of the user. This is an unlikely
+ # scenario because that will require admin knowing the user's
+ # original password which is forbidden under most security
+ # policies.
+ #
+ # Of the two scenarios above, user either authenticate using its
+ # original password or an authentication token. For scenario #1,
+ # if user is authenticating with its original password (i.e. passing
+ # --os-password argument), we can just make use of it instead of using
+ # --original-password or prompting. For scenario #2, admin will need
+ # to specify --original-password option or this won't work because
+ # --os-password is the admin's own password. In the future if we stop
+ # supporting scenario #2 then we can just do this.
+ #
+ # current_password = (parsed_args.original_password or
+ # self.app.cloud.password)
+ #
+ current_password = parsed_args.original_password
+ if current_password is None:
+ current_password = utils.get_password(
+ self.app.stdin, prompt="Current Password:", confirm=False)
password = parsed_args.password
if password is None:
@@ -409,11 +418,9 @@ class SetPasswordUser(command.Command):
identity_client.users.update_password(current_password, password)
-class ShowUser(show.ShowOne):
+class ShowUser(command.ShowOne):
"""Display user details"""
- log = logging.getLogger(__name__ + '.ShowUser')
-
def get_parser(self, prog_name):
parser = super(ShowUser, self).get_parser(prog_name)
parser.add_argument(
@@ -428,7 +435,6 @@ class ShowUser(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
diff --git a/openstackclient/image/v1/image.py b/openstackclient/image/v1/image.py
index 4ebc8f9..9cc5fac 100644
--- a/openstackclient/image/v1/image.py
+++ b/openstackclient/image/v1/image.py
@@ -17,7 +17,6 @@
import argparse
import io
-import logging
import os
import six
import sys
@@ -27,14 +26,12 @@ if os.name == "nt":
else:
msvcrt = None
-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 command
from openstackclient.common import parseractions
from openstackclient.common import utils
+from openstackclient.i18n import _ # noqa
DEFAULT_CONTAINER_FORMAT = 'bare'
@@ -56,11 +53,9 @@ def _format_visibility(data):
return 'private'
-class CreateImage(show.ShowOne):
+class CreateImage(command.ShowOne):
"""Create/upload an image"""
- log = logging.getLogger(__name__ + ".CreateImage")
-
def get_parser(self, prog_name):
parser = super(CreateImage, self).get_parser(prog_name)
parser.add_argument(
@@ -93,11 +88,6 @@ class CreateImage(show.ShowOne):
"(default: %s)" % DEFAULT_DISK_FORMAT,
)
parser.add_argument(
- "--owner",
- metavar="<project>",
- help="Image owner project name or ID",
- )
- parser.add_argument(
"--size",
metavar="<size>",
help="Image size, in bytes (only used with --location and"
@@ -178,12 +168,31 @@ class CreateImage(show.ShowOne):
help="Set a property on this image "
"(repeat option to set multiple properties)",
)
+ # NOTE(dtroyer): --owner is deprecated in Jan 2016 in an early
+ # 2.x release. Do not remove before Jan 2017
+ # and a 3.x release.
+ project_group = parser.add_mutually_exclusive_group()
+ project_group.add_argument(
+ "--project",
+ metavar="<project>",
+ help="Set an alternate project on this image (name or ID)",
+ )
+ project_group.add_argument(
+ "--owner",
+ metavar="<project>",
+ help=argparse.SUPPRESS,
+ )
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
image_client = self.app.client_manager.image
+ if getattr(parsed_args, 'owner', None) is not None:
+ self.log.warning(_(
+ 'The --owner option is deprecated, '
+ 'please use --project instead.'
+ ))
+
# Build an attribute dict from the parsed args, only include
# attributes that were actually set on the command line
kwargs = {}
@@ -198,6 +207,12 @@ class CreateImage(show.ShowOne):
# Only include a value in kwargs for attributes that are
# actually present on the command line
kwargs[attr] = val
+
+ # Special case project option back to API attribute name 'owner'
+ val = getattr(parsed_args, 'project', None)
+ if val:
+ kwargs['owner'] = val
+
# Handle exclusive booleans with care
# Avoid including attributes in kwargs if an option is not
# present on the command line. These exclusive booleans are not
@@ -261,8 +276,6 @@ class CreateImage(show.ShowOne):
class DeleteImage(command.Command):
"""Delete image(s)"""
- log = logging.getLogger(__name__ + ".DeleteImage")
-
def get_parser(self, prog_name):
parser = super(DeleteImage, self).get_parser(prog_name)
parser.add_argument(
@@ -274,8 +287,6 @@ class DeleteImage(command.Command):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
image_client = self.app.client_manager.image
for image in parsed_args.images:
image_obj = utils.find_resource(
@@ -285,11 +296,9 @@ class DeleteImage(command.Command):
image_client.images.delete(image_obj.id)
-class ListImage(lister.Lister):
+class ListImage(command.Lister):
"""List available images"""
- log = logging.getLogger(__name__ + ".ListImage")
-
def get_parser(self, prog_name):
parser = super(ListImage, self).get_parser(prog_name)
public_group = parser.add_mutually_exclusive_group()
@@ -345,8 +354,6 @@ class ListImage(lister.Lister):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
image_client = self.app.client_manager.image
kwargs = {}
@@ -383,7 +390,7 @@ class ListImage(lister.Lister):
'Status',
'Visibility',
'Protected',
- 'Owner',
+ 'Project',
'Properties',
)
else:
@@ -430,8 +437,6 @@ class ListImage(lister.Lister):
class SaveImage(command.Command):
"""Save an image locally"""
- log = logging.getLogger(__name__ + ".SaveImage")
-
def get_parser(self, prog_name):
parser = super(SaveImage, self).get_parser(prog_name)
parser.add_argument(
@@ -447,8 +452,6 @@ class SaveImage(command.Command):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
image_client = self.app.client_manager.image
image = utils.find_resource(
image_client.images,
@@ -462,8 +465,6 @@ class SaveImage(command.Command):
class SetImage(command.Command):
"""Set image properties"""
- log = logging.getLogger(__name__ + ".SetImage")
-
def get_parser(self, prog_name):
parser = super(SetImage, self).get_parser(prog_name)
parser.add_argument(
@@ -477,11 +478,6 @@ class SetImage(command.Command):
help="New image name",
)
parser.add_argument(
- "--owner",
- metavar="<project>",
- help="New image owner project (name or ID)",
- )
- parser.add_argument(
"--min-disk",
metavar="<disk-gb>",
type=int,
@@ -590,12 +586,31 @@ class SetImage(command.Command):
metavar="<checksum>",
help="Image hash used for verification",
)
+ # NOTE(dtroyer): --owner is deprecated in Jan 2016 in an early
+ # 2.x release. Do not remove before Jan 2017
+ # and a 3.x release.
+ project_group = parser.add_mutually_exclusive_group()
+ project_group.add_argument(
+ "--project",
+ metavar="<project>",
+ help="Set an alternate project on this image (name or ID)",
+ )
+ project_group.add_argument(
+ "--owner",
+ metavar="<project>",
+ help=argparse.SUPPRESS,
+ )
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
image_client = self.app.client_manager.image
+ if getattr(parsed_args, 'owner', None) is not None:
+ self.log.warning(_(
+ 'The --owner option is deprecated, '
+ 'please use --project instead.'
+ ))
+
kwargs = {}
copy_attrs = ('name', 'owner', 'min_disk', 'min_ram', 'properties',
'container_format', 'disk_format', 'size', 'store',
@@ -607,6 +622,12 @@ class SetImage(command.Command):
# Only include a value in kwargs for attributes that are
# actually present on the command line
kwargs[attr] = val
+
+ # Special case project option back to API attribute name 'owner'
+ val = getattr(parsed_args, 'project', None)
+ if val:
+ kwargs['owner'] = val
+
# Handle exclusive booleans with care
# Avoid including attributes in kwargs if an option is not
# present on the command line. These exclusive booleans are not
@@ -679,14 +700,10 @@ class SetImage(command.Command):
kwargs['data'] != sys.stdin):
kwargs['data'].close()
- return
-
-class ShowImage(show.ShowOne):
+class ShowImage(command.ShowOne):
"""Display image details"""
- log = logging.getLogger(__name__ + ".ShowImage")
-
def get_parser(self, prog_name):
parser = super(ShowImage, self).get_parser(prog_name)
parser.add_argument(
@@ -697,8 +714,6 @@ class ShowImage(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
image_client = self.app.client_manager.image
image = utils.find_resource(
image_client.images,
diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py
index c0fb5b5..3f16218 100644
--- a/openstackclient/image/v2/image.py
+++ b/openstackclient/image/v2/image.py
@@ -16,18 +16,16 @@
"""Image V2 Action Implementations"""
import argparse
-import logging
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 command
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
@@ -66,11 +64,9 @@ def _format_image(image):
return info
-class AddProjectToImage(show.ShowOne):
+class AddProjectToImage(command.ShowOne):
"""Associate project with image"""
- log = logging.getLogger(__name__ + ".AddProjectToImage")
-
def get_parser(self, prog_name):
parser = super(AddProjectToImage, self).get_parser(prog_name)
parser.add_argument(
@@ -87,8 +83,6 @@ class AddProjectToImage(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
image_client = self.app.client_manager.image
identity_client = self.app.client_manager.identity
@@ -108,15 +102,13 @@ class AddProjectToImage(show.ShowOne):
return zip(*sorted(six.iteritems(image_member)))
-class CreateImage(show.ShowOne):
+class CreateImage(command.ShowOne):
"""Create/upload an image"""
- log = logging.getLogger(__name__ + ".CreateImage")
deadopts = ('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?
@@ -149,11 +141,6 @@ class CreateImage(show.ShowOne):
"(default: %s)" % DEFAULT_DISK_FORMAT,
)
parser.add_argument(
- "--owner",
- metavar="<owner>",
- help="Image owner project name or ID",
- )
- parser.add_argument(
"--min-disk",
metavar="<disk-gb>",
type=int,
@@ -170,6 +157,19 @@ class CreateImage(show.ShowOne):
metavar="<file>",
help="Upload image from local file",
)
+ parser.add_argument(
+ "--volume",
+ metavar="<volume>",
+ help="Create image from a volume",
+ )
+ parser.add_argument(
+ "--force",
+ dest='force',
+ action='store_true',
+ default=False,
+ help="Force image creation if volume is in use "
+ "(only meaningful with --volume)",
+ )
protected_group = parser.add_mutually_exclusive_group()
protected_group.add_argument(
"--protected",
@@ -208,6 +208,21 @@ class CreateImage(show.ShowOne):
help="Set a tag on this image "
"(repeat option to set multiple tags)",
)
+ # NOTE(dtroyer): --owner is deprecated in Jan 2016 in an early
+ # 2.x release. Do not remove before Jan 2017
+ # and a 3.x release.
+ project_group = parser.add_mutually_exclusive_group()
+ project_group.add_argument(
+ "--project",
+ metavar="<project>",
+ help="Set an alternate project on this image (name or ID)",
+ )
+ project_group.add_argument(
+ "--owner",
+ metavar="<project>",
+ help=argparse.SUPPRESS,
+ )
+ common.add_project_domain_option_to_parser(parser)
for deadopt in self.deadopts:
parser.add_argument(
"--%s" % deadopt,
@@ -218,7 +233,7 @@ class CreateImage(show.ShowOne):
return parser
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
for deadopt in self.deadopts:
@@ -232,8 +247,7 @@ class CreateImage(show.ShowOne):
kwargs = {}
copy_attrs = ('name', 'id',
'container_format', 'disk_format',
- 'min_disk', 'min_ram',
- 'tags', 'owner')
+ 'min_disk', 'min_ram', 'tags')
for attr in copy_attrs:
if attr in parsed_args:
val = getattr(parsed_args, attr, None)
@@ -241,10 +255,12 @@ class CreateImage(show.ShowOne):
# Only include a value in kwargs for attributes that
# are actually present on the command line
kwargs[attr] = val
+
# properties should get flattened into the general kwargs
if getattr(parsed_args, 'properties', None):
for k, v in six.iteritems(parsed_args.properties):
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
@@ -260,15 +276,58 @@ class CreateImage(show.ShowOne):
if parsed_args.private:
kwargs['visibility'] = 'private'
+ # Handle deprecated --owner option
+ project_arg = parsed_args.project
+ if parsed_args.owner:
+ project_arg = parsed_args.owner
+ self.log.warning(_(
+ 'The --owner option is deprecated, '
+ 'please use --project instead.'
+ ))
+ if project_arg:
+ kwargs['owner'] = common.find_project(
+ identity_client,
+ project_arg,
+ parsed_args.project_domain,
+ ).id
+
# open the file first to ensure any failures are handled before the
# image is created
fp = gc_utils.get_data_file(parsed_args)
+ info = {}
+ if fp is not None and parsed_args.volume:
+ raise exceptions.CommandError("Uploading data and using container "
+ "are not allowed at the same time")
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 parsed_args.owner:
+ kwargs['owner'] = common.find_project(
+ identity_client,
+ parsed_args.owner,
+ parsed_args.project_domain,
+ ).id
+
+ # If a volume is specified.
+ if parsed_args.volume:
+ volume_client = self.app.client_manager.volume
+ source_volume = utils.find_resource(
+ volume_client.volumes,
+ parsed_args.volume,
+ )
+ response, body = volume_client.volumes.upload_to_image(
+ source_volume.id,
+ parsed_args.force,
+ parsed_args.name,
+ parsed_args.container_format,
+ parsed_args.disk_format,
+ )
+ info = body['os-volume_upload_image']
+ info['volume_type'] = info['volume_type']['name']
+ else:
+ image = image_client.images.create(**kwargs)
if fp is not None:
with fp:
@@ -289,15 +348,15 @@ class CreateImage(show.ShowOne):
# update the image after the data has been uploaded
image = image_client.images.get(image.id)
- info = _format_image(image)
+ if not info:
+ info = _format_image(image)
+
return zip(*sorted(six.iteritems(info)))
class DeleteImage(command.Command):
"""Delete image(s)"""
- log = logging.getLogger(__name__ + ".DeleteImage")
-
def get_parser(self, prog_name):
parser = super(DeleteImage, self).get_parser(prog_name)
parser.add_argument(
@@ -309,8 +368,6 @@ class DeleteImage(command.Command):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
image_client = self.app.client_manager.image
for image in parsed_args.images:
image_obj = utils.find_resource(
@@ -320,11 +377,9 @@ class DeleteImage(command.Command):
image_client.images.delete(image_obj.id)
-class ListImage(lister.Lister):
+class ListImage(command.Lister):
"""List available images"""
- log = logging.getLogger(__name__ + ".ListImage")
-
def get_parser(self, prog_name):
parser = super(ListImage, self).get_parser(prog_name)
public_group = parser.add_mutually_exclusive_group()
@@ -376,11 +431,23 @@ class ListImage(lister.Lister):
"(default: asc), multiple keys and directions can be "
"specified separated by comma",
)
+ parser.add_argument(
+ "--limit",
+ metavar="<limit>",
+ type=int,
+ help="Maximum number of images to display.",
+ )
+ parser.add_argument(
+ '--marker',
+ metavar='<marker>',
+ default=None,
+ help="The last image (name or ID) of the previous page. Display "
+ "list of images after marker. Display all images if not "
+ "specified."
+ )
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
image_client = self.app.client_manager.image
kwargs = {}
@@ -390,6 +457,11 @@ class ListImage(lister.Lister):
kwargs['private'] = True
if parsed_args.shared:
kwargs['shared'] = True
+ if parsed_args.limit:
+ kwargs['limit'] = parsed_args.limit
+ if parsed_args.marker:
+ kwargs['marker'] = utils.find_resource(image_client.images,
+ parsed_args.marker).id
if parsed_args.long:
columns = (
@@ -413,7 +485,7 @@ class ListImage(lister.Lister):
'Status',
'Visibility',
'Protected',
- 'Owner',
+ 'Project',
'Tags',
)
else:
@@ -421,16 +493,7 @@ class ListImage(lister.Lister):
column_headers = columns
# List of image data received
- data = []
- # No pages received yet, so start the page marker at None.
- marker = None
- while True:
- page = image_client.api.image_list(marker=marker, **kwargs)
- if not page:
- break
- data.extend(page)
- # Set the marker to the id of the last item we received
- marker = page[-1]['id']
+ data = image_client.api.image_list(**kwargs)
if parsed_args.property:
# NOTE(dtroyer): coerce to a list to subscript it in py3
@@ -459,8 +522,6 @@ class ListImage(lister.Lister):
class RemoveProjectImage(command.Command):
"""Disassociate project with image"""
- log = logging.getLogger(__name__ + ".RemoveProjectImage")
-
def get_parser(self, prog_name):
parser = super(RemoveProjectImage, self).get_parser(prog_name)
parser.add_argument(
@@ -477,8 +538,6 @@ class RemoveProjectImage(command.Command):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
image_client = self.app.client_manager.image
identity_client = self.app.client_manager.identity
@@ -496,8 +555,6 @@ class RemoveProjectImage(command.Command):
class SaveImage(command.Command):
"""Save an image locally"""
- log = logging.getLogger(__name__ + ".SaveImage")
-
def get_parser(self, prog_name):
parser = super(SaveImage, self).get_parser(prog_name)
parser.add_argument(
@@ -513,8 +570,6 @@ class SaveImage(command.Command):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
image_client = self.app.client_manager.image
image = utils.find_resource(
image_client.images,
@@ -528,7 +583,6 @@ class SaveImage(command.Command):
class SetImage(command.Command):
"""Set image properties"""
- log = logging.getLogger(__name__ + ".SetImage")
deadopts = ('visibility',)
def get_parser(self, prog_name):
@@ -539,8 +593,8 @@ class SetImage(command.Command):
# --location - maybe location add?
# --copy-from - does not exist in v2
# --file - should be able to upload file
- # --volume - needs adding
- # --force - needs adding
+ # --volume - not possible with v2 as can't change id
+ # --force - see `--volume`
# --checksum - maybe could be done client side
# --stdin - could be implemented
parser.add_argument(
@@ -554,11 +608,6 @@ class SetImage(command.Command):
help="New image name"
)
parser.add_argument(
- "--owner",
- metavar="<project>",
- help="New image owner project (name or ID)",
- )
- parser.add_argument(
"--min-disk",
type=int,
metavar="<disk-gb>",
@@ -657,6 +706,32 @@ class SetImage(command.Command):
metavar="<ramdisk-id>",
help="ID of ramdisk image used to boot this disk image",
)
+ deactivate_group = parser.add_mutually_exclusive_group()
+ deactivate_group.add_argument(
+ "--deactivate",
+ action="store_true",
+ help="Deactivate the image",
+ )
+ deactivate_group.add_argument(
+ "--activate",
+ action="store_true",
+ help="Activate the image",
+ )
+ # NOTE(dtroyer): --owner is deprecated in Jan 2016 in an early
+ # 2.x release. Do not remove before Jan 2017
+ # and a 3.x release.
+ project_group = parser.add_mutually_exclusive_group()
+ project_group.add_argument(
+ "--project",
+ metavar="<project>",
+ help="Set an alternate project on this image (name or ID)",
+ )
+ project_group.add_argument(
+ "--owner",
+ metavar="<project>",
+ help=argparse.SUPPRESS,
+ )
+ common.add_project_domain_option_to_parser(parser)
for deadopt in self.deadopts:
parser.add_argument(
"--%s" % deadopt,
@@ -667,7 +742,7 @@ class SetImage(command.Command):
return parser
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
for deadopt in self.deadopts:
@@ -680,7 +755,7 @@ class SetImage(command.Command):
copy_attrs = ('architecture', 'container_format', 'disk_format',
'file', 'instance_id', 'kernel_id', 'locations',
'min_disk', 'min_ram', 'name', 'os_distro', 'os_version',
- 'owner', 'prefix', 'progress', 'ramdisk_id', 'tags')
+ 'prefix', 'progress', 'ramdisk_id', 'tags')
for attr in copy_attrs:
if attr in parsed_args:
val = getattr(parsed_args, attr, None)
@@ -709,25 +784,56 @@ class SetImage(command.Command):
if parsed_args.private:
kwargs['visibility'] = 'private'
- if not kwargs:
+ # Handle deprecated --owner option
+ project_arg = parsed_args.project
+ if parsed_args.owner:
+ project_arg = parsed_args.owner
+ self.log.warning(_(
+ 'The --owner option is deprecated, '
+ 'please use --project instead.'
+ ))
+ if project_arg:
+ kwargs['owner'] = common.find_project(
+ identity_client,
+ project_arg,
+ parsed_args.project_domain,
+ ).id
+
+ # Checks if anything that requires getting the image
+ if not (kwargs or parsed_args.deactivate or parsed_args.activate):
self.log.warning("No arguments specified")
return {}, {}
image = utils.find_resource(
image_client.images, parsed_args.image)
+ activation_status = None
+ if parsed_args.deactivate:
+ image_client.images.deactivate(image.id)
+ activation_status = "deactivated"
+ if parsed_args.activate:
+ image_client.images.reactivate(image.id)
+ activation_status = "activated"
+
+ # Check if need to do the actual update
+ if not kwargs:
+ return {}, {}
+
if parsed_args.tags:
# Tags should be extended, but duplicates removed
kwargs['tags'] = list(set(image.tags).union(set(parsed_args.tags)))
- image = image_client.images.update(image.id, **kwargs)
+ try:
+ image = image_client.images.update(image.id, **kwargs)
+ except Exception as e:
+ if activation_status is not None:
+ print("Image %s was %s." % (image.id, activation_status))
+ raise e
-class ShowImage(show.ShowOne):
+class ShowImage(command.ShowOne):
"""Display image details"""
- log = logging.getLogger(__name__ + ".ShowImage")
-
def get_parser(self, prog_name):
parser = super(ShowImage, self).get_parser(prog_name)
parser.add_argument(
@@ -738,8 +844,6 @@ class ShowImage(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
image_client = self.app.client_manager.image
image = utils.find_resource(
image_client.images,
diff --git a/python-openstackclient/locale/de/LC_MESSAGES/python-openstackclient.po b/openstackclient/locale/de/LC_MESSAGES/openstackclient.po
index 983abdb..1c94b9d 100644
--- a/python-openstackclient/locale/de/LC_MESSAGES/python-openstackclient.po
+++ b/openstackclient/locale/de/LC_MESSAGES/openstackclient.po
@@ -1,4 +1,4 @@
-# German translations for python-openstackclient.
+# Translations template for python-openstackclient.
# Copyright (C) 2015 ORGANIZATION
# This file is distributed under the same license as the
# python-openstackclient project.
@@ -9,18 +9,19 @@
# OpenStack Infra <zanata@openstack.org>, 2015. #zanata
msgid ""
msgstr ""
-"Project-Id-Version: python-openstackclient 1.8.1.dev15\n"
+"Project-Id-Version: python-openstackclient 2.0.1.dev168\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2015-11-04 06:04+0000\n"
+"POT-Creation-Date: 2016-01-19 02:20+0000\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2015-09-19 07:10+0000\n"
"Last-Translator: Andreas Jaeger <jaegerandi@gmail.com>\n"
"Language: de\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Generated-By: Babel 2.0\n"
+"X-Generator: Zanata 3.7.3\n"
"Language-Team: German\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.1.1\n"
msgid ""
"\n"
@@ -126,15 +127,6 @@ msgstr ""
"Anmeldedaten in Projekt erstellen (Name oder Kennung; Standard: aktuell "
"authentifiziertes Projekt)"
-msgid "Create server from this image"
-msgstr "Server aus diesem Abbild erstellen"
-
-msgid "Create server from this volume"
-msgstr "Server aus diesem Datenträger erstellen"
-
-msgid "Create server with this flavor"
-msgstr "Server mit dieser Variante erstellen"
-
msgid "Credentials access key"
msgstr "Anmeldedaten-Zugriffsschlüssel"
@@ -358,9 +350,6 @@ msgstr ""
"Zu hinzufügende/ändernde Eigenschaft für diesen Server (wiederholen Sie die "
"Option, um mehrere Eigenschaften festzulegen)"
-msgid "Recreate server from this image"
-msgstr "Server aus diesem Abbild neu erstellen"
-
msgid "Region ID to delete"
msgstr "Zu löschende Regionskennung"
@@ -419,15 +408,9 @@ msgstr "Zu entfernende Rolle (Name oder Kennung)"
msgid "Role(s) to delete (name or ID)"
msgstr "Zu löschende Rolle(n) (Name oder Kennung)"
-msgid "Search by flavor"
-msgstr "Nach Variante suchen"
-
msgid "Search by hostname"
msgstr "Nach Hostname suchen"
-msgid "Search by image"
-msgstr "Nach Bild suchen"
-
msgid "Search by server status"
msgstr "Nach Serverstatus suchen"
@@ -437,11 +420,6 @@ msgstr "Nach Benutzer suchen (nur Administrator) (Name oder Kennung)"
msgid "Security group to add (name or ID)"
msgstr "Zu hinzufügende Sicherheitsgruppe (Name oder Kennung)"
-msgid "Security group to assign to this server (repeat for multiple groups)"
-msgstr ""
-"Zu diesem Server zuweisende Sicherheitsgruppe (für mehrere Gruppen "
-"wiederholen)"
-
msgid "Select an availability zone for the server"
msgstr "Wählen Sie eine Verfügbarkeitszone für den Server aus"
@@ -609,11 +587,6 @@ msgstr "Warten Sie, bis die Wiederherstellung abgeschlossen ist"
msgid "Wait for resize to complete"
msgstr "Warten Sie, bis die Größenänderung abgeschlossen ist"
-msgid "can't create server with port specified since neutron not enabled"
-msgstr ""
-"Server mit dem angegebenen Port kann nicht erstellt werden, da Neutron nicht "
-"aktiviert ist"
-
msgid "either net-id or port-id should be specified but not both"
msgstr "entweder net-id oder port-id sollten angegeben sein, aber nicht beide"
diff --git a/python-openstackclient/locale/python-openstackclient.pot b/openstackclient/locale/openstackclient.pot
index cc4f1a1..afc8926 100644
--- a/python-openstackclient/locale/python-openstackclient.pot
+++ b/openstackclient/locale/openstackclient.pot
@@ -1,22 +1,22 @@
# Translations template for python-openstackclient.
-# Copyright (C) 2015 ORGANIZATION
+# Copyright (C) 2016 ORGANIZATION
# This file is distributed under the same license as the
# python-openstackclient project.
-# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
#
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: python-openstackclient 1.8.1.dev15\n"
+"Project-Id-Version: python-openstackclient 2.0.1.dev168\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2015-11-04 06:04+0000\n"
+"POT-Creation-Date: 2016-01-19 06:03+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.1.1\n"
+"Generated-By: Babel 2.2.0\n"
#: openstackclient/api/auth.py:144
msgid "Set a username with --os-username, OS_USERNAME, or auth.username\n"
@@ -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:718
+#: openstackclient/compute/v2/server.py:737
#: openstackclient/identity/v2_0/endpoint.py:114
#: openstackclient/identity/v2_0/project.py:145
#: openstackclient/identity/v2_0/service.py:128
@@ -56,89 +56,85 @@ msgstr ""
msgid "List additional fields in output"
msgstr ""
-#: 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
+#: openstackclient/compute/v2/server.py:183
+#: openstackclient/compute/v2/server.py:219
+#: openstackclient/compute/v2/server.py:569
+#: openstackclient/compute/v2/server.py:923
+#: openstackclient/compute/v2/server.py:1031
+#: openstackclient/compute/v2/server.py:1086
+#: openstackclient/compute/v2/server.py:1179
+#: openstackclient/compute/v2/server.py:1219
+#: openstackclient/compute/v2/server.py:1245
+#: openstackclient/compute/v2/server.py:1336
+#: openstackclient/compute/v2/server.py:1420
+#: openstackclient/compute/v2/server.py:1457
+#: openstackclient/compute/v2/server.py:1732
+#: openstackclient/compute/v2/server.py:1756
msgid "Server (name or ID)"
msgstr ""
-#: openstackclient/compute/v2/server.py:166
+#: openstackclient/compute/v2/server.py:188
msgid "Security group to add (name or ID)"
msgstr ""
-#: openstackclient/compute/v2/server.py:203
+#: openstackclient/compute/v2/server.py:224
msgid "Volume to add (name or ID)"
msgstr ""
-#: openstackclient/compute/v2/server.py:208
+#: openstackclient/compute/v2/server.py:229
msgid "Server internal device name for volume"
msgstr ""
-#: openstackclient/compute/v2/server.py:248
-#: openstackclient/compute/v2/server.py:1258
+#: openstackclient/compute/v2/server.py:265
+#: openstackclient/compute/v2/server.py:1341
msgid "New server name"
msgstr ""
-#: openstackclient/compute/v2/server.py:256
-msgid "Create server from this image"
+#: openstackclient/compute/v2/server.py:273
+msgid "Create server from this image (name or ID)"
msgstr ""
-#: openstackclient/compute/v2/server.py:261
-msgid "Create server from this volume"
+#: openstackclient/compute/v2/server.py:278
+msgid "Create server from this volume (name or ID)"
msgstr ""
-#: openstackclient/compute/v2/server.py:267
-msgid "Create server with this flavor"
+#: openstackclient/compute/v2/server.py:284
+msgid "Create server with this flavor (name or ID)"
msgstr ""
-#: openstackclient/compute/v2/server.py:274
-msgid "Security group to assign to this server (repeat for multiple groups)"
+#: openstackclient/compute/v2/server.py:291
+msgid ""
+"Security group to assign to this server (name or ID) (repeat for multiple"
+" groups)"
msgstr ""
-#: openstackclient/compute/v2/server.py:280
+#: openstackclient/compute/v2/server.py:297
msgid "Keypair to inject into this server (optional extension)"
msgstr ""
-#: openstackclient/compute/v2/server.py:286
+#: openstackclient/compute/v2/server.py:303
msgid "Set a property on this server (repeat for multiple values)"
msgstr ""
-#: openstackclient/compute/v2/server.py:294
+#: openstackclient/compute/v2/server.py:311
msgid "File to inject into image before boot (repeat for multiple files)"
msgstr ""
-#: openstackclient/compute/v2/server.py:300
+#: openstackclient/compute/v2/server.py:317
msgid "User data file to serve from the metadata server"
msgstr ""
-#: openstackclient/compute/v2/server.py:305
+#: openstackclient/compute/v2/server.py:322
msgid "Select an availability zone for the server"
msgstr ""
-#: openstackclient/compute/v2/server.py:312
+#: openstackclient/compute/v2/server.py:329
msgid ""
"Map block devices; map is <id>:<type>:<size(GB)>:<delete_on_terminate> "
"(optional extension)"
msgstr ""
-#: openstackclient/compute/v2/server.py:322
+#: openstackclient/compute/v2/server.py:339
msgid ""
"Create a NIC on the server. Specify option multiple times to create "
"multiple NICs. Either net-id or port-id must be provided, but not both. "
@@ -147,321 +143,367 @@ msgid ""
"-fixed-ip: IPv6 fixed address for NIC (optional)."
msgstr ""
-#: openstackclient/compute/v2/server.py:335
+#: openstackclient/compute/v2/server.py:352
msgid "Hints for the scheduler (optional extension)"
msgstr ""
-#: openstackclient/compute/v2/server.py:341
+#: openstackclient/compute/v2/server.py:358
msgid ""
"Use specified volume as the config drive, or 'True' to use an ephemeral "
"drive"
msgstr ""
-#: openstackclient/compute/v2/server.py:349
+#: openstackclient/compute/v2/server.py:366
msgid "Minimum number of servers to launch (default=1)"
msgstr ""
-#: openstackclient/compute/v2/server.py:356
+#: openstackclient/compute/v2/server.py:373
msgid "Maximum number of servers to launch (default=1)"
msgstr ""
-#: openstackclient/compute/v2/server.py:361
+#: openstackclient/compute/v2/server.py:378
msgid "Wait for build to complete"
msgstr ""
-#: openstackclient/compute/v2/server.py:401
+#: openstackclient/compute/v2/server.py:418
msgid "min instances should be <= max instances"
msgstr ""
-#: openstackclient/compute/v2/server.py:404
+#: openstackclient/compute/v2/server.py:421
msgid "min instances should be > 0"
msgstr ""
-#: openstackclient/compute/v2/server.py:407
+#: openstackclient/compute/v2/server.py:424
msgid "max instances should be > 0"
msgstr ""
-#: openstackclient/compute/v2/server.py:443
-msgid "either net-id or port-id should be specified but not both"
+#: openstackclient/compute/v2/server.py:453
+msgid "Volume name or ID must be specified if --block-device-mapping is specified"
msgstr ""
#: openstackclient/compute/v2/server.py:465
-msgid "can't create server with port specified since neutron not enabled"
+msgid "either net-id or port-id should be specified but not both"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:485
+msgid "can't create server with port specified since network endpoint not enabled"
msgstr ""
-#: openstackclient/compute/v2/server.py:530
+#: openstackclient/compute/v2/server.py:550
#, python-format
msgid "Error creating server: %s"
msgstr ""
-#: openstackclient/compute/v2/server.py:532
+#: openstackclient/compute/v2/server.py:552
msgid ""
"\n"
"Error creating server"
msgstr ""
-#: openstackclient/compute/v2/server.py:554
+#: openstackclient/compute/v2/server.py:574
msgid "Name of new image (default is server name)"
msgstr ""
-#: openstackclient/compute/v2/server.py:559
+#: openstackclient/compute/v2/server.py:579
msgid "Wait for image create to complete"
msgstr ""
-#: openstackclient/compute/v2/server.py:589
+#: openstackclient/compute/v2/server.py:609
#, python-format
msgid "Error creating server snapshot: %s"
msgstr ""
-#: openstackclient/compute/v2/server.py:591
+#: openstackclient/compute/v2/server.py:611
msgid ""
"\n"
"Error creating server snapshot"
msgstr ""
-#: openstackclient/compute/v2/server.py:613
+#: openstackclient/compute/v2/server.py:633
msgid "Server(s) to delete (name or ID)"
msgstr ""
-#: openstackclient/compute/v2/server.py:618
+#: openstackclient/compute/v2/server.py:638
msgid "Wait for delete to complete"
msgstr ""
-#: openstackclient/compute/v2/server.py:637
+#: openstackclient/compute/v2/server.py:657
#, python-format
msgid "Error deleting server: %s"
msgstr ""
-#: openstackclient/compute/v2/server.py:639
+#: openstackclient/compute/v2/server.py:659
msgid ""
"\n"
"Error deleting server"
msgstr ""
-#: openstackclient/compute/v2/server.py:654
+#: openstackclient/compute/v2/server.py:673
msgid "Only return instances that match the reservation"
msgstr ""
-#: openstackclient/compute/v2/server.py:659
+#: openstackclient/compute/v2/server.py:678
msgid "Regular expression to match IP addresses"
msgstr ""
-#: openstackclient/compute/v2/server.py:664
+#: openstackclient/compute/v2/server.py:683
msgid "Regular expression to match IPv6 addresses"
msgstr ""
-#: openstackclient/compute/v2/server.py:669
+#: openstackclient/compute/v2/server.py:688
msgid "Regular expression to match names"
msgstr ""
-#: openstackclient/compute/v2/server.py:674
+#: openstackclient/compute/v2/server.py:693
msgid "Regular expression to match instance name (admin only)"
msgstr ""
-#: openstackclient/compute/v2/server.py:680
+#: openstackclient/compute/v2/server.py:699
msgid "Search by server status"
msgstr ""
-#: openstackclient/compute/v2/server.py:685
-msgid "Search by flavor"
+#: openstackclient/compute/v2/server.py:704
+msgid "Search by flavor (name or ID)"
msgstr ""
-#: openstackclient/compute/v2/server.py:690
-msgid "Search by image"
+#: openstackclient/compute/v2/server.py:709
+msgid "Search by image (name or ID)"
msgstr ""
-#: openstackclient/compute/v2/server.py:695
+#: openstackclient/compute/v2/server.py:714
msgid "Search by hostname"
msgstr ""
-#: openstackclient/compute/v2/server.py:701
+#: openstackclient/compute/v2/server.py:720
msgid "Include all projects (admin only)"
msgstr ""
-#: openstackclient/compute/v2/server.py:711
+#: openstackclient/compute/v2/server.py:730
msgid "Search by user (admin only) (name or ID)"
msgstr ""
-#: openstackclient/compute/v2/server.py:849
+#: openstackclient/compute/v2/server.py:888
+msgid "Server(s) to lock (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:928
msgid "Target hostname"
msgstr ""
-#: openstackclient/compute/v2/server.py:857
+#: openstackclient/compute/v2/server.py:936
msgid "Perform a shared live migration (default)"
msgstr ""
-#: openstackclient/compute/v2/server.py:863
+#: openstackclient/compute/v2/server.py:942
msgid "Perform a block live migration"
msgstr ""
-#: openstackclient/compute/v2/server.py:870
+#: openstackclient/compute/v2/server.py:949
msgid "Allow disk over-commit on the destination host"
msgstr ""
-#: openstackclient/compute/v2/server.py:877
+#: openstackclient/compute/v2/server.py:956
msgid "Do not over-commit disk on the destination host (default)"
msgstr ""
-#: openstackclient/compute/v2/server.py:883
-#: openstackclient/compute/v2/server.py:1184
+#: openstackclient/compute/v2/server.py:962
+#: openstackclient/compute/v2/server.py:1265
msgid "Wait for resize to complete"
msgstr ""
-#: openstackclient/compute/v2/server.py:911
-#: openstackclient/compute/v2/server.py:1209
+#: openstackclient/compute/v2/server.py:990
+#: openstackclient/compute/v2/server.py:1290
msgid "Complete\n"
msgstr ""
-#: openstackclient/compute/v2/server.py:913
+#: openstackclient/compute/v2/server.py:992
msgid ""
"\n"
"Error migrating server"
msgstr ""
-#: openstackclient/compute/v2/server.py:960
+#: openstackclient/compute/v2/server.py:1007
+msgid "Server(s) to pause (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1040
msgid "Perform a hard reboot"
msgstr ""
-#: openstackclient/compute/v2/server.py:968
+#: openstackclient/compute/v2/server.py:1048
msgid "Perform a soft reboot"
msgstr ""
-#: openstackclient/compute/v2/server.py:973
+#: openstackclient/compute/v2/server.py:1053
msgid "Wait for reboot to complete"
msgstr ""
-#: openstackclient/compute/v2/server.py:990
+#: openstackclient/compute/v2/server.py:1070
msgid ""
"\n"
"Reboot complete\n"
msgstr ""
-#: openstackclient/compute/v2/server.py:992
+#: openstackclient/compute/v2/server.py:1072
msgid ""
"\n"
"Error rebooting server\n"
msgstr ""
-#: openstackclient/compute/v2/server.py:1012
-msgid "Recreate server from this image"
+#: openstackclient/compute/v2/server.py:1091
+msgid ""
+"Recreate server from the specified image (name or ID). Defaults to the "
+"currently used one."
msgstr ""
-#: openstackclient/compute/v2/server.py:1022
+#: openstackclient/compute/v2/server.py:1102
msgid "Wait for rebuild to complete"
msgstr ""
-#: openstackclient/compute/v2/server.py:1043
+#: openstackclient/compute/v2/server.py:1124
msgid ""
"\n"
"Complete\n"
msgstr ""
-#: openstackclient/compute/v2/server.py:1045
+#: openstackclient/compute/v2/server.py:1126
msgid ""
"\n"
"Error rebuilding server"
msgstr ""
-#: openstackclient/compute/v2/server.py:1062
+#: openstackclient/compute/v2/server.py:1143
msgid "Name or ID of server to use"
msgstr ""
-#: openstackclient/compute/v2/server.py:1067
+#: openstackclient/compute/v2/server.py:1148
msgid "Name or ID of security group to remove from server"
msgstr ""
-#: openstackclient/compute/v2/server.py:1103
+#: openstackclient/compute/v2/server.py:1184
msgid "Volume to remove (name or ID)"
msgstr ""
-#: openstackclient/compute/v2/server.py:1169
+#: openstackclient/compute/v2/server.py:1250
msgid "Resize server to specified flavor"
msgstr ""
-#: openstackclient/compute/v2/server.py:1174
+#: openstackclient/compute/v2/server.py:1255
msgid "Confirm server resize is complete"
msgstr ""
-#: openstackclient/compute/v2/server.py:1179
+#: openstackclient/compute/v2/server.py:1260
msgid "Restore server state before resize"
msgstr ""
-#: openstackclient/compute/v2/server.py:1211
+#: openstackclient/compute/v2/server.py:1292
msgid ""
"\n"
"Error resizing server"
msgstr ""
-#: openstackclient/compute/v2/server.py:1263
+#: openstackclient/compute/v2/server.py:1311
+msgid "Server(s) to resume (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1346
msgid "Set new root password (interactive only)"
msgstr ""
-#: openstackclient/compute/v2/server.py:1269
+#: openstackclient/compute/v2/server.py:1352
msgid ""
"Property to add/change for this server (repeat option to set multiple "
"properties)"
msgstr ""
-#: openstackclient/compute/v2/server.py:1293
+#: openstackclient/compute/v2/server.py:1376
msgid "New password: "
msgstr ""
-#: openstackclient/compute/v2/server.py:1294
+#: openstackclient/compute/v2/server.py:1377
msgid "Retype new password: "
msgstr ""
-#: openstackclient/compute/v2/server.py:1298
+#: openstackclient/compute/v2/server.py:1381
msgid "Passwords do not match, password unchanged"
msgstr ""
-#: openstackclient/compute/v2/server.py:1318
+#: openstackclient/compute/v2/server.py:1396
+msgid "Server(s) to shelve (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1426
msgid "Display server diagnostics information"
msgstr ""
-#: openstackclient/compute/v2/server.py:1331
+#: openstackclient/compute/v2/server.py:1439
msgid "Error retrieving diagnostics data"
msgstr ""
-#: openstackclient/compute/v2/server.py:1354
+#: openstackclient/compute/v2/server.py:1462
msgid "Login name (ssh -l option)"
msgstr ""
-#: openstackclient/compute/v2/server.py:1366
+#: openstackclient/compute/v2/server.py:1474
msgid "Destination port (ssh -p option)"
msgstr ""
-#: openstackclient/compute/v2/server.py:1378
+#: openstackclient/compute/v2/server.py:1486
msgid "Private key file (ssh -i option)"
msgstr ""
-#: openstackclient/compute/v2/server.py:1389
+#: openstackclient/compute/v2/server.py:1497
msgid "Options in ssh_config(5) format (ssh -o option)"
msgstr ""
-#: openstackclient/compute/v2/server.py:1403
+#: openstackclient/compute/v2/server.py:1511
msgid "Use only IPv4 addresses"
msgstr ""
-#: openstackclient/compute/v2/server.py:1410
+#: openstackclient/compute/v2/server.py:1518
msgid "Use only IPv6 addresses"
msgstr ""
-#: openstackclient/compute/v2/server.py:1419
+#: openstackclient/compute/v2/server.py:1527
msgid "Use public IP address"
msgstr ""
-#: openstackclient/compute/v2/server.py:1427
+#: openstackclient/compute/v2/server.py:1535
msgid "Use private IP address"
msgstr ""
-#: openstackclient/compute/v2/server.py:1434
+#: openstackclient/compute/v2/server.py:1542
msgid "Use other IP address (public, private, etc)"
msgstr ""
-#: openstackclient/compute/v2/server.py:1599
+#: openstackclient/compute/v2/server.py:1605
+msgid "Server(s) to start (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1630
+msgid "Server(s) to stop (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1655
+msgid "Server(s) to suspend (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1681
+msgid "Server(s) to unlock (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1707
+msgid "Server(s) to unpause (name or ID)"
+msgstr ""
+
+#: openstackclient/compute/v2/server.py:1763
msgid "Property key to remove from server (repeat to unset multiple values)"
msgstr ""
+#: openstackclient/compute/v2/server.py:1794
+msgid "Server(s) to unshelve (name or ID)"
+msgstr ""
+
#: openstackclient/identity/v2_0/catalog.py:75
#: openstackclient/identity/v3/catalog.py:72
msgid "Service to display (type or name)"
@@ -562,6 +604,7 @@ msgid "Project(s) to delete (name or ID)"
msgstr ""
#: openstackclient/identity/v2_0/project.py:173
+#: openstackclient/identity/v2_0/project.py:313
msgid "Project to modify (name or ID)"
msgstr ""
@@ -585,6 +628,10 @@ msgstr ""
msgid "Project to display (name or ID)"
msgstr ""
+#: openstackclient/identity/v2_0/project.py:320
+msgid "Unset a project property (repeat option to unset multiple properties)"
+msgstr ""
+
#: openstackclient/identity/v2_0/role.py:41
msgid "Role to add to <project>:<user> (name or ID)"
msgstr ""
diff --git a/python-openstackclient/locale/zh_TW/LC_MESSAGES/python-openstackclient.po b/openstackclient/locale/zh_TW/LC_MESSAGES/openstackclient.po
index 301912c..2603266 100644
--- a/python-openstackclient/locale/zh_TW/LC_MESSAGES/python-openstackclient.po
+++ b/openstackclient/locale/zh_TW/LC_MESSAGES/openstackclient.po
@@ -1,4 +1,4 @@
-# Chinese (Traditional, Taiwan) translations for python-openstackclient.
+# Translations template for python-openstackclient.
# Copyright (C) 2015 ORGANIZATION
# This file is distributed under the same license as the
# python-openstackclient project.
@@ -7,18 +7,19 @@
# OpenStack Infra <zanata@openstack.org>, 2015. #zanata
msgid ""
msgstr ""
-"Project-Id-Version: python-openstackclient 1.8.1.dev15\n"
+"Project-Id-Version: python-openstackclient 2.0.1.dev168\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2015-11-04 06:04+0000\n"
+"POT-Creation-Date: 2016-01-19 02:20+0000\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2015-06-14 06:41+0000\n"
"Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language: zh_Hant_TW\n"
+"Language: zh-TW\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"Generated-By: Babel 2.0\n"
+"X-Generator: Zanata 3.7.3\n"
"Language-Team: Chinese (Taiwan)\n"
-"Plural-Forms: nplurals=1; plural=0\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.1.1\n"
msgid ""
"\n"
@@ -88,15 +89,6 @@ msgstr "完成\n"
msgid "Confirm server resize is complete"
msgstr "確認調整雲實例容量完成"
-msgid "Create server from this image"
-msgstr "從此映像檔新增雲實例"
-
-msgid "Create server from this volume"
-msgstr "從此雲硬碟新增雲實例"
-
-msgid "Create server with this flavor"
-msgstr "以這個虛擬硬體樣板新增雲實例"
-
msgid "Credentials access key"
msgstr "憑鑰存取密鑰"
@@ -303,9 +295,6 @@ msgid ""
"properties)"
msgstr "要加入這個雲實例的屬性(重復這選項來設定多個屬性)"
-msgid "Recreate server from this image"
-msgstr "從此映像檔重建雲實例"
-
msgid "Region ID to delete"
msgstr "要刪除的地區識別號"
@@ -363,24 +352,15 @@ msgstr "要移除的角色(名稱或識別號)"
msgid "Role(s) to delete (name or ID)"
msgstr "要刪除的角色(名稱或識別號)"
-msgid "Search by flavor"
-msgstr "以虛擬硬體樣板來尋找"
-
msgid "Search by hostname"
msgstr "以主機名稱來尋找"
-msgid "Search by image"
-msgstr "以映像檔來尋找"
-
msgid "Search by server status"
msgstr "以雲實例狀態來尋找"
msgid "Security group to add (name or ID)"
msgstr "要加入的安全性群組(名稱或識別號)"
-msgid "Security group to assign to this server (repeat for multiple groups)"
-msgstr "要指定到此雲實例的安全性群組(為多個群組重復指定)"
-
msgid "Select an availability zone for the server"
msgstr "為雲實例選擇可用的區域。"
@@ -502,9 +482,6 @@ msgstr "等待重建完成"
msgid "Wait for resize to complete"
msgstr "等待調整容量完成"
-msgid "can't create server with port specified since neutron not enabled"
-msgstr "Neutron 未啟用時,不能以指定的接口來新增雲實例"
-
msgid "either net-id or port-id should be specified but not both"
msgstr "任選網路識別號或接口識別號,但不能兩者都指定"
diff --git a/openstackclient/network/client.py b/openstackclient/network/client.py
index 69ed11f..7714c52 100644
--- a/openstackclient/network/client.py
+++ b/openstackclient/network/client.py
@@ -13,6 +13,8 @@
import logging
+from openstack import connection
+
from openstackclient.common import utils
@@ -22,62 +24,18 @@ DEFAULT_API_VERSION = '2.0'
API_VERSION_OPTION = 'os_network_api_version'
API_NAME = "network"
API_VERSIONS = {
- "2.0": "neutronclient.v2_0.client.Client",
- "2": "neutronclient.v2_0.client.Client",
-}
-# Translate our API version to auth plugin version prefix
-API_VERSION_MAP = {
- '2.0': 'v2.0',
- '2': 'v2.0',
-}
-
-NETWORK_API_TYPE = 'network'
-NETWORK_API_VERSIONS = {
- '2.0': 'openstackclient.api.network_v2.APIv2',
- '2': 'openstackclient.api.network_v2.APIv2',
+ "2.0": "openstack.connection.Connection",
+ "2": "openstack.connection.Connection",
}
def make_client(instance):
- """Returns an network service client"""
- network_client = utils.get_client_class(
- API_NAME,
- instance._api_version[API_NAME],
- API_VERSIONS)
- LOG.debug('Instantiating network client: %s', network_client)
-
- endpoint = instance.get_endpoint_for_service_type(
- API_NAME,
- region_name=instance._region_name,
- interface=instance._interface,
- )
-
- # Remember endpoint_type only if it is set
- kwargs = utils.build_kwargs_dict('endpoint_type', instance._interface)
-
- client = network_client(
- session=instance.session,
- region_name=instance._region_name,
- **kwargs
- )
-
- network_api = utils.get_client_class(
- API_NAME,
- instance._api_version[API_NAME],
- NETWORK_API_VERSIONS)
- LOG.debug('Instantiating network api: %s', network_client)
-
- # v2 is hard-coded until discovery is completed, neutron only has one atm
- client.api = network_api(
- session=instance.session,
- service_type=NETWORK_API_TYPE,
- endpoint='/'.join([
- endpoint,
- API_VERSION_MAP[instance._api_version[API_NAME]],
- ])
- )
-
- return client
+ """Returns a network proxy"""
+ conn = connection.Connection(authenticator=instance.session.auth)
+ LOG.debug('Connection: %s', conn)
+ LOG.debug('Network client initialized using OpenStack SDK: %s',
+ conn.network)
+ return conn.network
def build_option_parser(parser):
diff --git a/openstackclient/network/common.py b/openstackclient/network/common.py
index 31faef2..c539dd0 100644
--- a/openstackclient/network/common.py
+++ b/openstackclient/network/common.py
@@ -11,37 +11,52 @@
# under the License.
#
-from openstackclient.common import exceptions
-
-
-def find(client, resource, resources, name_or_id, name_attr='name'):
- """Find a network resource
-
- :param client: network client
- :param resource: name of the resource
- :param resources: plural name of resource
- :param name_or_id: name or id of resource user is looking for
- :param name_attr: key to the name attribute for the resource
-
- For example:
- n = find(netclient, 'network', 'networks', 'matrix')
- """
- list_method = getattr(client, "list_%s" % resources)
-
- # Search by name
- kwargs = {name_attr: name_or_id, 'fields': 'id'}
- data = list_method(**kwargs)
- info = data[resources]
- if len(info) == 1:
- return info[0]['id']
- if len(info) > 1:
- msg = "More than one %s exists with the name '%s'."
- raise exceptions.CommandError(msg % (resource, name_or_id))
-
- # Search by id
- data = list_method(id=name_or_id, fields='id')
- info = data[resources]
- if len(info) == 1:
- return info[0]['id']
- msg = "No %s with a name or ID of '%s' exists." % (resource, name_or_id)
- raise exceptions.CommandError(msg)
+import abc
+import six
+
+from openstackclient.common import command
+
+
+@six.add_metaclass(abc.ABCMeta)
+class NetworkAndComputeCommand(command.Command):
+ """Network and Compute Command"""
+
+ def take_action(self, parsed_args):
+ if self.app.client_manager.is_network_endpoint_enabled():
+ return self.take_action_network(self.app.client_manager.network,
+ parsed_args)
+ else:
+ return self.take_action_compute(self.app.client_manager.compute,
+ parsed_args)
+
+ def get_parser(self, prog_name):
+ self.log.debug('get_parser(%s)', prog_name)
+ parser = super(NetworkAndComputeCommand, self).get_parser(prog_name)
+ parser = self.update_parser_common(parser)
+ self.log.debug('common parser: %s', parser)
+ if self.app.client_manager.is_network_endpoint_enabled():
+ return self.update_parser_network(parser)
+ else:
+ return self.update_parser_compute(parser)
+
+ def update_parser_common(self, parser):
+ """Default is no updates to parser."""
+ return parser
+
+ def update_parser_network(self, parser):
+ """Default is no updates to parser."""
+ return parser
+
+ def update_parser_compute(self, parser):
+ """Default is no updates to parser."""
+ return parser
+
+ @abc.abstractmethod
+ def take_action_network(self, client, parsed_args):
+ """Override to do something useful."""
+ pass
+
+ @abc.abstractmethod
+ def take_action_compute(self, client, parsed_args):
+ """Override to do something useful."""
+ pass
diff --git a/openstackclient/network/v2/network.py b/openstackclient/network/v2/network.py
index 336b308..6123721 100644
--- a/openstackclient/network/v2/network.py
+++ b/openstackclient/network/v2/network.py
@@ -13,40 +13,69 @@
"""Network action implementations"""
-import logging
-import six
-
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import exceptions
from openstackclient.common import utils
from openstackclient.identity import common as identity_common
-from openstackclient.network import common
-def _prep_network_detail(net):
- """Prepare network object for output"""
+def _format_admin_state(item):
+ return 'UP' if item else 'DOWN'
- if 'subnets' in net:
- net['subnets'] = utils.format_list(net['subnets'])
- if 'admin_state_up' in net:
- net['state'] = 'UP' if net['admin_state_up'] else 'DOWN'
- net.pop('admin_state_up')
- if 'router:external' in net:
- net['router_type'] = 'External' if net['router:external'] \
- else 'Internal'
- net.pop('router:external')
- if 'tenant_id' in net:
- net['project_id'] = net.pop('tenant_id')
- return net
+def _format_router_external(item):
+ return 'External' if item else 'Internal'
-class CreateNetwork(show.ShowOne):
- """Create new network"""
- log = logging.getLogger(__name__ + '.CreateNetwork')
+_formatters = {
+ 'subnets': utils.format_list,
+ 'admin_state_up': _format_admin_state,
+ 'router_external': _format_router_external,
+ 'availability_zones': utils.format_list,
+ 'availability_zone_hints': utils.format_list,
+}
+
+
+def _get_columns(item):
+ columns = item.keys()
+ if 'tenant_id' in columns:
+ columns.remove('tenant_id')
+ columns.append('project_id')
+ if 'router:external' in columns:
+ columns.remove('router:external')
+ columns.append('router_external')
+ return tuple(sorted(columns))
+
+
+def _get_attrs(client_manager, parsed_args):
+ attrs = {}
+ if parsed_args.name is not None:
+ attrs['name'] = str(parsed_args.name)
+ if parsed_args.admin_state is not None:
+ attrs['admin_state_up'] = parsed_args.admin_state
+ if parsed_args.shared is not None:
+ attrs['shared'] = parsed_args.shared
+
+ # "network set" command doesn't support setting project.
+ if 'project' in parsed_args and parsed_args.project is not None:
+ identity_client = client_manager.identity
+ project_id = identity_common.find_project(
+ identity_client,
+ parsed_args.project,
+ parsed_args.project_domain,
+ ).id
+ attrs['tenant_id'] = project_id
+
+ # "network set" command doesn't support setting availability zone hints.
+ if 'availability_zone_hints' in parsed_args and \
+ parsed_args.availability_zone_hints is not None:
+ attrs['availability_zone_hints'] = parsed_args.availability_zone_hints
+
+ return attrs
+
+
+class CreateNetwork(command.ShowOne):
+ """Create new network"""
def get_parser(self, prog_name):
parser = super(CreateNetwork, self).get_parser(prog_name)
@@ -86,68 +115,55 @@ class CreateNetwork(show.ShowOne):
parser.add_argument(
'--project',
metavar='<project>',
- help="Owner's project (name or ID)")
+ help="Owner's project (name or ID)"
+ )
identity_common.add_project_domain_option_to_parser(parser)
+
+ parser.add_argument(
+ '--availability-zone-hint',
+ action='append',
+ dest='availability_zone_hints',
+ metavar='<availability-zone>',
+ help='Availability Zone in which to create this network '
+ '(requires the Network Availability Zone extension, '
+ 'this option can be repeated).',
+ )
return parser
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
client = self.app.client_manager.network
- body = self.get_body(parsed_args)
- create_method = getattr(client, "create_network")
- data = create_method(body)['network']
- if data:
- data = _prep_network_detail(data)
- else:
- data = {'': ''}
- return zip(*sorted(six.iteritems(data)))
-
- def get_body(self, parsed_args):
- body = {'name': str(parsed_args.name),
- 'admin_state_up': parsed_args.admin_state}
- if parsed_args.shared is not None:
- body['shared'] = parsed_args.shared
- if parsed_args.project is not None:
- identity_client = self.app.client_manager.identity
- project_id = identity_common.find_project(
- identity_client,
- parsed_args.project,
- parsed_args.project_domain,
- ).id
- body['tenant_id'] = project_id
- return {'network': body}
+
+ attrs = _get_attrs(self.app.client_manager, parsed_args)
+ obj = client.create_network(**attrs)
+ columns = _get_columns(obj)
+
+ data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ return (columns, data)
class DeleteNetwork(command.Command):
"""Delete network(s)"""
- log = logging.getLogger(__name__ + '.DeleteNetwork')
-
def get_parser(self, prog_name):
parser = super(DeleteNetwork, self).get_parser(prog_name)
parser.add_argument(
- 'networks',
+ 'network',
metavar="<network>",
nargs="+",
- help=("Network to delete (name or ID)")
+ help=("Network(s) to delete (name or ID)")
)
return parser
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
client = self.app.client_manager.network
- delete_method = getattr(client, "delete_network")
- for network in parsed_args.networks:
- _id = common.find(client, 'network', 'networks', network)
- delete_method(_id)
- return
+ for network in parsed_args.network:
+ obj = client.find_network(network)
+ client.delete_network(obj)
-class ListNetwork(lister.Lister):
+class ListNetwork(command.Lister):
"""List networks"""
- log = logging.getLogger(__name__ + '.ListNetwork')
-
def get_parser(self, prog_name):
parser = super(ListNetwork, self).get_parser(prog_name)
parser.add_argument(
@@ -165,22 +181,20 @@ class ListNetwork(lister.Lister):
return parser
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
client = self.app.client_manager.network
- data = client.api.network_list(external=parsed_args.external)
-
if parsed_args.long:
columns = (
- 'ID',
- 'Name',
- 'Status',
- 'project_id',
- 'state',
- 'Shared',
- 'Subnets',
- 'provider:network_type',
- 'router_type',
+ 'id',
+ 'name',
+ 'status',
+ 'tenant_id',
+ 'admin_state_up',
+ 'shared',
+ 'subnets',
+ 'provider_network_type',
+ 'router_external',
+ 'availability_zones',
)
column_headers = (
'ID',
@@ -192,26 +206,35 @@ class ListNetwork(lister.Lister):
'Subnets',
'Network Type',
'Router Type',
+ 'Availability Zones',
)
else:
- columns = ('ID', 'Name', 'Subnets')
- column_headers = columns
-
- for d in data:
- d = _prep_network_detail(d)
+ columns = (
+ 'id',
+ 'name',
+ 'subnets'
+ )
+ column_headers = (
+ 'ID',
+ 'Name',
+ 'Subnets',
+ )
+ if parsed_args.external:
+ args = {'router:external': True}
+ else:
+ args = {}
+ data = client.networks(**args)
return (column_headers,
- (utils.get_dict_properties(
+ (utils.get_item_properties(
s, columns,
- formatters={'subnets': utils.format_list},
+ formatters=_formatters,
) for s in data))
class SetNetwork(command.Command):
"""Set network properties"""
- log = logging.getLogger(__name__ + '.SetNetwork')
-
def get_parser(self, prog_name):
parser = super(SetNetwork, self).get_parser(prog_name)
parser.add_argument(
@@ -255,30 +278,21 @@ class SetNetwork(command.Command):
return parser
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
client = self.app.client_manager.network
- _id = common.find(client, 'network', 'networks',
- parsed_args.identifier)
- body = {}
- if parsed_args.name is not None:
- body['name'] = str(parsed_args.name)
- if parsed_args.admin_state is not None:
- body['admin_state_up'] = parsed_args.admin_state
- if parsed_args.shared is not None:
- body['shared'] = parsed_args.shared
- if body == {}:
+ obj = client.find_network(parsed_args.identifier, ignore_missing=False)
+
+ attrs = _get_attrs(self.app.client_manager, parsed_args)
+ if attrs == {}:
msg = "Nothing specified to be set"
raise exceptions.CommandError(msg)
- update_method = getattr(client, "update_network")
- update_method(_id, {'network': body})
+
+ client.update_network(obj, **attrs)
return
-class ShowNetwork(show.ShowOne):
+class ShowNetwork(command.ShowOne):
"""Show network details"""
- log = logging.getLogger(__name__ + '.ShowNetwork')
-
def get_parser(self, prog_name):
parser = super(ShowNetwork, self).get_parser(prog_name)
parser.add_argument(
@@ -289,11 +303,8 @@ class ShowNetwork(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
client = self.app.client_manager.network
- net = client.api.find_attr(
- 'networks',
- parsed_args.identifier,
- )
- data = _prep_network_detail(net)
- return zip(*sorted(six.iteritems(data)))
+ obj = client.find_network(parsed_args.identifier, ignore_missing=False)
+ columns = _get_columns(obj)
+ data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ return (columns, data)
diff --git a/openstackclient/network/v2/port.py b/openstackclient/network/v2/port.py
new file mode 100644
index 0000000..46cb031
--- /dev/null
+++ b/openstackclient/network/v2/port.py
@@ -0,0 +1,93 @@
+# 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.
+#
+
+"""Port action implementations"""
+
+from openstackclient.common import command
+from openstackclient.common import utils
+
+
+def _format_admin_state(state):
+ return 'UP' if state else 'DOWN'
+
+
+_formatters = {
+ 'admin_state_up': _format_admin_state,
+ 'allowed_address_pairs': utils.format_list_of_dicts,
+ 'binding_profile': utils.format_dict,
+ 'binding_vif_details': utils.format_dict,
+ 'dns_assignment': utils.format_list_of_dicts,
+ 'extra_dhcp_opts': utils.format_list_of_dicts,
+ 'fixed_ips': utils.format_list_of_dicts,
+ 'security_groups': utils.format_list,
+}
+
+
+def _get_columns(item):
+ columns = item.keys()
+ if 'tenant_id' in columns:
+ columns.remove('tenant_id')
+ columns.append('project_id')
+ binding_columns = [
+ 'binding:host_id',
+ 'binding:profile',
+ 'binding:vif_details',
+ 'binding:vif_type',
+ 'binding:vnic_type',
+ ]
+ for binding_column in binding_columns:
+ if binding_column in columns:
+ columns.remove(binding_column)
+ columns.append(binding_column.replace('binding:', 'binding_', 1))
+ return sorted(columns)
+
+
+class DeletePort(command.Command):
+ """Delete port(s)"""
+
+ def get_parser(self, prog_name):
+ parser = super(DeletePort, self).get_parser(prog_name)
+ parser.add_argument(
+ 'port',
+ metavar="<port>",
+ nargs="+",
+ help=("Port(s) to delete (name or ID)")
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.network
+
+ for port in parsed_args.port:
+ res = client.find_port(port)
+ client.delete_port(res)
+
+
+class ShowPort(command.ShowOne):
+ """Display port details"""
+
+ def get_parser(self, prog_name):
+ parser = super(ShowPort, self).get_parser(prog_name)
+ parser.add_argument(
+ 'port',
+ metavar="<port>",
+ help="Port to display (name or ID)"
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.network
+ obj = client.find_port(parsed_args.port, ignore_missing=False)
+ columns = _get_columns(obj)
+ data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ return (tuple(columns), data)
diff --git a/openstackclient/network/v2/router.py b/openstackclient/network/v2/router.py
new file mode 100644
index 0000000..60db816
--- /dev/null
+++ b/openstackclient/network/v2/router.py
@@ -0,0 +1,295 @@
+# 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.
+#
+
+"""Router action implementations"""
+
+import json
+
+from openstackclient.common import command
+from openstackclient.common import exceptions
+from openstackclient.common import utils
+from openstackclient.identity import common as identity_common
+
+
+def _format_admin_state(state):
+ return 'UP' if state else 'DOWN'
+
+
+def _format_external_gateway_info(info):
+ try:
+ return json.dumps(info)
+ except (TypeError, KeyError):
+ return ''
+
+
+_formatters = {
+ 'admin_state_up': _format_admin_state,
+ 'external_gateway_info': _format_external_gateway_info,
+ 'availability_zones': utils.format_list,
+ 'availability_zone_hints': utils.format_list,
+}
+
+
+def _get_attrs(client_manager, parsed_args):
+ attrs = {}
+ if parsed_args.name is not None:
+ attrs['name'] = str(parsed_args.name)
+ if parsed_args.admin_state_up is not None:
+ attrs['admin_state_up'] = parsed_args.admin_state_up
+ if parsed_args.distributed is not None:
+ attrs['distributed'] = parsed_args.distributed
+ if ('availability_zone_hints' in parsed_args
+ and parsed_args.availability_zone_hints is not None):
+ attrs['availability_zone_hints'] = parsed_args.availability_zone_hints
+ # "router set" command doesn't support setting project.
+ if 'project' in parsed_args and parsed_args.project is not None:
+ identity_client = client_manager.identity
+ project_id = identity_common.find_project(
+ identity_client,
+ parsed_args.project,
+ parsed_args.project_domain,
+ ).id
+ attrs['tenant_id'] = project_id
+
+ # TODO(tangchen): Support getting 'ha' property.
+ # TODO(tangchen): Support getting 'external_gateway_info' property.
+ # TODO(tangchen): Support getting 'routes' property.
+
+ return attrs
+
+
+class CreateRouter(command.ShowOne):
+ """Create a new router"""
+
+ def get_parser(self, prog_name):
+ parser = super(CreateRouter, self).get_parser(prog_name)
+ parser.add_argument(
+ 'name',
+ metavar='<name>',
+ help="New router name",
+ )
+ admin_group = parser.add_mutually_exclusive_group()
+ admin_group.add_argument(
+ '--enable',
+ dest='admin_state_up',
+ action='store_true',
+ default=True,
+ help="Enable router (default)",
+ )
+ admin_group.add_argument(
+ '--disable',
+ dest='admin_state_up',
+ action='store_false',
+ help="Disable router",
+ )
+ parser.add_argument(
+ '--distributed',
+ dest='distributed',
+ action='store_true',
+ default=False,
+ help="Create a distributed router",
+ )
+ parser.add_argument(
+ '--project',
+ metavar='<project>',
+ help="Owner's project (name or ID)",
+ )
+ parser.add_argument(
+ '--availability-zone-hint',
+ metavar='<availability-zone>',
+ action='append',
+ dest='availability_zone_hints',
+ help='Availability Zone in which to create this router '
+ '(requires the Router Availability Zone extension, '
+ 'this option can be repeated).',
+ )
+
+ identity_common.add_project_domain_option_to_parser(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.network
+
+ attrs = _get_attrs(self.app.client_manager, parsed_args)
+ obj = client.create_router(**attrs)
+
+ columns = sorted(obj.keys())
+ data = utils.get_item_properties(obj, columns, formatters=_formatters)
+
+ if 'tenant_id' in columns:
+ # Rename "tenant_id" to "project_id".
+ index = columns.index('tenant_id')
+ columns[index] = 'project_id'
+ return (tuple(columns), data)
+
+
+class DeleteRouter(command.Command):
+ """Delete router(s)"""
+
+ def get_parser(self, prog_name):
+ parser = super(DeleteRouter, self).get_parser(prog_name)
+ parser.add_argument(
+ 'router',
+ metavar="<router>",
+ nargs="+",
+ help=("Router(s) to delete (name or ID)")
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.network
+ for router in parsed_args.router:
+ obj = client.find_router(router)
+ client.delete_router(obj)
+
+
+class ListRouter(command.Lister):
+ """List routers"""
+
+ def get_parser(self, prog_name):
+ parser = super(ListRouter, self).get_parser(prog_name)
+ parser.add_argument(
+ '--long',
+ action='store_true',
+ default=False,
+ help='List additional fields in output',
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.network
+
+ columns = (
+ 'id',
+ 'name',
+ 'status',
+ 'admin_state_up',
+ 'distributed',
+ 'ha',
+ 'tenant_id',
+ )
+ column_headers = (
+ 'ID',
+ 'Name',
+ 'Status',
+ 'State',
+ 'Distributed',
+ 'HA',
+ 'Project',
+ )
+ if parsed_args.long:
+ columns = columns + (
+ 'routes',
+ 'external_gateway_info',
+ 'availability_zones'
+ )
+ column_headers = column_headers + (
+ 'Routes',
+ 'External gateway info',
+ 'Availability zones'
+ )
+
+ data = client.routers()
+ return (column_headers,
+ (utils.get_item_properties(
+ s, columns,
+ formatters=_formatters,
+ ) for s in data))
+
+
+class SetRouter(command.Command):
+ """Set router properties"""
+
+ def get_parser(self, prog_name):
+ parser = super(SetRouter, self).get_parser(prog_name)
+ parser.add_argument(
+ 'router',
+ metavar="<router>",
+ help=("Router to modify (name or ID)")
+ )
+ parser.add_argument(
+ '--name',
+ metavar='<name>',
+ help='Set router name',
+ )
+ admin_group = parser.add_mutually_exclusive_group()
+ admin_group.add_argument(
+ '--enable',
+ dest='admin_state_up',
+ action='store_true',
+ default=None,
+ help='Enable router',
+ )
+ admin_group.add_argument(
+ '--disable',
+ dest='admin_state_up',
+ action='store_false',
+ help='Disable router',
+ )
+ distribute_group = parser.add_mutually_exclusive_group()
+ distribute_group.add_argument(
+ '--distributed',
+ dest='distributed',
+ action='store_true',
+ default=None,
+ help="Set router to distributed mode (disabled router only)",
+ )
+ distribute_group.add_argument(
+ '--centralized',
+ dest='distributed',
+ action='store_false',
+ help="Set router to centralized mode (disabled router only)",
+ )
+
+ # TODO(tangchen): Support setting 'ha' property in 'router set'
+ # command. It appears that changing the ha state is supported by
+ # neutron under certain conditions.
+
+ # TODO(tangchen): Support setting 'external_gateway_info' property in
+ # 'router set' command.
+
+ # TODO(tangchen): Support setting 'routes' property in 'router set'
+ # command.
+
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.network
+ obj = client.find_router(parsed_args.router, ignore_missing=False)
+
+ attrs = _get_attrs(self.app.client_manager, parsed_args)
+ if attrs == {}:
+ msg = "Nothing specified to be set"
+ raise exceptions.CommandError(msg)
+
+ client.update_router(obj, **attrs)
+
+
+class ShowRouter(command.ShowOne):
+ """Display router details"""
+
+ def get_parser(self, prog_name):
+ parser = super(ShowRouter, self).get_parser(prog_name)
+ parser.add_argument(
+ 'router',
+ metavar="<router>",
+ help="Router to display (name or ID)"
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.network
+ obj = client.find_router(parsed_args.router, ignore_missing=False)
+ columns = sorted(obj.keys())
+ data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ return (tuple(columns), data)
diff --git a/openstackclient/network/v2/security_group.py b/openstackclient/network/v2/security_group.py
new file mode 100644
index 0000000..4e122f2
--- /dev/null
+++ b/openstackclient/network/v2/security_group.py
@@ -0,0 +1,40 @@
+# 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.
+#
+
+"""Security Group action implementations"""
+
+from openstackclient.common import utils
+from openstackclient.network import common
+
+
+class DeleteSecurityGroup(common.NetworkAndComputeCommand):
+ """Delete a security group"""
+
+ def update_parser_common(self, parser):
+ parser.add_argument(
+ 'group',
+ metavar='<group>',
+ help='Security group to delete (name or ID)',
+ )
+ return parser
+
+ def take_action_network(self, client, parsed_args):
+ obj = client.find_security_group(parsed_args.group)
+ client.delete_security_group(obj)
+
+ def take_action_compute(self, client, parsed_args):
+ data = utils.find_resource(
+ client.security_groups,
+ parsed_args.group,
+ )
+ client.security_groups.delete(data.id)
diff --git a/openstackclient/network/v2/subnet.py b/openstackclient/network/v2/subnet.py
new file mode 100644
index 0000000..b948c65
--- /dev/null
+++ b/openstackclient/network/v2/subnet.py
@@ -0,0 +1,63 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+"""Subnet action implementations"""
+
+from openstackclient.common import command
+from openstackclient.common import utils
+
+
+def _format_allocation_pools(data):
+ pool_formatted = ['%s-%s' % (pool.get('start', ''), pool.get('end', ''))
+ for pool in data]
+ return ','.join(pool_formatted)
+
+
+_formatters = {
+ 'allocation_pools': _format_allocation_pools,
+ 'dns_nameservers': utils.format_list,
+ 'host_routes': utils.format_list,
+}
+
+
+class ListSubnet(command.Lister):
+ """List subnets"""
+
+ def get_parser(self, prog_name):
+ parser = super(ListSubnet, self).get_parser(prog_name)
+ parser.add_argument(
+ '--long',
+ action='store_true',
+ default=False,
+ help='List additional fields in output',
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ data = self.app.client_manager.network.subnets()
+
+ headers = ('ID', 'Name', 'Network', 'Subnet')
+ columns = ('id', 'name', 'network_id', 'cidr')
+ if parsed_args.long:
+ headers += ('Project', 'DHCP', 'Name Servers',
+ 'Allocation Pools', 'Host Routes', 'IP Version',
+ 'Gateway')
+ columns += ('tenant_id', 'enable_dhcp', 'dns_nameservers',
+ 'allocation_pools', 'host_routes', 'ip_version',
+ 'gateway_ip')
+
+ return (headers,
+ (utils.get_item_properties(
+ s, columns,
+ formatters=_formatters,
+ ) for s in data))
diff --git a/openstackclient/object/client.py b/openstackclient/object/client.py
index e758780..3af6f8a 100644
--- a/openstackclient/object/client.py
+++ b/openstackclient/object/client.py
@@ -15,13 +15,9 @@
"""Object client"""
-import logging
-
from openstackclient.api import object_store_v1
from openstackclient.common import utils
-LOG = logging.getLogger(__name__)
-
DEFAULT_API_VERSION = '1'
API_VERSION_OPTION = 'os_object_api_version'
API_NAME = 'object_store'
diff --git a/openstackclient/object/v1/account.py b/openstackclient/object/v1/account.py
index aa94ff5..543ce4f 100644
--- a/openstackclient/object/v1/account.py
+++ b/openstackclient/object/v1/account.py
@@ -13,12 +13,9 @@
"""Account v1 action implementations"""
-import logging
-
-from cliff import command
-from cliff import show
import six
+from openstackclient.common import command
from openstackclient.common import parseractions
from openstackclient.common import utils
@@ -26,8 +23,6 @@ from openstackclient.common import utils
class SetAccount(command.Command):
"""Set account properties"""
- log = logging.getLogger(__name__ + '.SetAccount')
-
def get_parser(self, prog_name):
parser = super(SetAccount, self).get_parser(prog_name)
parser.add_argument(
@@ -40,19 +35,15 @@ class SetAccount(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
self.app.client_manager.object_store.account_set(
properties=parsed_args.property,
)
-class ShowAccount(show.ShowOne):
+class ShowAccount(command.ShowOne):
"""Display account details"""
- log = logging.getLogger(__name__ + '.ShowAccount')
-
- @utils.log_method(log)
def take_action(self, parsed_args):
data = self.app.client_manager.object_store.account_show()
if 'properties' in data:
@@ -63,8 +54,6 @@ class ShowAccount(show.ShowOne):
class UnsetAccount(command.Command):
"""Unset account properties"""
- log = logging.getLogger(__name__ + '.UnsetAccount')
-
def get_parser(self, prog_name):
parser = super(UnsetAccount, self).get_parser(prog_name)
parser.add_argument(
@@ -78,7 +67,6 @@ class UnsetAccount(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
self.app.client_manager.object_store.account_unset(
properties=parsed_args.property,
diff --git a/openstackclient/object/v1/container.py b/openstackclient/object/v1/container.py
index 8c8844e..e70afd9 100644
--- a/openstackclient/object/v1/container.py
+++ b/openstackclient/object/v1/container.py
@@ -16,22 +16,16 @@
"""Container v1 action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import parseractions
from openstackclient.common import utils
-class CreateContainer(lister.Lister):
+class CreateContainer(command.Lister):
"""Create new container"""
- log = logging.getLogger(__name__ + '.CreateContainer')
-
def get_parser(self, prog_name):
parser = super(CreateContainer, self).get_parser(prog_name)
parser.add_argument(
@@ -42,7 +36,6 @@ class CreateContainer(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
results = []
@@ -63,8 +56,6 @@ class CreateContainer(lister.Lister):
class DeleteContainer(command.Command):
"""Delete container"""
- log = logging.getLogger(__name__ + '.DeleteContainer')
-
def get_parser(self, prog_name):
parser = super(DeleteContainer, self).get_parser(prog_name)
parser.add_argument(
@@ -75,7 +66,6 @@ class DeleteContainer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
for container in parsed_args.containers:
@@ -84,11 +74,9 @@ class DeleteContainer(command.Command):
)
-class ListContainer(lister.Lister):
+class ListContainer(command.Lister):
"""List containers"""
- log = logging.getLogger(__name__ + '.ListContainer')
-
def get_parser(self, prog_name):
parser = super(ListContainer, self).get_parser(prog_name)
parser.add_argument(
@@ -126,7 +114,6 @@ class ListContainer(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
if parsed_args.long:
@@ -160,8 +147,6 @@ class ListContainer(lister.Lister):
class SaveContainer(command.Command):
"""Save container contents locally"""
- log = logging.getLogger(__name__ + ".SaveContainer")
-
def get_parser(self, prog_name):
parser = super(SaveContainer, self).get_parser(prog_name)
parser.add_argument(
@@ -172,8 +157,6 @@ class SaveContainer(command.Command):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
self.app.client_manager.object_store.container_save(
container=parsed_args.container,
)
@@ -182,8 +165,6 @@ class SaveContainer(command.Command):
class SetContainer(command.Command):
"""Set container properties"""
- log = logging.getLogger(__name__ + '.SetContainer')
-
def get_parser(self, prog_name):
parser = super(SetContainer, self).get_parser(prog_name)
parser.add_argument(
@@ -201,7 +182,6 @@ class SetContainer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
self.app.client_manager.object_store.container_set(
parsed_args.container,
@@ -209,11 +189,9 @@ class SetContainer(command.Command):
)
-class ShowContainer(show.ShowOne):
+class ShowContainer(command.ShowOne):
"""Display container details"""
- log = logging.getLogger(__name__ + '.ShowContainer')
-
def get_parser(self, prog_name):
parser = super(ShowContainer, self).get_parser(prog_name)
parser.add_argument(
@@ -223,7 +201,6 @@ class ShowContainer(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
data = self.app.client_manager.object_store.container_show(
@@ -238,8 +215,6 @@ class ShowContainer(show.ShowOne):
class UnsetContainer(command.Command):
"""Unset container properties"""
- log = logging.getLogger(__name__ + '.UnsetContainer')
-
def get_parser(self, prog_name):
parser = super(UnsetContainer, self).get_parser(prog_name)
parser.add_argument(
@@ -258,7 +233,6 @@ class UnsetContainer(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
self.app.client_manager.object_store.container_unset(
parsed_args.container,
diff --git a/openstackclient/object/v1/object.py b/openstackclient/object/v1/object.py
index 4bd0612..f9a55e9 100644
--- a/openstackclient/object/v1/object.py
+++ b/openstackclient/object/v1/object.py
@@ -16,22 +16,16 @@
"""Object v1 action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import parseractions
from openstackclient.common import utils
-class CreateObject(lister.Lister):
+class CreateObject(command.Lister):
"""Upload object to container"""
- log = logging.getLogger(__name__ + '.CreateObject')
-
def get_parser(self, prog_name):
parser = super(CreateObject, self).get_parser(prog_name)
parser.add_argument(
@@ -47,7 +41,6 @@ class CreateObject(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
results = []
@@ -69,8 +62,6 @@ class CreateObject(lister.Lister):
class DeleteObject(command.Command):
"""Delete object from container"""
- log = logging.getLogger(__name__ + '.DeleteObject')
-
def get_parser(self, prog_name):
parser = super(DeleteObject, self).get_parser(prog_name)
parser.add_argument(
@@ -86,7 +77,6 @@ class DeleteObject(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
for obj in parsed_args.objects:
@@ -96,11 +86,9 @@ class DeleteObject(command.Command):
)
-class ListObject(lister.Lister):
+class ListObject(command.Lister):
"""List objects"""
- log = logging.getLogger(__name__ + '.ListObject')
-
def get_parser(self, prog_name):
parser = super(ListObject, self).get_parser(prog_name)
parser.add_argument(
@@ -148,7 +136,6 @@ class ListObject(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
if parsed_args.long:
@@ -191,8 +178,6 @@ class ListObject(lister.Lister):
class SaveObject(command.Command):
"""Save object locally"""
- log = logging.getLogger(__name__ + ".SaveObject")
-
def get_parser(self, prog_name):
parser = super(SaveObject, self).get_parser(prog_name)
parser.add_argument(
@@ -213,8 +198,6 @@ class SaveObject(command.Command):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action(%s)", parsed_args)
-
self.app.client_manager.object_store.object_save(
container=parsed_args.container,
object=parsed_args.object,
@@ -225,8 +208,6 @@ class SaveObject(command.Command):
class SetObject(command.Command):
"""Set object properties"""
- log = logging.getLogger(__name__ + '.SetObject')
-
def get_parser(self, prog_name):
parser = super(SetObject, self).get_parser(prog_name)
parser.add_argument(
@@ -249,7 +230,6 @@ class SetObject(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
self.app.client_manager.object_store.object_set(
parsed_args.container,
@@ -258,11 +238,9 @@ class SetObject(command.Command):
)
-class ShowObject(show.ShowOne):
+class ShowObject(command.ShowOne):
"""Display object details"""
- log = logging.getLogger(__name__ + '.ShowObject')
-
def get_parser(self, prog_name):
parser = super(ShowObject, self).get_parser(prog_name)
parser.add_argument(
@@ -277,7 +255,6 @@ class ShowObject(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
data = self.app.client_manager.object_store.object_show(
@@ -293,8 +270,6 @@ class ShowObject(show.ShowOne):
class UnsetObject(command.Command):
"""Unset object properties"""
- log = logging.getLogger(__name__ + '.UnsetObject')
-
def get_parser(self, prog_name):
parser = super(UnsetObject, self).get_parser(prog_name)
parser.add_argument(
@@ -318,7 +293,6 @@ class UnsetObject(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
self.app.client_manager.object_store.object_unset(
parsed_args.container,
diff --git a/openstackclient/shell.py b/openstackclient/shell.py
index 5b4939a..c84e2b1 100644
--- a/openstackclient/shell.py
+++ b/openstackclient/shell.py
@@ -116,7 +116,7 @@ class OpenStackShell(app.App):
if not logging.getLogger('').handlers:
logging.basicConfig()
if self.dump_stack_trace:
- self.log.error(traceback.format_exc(e))
+ self.log.error(traceback.format_exc())
else:
self.log.error('Exception raised: ' + str(e))
diff --git a/openstackclient/tests/api/test_network_v2.py b/openstackclient/tests/api/test_network_v2.py
deleted file mode 100644
index 80f1d9d..0000000
--- a/openstackclient/tests/api/test_network_v2.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# 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.
-#
-
-"""Network v2 API Library Tests"""
-
-from requests_mock.contrib import fixture
-
-from keystoneauth1 import session
-from openstackclient.api import network_v2 as network
-from openstackclient.tests import utils
-
-
-FAKE_PROJECT = 'xyzpdq'
-FAKE_URL = 'http://gopher.com/v2/' + FAKE_PROJECT
-
-
-class TestNetworkAPIv2(utils.TestCase):
-
- def setUp(self):
- super(TestNetworkAPIv2, self).setUp()
- sess = session.Session()
- self.api = network.APIv2(session=sess, endpoint=FAKE_URL)
- self.requests_mock = self.useFixture(fixture.Fixture())
-
-
-class TestNetwork(TestNetworkAPIv2):
-
- LIST_NETWORK_RESP = [
- {'id': '1', 'name': 'p1', 'description': 'none', 'enabled': True},
- {'id': '2', 'name': 'p2', 'description': 'none', 'enabled': False},
- {'id': '3', 'name': 'p3', 'description': 'none', 'enabled': True},
- ]
-
- def test_network_list_no_options(self):
- self.requests_mock.register_uri(
- 'GET',
- FAKE_URL + '/networks',
- json={'networks': self.LIST_NETWORK_RESP},
- status_code=200,
- )
- ret = self.api.network_list()
- self.assertEqual(self.LIST_NETWORK_RESP, ret)
diff --git a/openstackclient/tests/api/test_object_store_v1.py b/openstackclient/tests/api/test_object_store_v1.py
index 992bf26..8cc3a92 100644
--- a/openstackclient/tests/api/test_object_store_v1.py
+++ b/openstackclient/tests/api/test_object_store_v1.py
@@ -157,6 +157,7 @@ class TestContainer(TestObjectAPIv1):
'container': 'qaz',
'object_count': '1',
'bytes_used': '577',
+ 'properties': {'Owner': FAKE_ACCOUNT},
}
self.requests_mock.register_uri(
'HEAD',
@@ -309,6 +310,7 @@ class TestObject(TestObjectAPIv1):
'etag': 'qaz',
'x-container-meta-owner': FAKE_ACCOUNT,
'x-object-meta-wife': 'Wilma',
+ 'x-object-meta-Husband': 'fred',
'x-tra-header': 'yabba-dabba-do',
}
resp = {
@@ -319,7 +321,8 @@ class TestObject(TestObjectAPIv1):
'content-length': '577',
'last-modified': '20130101',
'etag': 'qaz',
- 'properties': {'wife': 'Wilma'},
+ 'properties': {'wife': 'Wilma',
+ 'Husband': 'fred'},
}
self.requests_mock.register_uri(
'HEAD',
diff --git a/openstackclient/tests/common/test_availability_zone.py b/openstackclient/tests/common/test_availability_zone.py
new file mode 100644
index 0000000..e44455c
--- /dev/null
+++ b/openstackclient/tests/common/test_availability_zone.py
@@ -0,0 +1,257 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+import mock
+import six
+
+from openstackclient.common import availability_zone
+from openstackclient.tests.compute.v2 import fakes as compute_fakes
+from openstackclient.tests import fakes
+from openstackclient.tests.network.v2 import fakes as network_fakes
+from openstackclient.tests import utils
+from openstackclient.tests.volume.v2 import fakes as volume_fakes
+
+
+def _build_compute_az_datalist(compute_az, long_datalist=False):
+ datalist = ()
+ if not long_datalist:
+ datalist = (
+ compute_az.zoneName,
+ 'available',
+ )
+ else:
+ for host, services in six.iteritems(compute_az.hosts):
+ for service, state in six.iteritems(services):
+ datalist += (
+ compute_az.zoneName,
+ 'available',
+ '',
+ host,
+ service,
+ 'enabled :-) ' + state['updated_at'],
+ )
+ return (datalist,)
+
+
+def _build_volume_az_datalist(volume_az, long_datalist=False):
+ datalist = ()
+ if not long_datalist:
+ datalist = (
+ volume_az.zoneName,
+ 'available',
+ )
+ else:
+ datalist = (
+ volume_az.zoneName,
+ 'available',
+ '', '', '', '',
+ )
+ return (datalist,)
+
+
+def _build_network_az_datalist(network_az, long_datalist=False):
+ datalist = ()
+ if not long_datalist:
+ datalist = (
+ network_az.name,
+ network_az.state,
+ )
+ else:
+ datalist = (
+ network_az.name,
+ network_az.state,
+ network_az.resource,
+ '', '', '',
+ )
+ return (datalist,)
+
+
+class TestAvailabilityZone(utils.TestCommand):
+
+ def setUp(self):
+ super(TestAvailabilityZone, self).setUp()
+
+ compute_client = compute_fakes.FakeComputev2Client(
+ endpoint=fakes.AUTH_URL,
+ token=fakes.AUTH_TOKEN,
+ )
+ self.app.client_manager.compute = compute_client
+
+ self.compute_azs_mock = compute_client.availability_zones
+ self.compute_azs_mock.reset_mock()
+
+ volume_client = volume_fakes.FakeVolumeClient(
+ endpoint=fakes.AUTH_URL,
+ token=fakes.AUTH_TOKEN,
+ )
+ self.app.client_manager.volume = volume_client
+
+ self.volume_azs_mock = volume_client.availability_zones
+ self.volume_azs_mock.reset_mock()
+
+ network_client = network_fakes.FakeNetworkV2Client(
+ endpoint=fakes.AUTH_URL,
+ token=fakes.AUTH_TOKEN,
+ )
+ self.app.client_manager.network = network_client
+
+ network_client.availability_zones = mock.Mock()
+ network_client.find_extension = mock.Mock()
+ self.network_azs_mock = network_client.availability_zones
+
+
+class TestAvailabilityZoneList(TestAvailabilityZone):
+
+ compute_azs = \
+ compute_fakes.FakeAvailabilityZone.create_availability_zones()
+ volume_azs = \
+ volume_fakes.FakeAvailabilityZone.create_availability_zones(count=1)
+ network_azs = \
+ network_fakes.FakeAvailabilityZone.create_availability_zones()
+
+ short_columnslist = ('Zone Name', 'Zone Status')
+ long_columnslist = (
+ 'Zone Name',
+ 'Zone Status',
+ 'Zone Resource',
+ 'Host Name',
+ 'Service Name',
+ 'Service Status',
+ )
+
+ def setUp(self):
+ super(TestAvailabilityZoneList, self).setUp()
+
+ self.compute_azs_mock.list.return_value = self.compute_azs
+ self.volume_azs_mock.list.return_value = self.volume_azs
+ self.network_azs_mock.return_value = self.network_azs
+
+ # Get the command object to test
+ self.cmd = availability_zone.ListAvailabilityZone(self.app, None)
+
+ def test_availability_zone_list_no_options(self):
+ arglist = []
+ verifylist = []
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.compute_azs_mock.list.assert_called_with()
+ self.volume_azs_mock.list.assert_called_with()
+ self.network_azs_mock.assert_called_with()
+
+ self.assertEqual(self.short_columnslist, columns)
+ datalist = ()
+ for compute_az in self.compute_azs:
+ datalist += _build_compute_az_datalist(compute_az)
+ for volume_az in self.volume_azs:
+ datalist += _build_volume_az_datalist(volume_az)
+ for network_az in self.network_azs:
+ datalist += _build_network_az_datalist(network_az)
+ self.assertEqual(datalist, tuple(data))
+
+ def test_availability_zone_list_long(self):
+ arglist = [
+ '--long',
+ ]
+ verifylist = [
+ ('long', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.compute_azs_mock.list.assert_called_with()
+ self.volume_azs_mock.list.assert_called_with()
+ self.network_azs_mock.assert_called_with()
+
+ self.assertEqual(self.long_columnslist, columns)
+ datalist = ()
+ for compute_az in self.compute_azs:
+ datalist += _build_compute_az_datalist(compute_az,
+ long_datalist=True)
+ for volume_az in self.volume_azs:
+ datalist += _build_volume_az_datalist(volume_az,
+ long_datalist=True)
+ for network_az in self.network_azs:
+ datalist += _build_network_az_datalist(network_az,
+ long_datalist=True)
+ self.assertEqual(datalist, tuple(data))
+
+ def test_availability_zone_list_compute(self):
+ arglist = [
+ '--compute',
+ ]
+ verifylist = [
+ ('compute', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.compute_azs_mock.list.assert_called_with()
+ self.volume_azs_mock.list.assert_not_called()
+ self.network_azs_mock.assert_not_called()
+
+ self.assertEqual(self.short_columnslist, columns)
+ datalist = ()
+ for compute_az in self.compute_azs:
+ datalist += _build_compute_az_datalist(compute_az)
+ self.assertEqual(datalist, tuple(data))
+
+ def test_availability_zone_list_volume(self):
+ arglist = [
+ '--volume',
+ ]
+ verifylist = [
+ ('volume', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.compute_azs_mock.list.assert_not_called()
+ self.volume_azs_mock.list.assert_called_with()
+ self.network_azs_mock.assert_not_called()
+
+ self.assertEqual(self.short_columnslist, columns)
+ datalist = ()
+ for volume_az in self.volume_azs:
+ datalist += _build_volume_az_datalist(volume_az)
+ self.assertEqual(datalist, tuple(data))
+
+ def test_availability_zone_list_network(self):
+ arglist = [
+ '--network',
+ ]
+ verifylist = [
+ ('network', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.compute_azs_mock.list.assert_not_called()
+ self.volume_azs_mock.list.assert_not_called()
+ self.network_azs_mock.assert_called_with()
+
+ self.assertEqual(self.short_columnslist, columns)
+ datalist = ()
+ for network_az in self.network_azs:
+ datalist += _build_network_az_datalist(network_az)
+ self.assertEqual(datalist, tuple(data))
diff --git a/openstackclient/tests/common/test_clientmanager.py b/openstackclient/tests/common/test_clientmanager.py
index 29cc59e..523f79a 100644
--- a/openstackclient/tests/common/test_clientmanager.py
+++ b/openstackclient/tests/common/test_clientmanager.py
@@ -77,6 +77,9 @@ class TestClientManager(utils.TestCase):
self.requests = self.useFixture(fixture.Fixture())
# fake v2password token retrieval
self.stub_auth(json=fakes.TEST_RESPONSE_DICT)
+ # fake token and token_endpoint retrieval
+ self.stub_auth(json=fakes.TEST_RESPONSE_DICT,
+ url='/'.join([fakes.AUTH_URL, 'v2.0/tokens']))
# fake v3password token retrieval
self.stub_auth(json=fakes.TEST_RESPONSE_DICT_V3,
url='/'.join([fakes.AUTH_URL, 'auth/tokens']))
@@ -99,6 +102,7 @@ class TestClientManager(utils.TestCase):
verify=True
)
client_manager.setup_auth()
+ client_manager.auth_ref
self.assertEqual(
fakes.AUTH_URL,
@@ -114,6 +118,7 @@ class TestClientManager(utils.TestCase):
)
self.assertFalse(client_manager._insecure)
self.assertTrue(client_manager._verify)
+ self.assertTrue(client_manager.is_network_endpoint_enabled())
def test_client_manager_token(self):
@@ -131,6 +136,7 @@ class TestClientManager(utils.TestCase):
verify=True
)
client_manager.setup_auth()
+ client_manager.auth_ref
self.assertEqual(
fakes.AUTH_URL,
@@ -150,6 +156,7 @@ class TestClientManager(utils.TestCase):
)
self.assertFalse(client_manager._insecure)
self.assertTrue(client_manager._verify)
+ self.assertTrue(client_manager.is_network_endpoint_enabled())
def test_client_manager_password(self):
@@ -166,6 +173,7 @@ class TestClientManager(utils.TestCase):
verify=False,
)
client_manager.setup_auth()
+ client_manager.auth_ref
self.assertEqual(
fakes.AUTH_URL,
@@ -195,6 +203,28 @@ class TestClientManager(utils.TestCase):
dir(SERVICE_CATALOG),
dir(client_manager.auth_ref.service_catalog),
)
+ self.assertTrue(client_manager.is_network_endpoint_enabled())
+
+ def test_client_manager_network_endpoint_disabled(self):
+
+ client_manager = clientmanager.ClientManager(
+ cli_options=FakeOptions(
+ auth=dict(
+ auth_url=fakes.AUTH_URL,
+ username=fakes.USERNAME,
+ password=fakes.PASSWORD,
+ project_name=fakes.PROJECT_NAME,
+ ),
+ auth_type='v3password',
+ ),
+ api_version={"identity": "3"},
+ verify=False,
+ )
+ client_manager.setup_auth()
+ client_manager.auth_ref
+
+ # v3 fake doesn't have network endpoint.
+ self.assertFalse(client_manager.is_network_endpoint_enabled())
def stub_auth(self, json=None, url=None, verb=None, **kwargs):
subject_token = fakes.AUTH_TOKEN
@@ -229,10 +259,12 @@ class TestClientManager(utils.TestCase):
verify='cafile',
)
client_manager.setup_auth()
+ client_manager.auth_ref
self.assertFalse(client_manager._insecure)
self.assertTrue(client_manager._verify)
self.assertEqual('cafile', client_manager._cacert)
+ self.assertTrue(client_manager.is_network_endpoint_enabled())
def _select_auth_plugin(self, auth_params, api_version, auth_plugin_name):
auth_params['auth_type'] = auth_plugin_name
@@ -243,6 +275,7 @@ class TestClientManager(utils.TestCase):
verify=True
)
client_manager.setup_auth()
+ client_manager.auth_ref
self.assertEqual(
auth_plugin_name,
diff --git a/openstackclient/tests/network/common.py b/openstackclient/tests/common/test_command.py
index 31fde25..1b2584b 100644
--- a/openstackclient/tests/network/common.py
+++ b/openstackclient/tests/common/test_command.py
@@ -1,3 +1,5 @@
+# Copyright 2016 NEC Corporation
+#
# 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
@@ -9,27 +11,22 @@
# 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 argparse
import mock
-from openstackclient.api import network_v2
-from openstackclient.tests import utils
+from openstackclient.common import command
+from openstackclient.tests import utils as test_utils
-class FakeNetworkClient(object):
- pass
+class FakeCommand(command.Command):
+ def take_action(self, parsed_args):
+ pass
-class TestNetworkBase(utils.TestCommand):
- def setUp(self):
- super(TestNetworkBase, self).setUp()
- self.namespace = argparse.Namespace()
+class TestCommand(test_utils.TestCase):
- self.app.client_manager.network = FakeNetworkClient()
- self.app.client_manager.network.api = network_v2.APIv2(
- session=mock.Mock(),
- service_type="network",
- )
- self.api = self.app.client_manager.network.api
+ def test_command_has_logger(self):
+ cmd = FakeCommand(mock.Mock(), mock.Mock())
+ self.assertTrue(hasattr(cmd, 'log'))
+ self.assertEqual('openstackclient.tests.common.test_command.'
+ 'FakeCommand', cmd.log.name)
diff --git a/openstackclient/tests/common/test_configuration.py b/openstackclient/tests/common/test_configuration.py
index 3b94253..e81550e 100644
--- a/openstackclient/tests/common/test_configuration.py
+++ b/openstackclient/tests/common/test_configuration.py
@@ -18,6 +18,21 @@ from openstackclient.tests import utils
class TestConfiguration(utils.TestCommand):
+ columns = (
+ 'auth.password',
+ 'auth.token',
+ 'auth.username',
+ 'identity_api_version',
+ 'region',
+ )
+ datalist = (
+ configuration.REDACTED,
+ configuration.REDACTED,
+ fakes.USERNAME,
+ fakes.VERSION,
+ fakes.REGION_NAME,
+ )
+
def test_show(self):
arglist = []
verifylist = [('mask', True)]
@@ -26,17 +41,8 @@ class TestConfiguration(utils.TestCommand):
columns, data = cmd.take_action(parsed_args)
- collist = ('auth.password', 'auth.token', 'auth.username',
- 'identity_api_version', 'region')
- self.assertEqual(collist, columns)
- datalist = (
- configuration.REDACTED,
- configuration.REDACTED,
- fakes.USERNAME,
- fakes.VERSION,
- fakes.REGION_NAME,
- )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_show_unmask(self):
arglist = ['--unmask']
@@ -46,9 +52,7 @@ class TestConfiguration(utils.TestCommand):
columns, data = cmd.take_action(parsed_args)
- collist = ('auth.password', 'auth.token', 'auth.username',
- 'identity_api_version', 'region')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
fakes.PASSWORD,
fakes.AUTH_TOKEN,
@@ -56,7 +60,7 @@ class TestConfiguration(utils.TestCommand):
fakes.VERSION,
fakes.REGION_NAME,
)
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(datalist, data)
def test_show_mask(self):
arglist = ['--mask']
@@ -66,14 +70,5 @@ class TestConfiguration(utils.TestCommand):
columns, data = cmd.take_action(parsed_args)
- collist = ('auth.password', 'auth.token', 'auth.username',
- 'identity_api_version', 'region')
- self.assertEqual(collist, columns)
- datalist = (
- configuration.REDACTED,
- configuration.REDACTED,
- fakes.USERNAME,
- fakes.VERSION,
- fakes.REGION_NAME,
- )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
diff --git a/openstackclient/tests/common/test_extension.py b/openstackclient/tests/common/test_extension.py
index 6d34bdd..21c2cc2 100644
--- a/openstackclient/tests/common/test_extension.py
+++ b/openstackclient/tests/common/test_extension.py
@@ -34,14 +34,16 @@ class TestExtension(utils.TestCommand):
self.app.client_manager.identity.extensions)
self.identity_extensions_mock.reset_mock()
- network = network_fakes.FakeNetworkV2Client()
- self.app.client_manager.network = network
- self.network_extensions_mock = network.list_extensions
+ network_client = network_fakes.FakeNetworkV2Client()
+ self.app.client_manager.network = network_client
+ self.network_extensions_mock = network_client.extensions
self.network_extensions_mock.reset_mock()
class TestExtensionList(TestExtension):
+ columns = ('Name', 'Alias', 'Description')
+
def setUp(self):
super(TestExtensionList, self).setUp()
@@ -67,8 +69,7 @@ class TestExtensionList(TestExtension):
# no args should output from all services
self.identity_extensions_mock.list.assert_called_with()
- collist = ('Name', 'Alias', 'Description')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(
identity_fakes.extension_name,
@@ -135,8 +136,7 @@ class TestExtensionList(TestExtension):
self.identity_extensions_mock.list.assert_called_with()
- collist = ('Name', 'Alias', 'Description')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = ((
identity_fakes.extension_name,
identity_fakes.extension_alias,
@@ -157,8 +157,7 @@ class TestExtensionList(TestExtension):
self.network_extensions_mock.assert_called_with()
- collist = ('Name', 'Alias', 'Description')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(
network_fakes.extension_name,
diff --git a/openstackclient/tests/common/test_logs.py b/openstackclient/tests/common/test_logs.py
index fe054a3..a319533 100644
--- a/openstackclient/tests/common/test_logs.py
+++ b/openstackclient/tests/common/test_logs.py
@@ -137,7 +137,7 @@ class TestLogConfigurator(utils.TestCase):
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)
+ self.assertFalse(configurator.dump_trace)
@mock.patch('logging.getLogger')
@mock.patch('openstackclient.common.logs.set_warning_filter')
@@ -149,7 +149,7 @@ class TestLogConfigurator(utils.TestCase):
warning_filter.assert_called_with(logging.DEBUG)
self.requests_log.setLevel.assert_called_with(logging.DEBUG)
- self.assertEqual(True, configurator.dump_trace)
+ self.assertTrue(configurator.dump_trace)
@mock.patch('logging.FileHandler')
@mock.patch('logging.getLogger')
@@ -199,4 +199,4 @@ class TestLogConfigurator(utils.TestCase):
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)
+ self.assertFalse(configurator.dump_trace)
diff --git a/openstackclient/tests/common/test_parseractions.py b/openstackclient/tests/common/test_parseractions.py
index b75c481..0109a3f 100644
--- a/openstackclient/tests/common/test_parseractions.py
+++ b/openstackclient/tests/common/test_parseractions.py
@@ -20,34 +20,14 @@ from openstackclient.tests import utils
class TestKeyValueAction(utils.TestCase):
- def test_good_values(self):
- parser = argparse.ArgumentParser()
-
- # Set up our typical usage
- parser.add_argument(
- '--property',
- metavar='<key=value>',
- action=parseractions.KeyValueAction,
- help='Property to store for this volume '
- '(repeat option to set multiple properties)',
- )
-
- results = parser.parse_args([
- '--property', 'red=',
- '--property', 'green=100%',
- '--property', 'blue=50%',
- ])
- actual = getattr(results, 'property', {})
- # All should pass through unmolested
- expect = {'red': '', 'green': '100%', 'blue': '50%'}
- self.assertDictEqual(expect, actual)
+ def setUp(self):
+ super(TestKeyValueAction, self).setUp()
- def test_default_values(self):
- parser = argparse.ArgumentParser()
+ self.parser = argparse.ArgumentParser()
# Set up our typical usage
- parser.add_argument(
+ self.parser.add_argument(
'--property',
metavar='<key=value>',
action=parseractions.KeyValueAction,
@@ -56,84 +36,55 @@ class TestKeyValueAction(utils.TestCase):
'(repeat option to set multiple properties)',
)
- results = parser.parse_args([
+ def test_good_values(self):
+ results = self.parser.parse_args([
'--property', 'red=',
'--property', 'green=100%',
'--property', 'blue=50%',
])
actual = getattr(results, 'property', {})
- # Verify green default is changed, format default is unchanged
+ # All should pass through unmolested
expect = {'red': '', 'green': '100%', 'blue': '50%', 'format': '#rgb'}
self.assertDictEqual(expect, actual)
def test_error_values(self):
- parser = argparse.ArgumentParser()
-
- # Set up our typical usage
- parser.add_argument(
- '--property',
- metavar='<key=value>',
- action=parseractions.KeyValueAction,
- default={'green': '20%', 'blue': '40%'},
- help='Property to store for this volume '
- '(repeat option to set multiple properties)',
- )
-
- results = parser.parse_args([
+ results = self.parser.parse_args([
'--property', 'red',
'--property', 'green=100%',
'--property', 'blue',
])
- failhere = None
actual = getattr(results, 'property', {})
- # Verify non-existent red key
- try:
- failhere = actual['red']
- except Exception as e:
- self.assertTrue(type(e) == KeyError)
- # Verify removal of blue key
- try:
- failhere = actual['blue']
- except Exception as e:
- self.assertTrue(type(e) == KeyError)
# There should be no red or blue
- expect = {'green': '100%'}
+ expect = {'green': '100%', 'format': '#rgb'}
self.assertDictEqual(expect, actual)
- self.assertEqual(None, failhere)
class TestNonNegativeAction(utils.TestCase):
- def test_negative_values(self):
- parser = argparse.ArgumentParser()
+
+ def setUp(self):
+ super(TestNonNegativeAction, self).setUp()
+
+ self.parser = argparse.ArgumentParser()
# Set up our typical usage
- parser.add_argument(
+ self.parser.add_argument(
'--foo',
metavar='<foo>',
type=int,
action=parseractions.NonNegativeAction,
)
+ def test_negative_values(self):
self.assertRaises(
argparse.ArgumentTypeError,
- parser.parse_args,
+ self.parser.parse_args,
"--foo -1".split()
)
def test_zero_values(self):
- parser = argparse.ArgumentParser()
-
- # Set up our typical usage
- parser.add_argument(
- '--foo',
- metavar='<foo>',
- type=int,
- action=parseractions.NonNegativeAction,
- )
-
- results = parser.parse_args(
+ results = self.parser.parse_args(
'--foo 0'.split()
)
@@ -141,17 +92,7 @@ class TestNonNegativeAction(utils.TestCase):
self.assertEqual(actual, 0)
def test_positive_values(self):
- parser = argparse.ArgumentParser()
-
- # Set up our typical usage
- parser.add_argument(
- '--foo',
- metavar='<foo>',
- type=int,
- action=parseractions.NonNegativeAction,
- )
-
- results = parser.parse_args(
+ results = self.parser.parse_args(
'--foo 1'.split()
)
diff --git a/openstackclient/tests/common/test_quota.py b/openstackclient/tests/common/test_quota.py
index 485b8a8..edf29c9 100644
--- a/openstackclient/tests/common/test_quota.py
+++ b/openstackclient/tests/common/test_quota.py
@@ -214,13 +214,15 @@ class TestQuotaShow(TestQuota):
loaded=True,
)
- self.service_catalog_mock.get_endpoints.return_value = [
- fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ENDPOINT),
- loaded=True,
- )
- ]
+ fake_network_endpoint = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes.ENDPOINT),
+ loaded=True,
+ )
+
+ self.service_catalog_mock.get_endpoints.return_value = {
+ 'network': fake_network_endpoint
+ }
self.quotas_class_mock.get.return_value = FakeQuotaResource(
None,
@@ -244,6 +246,8 @@ class TestQuotaShow(TestQuota):
endpoint=fakes.AUTH_URL,
token=fakes.AUTH_TOKEN,
)
+ self.network = self.app.client_manager.network
+ self.network.get_quota = mock.Mock(return_value=network_fakes.QUOTA)
self.cmd = quota.ShowQuota(self.app, None)
@@ -260,6 +264,9 @@ class TestQuotaShow(TestQuota):
self.cmd.take_action(parsed_args)
self.quotas_mock.get.assert_called_with(identity_fakes.project_id)
+ self.volume_quotas_mock.get.assert_called_with(
+ identity_fakes.project_id)
+ self.network.get_quota.assert_called_with(identity_fakes.project_id)
def test_quota_show_with_default(self):
arglist = [
@@ -276,6 +283,8 @@ class TestQuotaShow(TestQuota):
self.cmd.take_action(parsed_args)
self.quotas_mock.defaults.assert_called_with(identity_fakes.project_id)
+ self.volume_quotas_mock.defaults.assert_called_with(
+ identity_fakes.project_id)
def test_quota_show_with_class(self):
arglist = [
@@ -293,3 +302,5 @@ class TestQuotaShow(TestQuota):
self.quotas_class_mock.get.assert_called_with(
identity_fakes.project_id)
+ self.volume_quotas_class_mock.get.assert_called_with(
+ identity_fakes.project_id)
diff --git a/openstackclient/tests/common/test_timing.py b/openstackclient/tests/common/test_timing.py
index a7f93b5..e7b9a04 100644
--- a/openstackclient/tests/common/test_timing.py
+++ b/openstackclient/tests/common/test_timing.py
@@ -33,6 +33,11 @@ class FakeGenericClient(object):
class TestTiming(utils.TestCommand):
+ columns = (
+ 'URL',
+ 'Seconds',
+ )
+
def setUp(self):
super(TestTiming, self).setUp()
@@ -59,8 +64,7 @@ class TestTiming(utils.TestCommand):
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- collist = ('URL', 'Seconds')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = [
('Total', 0.0,)
]
@@ -78,9 +82,7 @@ class TestTiming(utils.TestCommand):
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
-
- collist = ('URL', 'Seconds')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = [
(timing_url, timing_elapsed),
('Total', timing_elapsed),
diff --git a/openstackclient/tests/common/test_utils.py b/openstackclient/tests/common/test_utils.py
index b564ffa..0954507 100644
--- a/openstackclient/tests/common/test_utils.py
+++ b/openstackclient/tests/common/test_utils.py
@@ -212,6 +212,28 @@ class TestUtils(test_utils.TestCase):
self.assertFalse(utils.wait_for_delete(manager, res_id))
self.assertFalse(mock_sleep.called)
+ @mock.patch.object(time, 'sleep')
+ def test_wait_for_delete_error_with_overrides(self, mock_sleep):
+ # Tests that we fail if the resource is my_status=failed
+ resource = mock.MagicMock(my_status='FAILED')
+ mock_get = mock.Mock(return_value=resource)
+ manager = mock.MagicMock(get=mock_get)
+ res_id = str(uuid.uuid4())
+ self.assertFalse(utils.wait_for_delete(manager, res_id,
+ status_field='my_status',
+ error_status=['failed']))
+ self.assertFalse(mock_sleep.called)
+
+ @mock.patch.object(time, 'sleep')
+ def test_wait_for_delete_error_with_overrides_exception(self, mock_sleep):
+ # Tests that we succeed if the resource is specific exception
+ mock_get = mock.Mock(side_effect=Exception)
+ manager = mock.MagicMock(get=mock_get)
+ res_id = str(uuid.uuid4())
+ self.assertTrue(utils.wait_for_delete(manager, res_id,
+ exception_name=['Exception']))
+ self.assertFalse(mock_sleep.called)
+
def test_build_kwargs_dict_value_set(self):
self.assertEqual({'arg_bla': 'bla'},
utils.build_kwargs_dict('arg_bla', 'bla'))
@@ -347,3 +369,19 @@ class TestFindResource(test_utils.TestCase):
expected = 'a, b, c'
self.assertEqual(expected, utils.format_list(['a', 'b', 'c']))
self.assertEqual(expected, utils.format_list(['c', 'b', 'a']))
+
+ def test_format_list_of_dicts(self):
+ expected = "a='b', c='d'\ne='f'"
+ sorted_data = [{'a': 'b', 'c': 'd'}, {'e': 'f'}]
+ unsorted_data = [{'c': 'd', 'a': 'b'}, {'e': 'f'}]
+ self.assertEqual(expected, utils.format_list_of_dicts(sorted_data))
+ self.assertEqual(expected, utils.format_list_of_dicts(unsorted_data))
+ self.assertEqual('', utils.format_list_of_dicts([]))
+ self.assertEqual('', utils.format_list_of_dicts([{}]))
+
+ def test_format_list_separator(self):
+ expected = 'a\nb\nc'
+ actual_pre_sorted = utils.format_list(['a', 'b', 'c'], separator='\n')
+ actual_unsorted = utils.format_list(['c', 'b', 'a'], separator='\n')
+ self.assertEqual(expected, actual_pre_sorted)
+ self.assertEqual(expected, actual_unsorted)
diff --git a/openstackclient/tests/compute/v2/fakes.py b/openstackclient/tests/compute/v2/fakes.py
index 91cc2bd..a90c9ee 100644
--- a/openstackclient/tests/compute/v2/fakes.py
+++ b/openstackclient/tests/compute/v2/fakes.py
@@ -76,8 +76,6 @@ QUOTA = {
QUOTA_columns = tuple(sorted(QUOTA))
QUOTA_data = tuple(QUOTA[x] for x in sorted(QUOTA))
-block_device_mapping = 'vda=' + volume_fakes.volume_name + ':::0'
-
service_host = 'host_test'
service_binary = 'compute_test'
service_status = 'enabled'
@@ -90,6 +88,8 @@ SERVICE = {
class FakeComputev2Client(object):
def __init__(self, **kwargs):
+ self.availability_zones = mock.Mock()
+ self.availability_zones.resource_class = fakes.FakeResource(None, {})
self.images = mock.Mock()
self.images.resource_class = fakes.FakeResource(None, {})
self.servers = mock.Mock()
@@ -291,3 +291,63 @@ class FakeFlavor(object):
if flavors is None:
flavors = FakeServer.create_flavors(count)
return mock.MagicMock(side_effect=flavors)
+
+
+class FakeAvailabilityZone(object):
+ """Fake one or more compute availability zones (AZs)."""
+
+ @staticmethod
+ def create_one_availability_zone(attrs={}, methods={}):
+ """Create a fake AZ.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :return:
+ A FakeResource object with zoneName, zoneState, etc.
+ """
+ # Set default attributes.
+ host_name = uuid.uuid4().hex
+ service_name = uuid.uuid4().hex
+ service_updated_at = uuid.uuid4().hex
+ availability_zone = {
+ 'zoneName': uuid.uuid4().hex,
+ 'zoneState': {'available': True},
+ 'hosts': {host_name: {service_name: {
+ 'available': True,
+ 'active': True,
+ 'updated_at': service_updated_at,
+ }}},
+ }
+
+ # Overwrite default attributes.
+ availability_zone.update(attrs)
+
+ availability_zone = fakes.FakeResource(
+ info=copy.deepcopy(availability_zone),
+ methods=methods,
+ loaded=True)
+ return availability_zone
+
+ @staticmethod
+ def create_availability_zones(attrs={}, methods={}, count=2):
+ """Create multiple fake AZs.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :param int count:
+ The number of AZs to fake
+ :return:
+ A list of FakeResource objects faking the AZs
+ """
+ availability_zones = []
+ for i in range(0, count):
+ availability_zone = \
+ FakeAvailabilityZone.create_one_availability_zone(
+ attrs, methods)
+ availability_zones.append(availability_zone)
+
+ return availability_zones
diff --git a/openstackclient/tests/compute/v2/test_flavor.py b/openstackclient/tests/compute/v2/test_flavor.py
index 60356ef..3a59020 100644
--- a/openstackclient/tests/compute/v2/test_flavor.py
+++ b/openstackclient/tests/compute/v2/test_flavor.py
@@ -173,10 +173,10 @@ class TestFlavorList(TestFlavor):
def test_flavor_list_private_flavors(self):
arglist = [
'--private',
- ]
+ ]
verifylist = [
('public', False),
- ]
+ ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -200,10 +200,10 @@ class TestFlavorList(TestFlavor):
def test_flavor_list_public_flavors(self):
arglist = [
'--public',
- ]
+ ]
verifylist = [
('public', True),
- ]
+ ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/compute/v2/test_security_group.py b/openstackclient/tests/compute/v2/test_security_group.py
index fdb659a..87cc487 100644
--- a/openstackclient/tests/compute/v2/test_security_group.py
+++ b/openstackclient/tests/compute/v2/test_security_group.py
@@ -56,6 +56,19 @@ class TestSecurityGroup(compute_fakes.TestComputev2):
class TestSecurityGroupCreate(TestSecurityGroup):
+ columns = (
+ 'description',
+ 'id',
+ 'name',
+ 'tenant_id',
+ )
+ data = (
+ security_group_description,
+ security_group_id,
+ security_group_name,
+ identity_fakes.project_id,
+ )
+
def setUp(self):
super(TestSecurityGroupCreate, self).setUp()
@@ -86,20 +99,8 @@ class TestSecurityGroupCreate(TestSecurityGroup):
security_group_name,
)
- collist = (
- 'description',
- 'id',
- 'name',
- 'tenant_id',
- )
- self.assertEqual(collist, columns)
- datalist = (
- security_group_description,
- security_group_id,
- security_group_name,
- identity_fakes.project_id,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
def test_security_group_create_description(self):
arglist = [
@@ -121,20 +122,8 @@ class TestSecurityGroupCreate(TestSecurityGroup):
security_group_description,
)
- collist = (
- 'description',
- 'id',
- 'name',
- 'tenant_id',
- )
- self.assertEqual(collist, columns)
- datalist = (
- security_group_description,
- security_group_id,
- security_group_name,
- identity_fakes.project_id,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
class TestSecurityGroupList(TestSecurityGroup):
diff --git a/openstackclient/tests/compute/v2/test_security_group_rule.py b/openstackclient/tests/compute/v2/test_security_group_rule.py
index 9516f8d..a2f9b10 100644
--- a/openstackclient/tests/compute/v2/test_security_group_rule.py
+++ b/openstackclient/tests/compute/v2/test_security_group_rule.py
@@ -18,6 +18,7 @@ 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
+from openstackclient.tests import utils
security_group_id = '11'
@@ -25,19 +26,13 @@ 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_cidr = '0.0.0.0/0'
SECURITY_GROUP_RULE = {
'id': security_group_rule_id,
'group': {},
'ip_protocol': 'tcp',
- 'ip_range': '0.0.0.0/0',
+ 'ip_range': {'cidr': security_group_rule_cidr},
'parent_group_id': security_group_id,
'from_port': 0,
'to_port': 0,
@@ -47,12 +42,54 @@ SECURITY_GROUP_RULE_ICMP = {
'id': security_group_rule_id,
'group': {},
'ip_protocol': 'icmp',
- 'ip_range': '0.0.0.0/0',
+ 'ip_range': {'cidr': security_group_rule_cidr},
'parent_group_id': security_group_id,
'from_port': -1,
'to_port': -1,
}
+SECURITY_GROUP_RULE_REMOTE_GROUP = {
+ 'id': security_group_rule_id,
+ 'group': {"tenant_id": "14", "name": "default"},
+ 'ip_protocol': 'tcp',
+ 'ip_range': {},
+ 'parent_group_id': security_group_id,
+ 'from_port': 80,
+ 'to_port': 80,
+}
+
+SECURITY_GROUP = {
+ 'id': security_group_id,
+ 'name': security_group_name,
+ 'description': security_group_description,
+ 'tenant_id': identity_fakes.project_id,
+ 'rules': [SECURITY_GROUP_RULE,
+ SECURITY_GROUP_RULE_ICMP,
+ SECURITY_GROUP_RULE_REMOTE_GROUP],
+}
+
+security_group_2_id = '12'
+security_group_2_name = 'he-shoots'
+security_group_2_description = 'he scores'
+
+SECURITY_GROUP_2_RULE = {
+ 'id': '2',
+ 'group': {},
+ 'ip_protocol': 'tcp',
+ 'ip_range': {},
+ 'parent_group_id': security_group_2_id,
+ 'from_port': 80,
+ 'to_port': 80,
+}
+
+SECURITY_GROUP_2 = {
+ 'id': security_group_2_id,
+ 'name': security_group_2_name,
+ 'description': security_group_2_description,
+ 'tenant_id': identity_fakes.project_id,
+ 'rules': [SECURITY_GROUP_2_RULE],
+}
+
class FakeSecurityGroupRuleResource(fakes.FakeResource):
@@ -79,6 +116,15 @@ class TestSecurityGroupRule(compute_fakes.TestComputev2):
class TestSecurityGroupRuleCreate(TestSecurityGroupRule):
+ columns = (
+ 'id',
+ 'ip_protocol',
+ 'ip_range',
+ 'parent_group_id',
+ 'port_range',
+ 'remote_security_group',
+ )
+
def setUp(self):
super(TestSecurityGroupRuleCreate, self).setUp()
@@ -115,25 +161,18 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule):
'tcp',
0,
0,
- '0.0.0.0/0',
+ security_group_rule_cidr,
+ None,
)
- collist = (
- 'group',
- 'id',
- 'ip_protocol',
- 'ip_range',
- 'parent_group_id',
- 'port_range',
- )
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
- {},
security_group_rule_id,
'tcp',
- '',
+ security_group_rule_cidr,
security_group_id,
'0:0',
+ '',
)
self.assertEqual(datalist, data)
@@ -166,25 +205,18 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule):
'tcp',
20,
21,
- '0.0.0.0/0',
+ security_group_rule_cidr,
+ None,
)
- collist = (
- 'group',
- 'id',
- 'ip_protocol',
- 'ip_range',
- 'parent_group_id',
- 'port_range',
- )
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
- {},
security_group_rule_id,
'tcp',
- '',
+ security_group_rule_cidr,
security_group_id,
'20:21',
+ '',
)
self.assertEqual(datalist, data)
@@ -192,6 +224,8 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule):
sg_rule = copy.deepcopy(SECURITY_GROUP_RULE)
sg_rule['from_port'] = 22
sg_rule['to_port'] = 22
+ sg_rule['ip_range'] = {}
+ sg_rule['group'] = {'name': security_group_name}
self.sg_rules_mock.create.return_value = FakeSecurityGroupRuleResource(
None,
sg_rule,
@@ -201,10 +235,12 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule):
arglist = [
security_group_name,
'--dst-port', '22',
+ '--src-group', security_group_id,
]
verifylist = [
('group', security_group_name),
('dst_port', (22, 22)),
+ ('src_group', security_group_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -217,25 +253,18 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule):
'tcp',
22,
22,
- '0.0.0.0/0',
+ security_group_rule_cidr,
+ security_group_id,
)
- collist = (
- 'group',
- 'id',
- 'ip_protocol',
- 'ip_range',
- 'parent_group_id',
- 'port_range',
- )
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
- {},
security_group_rule_id,
'tcp',
'',
security_group_id,
'22:22',
+ security_group_name,
)
self.assertEqual(datalist, data)
@@ -267,42 +296,40 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule):
'udp',
0,
0,
- '0.0.0.0/0',
+ security_group_rule_cidr,
+ None,
)
- collist = (
- 'group',
- 'id',
- 'ip_protocol',
- 'ip_range',
- 'parent_group_id',
- 'port_range',
- )
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
- {},
security_group_rule_id,
'udp',
- '',
+ security_group_rule_cidr,
security_group_id,
'0:0',
+ '',
)
self.assertEqual(datalist, data)
def test_security_group_rule_create_icmp(self):
+ sg_rule_cidr = '10.0.2.0/24'
+ sg_rule = copy.deepcopy(SECURITY_GROUP_RULE_ICMP)
+ sg_rule['ip_range'] = {'cidr': sg_rule_cidr}
self.sg_rules_mock.create.return_value = FakeSecurityGroupRuleResource(
None,
- copy.deepcopy(SECURITY_GROUP_RULE_ICMP),
+ sg_rule,
loaded=True,
)
arglist = [
security_group_name,
'--proto', 'ICMP',
+ '--src-ip', sg_rule_cidr,
]
verifylist = [
('group', security_group_name),
('proto', 'ICMP'),
+ ('src_ip', sg_rule_cidr)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -315,24 +342,143 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule):
'ICMP',
-1,
-1,
- '0.0.0.0/0',
+ sg_rule_cidr,
+ None,
+ )
+
+ self.assertEqual(self.columns, columns)
+ datalist = (
+ security_group_rule_id,
+ 'icmp',
+ sg_rule_cidr,
+ security_group_id,
+ '',
+ '',
+ )
+ self.assertEqual(datalist, data)
+
+ def test_security_group_rule_create_src_invalid(self):
+ arglist = [
+ security_group_name,
+ '--proto', 'ICMP',
+ '--src-ip', security_group_rule_cidr,
+ '--src-group', security_group_id,
+ ]
+
+ self.assertRaises(utils.ParserException,
+ self.check_parser, self.cmd, arglist, [])
+
+
+class TestSecurityGroupRuleList(TestSecurityGroupRule):
+
+ def setUp(self):
+ super(TestSecurityGroupRuleList, self).setUp()
+
+ security_group_mock = FakeSecurityGroupRuleResource(
+ None,
+ copy.deepcopy(SECURITY_GROUP),
+ loaded=True,
+ )
+
+ security_group_2_mock = FakeSecurityGroupRuleResource(
+ None,
+ copy.deepcopy(SECURITY_GROUP_2),
+ loaded=True,
)
+ self.secgroups_mock.get.return_value = security_group_mock
+ self.secgroups_mock.list.return_value = [security_group_mock,
+ security_group_2_mock]
+
+ # Get the command object to test
+ self.cmd = security_group.ListSecurityGroupRule(self.app, None)
+
+ def test_security_group_rule_list(self):
+
+ 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)
+
collist = (
- 'group',
- 'id',
- 'ip_protocol',
- 'ip_range',
- 'parent_group_id',
- 'port_range',
+ 'ID',
+ 'IP Protocol',
+ 'IP Range',
+ 'Port Range',
+ 'Remote Security Group',
)
self.assertEqual(collist, columns)
- datalist = (
- {},
+ datalist = ((
+ security_group_rule_id,
+ 'tcp',
+ security_group_rule_cidr,
+ '0:0',
+ '',
+ ), (
security_group_rule_id,
'icmp',
+ security_group_rule_cidr,
'',
- security_group_id,
'',
+ ), (
+ security_group_rule_id,
+ 'tcp',
+ '',
+ '80:80',
+ 'default',
+ ),)
+ self.assertEqual(datalist, tuple(data))
+
+ def test_security_group_rule_list_no_group(self):
+
+ parsed_args = self.check_parser(self.cmd, [], [])
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ collist = (
+ 'ID',
+ 'IP Protocol',
+ 'IP Range',
+ 'Port Range',
+ 'Remote Security Group',
+ 'Security Group',
)
- self.assertEqual(datalist, data)
+ self.assertEqual(collist, columns)
+ datalist = ((
+ security_group_rule_id,
+ 'tcp',
+ security_group_rule_cidr,
+ '0:0',
+ '',
+ security_group_id,
+ ), (
+ security_group_rule_id,
+ 'icmp',
+ security_group_rule_cidr,
+ '',
+ '',
+ security_group_id,
+ ), (
+ security_group_rule_id,
+ 'tcp',
+ '',
+ '80:80',
+ 'default',
+ security_group_id,
+ ), (
+ '2',
+ 'tcp',
+ '',
+ '80:80',
+ '',
+ security_group_2_id,
+ ),)
+ self.assertEqual(datalist, tuple(data))
diff --git a/openstackclient/tests/compute/v2/test_server.py b/openstackclient/tests/compute/v2/test_server.py
index 359920f..f6b6229 100644
--- a/openstackclient/tests/compute/v2/test_server.py
+++ b/openstackclient/tests/compute/v2/test_server.py
@@ -13,16 +13,13 @@
# under the License.
#
-import copy
import mock
-import testtools
from mock import call
from openstackclient.common import exceptions
from openstackclient.common import utils as common_utils
from openstackclient.compute.v2 import server
from openstackclient.tests.compute.v2 import fakes as compute_fakes
-from openstackclient.tests import fakes
from openstackclient.tests.image.v2 import fakes as image_fakes
from openstackclient.tests import utils
from openstackclient.tests.volume.v2 import fakes as volume_fakes
@@ -33,23 +30,23 @@ class TestServer(compute_fakes.TestComputev2):
def setUp(self):
super(TestServer, self).setUp()
- # Get a shortcut to the ServerManager Mock
+ # Get a shortcut to the compute client ServerManager Mock
self.servers_mock = self.app.client_manager.compute.servers
self.servers_mock.reset_mock()
- # Get a shortcut to the ImageManager Mock
+ # Get a shortcut to the compute client ImageManager Mock
self.cimages_mock = self.app.client_manager.compute.images
self.cimages_mock.reset_mock()
- # Get a shortcut to the FlavorManager Mock
+ # Get a shortcut to the compute client FlavorManager Mock
self.flavors_mock = self.app.client_manager.compute.flavors
self.flavors_mock.reset_mock()
- # Get a shortcut to the ImageManager Mock
+ # Get a shortcut to the image client ImageManager Mock
self.images_mock = self.app.client_manager.image.images
self.images_mock.reset_mock()
- # Get a shortcut to the VolumeManager Mock
+ # Get a shortcut to the volume client VolumeManager Mock
self.volumes_mock = self.app.client_manager.volume.volumes
self.volumes_mock.reset_mock()
@@ -92,6 +89,26 @@ class TestServer(compute_fakes.TestComputev2):
class TestServerCreate(TestServer):
+ columns = (
+ 'addresses',
+ 'flavor',
+ 'id',
+ 'name',
+ 'networks',
+ 'properties',
+ )
+
+ def datalist(self):
+ datalist = (
+ '',
+ self.flavor.name + ' ()',
+ self.new_server.id,
+ self.new_server.name,
+ self.new_server.networks,
+ '',
+ )
+ return datalist
+
def setUp(self):
super(TestServerCreate, self).setUp()
@@ -107,22 +124,15 @@ class TestServerCreate(TestServer):
self.servers_mock.create.return_value = self.new_server
- self.image = fakes.FakeResource(
- None,
- copy.deepcopy(image_fakes.IMAGE),
- loaded=True,
- )
+ self.image = image_fakes.FakeImage.create_one_image()
self.cimages_mock.get.return_value = self.image
self.flavor = compute_fakes.FakeFlavor.create_one_flavor()
self.flavors_mock.get.return_value = self.flavor
- self.volume = fakes.FakeResource(
- None,
- copy.deepcopy(volume_fakes.VOLUME),
- loaded=True,
- )
+ self.volume = volume_fakes.FakeVolume.create_one_volume()
self.volumes_mock.get.return_value = self.volume
+ self.block_device_mapping = 'vda=' + self.volume.name + ':::0'
# Get the command object to test
self.cmd = server.CreateServer(self.app, None)
@@ -181,24 +191,8 @@ class TestServerCreate(TestServer):
**kwargs
)
- collist = (
- 'addresses',
- 'flavor',
- 'id',
- 'name',
- 'networks',
- 'properties',
- )
- self.assertEqual(collist, columns)
- datalist = (
- '',
- self.flavor.name + ' ()',
- self.new_server.id,
- self.new_server.name,
- self.new_server.networks,
- '',
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist(), data)
def test_server_create_with_network(self):
arglist = [
@@ -224,12 +218,29 @@ class TestServerCreate(TestServer):
self.app.client_manager.auth_ref.service_catalog.get_endpoints = (
get_endpoints)
- list_networks = mock.Mock()
- list_ports = mock.Mock()
- self.app.client_manager.network.list_networks = list_networks
- self.app.client_manager.network.list_ports = list_ports
- list_networks.return_value = {'networks': [{'id': 'net1_uuid'}]}
- list_ports.return_value = {'ports': [{'id': 'port1_uuid'}]}
+ find_network = mock.Mock()
+ find_port = mock.Mock()
+ network_client = self.app.client_manager.network
+ network_client.find_network = find_network
+ network_client.find_port = find_port
+ network_resource = mock.Mock()
+ network_resource.id = 'net1_uuid'
+ port_resource = mock.Mock()
+ port_resource.id = 'port1_uuid'
+ find_network.return_value = network_resource
+ find_port.return_value = port_resource
+
+ # Mock sdk APIs.
+ _network = mock.Mock()
+ _network.id = 'net1_uuid'
+ _port = mock.Mock()
+ _port.id = 'port1_uuid'
+ find_network = mock.Mock()
+ find_port = mock.Mock()
+ find_network.return_value = _network
+ find_port.return_value = _port
+ self.app.client_manager.network.find_network = find_network
+ self.app.client_manager.network.find_port = find_port
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
@@ -265,24 +276,8 @@ class TestServerCreate(TestServer):
**kwargs
)
- collist = (
- 'addresses',
- 'flavor',
- 'id',
- 'name',
- 'networks',
- 'properties',
- )
- self.assertEqual(collist, columns)
- datalist = (
- '',
- self.flavor.name + ' ()',
- self.new_server.id,
- self.new_server.name,
- self.new_server.networks,
- '',
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist(), data)
@mock.patch('openstackclient.compute.v2.server.io.open')
def test_server_create_userdata(self, mock_open):
@@ -338,36 +333,20 @@ class TestServerCreate(TestServer):
**kwargs
)
- collist = (
- 'addresses',
- 'flavor',
- 'id',
- 'name',
- 'networks',
- 'properties',
- )
- self.assertEqual(collist, columns)
- datalist = (
- '',
- self.flavor.name + ' ()',
- self.new_server.id,
- self.new_server.name,
- self.new_server.networks,
- '',
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist(), data)
def test_server_create_with_block_device_mapping(self):
arglist = [
'--image', 'image1',
'--flavor', self.flavor.id,
- '--block-device-mapping', compute_fakes.block_device_mapping,
+ '--block-device-mapping', self.block_device_mapping,
self.new_server.name,
]
verifylist = [
('image', 'image1'),
('flavor', self.flavor.id),
- ('block_device_mapping', [compute_fakes.block_device_mapping]),
+ ('block_device_mapping', [self.block_device_mapping]),
('config_drive', False),
('server_name', self.new_server.name),
]
@@ -377,9 +356,9 @@ class TestServerCreate(TestServer):
columns, data = self.cmd.take_action(parsed_args)
real_volume_mapping = (
- (compute_fakes.block_device_mapping.split('=', 1)[1]).replace(
- volume_fakes.volume_name,
- volume_fakes.volume_id))
+ (self.block_device_mapping.split('=', 1)[1]).replace(
+ self.volume.name,
+ self.volume.id))
# Set expected values
kwargs = dict(
@@ -407,24 +386,8 @@ class TestServerCreate(TestServer):
**kwargs
)
- collist = (
- 'addresses',
- 'flavor',
- 'id',
- 'name',
- 'networks',
- 'properties',
- )
- self.assertEqual(collist, columns)
- datalist = (
- '',
- self.flavor.name + ' ()',
- self.new_server.id,
- self.new_server.name,
- self.new_server.networks,
- '',
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist(), data)
class TestServerDelete(TestServer):
@@ -529,6 +492,26 @@ class TestServerDelete(TestServer):
class TestServerImageCreate(TestServer):
+ columns = (
+ 'id',
+ 'name',
+ 'owner',
+ 'protected',
+ 'tags',
+ 'visibility',
+ )
+
+ def datalist(self):
+ datalist = (
+ self.image.id,
+ self.image.name,
+ self.image.owner,
+ self.image.protected,
+ self.image.tags,
+ self.image.visibility,
+ )
+ return datalist
+
def setUp(self):
super(TestServerImageCreate, self).setUp()
@@ -537,13 +520,9 @@ class TestServerImageCreate(TestServer):
# This is the return value for utils.find_resource()
self.servers_mock.get.return_value = self.server
- self.servers_mock.create_image.return_value = image_fakes.image_id
-
- self.images_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(image_fakes.IMAGE),
- loaded=True,
- )
+ self.image = image_fakes.FakeImage.create_one_image()
+ self.images_mock.get.return_value = self.image
+ self.servers_mock.create_image.return_value = self.image.id
# Get the command object to test
self.cmd = server.CreateServerImage(self.app, None)
@@ -566,17 +545,8 @@ class TestServerImageCreate(TestServer):
self.server.name,
)
- collist = ('id', 'name', 'owner', 'protected', 'tags', 'visibility')
- self.assertEqual(collist, columns)
- datalist = (
- image_fakes.image_id,
- image_fakes.image_name,
- image_fakes.image_owner,
- image_fakes.image_protected,
- image_fakes.image_tags,
- image_fakes.image_visibility,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist(), data)
def test_server_image_create_name(self):
arglist = [
@@ -598,17 +568,8 @@ class TestServerImageCreate(TestServer):
'img-nam',
)
- collist = ('id', 'name', 'owner', 'protected', 'tags', 'visibility')
- self.assertEqual(collist, columns)
- datalist = (
- image_fakes.image_id,
- image_fakes.image_name,
- image_fakes.image_owner,
- image_fakes.image_protected,
- image_fakes.image_tags,
- image_fakes.image_visibility,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist(), data)
class TestServerList(TestServer):
@@ -620,10 +581,17 @@ class TestServerList(TestServer):
'Status',
'Networks',
)
-
- # Data returned by corresponding Nova API. The elements in this list are
- # tuples filled with server attributes.
- data = []
+ columns_long = (
+ 'ID',
+ 'Name',
+ 'Status',
+ 'Task State',
+ 'Power State',
+ 'Networks',
+ 'Availability Zone',
+ 'Host',
+ 'Properties',
+ )
# Default search options, in the case of no commandline option specified.
search_opts = {
@@ -652,12 +620,18 @@ class TestServerList(TestServer):
def setUp(self):
super(TestServerList, self).setUp()
- # The fake servers' attributes.
+ # The fake servers' attributes. Use the original attributes names in
+ # nova, not the ones printed by "server list" command.
self.attrs = {
'status': 'ACTIVE',
+ 'OS-EXT-STS:task_state': 'None',
+ 'OS-EXT-STS:power_state': 0x01, # Running
'networks': {
u'public': [u'10.20.30.40', u'2001:db8::5']
},
+ 'OS-EXT-AZ:availability_zone': 'availability-zone-xxx',
+ 'OS-EXT-SRV-ATTR:host': 'host-name-xxx',
+ 'Metadata': '',
}
# The servers to be listed.
@@ -669,12 +643,28 @@ class TestServerList(TestServer):
self.cmd = server.ListServer(self.app, None)
# Prepare data returned by fake Nova API.
+ self.data = []
+ self.data_long = []
+
for s in self.servers:
self.data.append((
s.id,
s.name,
s.status,
- u'public=10.20.30.40, 2001:db8::5',
+ server._format_servers_list_networks(s.networks),
+ ))
+ self.data_long.append((
+ s.id,
+ s.name,
+ s.status,
+ getattr(s, 'OS-EXT-STS:task_state'),
+ server._format_servers_list_power_state(
+ getattr(s, 'OS-EXT-STS:power_state')
+ ),
+ server._format_servers_list_networks(s.networks),
+ getattr(s, 'OS-EXT-AZ:availability_zone'),
+ getattr(s, 'OS-EXT-SRV-ATTR:host'),
+ s.Metadata,
))
def test_server_list_no_option(self):
@@ -691,6 +681,22 @@ class TestServerList(TestServer):
self.assertEqual(self.columns, columns)
self.assertEqual(tuple(self.data), tuple(data))
+ def test_server_list_long_option(self):
+ arglist = [
+ '--long',
+ ]
+ verifylist = [
+ ('all_projects', False),
+ ('long', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.servers_mock.list.assert_called_with(**self.kwargs)
+ self.assertEqual(self.columns_long, columns)
+ self.assertEqual(tuple(self.data_long), tuple(data))
+
class TestServerLock(TestServer):
@@ -732,6 +738,76 @@ class TestServerPause(TestServer):
self.run_method_with_servers('pause', 3)
+class TestServerRebuild(TestServer):
+
+ def setUp(self):
+ super(TestServerRebuild, self).setUp()
+
+ # Return value for utils.find_resource for image
+ self.image = image_fakes.FakeImage.create_one_image()
+ self.cimages_mock.get.return_value = self.image
+
+ # Fake the rebuilt new server.
+ new_server = compute_fakes.FakeServer.create_one_server()
+
+ # Fake the server to be rebuilt. The IDs of them should be the same.
+ attrs = {
+ 'id': new_server.id,
+ 'image': {
+ 'id': self.image.id
+ },
+ 'networks': {},
+ 'adminPass': 'passw0rd',
+ }
+ methods = {
+ 'rebuild': new_server,
+ }
+ self.server = compute_fakes.FakeServer.create_one_server(
+ attrs=attrs,
+ methods=methods
+ )
+
+ # Return value for utils.find_resource for server.
+ self.servers_mock.get.return_value = self.server
+
+ self.cmd = server.RebuildServer(self.app, None)
+
+ def test_rebuild_with_current_image(self):
+ arglist = [
+ self.server.id,
+ ]
+ verifylist = [
+ ('server', self.server.id)
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # Get the command object to test.
+ self.cmd.take_action(parsed_args)
+
+ self.servers_mock.get.assert_called_with(self.server.id)
+ self.cimages_mock.get.assert_called_with(self.image.id)
+ self.server.rebuild.assert_called_with(self.image, None)
+
+ def test_rebuild_with_current_image_and_password(self):
+ password = 'password-xxx'
+ arglist = [
+ self.server.id,
+ '--password', password
+ ]
+ verifylist = [
+ ('server', self.server.id),
+ ('password', password)
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # Get the command object to test
+ self.cmd.take_action(parsed_args)
+
+ self.servers_mock.get.assert_called_with(self.server.id)
+ self.cimages_mock.get.assert_called_with(self.image.id)
+ self.server.rebuild.assert_called_with(self.image, password)
+
+
class TestServerResize(TestServer):
def setUp(self):
@@ -1017,7 +1093,7 @@ class TestServerUnshelve(TestServer):
self.run_method_with_servers('unshelve', 3)
-class TestServerGeneral(testtools.TestCase):
+class TestServerGeneral(TestServer):
OLD = {
'private': [
{
@@ -1067,3 +1143,90 @@ class TestServerGeneral(testtools.TestCase):
server._get_ip_address, self.OLD, 'public', [4, 6])
self.assertRaises(exceptions.CommandError,
server._get_ip_address, self.OLD, 'private', [6])
+
+ def test_format_servers_list_power_state(self):
+ self.assertEqual("NOSTATE",
+ server._format_servers_list_power_state(0x00))
+ self.assertEqual("Running",
+ server._format_servers_list_power_state(0x01))
+ self.assertEqual("",
+ server._format_servers_list_power_state(0x02))
+ self.assertEqual("Paused",
+ server._format_servers_list_power_state(0x03))
+ self.assertEqual("Shutdown",
+ server._format_servers_list_power_state(0x04))
+ self.assertEqual("",
+ server._format_servers_list_power_state(0x05))
+ self.assertEqual("Crashed",
+ server._format_servers_list_power_state(0x06))
+ self.assertEqual("Suspended",
+ server._format_servers_list_power_state(0x07))
+ self.assertEqual("N/A",
+ server._format_servers_list_power_state(0x08))
+
+ def test_format_servers_list_networks(self):
+ # Setup network info to test.
+ networks = {
+ u'public': [u'10.20.30.40', u'2001:db8::f'],
+ u'private': [u'2001:db8::f', u'10.20.30.40'],
+ }
+
+ # Prepare expected data.
+ # Since networks is a dict, whose items are in random order, there
+ # could be two results after formatted.
+ data_1 = (u'private=2001:db8::f, 10.20.30.40; '
+ u'public=10.20.30.40, 2001:db8::f')
+ data_2 = (u'public=10.20.30.40, 2001:db8::f; '
+ u'private=2001:db8::f, 10.20.30.40')
+
+ # Call _format_servers_list_networks().
+ networks_format = server._format_servers_list_networks(networks)
+
+ msg = ('Network string is not formatted correctly.\n'
+ 'reference = %s or %s\n'
+ 'actual = %s\n' %
+ (data_1, data_2, networks_format))
+ self.assertIn(networks_format, (data_1, data_2), msg)
+
+ @mock.patch('openstackclient.common.utils.find_resource')
+ def test_prep_server_detail(self, find_resource):
+ # Setup mock method return value. utils.find_resource() will be called
+ # twice in _prep_server_detail():
+ # - The first time, return image info.
+ # - The second time, return flavor info.
+ _image = image_fakes.FakeImage.create_one_image()
+ _flavor = compute_fakes.FakeFlavor.create_one_flavor()
+ find_resource.side_effect = [_image, _flavor]
+
+ # compute_client.servers.get() will be called once, return server info.
+ server_info = {
+ 'image': {u'id': _image.id},
+ 'flavor': {u'id': _flavor.id},
+ 'tenant_id': u'tenant-id-xxx',
+ 'networks': {u'public': [u'10.20.30.40', u'2001:db8::f']},
+ 'links': u'http://xxx.yyy.com',
+ }
+ _server = compute_fakes.FakeServer.create_one_server(attrs=server_info)
+ self.servers_mock.get.return_value = _server
+
+ # Prepare result data.
+ info = {
+ 'id': _server.id,
+ 'name': _server.name,
+ 'addresses': u'public=10.20.30.40, 2001:db8::f',
+ 'flavor': u'%s (%s)' % (_flavor.name, _flavor.id),
+ 'image': u'%s (%s)' % (_image.name, _image.id),
+ 'project_id': u'tenant-id-xxx',
+ 'properties': '',
+ }
+
+ # Call _prep_server_detail().
+ server_detail = server._prep_server_detail(
+ self.app.client_manager.compute,
+ _server
+ )
+ # 'networks' is used to create _server. Remove it.
+ server_detail.pop('networks')
+
+ # Check the results.
+ self.assertDictEqual(info, server_detail)
diff --git a/openstackclient/tests/fakes.py b/openstackclient/tests/fakes.py
index 9f4dcc5..718dff6 100644
--- a/openstackclient/tests/fakes.py
+++ b/openstackclient/tests/fakes.py
@@ -34,7 +34,15 @@ VERSION = "3"
TEST_RESPONSE_DICT = fixture.V2Token(token_id=AUTH_TOKEN,
user_name=USERNAME)
_s = TEST_RESPONSE_DICT.add_service('identity', name='keystone')
-_s.add_endpoint(AUTH_URL + '/v2.0')
+_s.add_endpoint(AUTH_URL + ':5000/v2.0')
+_s = TEST_RESPONSE_DICT.add_service('network', name='neutron')
+_s.add_endpoint(AUTH_URL + ':9696')
+_s = TEST_RESPONSE_DICT.add_service('compute', name='nova')
+_s.add_endpoint(AUTH_URL + ':8774/v2')
+_s = TEST_RESPONSE_DICT.add_service('image', name='glance')
+_s.add_endpoint(AUTH_URL + ':9292')
+_s = TEST_RESPONSE_DICT.add_service('object', name='swift')
+_s.add_endpoint(AUTH_URL + ':8080/v1')
TEST_RESPONSE_DICT_V3 = fixture.V3Token(user_name=USERNAME)
TEST_RESPONSE_DICT_V3.set_project_scope()
@@ -103,6 +111,7 @@ class FakeClientManager(object):
self.session = None
self.auth_ref = None
self.auth_plugin_name = None
+ self.network_endpoint_enabled = True
def get_configuration(self):
return {
@@ -115,6 +124,9 @@ class FakeClientManager(object):
'identity_api_version': VERSION,
}
+ def is_network_endpoint_enabled(self):
+ return self.network_endpoint_enabled
+
class FakeModule(object):
def __init__(self, name, version):
diff --git a/openstackclient/tests/identity/v2_0/test_catalog.py b/openstackclient/tests/identity/v2_0/test_catalog.py
index 7f1835d..ff1d993 100644
--- a/openstackclient/tests/identity/v2_0/test_catalog.py
+++ b/openstackclient/tests/identity/v2_0/test_catalog.py
@@ -55,6 +55,12 @@ class TestCatalog(utils.TestCommand):
class TestCatalogList(TestCatalog):
+ columns = (
+ 'Name',
+ 'Type',
+ 'Endpoints',
+ )
+
def setUp(self):
super(TestCatalogList, self).setUp()
@@ -70,8 +76,7 @@ class TestCatalogList(TestCatalog):
columns, data = self.cmd.take_action(parsed_args)
self.sc_mock.service_catalog.get_data.assert_called_with()
- collist = ('Name', 'Type', 'Endpoints')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = ((
'supernova',
'compute',
@@ -113,8 +118,7 @@ class TestCatalogList(TestCatalog):
columns, data = self.cmd.take_action(parsed_args)
self.sc_mock.service_catalog.get_data.assert_called_with()
- collist = ('Name', 'Type', 'Endpoints')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = ((
'supernova',
'compute',
diff --git a/openstackclient/tests/identity/v2_0/test_project.py b/openstackclient/tests/identity/v2_0/test_project.py
index 16ab195..69b2926 100644
--- a/openstackclient/tests/identity/v2_0/test_project.py
+++ b/openstackclient/tests/identity/v2_0/test_project.py
@@ -34,6 +34,19 @@ class TestProject(identity_fakes.TestIdentityv2):
class TestProjectCreate(TestProject):
+ columns = (
+ 'description',
+ 'enabled',
+ 'id',
+ 'name',
+ )
+ datalist = (
+ identity_fakes.project_description,
+ True,
+ identity_fakes.project_id,
+ identity_fakes.project_name,
+ )
+
def setUp(self):
super(TestProjectCreate, self).setUp()
@@ -69,16 +82,8 @@ class TestProjectCreate(TestProject):
identity_fakes.project_name,
**kwargs
)
-
- collist = ('description', 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_description,
- True,
- identity_fakes.project_id,
- identity_fakes.project_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_project_create_description(self):
arglist = [
@@ -104,15 +109,8 @@ class TestProjectCreate(TestProject):
**kwargs
)
- collist = ('description', 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_description,
- True,
- identity_fakes.project_id,
- identity_fakes.project_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_project_create_enable(self):
arglist = [
@@ -139,15 +137,8 @@ class TestProjectCreate(TestProject):
**kwargs
)
- collist = ('description', 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_description,
- True,
- identity_fakes.project_id,
- identity_fakes.project_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_project_create_disable(self):
arglist = [
@@ -174,15 +165,8 @@ class TestProjectCreate(TestProject):
**kwargs
)
- collist = ('description', 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_description,
- True,
- identity_fakes.project_id,
- identity_fakes.project_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_project_create_property(self):
arglist = [
@@ -211,15 +195,8 @@ class TestProjectCreate(TestProject):
**kwargs
)
- collist = ('description', 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_description,
- True,
- identity_fakes.project_id,
- identity_fakes.project_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_project_create_or_show_exists(self):
def _raise_conflict(*args, **kwargs):
@@ -260,15 +237,8 @@ class TestProjectCreate(TestProject):
**kwargs
)
- collist = ('description', 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_description,
- True,
- identity_fakes.project_id,
- identity_fakes.project_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_project_create_or_show_not_exists(self):
arglist = [
@@ -294,15 +264,8 @@ class TestProjectCreate(TestProject):
**kwargs
)
- collist = ('description', 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_description,
- True,
- identity_fakes.project_id,
- identity_fakes.project_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
class TestProjectDelete(TestProject):
@@ -592,12 +555,58 @@ class TestProjectShow(TestProject):
identity_fakes.project_id,
)
- collist = ('description', 'enabled', 'id', 'name')
+ collist = ('description', 'enabled', 'id', 'name', 'properties')
self.assertEqual(collist, columns)
datalist = (
identity_fakes.project_description,
True,
identity_fakes.project_id,
identity_fakes.project_name,
+ '',
)
self.assertEqual(datalist, data)
+
+
+class TestProjectUnset(TestProject):
+
+ def setUp(self):
+ super(TestProjectUnset, self).setUp()
+
+ project_dict = {'fee': 'fi', 'fo': 'fum'}
+ project_dict.update(identity_fakes.PROJECT)
+ self.projects_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(project_dict),
+ loaded=True,
+ )
+
+ # Get the command object to test
+ self.cmd = project.UnsetProject(self.app, None)
+
+ def test_project_unset_key(self):
+ arglist = [
+ '--property', 'fee',
+ '--property', 'fo',
+ identity_fakes.project_name,
+ ]
+ verifylist = [
+ ('property', ['fee', 'fo']),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.cmd.run(parsed_args)
+ # Set expected values
+ kwargs = {
+ 'description': identity_fakes.project_description,
+ 'enabled': True,
+ 'fee': None,
+ 'fo': None,
+ 'id': identity_fakes.project_id,
+ 'name': identity_fakes.project_name,
+ }
+
+ self.projects_mock.update.assert_called_with(
+ identity_fakes.project_id,
+ **kwargs
+ )
diff --git a/openstackclient/tests/identity/v2_0/test_role.py b/openstackclient/tests/identity/v2_0/test_role.py
index ec48433..c2bacc5 100644
--- a/openstackclient/tests/identity/v2_0/test_role.py
+++ b/openstackclient/tests/identity/v2_0/test_role.py
@@ -107,6 +107,15 @@ class TestRoleAdd(TestRole):
class TestRoleCreate(TestRole):
+ columns = (
+ 'id',
+ 'name'
+ )
+ datalist = (
+ identity_fakes.role_id,
+ identity_fakes.role_name,
+ )
+
def setUp(self):
super(TestRoleCreate, self).setUp()
@@ -136,13 +145,8 @@ class TestRoleCreate(TestRole):
identity_fakes.role_name,
)
- collist = ('id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.role_id,
- identity_fakes.role_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_role_create_or_show_exists(self):
def _raise_conflict(*args, **kwargs):
@@ -178,13 +182,8 @@ class TestRoleCreate(TestRole):
identity_fakes.role_name,
)
- collist = ('id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.role_id,
- identity_fakes.role_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_role_create_or_show_not_exists(self):
arglist = [
@@ -205,13 +204,8 @@ class TestRoleCreate(TestRole):
identity_fakes.role_name,
)
- collist = ('id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.role_id,
- identity_fakes.role_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
class TestRoleDelete(TestRole):
@@ -283,6 +277,13 @@ class TestRoleList(TestRole):
class TestUserRoleList(TestRole):
+ columns = (
+ 'ID',
+ 'Name',
+ 'Project',
+ 'User'
+ )
+
def setUp(self):
super(TestUserRoleList, self).setUp()
@@ -395,8 +396,7 @@ class TestUserRoleList(TestRole):
identity_fakes.PROJECT_2['id'],
)
- collist = ('ID', 'Name', 'Project', 'User')
- self.assertEqual(collist, columns)
+ self.assertEqual(columns, columns)
datalist = ((
identity_fakes.role_id,
identity_fakes.role_name,
diff --git a/openstackclient/tests/identity/v2_0/test_service.py b/openstackclient/tests/identity/v2_0/test_service.py
index 26a9716..b97786b 100644
--- a/openstackclient/tests/identity/v2_0/test_service.py
+++ b/openstackclient/tests/identity/v2_0/test_service.py
@@ -32,6 +32,19 @@ class TestService(identity_fakes.TestIdentityv2):
class TestServiceCreate(TestService):
+ columns = (
+ 'description',
+ 'id',
+ 'name',
+ 'type',
+ )
+ datalist = (
+ identity_fakes.service_description,
+ identity_fakes.service_id,
+ identity_fakes.service_name,
+ identity_fakes.service_type,
+ )
+
def setUp(self):
super(TestServiceCreate, self).setUp()
@@ -66,15 +79,8 @@ class TestServiceCreate(TestService):
None,
)
- collist = ('description', 'id', 'name', 'type')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.service_description,
- identity_fakes.service_id,
- identity_fakes.service_name,
- identity_fakes.service_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_service_create_with_type_option(self):
arglist = [
@@ -99,15 +105,8 @@ class TestServiceCreate(TestService):
None,
)
- collist = ('description', 'id', 'name', 'type')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.service_description,
- identity_fakes.service_id,
- identity_fakes.service_name,
- identity_fakes.service_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_service_create_with_name_option(self):
arglist = [
@@ -132,15 +131,8 @@ class TestServiceCreate(TestService):
None,
)
- collist = ('description', 'id', 'name', 'type')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.service_description,
- identity_fakes.service_id,
- identity_fakes.service_name,
- identity_fakes.service_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_service_create_description(self):
arglist = [
@@ -166,15 +158,8 @@ class TestServiceCreate(TestService):
identity_fakes.service_description,
)
- collist = ('description', 'id', 'name', 'type')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.service_description,
- identity_fakes.service_id,
- identity_fakes.service_name,
- identity_fakes.service_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
class TestServiceDelete(TestService):
diff --git a/openstackclient/tests/identity/v2_0/test_user.py b/openstackclient/tests/identity/v2_0/test_user.py
index bf25681..a25def8 100644
--- a/openstackclient/tests/identity/v2_0/test_user.py
+++ b/openstackclient/tests/identity/v2_0/test_user.py
@@ -39,6 +39,21 @@ class TestUser(identity_fakes.TestIdentityv2):
class TestUserCreate(TestUser):
+ columns = (
+ 'email',
+ 'enabled',
+ 'id',
+ 'name',
+ 'project_id',
+ )
+ datalist = (
+ identity_fakes.user_email,
+ True,
+ identity_fakes.user_id,
+ identity_fakes.user_name,
+ identity_fakes.project_id,
+ )
+
def setUp(self):
super(TestUserCreate, self).setUp()
@@ -84,16 +99,8 @@ class TestUserCreate(TestUser):
**kwargs
)
- collist = ('email', 'enabled', 'id', 'name', 'project_id')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.user_email,
- True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- identity_fakes.project_id,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_user_create_password(self):
arglist = [
@@ -122,17 +129,8 @@ class TestUserCreate(TestUser):
None,
**kwargs
)
-
- collist = ('email', 'enabled', 'id', 'name', 'project_id')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.user_email,
- True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- identity_fakes.project_id,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_user_create_password_prompt(self):
arglist = [
@@ -164,16 +162,8 @@ class TestUserCreate(TestUser):
**kwargs
)
- collist = ('email', 'enabled', 'id', 'name', 'project_id')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.user_email,
- True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- identity_fakes.project_id,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_user_create_email(self):
arglist = [
@@ -202,16 +192,8 @@ class TestUserCreate(TestUser):
**kwargs
)
- collist = ('email', 'enabled', 'id', 'name', 'project_id')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.user_email,
- True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- identity_fakes.project_id,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_user_create_project(self):
# Return the new project
@@ -255,8 +237,7 @@ class TestUserCreate(TestUser):
**kwargs
)
- collist = ('email', 'enabled', 'id', 'name', 'project_id')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
identity_fakes.user_email,
True,
@@ -294,16 +275,8 @@ class TestUserCreate(TestUser):
**kwargs
)
- collist = ('email', 'enabled', 'id', 'name', 'project_id')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.user_email,
- True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- identity_fakes.project_id,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_user_create_disable(self):
arglist = [
@@ -333,16 +306,8 @@ class TestUserCreate(TestUser):
**kwargs
)
- collist = ('email', 'enabled', 'id', 'name', 'project_id')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.user_email,
- True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- identity_fakes.project_id,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_user_create_or_show_exists(self):
def _raise_conflict(*args, **kwargs):
@@ -373,16 +338,8 @@ class TestUserCreate(TestUser):
# UserManager.create(name, password, email, tenant_id=, enabled=)
self.users_mock.get.assert_called_with(identity_fakes.user_name)
- collist = ('email', 'enabled', 'id', 'name', 'project_id')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.user_email,
- True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- identity_fakes.project_id,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_user_create_or_show_not_exists(self):
arglist = [
@@ -410,17 +367,8 @@ class TestUserCreate(TestUser):
None,
**kwargs
)
-
- collist = ('email', 'enabled', 'id', 'name', 'project_id')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.user_email,
- True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- identity_fakes.project_id,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
class TestUserDelete(TestUser):
@@ -458,6 +406,17 @@ class TestUserDelete(TestUser):
class TestUserList(TestUser):
+ columns = (
+ 'ID',
+ 'Name',
+ )
+ datalist = (
+ (
+ identity_fakes.user_id,
+ identity_fakes.user_name,
+ ),
+ )
+
def setUp(self):
super(TestUserList, self).setUp()
@@ -495,13 +454,8 @@ class TestUserList(TestUser):
self.users_mock.list.assert_called_with(tenant_id=None)
- collist = ('ID', 'Name')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.user_id,
- identity_fakes.user_name,
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_user_list_project(self):
arglist = [
@@ -518,13 +472,8 @@ class TestUserList(TestUser):
self.users_mock.list.assert_called_with(tenant_id=project_id)
- collist = ('ID', 'Name')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.user_id,
- identity_fakes.user_name,
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_user_list_long(self):
arglist = [
diff --git a/openstackclient/tests/identity/v3/test_domain.py b/openstackclient/tests/identity/v3/test_domain.py
index cfec10e..969c2df 100644
--- a/openstackclient/tests/identity/v3/test_domain.py
+++ b/openstackclient/tests/identity/v3/test_domain.py
@@ -29,6 +29,19 @@ class TestDomain(identity_fakes.TestIdentityv3):
class TestDomainCreate(TestDomain):
+ columns = (
+ 'description',
+ 'enabled',
+ 'id',
+ 'name',
+ )
+ datalist = (
+ identity_fakes.domain_description,
+ True,
+ identity_fakes.domain_id,
+ identity_fakes.domain_name,
+ )
+
def setUp(self):
super(TestDomainCreate, self).setUp()
@@ -63,15 +76,8 @@ class TestDomainCreate(TestDomain):
**kwargs
)
- collist = ('description', 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.domain_description,
- True,
- identity_fakes.domain_id,
- identity_fakes.domain_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_domain_create_description(self):
arglist = [
@@ -97,15 +103,8 @@ class TestDomainCreate(TestDomain):
**kwargs
)
- collist = ('description', 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.domain_description,
- True,
- identity_fakes.domain_id,
- identity_fakes.domain_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_domain_create_enable(self):
arglist = [
@@ -131,15 +130,8 @@ class TestDomainCreate(TestDomain):
**kwargs
)
- collist = ('description', 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.domain_description,
- True,
- identity_fakes.domain_id,
- identity_fakes.domain_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_domain_create_disable(self):
arglist = [
@@ -165,15 +157,8 @@ class TestDomainCreate(TestDomain):
**kwargs
)
- collist = ('description', 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.domain_description,
- True,
- identity_fakes.domain_id,
- identity_fakes.domain_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
class TestDomainDelete(TestDomain):
diff --git a/openstackclient/tests/identity/v3/test_endpoint.py b/openstackclient/tests/identity/v3/test_endpoint.py
index ecfa71a..fb88e00 100644
--- a/openstackclient/tests/identity/v3/test_endpoint.py
+++ b/openstackclient/tests/identity/v3/test_endpoint.py
@@ -37,6 +37,17 @@ class TestEndpoint(identity_fakes.TestIdentityv3):
class TestEndpointCreate(TestEndpoint):
+ columns = (
+ 'enabled',
+ 'id',
+ 'interface',
+ 'region',
+ 'service_id',
+ 'service_name',
+ 'service_type',
+ 'url',
+ )
+
def setUp(self):
super(TestEndpointCreate, self).setUp()
@@ -86,9 +97,7 @@ class TestEndpointCreate(TestEndpoint):
**kwargs
)
- collist = ('enabled', 'id', 'interface', 'region', 'service_id',
- 'service_name', 'service_type', 'url')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
True,
identity_fakes.endpoint_id,
@@ -133,9 +142,7 @@ class TestEndpointCreate(TestEndpoint):
**kwargs
)
- collist = ('enabled', 'id', 'interface', 'region', 'service_id',
- 'service_name', 'service_type', 'url')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
True,
identity_fakes.endpoint_id,
@@ -179,9 +186,7 @@ class TestEndpointCreate(TestEndpoint):
**kwargs
)
- collist = ('enabled', 'id', 'interface', 'region', 'service_id',
- 'service_name', 'service_type', 'url')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
True,
identity_fakes.endpoint_id,
@@ -225,9 +230,7 @@ class TestEndpointCreate(TestEndpoint):
**kwargs
)
- collist = ('enabled', 'id', 'interface', 'region', 'service_id',
- 'service_name', 'service_type', 'url')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
True,
identity_fakes.endpoint_id,
@@ -276,6 +279,16 @@ class TestEndpointDelete(TestEndpoint):
class TestEndpointList(TestEndpoint):
+ columns = (
+ 'ID',
+ 'Region',
+ 'Service Name',
+ 'Service Type',
+ 'Enabled',
+ 'Interface',
+ 'URL',
+ )
+
def setUp(self):
super(TestEndpointList, self).setUp()
@@ -306,18 +319,18 @@ class TestEndpointList(TestEndpoint):
columns, data = self.cmd.take_action(parsed_args)
self.endpoints_mock.list.assert_called_with()
- collist = ('ID', 'Region', 'Service Name', 'Service Type',
- 'Enabled', 'Interface', 'URL')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.endpoint_id,
- identity_fakes.endpoint_region,
- self.get_fake_service_name(),
- identity_fakes.service_type,
- True,
- identity_fakes.endpoint_interface,
- identity_fakes.endpoint_url,
- ),)
+ self.assertEqual(self.columns, columns)
+ datalist = (
+ (
+ identity_fakes.endpoint_id,
+ identity_fakes.endpoint_region,
+ self.get_fake_service_name(),
+ identity_fakes.service_type,
+ True,
+ identity_fakes.endpoint_interface,
+ identity_fakes.endpoint_url,
+ ),
+ )
self.assertEqual(datalist, tuple(data))
def test_endpoint_list_service(self):
@@ -338,18 +351,18 @@ class TestEndpointList(TestEndpoint):
}
self.endpoints_mock.list.assert_called_with(**kwargs)
- collist = ('ID', 'Region', 'Service Name', 'Service Type',
- 'Enabled', 'Interface', 'URL')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.endpoint_id,
- identity_fakes.endpoint_region,
- self.get_fake_service_name(),
- identity_fakes.service_type,
- True,
- identity_fakes.endpoint_interface,
- identity_fakes.endpoint_url,
- ),)
+ self.assertEqual(self.columns, columns)
+ datalist = (
+ (
+ identity_fakes.endpoint_id,
+ identity_fakes.endpoint_region,
+ self.get_fake_service_name(),
+ identity_fakes.service_type,
+ True,
+ identity_fakes.endpoint_interface,
+ identity_fakes.endpoint_url,
+ ),
+ )
self.assertEqual(datalist, tuple(data))
def test_endpoint_list_interface(self):
@@ -370,18 +383,18 @@ class TestEndpointList(TestEndpoint):
}
self.endpoints_mock.list.assert_called_with(**kwargs)
- collist = ('ID', 'Region', 'Service Name', 'Service Type',
- 'Enabled', 'Interface', 'URL')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.endpoint_id,
- identity_fakes.endpoint_region,
- self.get_fake_service_name(),
- identity_fakes.service_type,
- True,
- identity_fakes.endpoint_interface,
- identity_fakes.endpoint_url,
- ),)
+ self.assertEqual(self.columns, columns)
+ datalist = (
+ (
+ identity_fakes.endpoint_id,
+ identity_fakes.endpoint_region,
+ self.get_fake_service_name(),
+ identity_fakes.service_type,
+ True,
+ identity_fakes.endpoint_interface,
+ identity_fakes.endpoint_url,
+ ),
+ )
self.assertEqual(datalist, tuple(data))
def test_endpoint_list_region(self):
@@ -402,18 +415,18 @@ class TestEndpointList(TestEndpoint):
}
self.endpoints_mock.list.assert_called_with(**kwargs)
- collist = ('ID', 'Region', 'Service Name', 'Service Type',
- 'Enabled', 'Interface', 'URL')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.endpoint_id,
- identity_fakes.endpoint_region,
- self.get_fake_service_name(),
- identity_fakes.service_type,
- True,
- identity_fakes.endpoint_interface,
- identity_fakes.endpoint_url,
- ),)
+ self.assertEqual(self.columns, columns)
+ datalist = (
+ (
+ identity_fakes.endpoint_id,
+ identity_fakes.endpoint_region,
+ self.get_fake_service_name(),
+ identity_fakes.service_type,
+ True,
+ identity_fakes.endpoint_interface,
+ identity_fakes.endpoint_url,
+ ),
+ )
self.assertEqual(datalist, tuple(data))
@@ -658,8 +671,16 @@ class TestEndpointShow(TestEndpoint):
identity_fakes.endpoint_id,
)
- collist = ('enabled', 'id', 'interface', 'region', 'service_id',
- 'service_name', 'service_type', 'url')
+ collist = (
+ 'enabled',
+ 'id',
+ 'interface',
+ 'region',
+ 'service_id',
+ 'service_name',
+ 'service_type',
+ 'url',
+ )
self.assertEqual(collist, columns)
datalist = (
True,
diff --git a/openstackclient/tests/identity/v3/test_group.py b/openstackclient/tests/identity/v3/test_group.py
index 6766a08..59a3681 100644
--- a/openstackclient/tests/identity/v3/test_group.py
+++ b/openstackclient/tests/identity/v3/test_group.py
@@ -38,6 +38,17 @@ class TestGroup(identity_fakes.TestIdentityv3):
class TestGroupList(TestGroup):
+ columns = (
+ 'ID',
+ 'Name',
+ )
+ datalist = (
+ (
+ identity_fakes.group_id,
+ identity_fakes.group_name,
+ ),
+ )
+
def setUp(self):
super(TestGroupList, self).setUp()
@@ -87,13 +98,8 @@ class TestGroupList(TestGroup):
**kwargs
)
- collist = ('ID', 'Name')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.group_id,
- identity_fakes.group_name,
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_group_list_domain(self):
arglist = [
@@ -117,13 +123,8 @@ class TestGroupList(TestGroup):
**kwargs
)
- collist = ('ID', 'Name')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.group_id,
- identity_fakes.group_name,
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_group_list_user(self):
arglist = [
@@ -147,13 +148,8 @@ class TestGroupList(TestGroup):
**kwargs
)
- collist = ('ID', 'Name')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.group_id,
- identity_fakes.group_name,
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_group_list_long(self):
arglist = [
@@ -177,17 +173,15 @@ class TestGroupList(TestGroup):
**kwargs
)
- collist = (
- 'ID',
- 'Name',
+ columns = self.columns + (
'Domain ID',
'Description',
)
- self.assertEqual(collist, columns)
datalist = ((
identity_fakes.group_id,
identity_fakes.group_name,
'',
'',
), )
+ self.assertEqual(columns, columns)
self.assertEqual(datalist, tuple(data))
diff --git a/openstackclient/tests/identity/v3/test_identity_provider.py b/openstackclient/tests/identity/v3/test_identity_provider.py
index db097d5..50a922b 100644
--- a/openstackclient/tests/identity/v3/test_identity_provider.py
+++ b/openstackclient/tests/identity/v3/test_identity_provider.py
@@ -33,6 +33,19 @@ class TestIdentityProvider(identity_fakes.TestFederatedIdentity):
class TestIdentityProviderCreate(TestIdentityProvider):
+ columns = (
+ 'description',
+ 'enabled',
+ 'id',
+ 'remote_ids',
+ )
+ datalist = (
+ identity_fakes.idp_description,
+ True,
+ identity_fakes.idp_id,
+ identity_fakes.formatted_idp_remote_ids,
+ )
+
def setUp(self):
super(TestIdentityProviderCreate, self).setUp()
@@ -63,15 +76,8 @@ class TestIdentityProviderCreate(TestIdentityProvider):
**kwargs
)
- collist = ('description', 'enabled', 'id', 'remote_ids')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.idp_description,
- True,
- identity_fakes.idp_id,
- identity_fakes.formatted_idp_remote_ids
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_create_identity_provider_description(self):
arglist = [
@@ -97,15 +103,8 @@ class TestIdentityProviderCreate(TestIdentityProvider):
**kwargs
)
- collist = ('description', 'enabled', 'id', 'remote_ids')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.idp_description,
- True,
- identity_fakes.idp_id,
- identity_fakes.formatted_idp_remote_ids
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_create_identity_provider_remote_id(self):
arglist = [
@@ -131,15 +130,8 @@ class TestIdentityProviderCreate(TestIdentityProvider):
**kwargs
)
- collist = ('description', 'enabled', 'id', 'remote_ids')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.idp_description,
- True,
- identity_fakes.idp_id,
- identity_fakes.formatted_idp_remote_ids
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_create_identity_provider_remote_ids_multiple(self):
arglist = [
@@ -166,15 +158,8 @@ class TestIdentityProviderCreate(TestIdentityProvider):
**kwargs
)
- collist = ('description', 'enabled', 'id', 'remote_ids')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.idp_description,
- True,
- identity_fakes.idp_id,
- identity_fakes.formatted_idp_remote_ids
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_create_identity_provider_remote_ids_file(self):
arglist = [
@@ -205,15 +190,8 @@ class TestIdentityProviderCreate(TestIdentityProvider):
**kwargs
)
- collist = ('description', 'enabled', 'id', 'remote_ids')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.idp_description,
- True,
- identity_fakes.idp_id,
- identity_fakes.formatted_idp_remote_ids
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_create_identity_provider_disabled(self):
@@ -247,8 +225,7 @@ class TestIdentityProviderCreate(TestIdentityProvider):
**kwargs
)
- collist = ('description', 'enabled', 'id', 'remote_ids')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
None,
False,
@@ -370,6 +347,19 @@ class TestIdentityProviderShow(TestIdentityProvider):
class TestIdentityProviderSet(TestIdentityProvider):
+ columns = (
+ 'description',
+ 'enabled',
+ 'id',
+ 'remote_ids',
+ )
+ datalist = (
+ identity_fakes.idp_description,
+ True,
+ identity_fakes.idp_id,
+ identity_fakes.idp_remote_ids,
+ )
+
def setUp(self):
super(TestIdentityProviderSet, self).setUp()
self.cmd = identity_provider.SetIdentityProvider(self.app, None)
@@ -401,15 +391,12 @@ class TestIdentityProviderSet(TestIdentityProvider):
('remote_id', None)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
columns, data = self.cmd.take_action(parsed_args)
self.identity_providers_mock.update.assert_called_with(
identity_fakes.idp_id,
- description=new_description
+ description=new_description,
)
-
- collist = ('description', 'enabled', 'id', 'remote_ids')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
identity_fakes.idp_description,
False,
@@ -456,8 +443,7 @@ class TestIdentityProviderSet(TestIdentityProvider):
remote_ids=identity_fakes.idp_remote_ids
)
- collist = ('description', 'enabled', 'id', 'remote_ids')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
identity_fakes.idp_description,
False,
@@ -499,15 +485,8 @@ class TestIdentityProviderSet(TestIdentityProvider):
self.identity_providers_mock.update.assert_called_with(
identity_fakes.idp_id, enabled=True,
remote_ids=identity_fakes.idp_remote_ids)
- collist = ('description', 'enabled', 'id', 'remote_ids')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.idp_description,
- True,
- identity_fakes.idp_id,
- identity_fakes.idp_remote_ids
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_identity_provider_replace_remote_ids(self):
"""Enable Identity Provider.
@@ -545,8 +524,7 @@ class TestIdentityProviderSet(TestIdentityProvider):
self.identity_providers_mock.update.assert_called_with(
identity_fakes.idp_id, enabled=True,
remote_ids=[self.new_remote_id])
- collist = ('description', 'enabled', 'id', 'remote_ids')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
identity_fakes.idp_description,
True,
@@ -595,8 +573,7 @@ class TestIdentityProviderSet(TestIdentityProvider):
self.identity_providers_mock.update.assert_called_with(
identity_fakes.idp_id, enabled=True,
remote_ids=[self.new_remote_id])
- collist = ('description', 'enabled', 'id', 'remote_ids')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
identity_fakes.idp_description,
True,
@@ -638,5 +615,5 @@ class TestIdentityProviderSet(TestIdentityProvider):
# expect take_action() to return (None, None) as
# neither --enable nor --disable was specified
- self.assertEqual(None, columns)
- self.assertEqual(None, data)
+ self.assertIsNone(columns)
+ self.assertIsNone(data)
diff --git a/openstackclient/tests/identity/v3/test_project.py b/openstackclient/tests/identity/v3/test_project.py
index 946bbdc..3654020 100644
--- a/openstackclient/tests/identity/v3/test_project.py
+++ b/openstackclient/tests/identity/v3/test_project.py
@@ -38,6 +38,21 @@ class TestProject(identity_fakes.TestIdentityv3):
class TestProjectCreate(TestProject):
+ columns = (
+ 'description',
+ 'domain_id',
+ 'enabled',
+ 'id',
+ 'name'
+ )
+ datalist = (
+ identity_fakes.project_description,
+ identity_fakes.domain_id,
+ True,
+ identity_fakes.project_id,
+ identity_fakes.project_name,
+ )
+
def setUp(self):
super(TestProjectCreate, self).setUp()
@@ -127,16 +142,8 @@ class TestProjectCreate(TestProject):
**kwargs
)
- collist = ('description', 'domain_id', 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_description,
- identity_fakes.domain_id,
- True,
- identity_fakes.project_id,
- identity_fakes.project_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_project_create_domain(self):
arglist = [
@@ -169,16 +176,8 @@ class TestProjectCreate(TestProject):
**kwargs
)
- collist = ('description', 'domain_id', 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_description,
- identity_fakes.domain_id,
- True,
- identity_fakes.project_id,
- identity_fakes.project_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_project_create_domain_no_perms(self):
arglist = [
@@ -210,16 +209,8 @@ class TestProjectCreate(TestProject):
self.projects_mock.create.assert_called_with(
**kwargs
)
- collist = ('description', 'domain_id', 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_description,
- identity_fakes.domain_id,
- True,
- identity_fakes.project_id,
- identity_fakes.project_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_project_create_enable(self):
arglist = [
@@ -251,16 +242,8 @@ class TestProjectCreate(TestProject):
**kwargs
)
- collist = ('description', 'domain_id', 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_description,
- identity_fakes.domain_id,
- True,
- identity_fakes.project_id,
- identity_fakes.project_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_project_create_disable(self):
arglist = [
@@ -292,16 +275,8 @@ class TestProjectCreate(TestProject):
**kwargs
)
- collist = ('description', 'domain_id', 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_description,
- identity_fakes.domain_id,
- True,
- identity_fakes.project_id,
- identity_fakes.project_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_project_create_property(self):
arglist = [
@@ -334,16 +309,8 @@ class TestProjectCreate(TestProject):
**kwargs
)
- collist = ('description', 'domain_id', 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_description,
- identity_fakes.domain_id,
- True,
- identity_fakes.project_id,
- identity_fakes.project_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_project_create_parent(self):
self.projects_mock.get.return_value = fakes.FakeResource(
@@ -467,6 +434,17 @@ class TestProjectDelete(TestProject):
class TestProjectList(TestProject):
+ columns = (
+ 'ID',
+ 'Name',
+ )
+ datalist = (
+ (
+ identity_fakes.project_id,
+ identity_fakes.project_name,
+ ),
+ )
+
def setUp(self):
super(TestProjectList, self).setUp()
@@ -490,13 +468,8 @@ class TestProjectList(TestProject):
columns, data = self.cmd.take_action(parsed_args)
self.projects_mock.list.assert_called_with()
- collist = ('ID', 'Name')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.project_id,
- identity_fakes.project_name,
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_project_list_long(self):
arglist = [
@@ -543,13 +516,8 @@ class TestProjectList(TestProject):
self.projects_mock.list.assert_called_with(
domain=identity_fakes.domain_id)
- collist = ('ID', 'Name')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.project_id,
- identity_fakes.project_name,
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_project_list_domain_no_perms(self):
arglist = [
@@ -567,13 +535,8 @@ class TestProjectList(TestProject):
self.projects_mock.list.assert_called_with(
domain=identity_fakes.domain_id)
- collist = ('ID', 'Name')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.project_id,
- identity_fakes.project_name,
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
class TestProjectSet(TestProject):
@@ -636,7 +599,6 @@ class TestProjectSet(TestProject):
# Set expected values
kwargs = {
'name': 'qwerty',
- 'domain': identity_fakes.domain_id,
}
# ProjectManager.update(project, name=, domain=, description=,
# enabled=, **kwargs)
@@ -665,7 +627,6 @@ class TestProjectSet(TestProject):
# Set expected values
kwargs = {
- 'domain': identity_fakes.domain_id,
'description': 'new desc',
}
self.projects_mock.update.assert_called_with(
@@ -692,7 +653,6 @@ class TestProjectSet(TestProject):
# Set expected values
kwargs = {
- 'domain': identity_fakes.domain_id,
'enabled': True,
}
self.projects_mock.update.assert_called_with(
@@ -719,7 +679,6 @@ class TestProjectSet(TestProject):
# Set expected values
kwargs = {
- 'domain': identity_fakes.domain_id,
'enabled': False,
}
self.projects_mock.update.assert_called_with(
@@ -746,7 +705,6 @@ class TestProjectSet(TestProject):
# Set expected values
kwargs = {
- 'domain': identity_fakes.domain_id,
'fee': 'fi',
'fo': 'fum',
}
diff --git a/openstackclient/tests/identity/v3/test_region.py b/openstackclient/tests/identity/v3/test_region.py
index 0ebbbec..9ac9ddf 100644
--- a/openstackclient/tests/identity/v3/test_region.py
+++ b/openstackclient/tests/identity/v3/test_region.py
@@ -30,6 +30,17 @@ class TestRegion(identity_fakes.TestIdentityv3):
class TestRegionCreate(TestRegion):
+ columns = (
+ 'description',
+ 'parent_region',
+ 'region',
+ )
+ datalist = (
+ identity_fakes.region_description,
+ identity_fakes.region_parent_region_id,
+ identity_fakes.region_id,
+ )
+
def setUp(self):
super(TestRegionCreate, self).setUp()
@@ -66,14 +77,8 @@ class TestRegionCreate(TestRegion):
**kwargs
)
- collist = ('description', 'parent_region', 'region')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.region_description,
- identity_fakes.region_parent_region_id,
- identity_fakes.region_id,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_region_create_no_options(self):
arglist = [
@@ -97,14 +102,8 @@ class TestRegionCreate(TestRegion):
**kwargs
)
- collist = ('description', 'parent_region', 'region')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.region_description,
- identity_fakes.region_parent_region_id,
- identity_fakes.region_id,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_region_create_parent_region_id(self):
arglist = [
@@ -129,15 +128,8 @@ class TestRegionCreate(TestRegion):
self.regions_mock.create.assert_called_with(
**kwargs
)
-
- collist = ('description', 'parent_region', 'region')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.region_description,
- identity_fakes.region_parent_region_id,
- identity_fakes.region_id,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
class TestRegionDelete(TestRegion):
@@ -169,6 +161,19 @@ class TestRegionDelete(TestRegion):
class TestRegionList(TestRegion):
+ columns = (
+ 'Region',
+ 'Parent Region',
+ 'Description',
+ )
+ datalist = (
+ (
+ identity_fakes.region_id,
+ identity_fakes.region_parent_region_id,
+ identity_fakes.region_description,
+ ),
+ )
+
def setUp(self):
super(TestRegionList, self).setUp()
@@ -192,14 +197,8 @@ class TestRegionList(TestRegion):
columns, data = self.cmd.take_action(parsed_args)
self.regions_mock.list.assert_called_with()
- collist = ('Region', 'Parent Region', 'Description')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.region_id,
- identity_fakes.region_parent_region_id,
- identity_fakes.region_description,
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_region_list_parent_region_id(self):
arglist = [
@@ -215,14 +214,8 @@ class TestRegionList(TestRegion):
self.regions_mock.list.assert_called_with(
parent_region_id=identity_fakes.region_parent_region_id)
- collist = ('Region', 'Parent Region', 'Description')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.region_id,
- identity_fakes.region_parent_region_id,
- identity_fakes.region_description,
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
class TestRegionSet(TestRegion):
diff --git a/openstackclient/tests/identity/v3/test_role.py b/openstackclient/tests/identity/v3/test_role.py
index 8ad4b09..1910c87 100644
--- a/openstackclient/tests/identity/v3/test_role.py
+++ b/openstackclient/tests/identity/v3/test_role.py
@@ -314,6 +314,17 @@ class TestRoleDelete(TestRole):
class TestRoleList(TestRole):
+ columns = (
+ 'ID',
+ 'Name',
+ )
+ datalist = (
+ (
+ identity_fakes.role_id,
+ identity_fakes.role_name,
+ ),
+ )
+
def setUp(self):
super(TestRoleList, self).setUp()
@@ -359,13 +370,8 @@ class TestRoleList(TestRole):
self.roles_mock.list.assert_called_with()
- collist = ('ID', 'Name')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.role_id,
- identity_fakes.role_name,
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_user_list_inherited(self):
arglist = [
@@ -392,13 +398,8 @@ class TestRoleList(TestRole):
**kwargs
)
- collist = ('ID', 'Name')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.role_id,
- identity_fakes.role_name,
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_user_list_user(self):
arglist = [
@@ -423,13 +424,8 @@ class TestRoleList(TestRole):
**kwargs
)
- collist = ('ID', 'Name')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.role_id,
- identity_fakes.role_name,
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_role_list_domain_user(self):
arglist = [
diff --git a/openstackclient/tests/identity/v3/test_role_assignment.py b/openstackclient/tests/identity/v3/test_role_assignment.py
index 9817f53..5723a33 100644
--- a/openstackclient/tests/identity/v3/test_role_assignment.py
+++ b/openstackclient/tests/identity/v3/test_role_assignment.py
@@ -26,6 +26,15 @@ class TestRoleAssignment(identity_fakes.TestIdentityv3):
class TestRoleAssignmentList(TestRoleAssignment):
+ columns = (
+ 'Role',
+ 'User',
+ 'Group',
+ 'Project',
+ 'Domain',
+ 'Inherited',
+ )
+
def setUp(self):
super(TestRoleAssignment, self).setUp()
@@ -89,8 +98,7 @@ class TestRoleAssignmentList(TestRoleAssignment):
project=None,
os_inherit_extension_inherited_to=None)
- collist = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited')
- self.assertEqual(columns, collist)
+ self.assertEqual(self.columns, columns)
datalist = ((
identity_fakes.role_id,
identity_fakes.user_id,
@@ -150,8 +158,7 @@ class TestRoleAssignmentList(TestRoleAssignment):
effective=False,
os_inherit_extension_inherited_to=None)
- collist = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited')
- self.assertEqual(columns, collist)
+ self.assertEqual(self.columns, columns)
datalist = ((
identity_fakes.role_id,
identity_fakes.user_id,
@@ -211,8 +218,7 @@ class TestRoleAssignmentList(TestRoleAssignment):
user=None,
os_inherit_extension_inherited_to=None)
- collist = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited')
- self.assertEqual(columns, collist)
+ self.assertEqual(self.columns, columns)
datalist = ((
identity_fakes.role_id,
'',
@@ -272,8 +278,7 @@ class TestRoleAssignmentList(TestRoleAssignment):
user=None,
os_inherit_extension_inherited_to=None)
- collist = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited')
- self.assertEqual(columns, collist)
+ self.assertEqual(self.columns, columns)
datalist = ((
identity_fakes.role_id,
identity_fakes.user_id,
@@ -333,8 +338,7 @@ class TestRoleAssignmentList(TestRoleAssignment):
user=None,
os_inherit_extension_inherited_to=None)
- collist = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited')
- self.assertEqual(columns, collist)
+ self.assertEqual(self.columns, columns)
datalist = ((
identity_fakes.role_id,
identity_fakes.user_id,
@@ -392,8 +396,7 @@ class TestRoleAssignmentList(TestRoleAssignment):
user=None,
os_inherit_extension_inherited_to=None)
- collist = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited')
- self.assertEqual(columns, collist)
+ self.assertEqual(self.columns, columns)
datalist = ((
identity_fakes.role_id,
identity_fakes.user_id,
@@ -453,8 +456,7 @@ class TestRoleAssignmentList(TestRoleAssignment):
user=None,
os_inherit_extension_inherited_to='projects')
- collist = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited')
- self.assertEqual(columns, collist)
+ self.assertEqual(self.columns, columns)
datalist = ((
identity_fakes.role_id,
identity_fakes.user_id,
diff --git a/openstackclient/tests/identity/v3/test_service.py b/openstackclient/tests/identity/v3/test_service.py
index d2b54c7..c609142 100644
--- a/openstackclient/tests/identity/v3/test_service.py
+++ b/openstackclient/tests/identity/v3/test_service.py
@@ -32,6 +32,21 @@ class TestService(identity_fakes.TestIdentityv3):
class TestServiceCreate(TestService):
+ columns = (
+ 'description',
+ 'enabled',
+ 'id',
+ 'name',
+ 'type',
+ )
+ datalist = (
+ identity_fakes.service_description,
+ True,
+ identity_fakes.service_id,
+ identity_fakes.service_name,
+ identity_fakes.service_type,
+ )
+
def setUp(self):
super(TestServiceCreate, self).setUp()
@@ -69,16 +84,8 @@ class TestServiceCreate(TestService):
enabled=True,
)
- collist = ('description', 'enabled', 'id', 'name', 'type')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.service_description,
- True,
- identity_fakes.service_id,
- identity_fakes.service_name,
- identity_fakes.service_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_service_create_description(self):
arglist = [
@@ -105,16 +112,8 @@ class TestServiceCreate(TestService):
enabled=True,
)
- collist = ('description', 'enabled', 'id', 'name', 'type')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.service_description,
- True,
- identity_fakes.service_id,
- identity_fakes.service_name,
- identity_fakes.service_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_service_create_enable(self):
arglist = [
@@ -141,16 +140,8 @@ class TestServiceCreate(TestService):
enabled=True,
)
- collist = ('description', 'enabled', 'id', 'name', 'type')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.service_description,
- True,
- identity_fakes.service_id,
- identity_fakes.service_name,
- identity_fakes.service_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_service_create_disable(self):
arglist = [
@@ -177,16 +168,8 @@ class TestServiceCreate(TestService):
enabled=False,
)
- collist = ('description', 'enabled', 'id', 'name', 'type')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.service_description,
- True,
- identity_fakes.service_id,
- identity_fakes.service_name,
- identity_fakes.service_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
class TestServiceDelete(TestService):
diff --git a/openstackclient/tests/identity/v3/test_service_provider.py b/openstackclient/tests/identity/v3/test_service_provider.py
index e77870d..24fa7c7 100644
--- a/openstackclient/tests/identity/v3/test_service_provider.py
+++ b/openstackclient/tests/identity/v3/test_service_provider.py
@@ -31,6 +31,21 @@ class TestServiceProvider(service_fakes.TestFederatedIdentity):
class TestServiceProviderCreate(TestServiceProvider):
+ columns = (
+ 'auth_url',
+ 'description',
+ 'enabled',
+ 'id',
+ 'sp_url',
+ )
+ datalist = (
+ service_fakes.sp_auth_url,
+ service_fakes.sp_description,
+ True,
+ service_fakes.sp_id,
+ service_fakes.service_provider_url
+ )
+
def setUp(self):
super(TestServiceProviderCreate, self).setUp()
@@ -67,16 +82,8 @@ class TestServiceProviderCreate(TestServiceProvider):
**kwargs
)
- collist = ('auth_url', 'description', 'enabled', 'id', 'sp_url')
- self.assertEqual(collist, columns)
- datalist = (
- service_fakes.sp_auth_url,
- service_fakes.sp_description,
- True,
- service_fakes.sp_id,
- service_fakes.service_provider_url
- )
- self.assertEqual(data, datalist)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_create_service_provider_description(self):
@@ -109,16 +116,8 @@ class TestServiceProviderCreate(TestServiceProvider):
**kwargs
)
- collist = ('auth_url', 'description', 'enabled', 'id', 'sp_url')
- self.assertEqual(columns, collist)
- datalist = (
- service_fakes.sp_auth_url,
- service_fakes.sp_description,
- True,
- service_fakes.sp_id,
- service_fakes.service_provider_url
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_create_service_provider_disabled(self):
@@ -155,9 +154,7 @@ class TestServiceProviderCreate(TestServiceProvider):
id=service_fakes.sp_id,
**kwargs
)
-
- collist = ('auth_url', 'description', 'enabled', 'id', 'sp_url')
- self.assertEqual(collist, collist)
+ self.assertEqual(self.columns, columns)
datalist = (
service_fakes.sp_auth_url,
None,
@@ -282,6 +279,21 @@ class TestServiceProviderShow(TestServiceProvider):
class TestServiceProviderSet(TestServiceProvider):
+ columns = (
+ 'auth_url',
+ 'description',
+ 'enabled',
+ 'id',
+ 'sp_url',
+ )
+ datalist = (
+ service_fakes.sp_auth_url,
+ service_fakes.sp_description,
+ False,
+ service_fakes.sp_id,
+ service_fakes.service_provider_url,
+ )
+
def setUp(self):
super(TestServiceProviderSet, self).setUp()
self.cmd = service_provider.SetServiceProvider(self.app, None)
@@ -321,16 +333,8 @@ class TestServiceProviderSet(TestServiceProvider):
sp_url=None
)
- collist = ('auth_url', 'description', 'enabled', 'id', 'sp_url')
- self.assertEqual(collist, columns)
- datalist = (
- service_fakes.sp_auth_url,
- service_fakes.sp_description,
- False,
- service_fakes.sp_id,
- service_fakes.service_provider_url
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_service_provider_enable(self):
"""Enable Service Provider.
@@ -361,8 +365,7 @@ class TestServiceProviderSet(TestServiceProvider):
self.service_providers_mock.update.assert_called_with(
service_fakes.sp_id, enabled=True, description=None,
auth_url=None, sp_url=None)
- collist = ('auth_url', 'description', 'enabled', 'id', 'sp_url')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
service_fakes.sp_auth_url,
service_fakes.sp_description,
@@ -370,7 +373,7 @@ class TestServiceProviderSet(TestServiceProvider):
service_fakes.sp_id,
service_fakes.service_provider_url
)
- self.assertEqual(data, datalist)
+ self.assertEqual(datalist, data)
def test_service_provider_no_options(self):
def prepare(self):
@@ -408,5 +411,5 @@ class TestServiceProviderSet(TestServiceProvider):
# expect take_action() to return (None, None) as none of --disabled,
# --enabled, --description, --service-provider-url, --auth_url option
# was set.
- self.assertEqual(columns, None)
- self.assertEqual(data, None)
+ self.assertIsNone(columns)
+ self.assertIsNone(data)
diff --git a/openstackclient/tests/identity/v3/test_user.py b/openstackclient/tests/identity/v3/test_user.py
index 76d5f83..1871ed1 100644
--- a/openstackclient/tests/identity/v3/test_user.py
+++ b/openstackclient/tests/identity/v3/test_user.py
@@ -52,6 +52,23 @@ class TestUser(identity_fakes.TestIdentityv3):
class TestUserCreate(TestUser):
+ columns = (
+ 'default_project_id',
+ 'domain_id',
+ 'email',
+ 'enabled',
+ 'id',
+ 'name',
+ )
+ datalist = (
+ identity_fakes.project_id,
+ identity_fakes.domain_id,
+ identity_fakes.user_email,
+ True,
+ identity_fakes.user_id,
+ identity_fakes.user_name,
+ )
+
def setUp(self):
super(TestUserCreate, self).setUp()
@@ -107,18 +124,8 @@ class TestUserCreate(TestUser):
**kwargs
)
- collist = ('default_project_id', 'domain_id', 'email',
- 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_id,
- identity_fakes.domain_id,
- identity_fakes.user_email,
- True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_user_create_password(self):
arglist = [
@@ -152,19 +159,8 @@ class TestUserCreate(TestUser):
self.users_mock.create.assert_called_with(
**kwargs
)
-
- collist = ('default_project_id', 'domain_id', 'email',
- 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_id,
- identity_fakes.domain_id,
- identity_fakes.user_email,
- True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_user_create_password_prompt(self):
arglist = [
@@ -202,18 +198,8 @@ class TestUserCreate(TestUser):
**kwargs
)
- collist = ('default_project_id', 'domain_id', 'email',
- 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_id,
- identity_fakes.domain_id,
- identity_fakes.user_email,
- True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_user_create_email(self):
arglist = [
@@ -247,18 +233,8 @@ class TestUserCreate(TestUser):
**kwargs
)
- collist = ('default_project_id', 'domain_id', 'email',
- 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_id,
- identity_fakes.domain_id,
- identity_fakes.user_email,
- True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_user_create_project(self):
# Return the new project
@@ -307,9 +283,7 @@ class TestUserCreate(TestUser):
**kwargs
)
- collist = ('default_project_id', 'domain_id', 'email',
- 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
identity_fakes.PROJECT_2['id'],
identity_fakes.domain_id,
@@ -369,9 +343,7 @@ class TestUserCreate(TestUser):
**kwargs
)
- collist = ('default_project_id', 'domain_id', 'email',
- 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
identity_fakes.PROJECT_2['id'],
identity_fakes.domain_id,
@@ -414,18 +386,8 @@ class TestUserCreate(TestUser):
**kwargs
)
- collist = ('default_project_id', 'domain_id', 'email',
- 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_id,
- identity_fakes.domain_id,
- identity_fakes.user_email,
- True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_user_create_enable(self):
arglist = [
@@ -458,18 +420,8 @@ class TestUserCreate(TestUser):
**kwargs
)
- collist = ('default_project_id', 'domain_id', 'email',
- 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_id,
- identity_fakes.domain_id,
- identity_fakes.user_email,
- True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_user_create_disable(self):
arglist = [
@@ -500,19 +452,8 @@ class TestUserCreate(TestUser):
self.users_mock.create.assert_called_with(
**kwargs
)
-
- collist = ('default_project_id', 'domain_id', 'email',
- 'enabled', 'id', 'name')
- self.assertEqual(collist, columns)
- datalist = (
- identity_fakes.project_id,
- identity_fakes.domain_id,
- identity_fakes.user_email,
- True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
class TestUserDelete(TestUser):
@@ -550,6 +491,17 @@ class TestUserDelete(TestUser):
class TestUserList(TestUser):
+ columns = [
+ 'ID',
+ 'Name'
+ ]
+ datalist = (
+ (
+ identity_fakes.user_id,
+ identity_fakes.user_name,
+ ),
+ )
+
def setUp(self):
super(TestUserList, self).setUp()
@@ -614,13 +566,8 @@ class TestUserList(TestUser):
**kwargs
)
- collist = ['ID', 'Name']
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.user_id,
- identity_fakes.user_name,
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_user_list_domain(self):
arglist = [
@@ -644,13 +591,8 @@ class TestUserList(TestUser):
**kwargs
)
- collist = ['ID', 'Name']
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.user_id,
- identity_fakes.user_name,
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_user_list_group(self):
arglist = [
@@ -674,13 +616,8 @@ class TestUserList(TestUser):
**kwargs
)
- collist = ['ID', 'Name']
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.user_id,
- identity_fakes.user_name,
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_user_list_long(self):
arglist = [
@@ -714,15 +651,17 @@ class TestUserList(TestUser):
'Enabled',
]
self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.user_id,
- identity_fakes.user_name,
- identity_fakes.project_id,
- identity_fakes.domain_id,
- '',
- identity_fakes.user_email,
- True,
- ), )
+ datalist = (
+ (
+ identity_fakes.user_id,
+ identity_fakes.user_name,
+ identity_fakes.project_id,
+ identity_fakes.domain_id,
+ '',
+ identity_fakes.user_email,
+ True,
+ ),
+ )
self.assertEqual(datalist, tuple(data))
def test_user_list_project(self):
@@ -744,13 +683,8 @@ class TestUserList(TestUser):
self.role_assignments_mock.list.assert_called_with(**kwargs)
self.users_mock.get.assert_called_with(identity_fakes.user_id)
- collist = ['ID', 'Name']
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.user_id,
- identity_fakes.user_name,
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
class TestUserSet(TestUser):
@@ -1095,6 +1029,25 @@ class TestUserSetPassword(TestUser):
current_pass, new_pass
)
+ def test_user_password_change_no_prompt(self):
+ current_pass = 'old_pass'
+ new_pass = 'new_pass'
+ arglist = [
+ '--password', new_pass,
+ '--original-password', current_pass,
+ ]
+ verifylist = [
+ ('password', new_pass),
+ ('original_password', current_pass),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.cmd.take_action(parsed_args)
+
+ self.users_mock.update_password.assert_called_with(
+ current_pass, new_pass
+ )
+
class TestUserShow(TestUser):
diff --git a/openstackclient/tests/image/v1/test_image.py b/openstackclient/tests/image/v1/test_image.py
index 4d964bd..1e0b29a 100644
--- a/openstackclient/tests/image/v1/test_image.py
+++ b/openstackclient/tests/image/v1/test_image.py
@@ -103,6 +103,7 @@ class TestImageCreate(TestImage):
'--min-ram', '4',
'--protected',
'--private',
+ '--project', 'q',
image_fakes.image_name,
]
verifylist = [
@@ -114,6 +115,7 @@ class TestImageCreate(TestImage):
('unprotected', False),
('public', False),
('private', True),
+ ('project', 'q'),
('name', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -130,6 +132,7 @@ class TestImageCreate(TestImage):
min_ram=4,
protected=True,
is_public=False,
+ owner='q',
data=mock.ANY,
)
@@ -237,6 +240,19 @@ class TestImageDelete(TestImage):
class TestImageList(TestImage):
+ columns = (
+ 'ID',
+ 'Name',
+ 'Status',
+ )
+ datalist = (
+ (
+ image_fakes.image_id,
+ image_fakes.image_name,
+ '',
+ ),
+ )
+
def setUp(self):
super(TestImageList, self).setUp()
@@ -265,15 +281,8 @@ class TestImageList(TestImage):
marker=image_fakes.image_id,
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(collist, columns)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_image_list_public_option(self):
arglist = [
@@ -294,15 +303,8 @@ class TestImageList(TestImage):
marker=image_fakes.image_id,
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(collist, columns)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_image_list_private_option(self):
arglist = [
@@ -323,15 +325,8 @@ class TestImageList(TestImage):
marker=image_fakes.image_id,
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(collist, columns)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_image_list_long_option(self):
arglist = [
@@ -358,7 +353,7 @@ class TestImageList(TestImage):
'Status',
'Visibility',
'Protected',
- 'Owner',
+ 'Project',
'Properties',
)
@@ -404,15 +399,8 @@ class TestImageList(TestImage):
property_field='properties',
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(columns, collist)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
@mock.patch('openstackclient.common.utils.sort_items')
def test_image_list_sort_option(self, si_mock):
@@ -435,15 +423,8 @@ class TestImageList(TestImage):
'name:asc'
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(collist, columns)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
class TestImageSet(TestImage):
@@ -484,22 +465,22 @@ class TestImageSet(TestImage):
def test_image_set_options(self):
arglist = [
'--name', 'new-name',
- '--owner', 'new-owner',
'--min-disk', '2',
'--min-ram', '4',
'--container-format', 'ovf',
'--disk-format', 'vmdk',
'--size', '35165824',
+ '--project', 'new-owner',
image_fakes.image_name,
]
verifylist = [
('name', 'new-name'),
- ('owner', 'new-owner'),
('min_disk', 2),
('min_ram', 4),
('container_format', 'ovf'),
('disk_format', 'vmdk'),
('size', 35165824),
+ ('project', 'new-owner'),
('image', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/image/v2/fakes.py b/openstackclient/tests/image/v2/fakes.py
index 11ad455..5441a3e 100644
--- a/openstackclient/tests/image/v2/fakes.py
+++ b/openstackclient/tests/image/v2/fakes.py
@@ -15,7 +15,10 @@
import copy
import mock
+import random
+import uuid
+from openstackclient.common import utils as common_utils
from openstackclient.tests import fakes
from openstackclient.tests import utils
@@ -167,3 +170,133 @@ class TestImagev2(utils.TestCommand):
endpoint=fakes.AUTH_URL,
token=fakes.AUTH_TOKEN,
)
+
+
+class FakeImage(object):
+ """Fake one or more images.
+
+ TODO(xiexs): Currently, only image API v2 is supported by this class.
+ """
+
+ @staticmethod
+ def create_one_image(attrs={}):
+ """Create a fake image.
+
+ :param Dictionary attrs:
+ A dictionary with all attrbutes of image
+ :retrun:
+ A FakeResource object with id, name, owner, protected,
+ visibility and tags attrs
+ """
+ # Set default attribute
+ image_info = {
+ 'id': 'image-id' + uuid.uuid4().hex,
+ 'name': 'image-name' + uuid.uuid4().hex,
+ 'owner': 'image-owner' + uuid.uuid4().hex,
+ 'protected': bool(random.choice([0, 1])),
+ 'visibility': random.choice(['public', 'private']),
+ 'tags': [uuid.uuid4().hex for r in range(2)],
+ }
+
+ # Overwrite default attributes if there are some attributes set
+ image_info.update(attrs)
+
+ image = fakes.FakeResource(
+ None,
+ image_info,
+ loaded=True)
+ return image
+
+ @staticmethod
+ def create_images(attrs={}, count=2):
+ """Create multiple fake images.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes of image
+ :param Integer count:
+ The number of images to be faked
+ :return:
+ A list of FakeResource objects
+ """
+ images = []
+ for n in range(0, count):
+ images.append(FakeImage.create_one_image(attrs))
+
+ return images
+
+ @staticmethod
+ def get_images(images=None, count=2):
+ """Get an iterable MagicMock object with a list of faked images.
+
+ If images list is provided, then initialize the Mock object with the
+ list. Otherwise create one.
+
+ :param List images:
+ A list of FakeResource objects faking images
+ :param Integer count:
+ The number of images to be faked
+ :return
+ An iterable Mock object with side_effect set to a list of faked
+ images
+ """
+ if images is None:
+ images = FakeImage.create_images(count)
+
+ return mock.MagicMock(side_effect=images)
+
+ @staticmethod
+ def get_image_info(image=None):
+ """Get the image info from a faked image object.
+
+ :param image:
+ A FakeResource objects faking image
+ :return
+ A dictionary which includes the faked image info as follows:
+ {
+ 'id': image_id,
+ 'name': image_name,
+ 'owner': image_owner,
+ 'protected': image_protected,
+ 'visibility': image_visibility,
+ 'tags': image_tags
+ }
+ """
+ if image is not None:
+ return image._info
+ return {}
+
+ @staticmethod
+ def get_image_columns(image=None):
+ """Get the image columns from a faked image object.
+
+ :param image:
+ A FakeResource objects faking image
+ :return
+ A tuple which may include the following keys:
+ ('id', 'name', 'owner', 'protected', 'visibility', 'tags')
+ """
+ if image is not None:
+ return tuple(k for k in sorted(
+ FakeImage.get_image_info(image).keys()))
+ return tuple([])
+
+ @staticmethod
+ def get_image_data(image=None):
+ """Get the image data from a faked image object.
+
+ :param image:
+ A FakeResource objects faking image
+ :return
+ A tuple which may include the following values:
+ ('image-123', 'image-foo', 'admin', False, 'public', 'bar, baz')
+ """
+ data_list = []
+ if image is not None:
+ for x in sorted(FakeImage.get_image_info(image).keys()):
+ if x == 'tags':
+ # The 'tags' should be format_list
+ data_list.append(
+ common_utils.format_list(getattr(image, x)))
+ else:
+ data_list.append(getattr(image, x))
+ return tuple(data_list)
diff --git a/openstackclient/tests/image/v2/test_image.py b/openstackclient/tests/image/v2/test_image.py
index be73c4c..d399c9e 100644
--- a/openstackclient/tests/image/v2/test_image.py
+++ b/openstackclient/tests/image/v2/test_image.py
@@ -31,35 +31,52 @@ class TestImage(image_fakes.TestImagev2):
def setUp(self):
super(TestImage, self).setUp()
- # Get a shortcut to the ServerManager Mock
+ # Get shortcuts to the Mocks in image client
self.images_mock = self.app.client_manager.image.images
self.images_mock.reset_mock()
self.image_members_mock = self.app.client_manager.image.image_members
self.image_members_mock.reset_mock()
+
+ # Get shortcut to the Mocks in identity client
self.project_mock = self.app.client_manager.identity.projects
self.project_mock.reset_mock()
self.domain_mock = self.app.client_manager.identity.domains
self.domain_mock.reset_mock()
+ def setup_images_mock(self, count):
+ images = image_fakes.FakeImage.create_images(count=count)
+
+ self.images_mock.get = image_fakes.FakeImage.get_images(
+ images,
+ 0)
+ return images
+
class TestImageCreate(TestImage):
def setUp(self):
super(TestImageCreate, self).setUp()
- self.images_mock.create.return_value = fakes.FakeResource(
+ self.new_image = image_fakes.FakeImage.create_one_image()
+ self.images_mock.create.return_value = self.new_image
+
+ self.project_mock.get.return_value = fakes.FakeResource(
None,
- copy.deepcopy(image_fakes.IMAGE),
+ copy.deepcopy(identity_fakes.PROJECT),
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(
+
+ self.domain_mock.get.return_value = fakes.FakeResource(
None,
- copy.deepcopy(image_fakes.IMAGE),
+ copy.deepcopy(identity_fakes.DOMAIN),
loaded=True,
)
+ # This is the return value for utils.find_resource()
+ self.images_mock.get.return_value = copy.deepcopy(
+ image_fakes.FakeImage.get_image_info(self.new_image))
+ self.images_mock.update.return_value = self.new_image
+
# Get the command object to test
self.cmd = image.CreateImage(self.app, None)
@@ -69,12 +86,12 @@ class TestImageCreate(TestImage):
}
self.images_mock.configure_mock(**mock_exception)
arglist = [
- image_fakes.image_name,
+ self.new_image.name
]
verifylist = [
('container_format', image.DEFAULT_CONTAINER_FORMAT),
('disk_format', image.DEFAULT_DISK_FORMAT),
- ('name', image_fakes.image_name),
+ ('name', self.new_image.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -83,7 +100,7 @@ class TestImageCreate(TestImage):
# ImageManager.create(name=, **)
self.images_mock.create.assert_called_with(
- name=image_fakes.image_name,
+ name=self.new_image.name,
container_format=image.DEFAULT_CONTAINER_FORMAT,
disk_format=image.DEFAULT_DISK_FORMAT,
)
@@ -95,8 +112,12 @@ class TestImageCreate(TestImage):
mock.ANY, mock.ANY,
)
- self.assertEqual(image_fakes.IMAGE_columns, columns)
- self.assertEqual(image_fakes.IMAGE_SHOW_data, data)
+ self.assertEqual(
+ image_fakes.FakeImage.get_image_columns(self.new_image),
+ columns)
+ self.assertEqual(
+ image_fakes.FakeImage.get_image_data(self.new_image),
+ data)
@mock.patch('glanceclient.common.utils.get_data_file', name='Open')
def test_image_reserve_options(self, mock_open):
@@ -112,22 +133,26 @@ class TestImageCreate(TestImage):
'--disk-format', 'fs',
'--min-disk', '10',
'--min-ram', '4',
- '--owner', '123456',
- '--protected',
- '--private',
- image_fakes.image_name,
+ ('--protected'
+ if self.new_image.protected else '--unprotected'),
+ ('--private'
+ if self.new_image.visibility == 'private' else '--public'),
+ '--project', self.new_image.owner,
+ '--project-domain', identity_fakes.domain_id,
+ self.new_image.name,
]
verifylist = [
('container_format', 'ovf'),
('disk_format', 'fs'),
('min_disk', 10),
('min_ram', 4),
- ('owner', '123456'),
- ('protected', True),
- ('unprotected', False),
- ('public', False),
- ('private', True),
- ('name', image_fakes.image_name),
+ ('protected', self.new_image.protected),
+ ('unprotected', not self.new_image.protected),
+ ('public', self.new_image.visibility == 'public'),
+ ('private', self.new_image.visibility == 'private'),
+ ('project', self.new_image.owner),
+ ('project_domain', identity_fakes.domain_id),
+ ('name', self.new_image.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -136,14 +161,14 @@ class TestImageCreate(TestImage):
# ImageManager.create(name=, **)
self.images_mock.create.assert_called_with(
- name=image_fakes.image_name,
+ name=self.new_image.name,
container_format='ovf',
disk_format='fs',
min_disk=10,
min_ram=4,
- owner='123456',
- protected=True,
- visibility='private',
+ owner=identity_fakes.project_id,
+ protected=self.new_image.protected,
+ visibility=self.new_image.visibility,
)
# Verify update() was not called, if it was show the args
@@ -153,14 +178,87 @@ class TestImageCreate(TestImage):
mock.ANY, mock.ANY,
)
- self.assertEqual(image_fakes.IMAGE_columns, columns)
- self.assertEqual(image_fakes.IMAGE_SHOW_data, data)
+ self.assertEqual(
+ image_fakes.FakeImage.get_image_columns(self.new_image),
+ columns)
+ self.assertEqual(
+ image_fakes.FakeImage.get_image_data(self.new_image),
+ data)
+
+ def test_image_create_with_unexist_owner(self):
+ self.project_mock.get.side_effect = exceptions.NotFound(None)
+ self.project_mock.find.side_effect = exceptions.NotFound(None)
+
+ arglist = [
+ '--container-format', 'ovf',
+ '--disk-format', 'fs',
+ '--min-disk', '10',
+ '--min-ram', '4',
+ '--owner', 'unexist_owner',
+ '--protected',
+ '--private',
+ image_fakes.image_name,
+ ]
+ verifylist = [
+ ('container_format', 'ovf'),
+ ('disk_format', 'fs'),
+ ('min_disk', 10),
+ ('min_ram', 4),
+ ('owner', 'unexist_owner'),
+ ('protected', True),
+ ('unprotected', False),
+ ('public', False),
+ ('private', True),
+ ('name', image_fakes.image_name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args,
+ )
+
+ def test_image_create_with_unexist_project(self):
+ self.project_mock.get.side_effect = exceptions.NotFound(None)
+ self.project_mock.find.side_effect = exceptions.NotFound(None)
+
+ arglist = [
+ '--container-format', 'ovf',
+ '--disk-format', 'fs',
+ '--min-disk', '10',
+ '--min-ram', '4',
+ '--protected',
+ '--private',
+ '--project', 'unexist_owner',
+ image_fakes.image_name,
+ ]
+ verifylist = [
+ ('container_format', 'ovf'),
+ ('disk_format', 'fs'),
+ ('min_disk', 10),
+ ('min_ram', 4),
+ ('protected', True),
+ ('unprotected', False),
+ ('public', False),
+ ('private', True),
+ ('project', 'unexist_owner'),
+ ('name', image_fakes.image_name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args,
+ )
@mock.patch('glanceclient.common.utils.get_data_file', name='Open')
def test_image_create_file(self, mock_open):
mock_file = mock.MagicMock(name='File')
mock_open.return_value = mock_file
- mock_open.read.return_value = image_fakes.IMAGE_data
+ mock_open.read.return_value = (
+ image_fakes.FakeImage.get_image_data(self.new_image))
mock_exception = {
'find.side_effect': exceptions.CommandError('x'),
}
@@ -168,23 +266,25 @@ class TestImageCreate(TestImage):
arglist = [
'--file', 'filer',
- '--unprotected',
- '--public',
+ ('--unprotected'
+ if not self.new_image.protected else '--protected'),
+ ('--public'
+ if self.new_image.visibility == 'public' else '--private'),
'--property', 'Alpha=1',
'--property', 'Beta=2',
- '--tag', 'awesome',
- '--tag', 'better',
- image_fakes.image_name,
+ '--tag', self.new_image.tags[0],
+ '--tag', self.new_image.tags[1],
+ self.new_image.name,
]
verifylist = [
('file', 'filer'),
- ('protected', False),
- ('unprotected', True),
- ('public', True),
- ('private', False),
+ ('protected', self.new_image.protected),
+ ('unprotected', not self.new_image.protected),
+ ('public', self.new_image.visibility == 'public'),
+ ('private', self.new_image.visibility == 'private'),
('properties', {'Alpha': '1', 'Beta': '2'}),
- ('tags', ['awesome', 'better']),
- ('name', image_fakes.image_name),
+ ('tags', self.new_image.tags),
+ ('name', self.new_image.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -193,14 +293,14 @@ class TestImageCreate(TestImage):
# ImageManager.create(name=, **)
self.images_mock.create.assert_called_with(
- name=image_fakes.image_name,
+ name=self.new_image.name,
container_format=image.DEFAULT_CONTAINER_FORMAT,
disk_format=image.DEFAULT_DISK_FORMAT,
- protected=False,
- visibility='public',
+ protected=self.new_image.protected,
+ visibility=self.new_image.visibility,
Alpha='1',
Beta='2',
- tags=['awesome', 'better'],
+ tags=self.new_image.tags,
)
# Verify update() was not called, if it was show the args
@@ -210,17 +310,21 @@ class TestImageCreate(TestImage):
mock.ANY, mock.ANY,
)
- self.assertEqual(image_fakes.IMAGE_columns, columns)
- self.assertEqual(image_fakes.IMAGE_SHOW_data, data)
+ self.assertEqual(
+ image_fakes.FakeImage.get_image_columns(self.new_image),
+ columns)
+ self.assertEqual(
+ image_fakes.FakeImage.get_image_data(self.new_image),
+ data)
def test_image_create_dead_options(self):
arglist = [
'--store', 'somewhere',
- image_fakes.image_name,
+ self.new_image.name,
]
verifylist = [
- ('name', image_fakes.image_name),
+ ('name', self.new_image.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -231,6 +335,17 @@ class TestImageCreate(TestImage):
class TestAddProjectToImage(TestImage):
+ columns = (
+ 'image_id',
+ 'member_id',
+ 'status',
+ )
+ datalist = (
+ image_fakes.image_id,
+ identity_fakes.project_id,
+ image_fakes.member_status,
+ )
+
def setUp(self):
super(TestAddProjectToImage, self).setUp()
@@ -273,14 +388,8 @@ class TestAddProjectToImage(TestImage):
image_fakes.image_id,
identity_fakes.project_id
)
- collist = ('image_id', 'member_id', 'status')
- self.assertEqual(collist, columns)
- datalist = (
- image_fakes.image_id,
- identity_fakes.project_id,
- image_fakes.member_status
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_add_project_to_image_with_option(self):
arglist = [
@@ -301,14 +410,8 @@ class TestAddProjectToImage(TestImage):
image_fakes.image_id,
identity_fakes.project_id
)
- collist = ('image_id', 'member_id', 'status')
- self.assertEqual(collist, columns)
- datalist = (
- image_fakes.image_id,
- identity_fakes.project_id,
- image_fakes.member_status
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
class TestImageDelete(TestImage):
@@ -316,23 +419,19 @@ class TestImageDelete(TestImage):
def setUp(self):
super(TestImageDelete, self).setUp()
- # This is the return value for utils.find_resource()
- self.images_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(image_fakes.IMAGE),
- loaded=True,
- )
self.images_mock.delete.return_value = None
# Get the command object to test
self.cmd = image.DeleteImage(self.app, None)
def test_image_delete_no_options(self):
+ images = self.setup_images_mock(count=1)
+
arglist = [
- image_fakes.image_id,
+ images[0].id,
]
verifylist = [
- ('images', [image_fakes.image_id]),
+ ('images', [images[0].id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -340,12 +439,41 @@ class TestImageDelete(TestImage):
self.cmd.take_action(parsed_args)
self.images_mock.delete.assert_called_with(
- image_fakes.image_id,
+ images[0].id,
)
+ def test_image_delete_multi_images(self):
+ images = self.setup_images_mock(count=3)
+
+ arglist = [i.id for i in images]
+ verifylist = [
+ ('images', arglist),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.cmd.take_action(parsed_args)
+
+ calls = [mock.call(i.id) for i in images]
+
+ self.images_mock.delete.assert_has_calls(calls)
+
class TestImageList(TestImage):
+ columns = (
+ 'ID',
+ 'Name',
+ 'Status',
+ )
+ datalist = (
+ (
+ image_fakes.image_id,
+ image_fakes.image_name,
+ '',
+ ),
+ )
+
def setUp(self):
super(TestImageList, self).setUp()
@@ -370,19 +498,10 @@ class TestImageList(TestImage):
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- self.api_mock.image_list.assert_called_with(
- marker=image_fakes.image_id,
- )
+ self.api_mock.image_list.assert_called_with()
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(collist, columns)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_image_list_public_option(self):
arglist = [
@@ -400,18 +519,10 @@ class TestImageList(TestImage):
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.image_list.assert_called_with(
public=True,
- marker=image_fakes.image_id,
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(collist, columns)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_image_list_private_option(self):
arglist = [
@@ -429,18 +540,10 @@ class TestImageList(TestImage):
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.image_list.assert_called_with(
private=True,
- marker=image_fakes.image_id,
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(collist, columns)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_image_list_shared_option(self):
arglist = [
@@ -458,18 +561,10 @@ class TestImageList(TestImage):
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.image_list.assert_called_with(
shared=True,
- marker=image_fakes.image_id,
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(columns, collist)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_image_list_long_option(self):
arglist = [
@@ -482,9 +577,7 @@ class TestImageList(TestImage):
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- self.api_mock.image_list.assert_called_with(
- marker=image_fakes.image_id,
- )
+ self.api_mock.image_list.assert_called_with()
collist = (
'ID',
@@ -495,7 +588,7 @@ class TestImageList(TestImage):
'Status',
'Visibility',
'Protected',
- 'Owner',
+ 'Project',
'Tags',
)
@@ -530,9 +623,7 @@ class TestImageList(TestImage):
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- self.api_mock.image_list.assert_called_with(
- marker=image_fakes.image_id,
- )
+ self.api_mock.image_list.assert_called_with()
sf_mock.assert_called_with(
[image_fakes.IMAGE],
attr='a',
@@ -540,15 +631,8 @@ class TestImageList(TestImage):
property_field='properties',
)
- collist = ('ID', 'Name', 'Status')
-
- self.assertEqual(columns, collist)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
@mock.patch('openstackclient.common.utils.sort_items')
def test_image_list_sort_option(self, si_mock):
@@ -562,23 +646,52 @@ class TestImageList(TestImage):
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- self.api_mock.image_list.assert_called_with(
- marker=image_fakes.image_id,
- )
+ self.api_mock.image_list.assert_called_with()
si_mock.assert_called_with(
[image_fakes.IMAGE],
'name:asc'
)
- collist = ('ID', 'Name', 'Status')
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
- self.assertEqual(collist, columns)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ def test_image_list_limit_option(self):
+ arglist = [
+ '--limit', str(1),
+ ]
+ verifylist = [
+ ('limit', 1),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ self.api_mock.image_list.assert_called_with(
+ limit=1,
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(len(self.datalist), len(tuple(data)))
+
+ @mock.patch('openstackclient.common.utils.find_resource')
+ def test_image_list_marker_option(self, fr_mock):
+ # tangchen: Since image_fakes.IMAGE is a dict, it cannot offer a .id
+ # operation. Will fix this by using FakeImage class instead
+ # of IMAGE dict.
+ fr_mock.return_value = mock.Mock()
+ fr_mock.return_value.id = image_fakes.image_id
+
+ arglist = [
+ '--marker', image_fakes.image_name,
+ ]
+ verifylist = [
+ ('marker', image_fakes.image_name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ self.api_mock.image_list.assert_called_with(
+ marker=image_fakes.image_id,
+ )
class TestRemoveProjectImage(TestImage):
@@ -655,6 +768,18 @@ class TestImageSet(TestImage):
schemas.SchemaBasedModel,
)
+ self.project_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes.PROJECT),
+ loaded=True,
+ )
+
+ self.domain_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes.DOMAIN),
+ loaded=True,
+ )
+
self.images_mock.get.return_value = self.model(**image_fakes.IMAGE)
self.images_mock.update.return_value = self.model(**image_fakes.IMAGE)
# Get the command object to test
@@ -663,20 +788,22 @@ class TestImageSet(TestImage):
def test_image_set_options(self):
arglist = [
'--name', 'new-name',
- '--owner', 'new-owner',
'--min-disk', '2',
'--min-ram', '4',
'--container-format', 'ovf',
'--disk-format', 'vmdk',
+ '--project', identity_fakes.project_name,
+ '--project-domain', identity_fakes.domain_id,
image_fakes.image_id,
]
verifylist = [
('name', 'new-name'),
- ('owner', 'new-owner'),
('min_disk', 2),
('min_ram', 4),
('container_format', 'ovf'),
('disk_format', 'vmdk'),
+ ('project', identity_fakes.project_name),
+ ('project_domain', identity_fakes.domain_id),
('image', image_fakes.image_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -686,7 +813,7 @@ class TestImageSet(TestImage):
kwargs = {
'name': 'new-name',
- 'owner': 'new-owner',
+ 'owner': identity_fakes.project_id,
'min_disk': 2,
'min_ram': 4,
'container_format': 'ovf',
@@ -696,6 +823,44 @@ class TestImageSet(TestImage):
self.images_mock.update.assert_called_with(
image_fakes.image_id, **kwargs)
+ def test_image_set_with_unexist_owner(self):
+ self.project_mock.get.side_effect = exceptions.NotFound(None)
+ self.project_mock.find.side_effect = exceptions.NotFound(None)
+
+ arglist = [
+ '--owner', 'unexist_owner',
+ image_fakes.image_id,
+ ]
+ verifylist = [
+ ('owner', 'unexist_owner'),
+ ('image', image_fakes.image_id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action, parsed_args)
+
+ def test_image_set_with_unexist_project(self):
+ self.project_mock.get.side_effect = exceptions.NotFound(None)
+ self.project_mock.find.side_effect = exceptions.NotFound(None)
+
+ arglist = [
+ '--project', 'unexist_owner',
+ image_fakes.image_id,
+ ]
+ verifylist = [
+ ('project', 'unexist_owner'),
+ ('image', image_fakes.image_id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action, parsed_args)
+
def test_image_set_bools1(self):
arglist = [
'--protected',
@@ -838,6 +1003,64 @@ class TestImageSet(TestImage):
**kwargs
)
+ def test_image_set_activate(self):
+ arglist = [
+ '--tag', 'test-tag',
+ '--activate',
+ image_fakes.image_name,
+ ]
+ verifylist = [
+ ('tags', ['test-tag']),
+ ('image', image_fakes.image_name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ self.cmd.take_action(parsed_args)
+
+ kwargs = {
+ 'tags': ['test-tag'],
+ }
+
+ self.images_mock.reactivate.assert_called_with(
+ image_fakes.image_id,
+ )
+
+ # ImageManager.update(image, **kwargs)
+ self.images_mock.update.assert_called_with(
+ image_fakes.image_id,
+ **kwargs
+ )
+
+ def test_image_set_deactivate(self):
+ arglist = [
+ '--tag', 'test-tag',
+ '--deactivate',
+ image_fakes.image_name,
+ ]
+ verifylist = [
+ ('tags', ['test-tag']),
+ ('image', image_fakes.image_name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ self.cmd.take_action(parsed_args)
+
+ kwargs = {
+ 'tags': ['test-tag'],
+ }
+
+ self.images_mock.deactivate.assert_called_with(
+ image_fakes.image_id,
+ )
+
+ # ImageManager.update(image, **kwargs)
+ self.images_mock.update.assert_called_with(
+ image_fakes.image_id,
+ **kwargs
+ )
+
def test_image_set_tag_merge(self):
old_image = copy.copy(image_fakes.IMAGE)
old_image['tags'] = ['old1', 'new2']
diff --git a/openstackclient/tests/network/test_common.py b/openstackclient/tests/network/test_common.py
index b30fdfc..a3396b9 100644
--- a/openstackclient/tests/network/test_common.py
+++ b/openstackclient/tests/network/test_common.py
@@ -11,62 +11,93 @@
# under the License.
#
+import argparse
import mock
-from openstackclient.common import exceptions
from openstackclient.network import common
from openstackclient.tests import utils
-RESOURCE = 'resource'
-RESOURCES = 'resources'
-NAME = 'matrix'
-ID = 'Fishburne'
-
-class TestFind(utils.TestCase):
+class FakeNetworkAndComputeCommand(common.NetworkAndComputeCommand):
+ def update_parser_common(self, parser):
+ parser.add_argument(
+ 'common',
+ metavar='<common>',
+ help='Common argument',
+ )
+ return parser
+
+ def update_parser_network(self, parser):
+ parser.add_argument(
+ 'network',
+ metavar='<network>',
+ help='Network argument',
+ )
+ return parser
+
+ def update_parser_compute(self, parser):
+ parser.add_argument(
+ 'compute',
+ metavar='<compute>',
+ help='Compute argument',
+ )
+ return parser
+
+ def take_action_network(self, client, parsed_args):
+ client.network_action(parsed_args)
+ return 'take_action_network'
+
+ def take_action_compute(self, client, parsed_args):
+ client.compute_action(parsed_args)
+ return 'take_action_compute'
+
+
+class TestNetworkAndComputeCommand(utils.TestCommand):
def setUp(self):
- super(TestFind, self).setUp()
- self.mock_client = mock.Mock()
- self.list_resources = mock.Mock()
- self.mock_client.list_resources = self.list_resources
- self.matrix = {'id': ID}
-
- def test_name(self):
- self.list_resources.return_value = {RESOURCES: [self.matrix]}
-
- result = common.find(self.mock_client, RESOURCE, RESOURCES, NAME)
-
- self.assertEqual(ID, result)
- self.list_resources.assert_called_with(fields='id', name=NAME)
-
- def test_id(self):
- self.list_resources.side_effect = [{RESOURCES: []},
- {RESOURCES: [self.matrix]}]
-
- result = common.find(self.mock_client, RESOURCE, RESOURCES, NAME)
-
- self.assertEqual(ID, result)
- self.list_resources.assert_called_with(fields='id', id=NAME)
-
- def test_nameo(self):
- self.list_resources.return_value = {RESOURCES: [self.matrix]}
-
- result = common.find(self.mock_client, RESOURCE, RESOURCES, NAME,
- name_attr='nameo')
-
- self.assertEqual(ID, result)
- self.list_resources.assert_called_with(fields='id', nameo=NAME)
-
- def test_dups(self):
- dup = {'id': 'Larry'}
- self.list_resources.return_value = {RESOURCES: [self.matrix, dup]}
-
- self.assertRaises(exceptions.CommandError, common.find,
- self.mock_client, RESOURCE, RESOURCES, NAME)
-
- def test_nada(self):
- self.list_resources.side_effect = [{RESOURCES: []},
- {RESOURCES: []}]
-
- self.assertRaises(exceptions.CommandError, common.find,
- self.mock_client, RESOURCE, RESOURCES, NAME)
+ super(TestNetworkAndComputeCommand, self).setUp()
+
+ self.namespace = argparse.Namespace()
+
+ # Create network client mocks.
+ self.app.client_manager.network = mock.Mock()
+ self.network = self.app.client_manager.network
+ self.network.network_action = mock.Mock(return_value=None)
+
+ # Create compute client mocks.
+ self.app.client_manager.compute = mock.Mock()
+ self.compute = self.app.client_manager.compute
+ self.compute.compute_action = mock.Mock(return_value=None)
+
+ # Get the command object to test
+ self.cmd = FakeNetworkAndComputeCommand(self.app, self.namespace)
+
+ def test_take_action_network(self):
+ arglist = [
+ 'common',
+ 'network'
+ ]
+ verifylist = [
+ ('common', 'common'),
+ ('network', 'network')
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+ self.network.network_action.assert_called_with(parsed_args)
+ self.assertEqual('take_action_network', result)
+
+ def test_take_action_compute(self):
+ arglist = [
+ 'common',
+ 'compute'
+ ]
+ verifylist = [
+ ('common', 'common'),
+ ('compute', 'compute')
+ ]
+
+ self.app.client_manager.network_endpoint_enabled = False
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+ self.compute.compute_action.assert_called_with(parsed_args)
+ self.assertEqual('take_action_compute', result)
diff --git a/openstackclient/tests/network/v2/fakes.py b/openstackclient/tests/network/v2/fakes.py
index ea191c8..516995e 100644
--- a/openstackclient/tests/network/v2/fakes.py
+++ b/openstackclient/tests/network/v2/fakes.py
@@ -11,7 +11,13 @@
# under the License.
#
+import argparse
+import copy
import mock
+import uuid
+
+from openstackclient.tests import fakes
+from openstackclient.tests import utils
extension_name = 'Matrix'
extension_namespace = 'http://docs.openstack.org/network/'
@@ -20,16 +26,530 @@ extension_updated = '2013-07-09T12:00:0-00:00'
extension_alias = 'Dystopian'
extension_links = '[{"href":''"https://github.com/os/network", "type"}]'
-NETEXT = {
- 'name': extension_name,
- 'namespace': extension_namespace,
- 'description': extension_description,
- 'updated': extension_updated,
- 'alias': extension_alias,
- 'links': extension_links,
+QUOTA = {
+ "subnet": 10,
+ "network": 10,
+ "floatingip": 50,
+ "subnetpool": -1,
+ "security_group_rule": 100,
+ "security_group": 10,
+ "router": 10,
+ "rbac_policy": -1,
+ "port": 50,
}
+def create_extension():
+ extension = mock.Mock()
+ extension.name = extension_name
+ extension.namespace = extension_namespace
+ extension.description = extension_description
+ extension.updated = extension_updated
+ extension.alias = extension_alias
+ extension.links = extension_links
+ return extension
+
+
class FakeNetworkV2Client(object):
def __init__(self, **kwargs):
- self.list_extensions = mock.Mock(return_value={'extensions': [NETEXT]})
+ self.extensions = mock.Mock(return_value=[create_extension()])
+
+
+class TestNetworkV2(utils.TestCommand):
+ def setUp(self):
+ super(TestNetworkV2, self).setUp()
+
+ self.namespace = argparse.Namespace()
+
+ self.app.client_manager.session = mock.Mock()
+
+ self.app.client_manager.network = FakeNetworkV2Client(
+ endpoint=fakes.AUTH_URL,
+ token=fakes.AUTH_TOKEN,
+ )
+
+
+class FakeAvailabilityZone(object):
+ """Fake one or more network availability zones (AZs)."""
+
+ @staticmethod
+ def create_one_availability_zone(attrs={}, methods={}):
+ """Create a fake AZ.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :return:
+ A FakeResource object with name, state, etc.
+ """
+ # Set default attributes.
+ availability_zone = {
+ 'name': uuid.uuid4().hex,
+ 'state': 'available',
+ 'resource': 'network',
+ }
+
+ # Overwrite default attributes.
+ availability_zone.update(attrs)
+
+ availability_zone = fakes.FakeResource(
+ info=copy.deepcopy(availability_zone),
+ methods=methods,
+ loaded=True)
+ return availability_zone
+
+ @staticmethod
+ def create_availability_zones(attrs={}, methods={}, count=2):
+ """Create multiple fake AZs.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :param int count:
+ The number of AZs to fake
+ :return:
+ A list of FakeResource objects faking the AZs
+ """
+ availability_zones = []
+ for i in range(0, count):
+ availability_zone = \
+ FakeAvailabilityZone.create_one_availability_zone(
+ attrs, methods)
+ availability_zones.append(availability_zone)
+
+ return availability_zones
+
+
+class FakeNetwork(object):
+ """Fake one or more networks."""
+
+ @staticmethod
+ def create_one_network(attrs={}, methods={}):
+ """Create a fake network.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :return:
+ A FakeResource object, with id, name, admin_state_up,
+ router_external, status, subnets, tenant_id
+ """
+ # Set default attributes.
+ project_id = 'project-id-' + uuid.uuid4().hex
+ network_attrs = {
+ 'id': 'network-id-' + uuid.uuid4().hex,
+ 'name': 'network-name-' + uuid.uuid4().hex,
+ 'status': 'ACTIVE',
+ 'tenant_id': project_id,
+ 'admin_state_up': True,
+ 'shared': False,
+ 'subnets': ['a', 'b'],
+ 'provider_network_type': 'vlan',
+ 'router_external': True,
+ 'availability_zones': [],
+ 'availability_zone_hints': [],
+ }
+
+ # Overwrite default attributes.
+ network_attrs.update(attrs)
+
+ # Set default methods.
+ network_methods = {
+ 'keys': ['id', 'name', 'admin_state_up', 'router_external',
+ 'status', 'subnets', 'tenant_id', 'availability_zones',
+ 'availability_zone_hints'],
+ }
+
+ # Overwrite default methods.
+ network_methods.update(methods)
+
+ network = fakes.FakeResource(info=copy.deepcopy(network_attrs),
+ methods=copy.deepcopy(network_methods),
+ loaded=True)
+ network.project_id = project_id
+
+ return network
+
+ @staticmethod
+ def create_networks(attrs={}, methods={}, count=2):
+ """Create multiple fake networks.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :param int count:
+ The number of networks to fake
+ :return:
+ A list of FakeResource objects faking the networks
+ """
+ networks = []
+ for i in range(0, count):
+ networks.append(FakeNetwork.create_one_network(attrs, methods))
+
+ return networks
+
+ @staticmethod
+ def get_networks(networks=None, count=2):
+ """Get an iterable MagicMock object with a list of faked networks.
+
+ If networks list is provided, then initialize the Mock object with the
+ list. Otherwise create one.
+
+ :param List networks:
+ A list of FakeResource objects faking networks
+ :param int count:
+ The number of networks to fake
+ :return:
+ An iterable Mock object with side_effect set to a list of faked
+ networks
+ """
+ if networks is None:
+ networks = FakeNetwork.create_networks(count)
+ return mock.MagicMock(side_effect=networks)
+
+
+class FakePort(object):
+ """Fake one or more ports."""
+
+ @staticmethod
+ def create_one_port(attrs={}, methods={}):
+ """Create a fake port.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :return:
+ A FakeResource object, with id, name, etc.
+ """
+
+ # Set default attributes.
+ port_attrs = {
+ 'admin_state_up': True,
+ 'allowed_address_pairs': [{}],
+ 'binding:host_id': 'binding-host-id-' + uuid.uuid4().hex,
+ 'binding:profile': {},
+ 'binding:vif_details': {},
+ 'binding:vif_type': 'ovs',
+ 'binding:vnic_type': 'normal',
+ 'device_id': 'device-id-' + uuid.uuid4().hex,
+ 'device_owner': 'compute:nova',
+ 'dns_assignment': [{}],
+ 'dns_name': 'dns-name-' + uuid.uuid4().hex,
+ 'extra_dhcp_opts': [{}],
+ 'fixed_ips': [{}],
+ 'id': 'port-id-' + uuid.uuid4().hex,
+ 'mac_address': 'fa:16:3e:a9:4e:72',
+ 'name': 'port-name-' + uuid.uuid4().hex,
+ 'network_id': 'network-id-' + uuid.uuid4().hex,
+ 'port_security_enabled': True,
+ 'security_groups': [],
+ 'status': 'ACTIVE',
+ 'tenant_id': 'project-id-' + uuid.uuid4().hex,
+ }
+
+ # Overwrite default attributes.
+ port_attrs.update(attrs)
+
+ # Set default methods.
+ port_methods = {
+ 'keys': ['admin_state_up', 'allowed_address_pairs',
+ 'binding:host_id', 'binding:profile',
+ 'binding:vif_details', 'binding:vif_type',
+ 'binding:vnic_type', 'device_id', 'device_owner',
+ 'dns_assignment', 'dns_name', 'extra_dhcp_opts',
+ 'fixed_ips', 'id', 'mac_address', 'name',
+ 'network_id', 'port_security_enabled',
+ 'security_groups', 'status', 'tenant_id'],
+ }
+
+ # Overwrite default methods.
+ port_methods.update(methods)
+
+ port = fakes.FakeResource(info=copy.deepcopy(port_attrs),
+ methods=copy.deepcopy(port_methods),
+ loaded=True)
+
+ # Set attributes with special mappings.
+ port.project_id = port_attrs['tenant_id']
+ port.binding_host_id = port_attrs['binding:host_id']
+ port.binding_profile = port_attrs['binding:profile']
+ port.binding_vif_details = port_attrs['binding:vif_details']
+ port.binding_vif_type = port_attrs['binding:vif_type']
+ port.binding_vnic_type = port_attrs['binding:vnic_type']
+
+ return port
+
+ @staticmethod
+ def create_ports(attrs={}, methods={}, count=2):
+ """Create multiple fake ports.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :param int count:
+ The number of ports to fake
+ :return:
+ A list of FakeResource objects faking the ports
+ """
+ ports = []
+ for i in range(0, count):
+ ports.append(FakePort.create_one_port(attrs, methods))
+
+ return ports
+
+ @staticmethod
+ def get_ports(ports=None, count=2):
+ """Get an iterable MagicMock object with a list of faked ports.
+
+ If ports list is provided, then initialize the Mock object with the
+ list. Otherwise create one.
+
+ :param List ports:
+ A list of FakeResource objects faking ports
+ :param int count:
+ The number of ports to fake
+ :return:
+ An iterable Mock object with side_effect set to a list of faked
+ ports
+ """
+ if ports is None:
+ ports = FakePort.create_ports(count)
+ return mock.MagicMock(side_effect=ports)
+
+
+class FakeRouter(object):
+ """Fake one or more routers."""
+
+ @staticmethod
+ def create_one_router(attrs={}, methods={}):
+ """Create a fake router.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :return:
+ A FakeResource object, with id, name, admin_state_up,
+ status, tenant_id
+ """
+ # Set default attributes.
+ router_attrs = {
+ 'id': 'router-id-' + uuid.uuid4().hex,
+ 'name': 'router-name-' + uuid.uuid4().hex,
+ 'status': 'ACTIVE',
+ 'admin_state_up': True,
+ 'distributed': False,
+ 'ha': False,
+ 'tenant_id': 'project-id-' + uuid.uuid4().hex,
+ 'routes': [],
+ 'external_gateway_info': {},
+ 'availability_zone_hints': [],
+ 'availability_zones': [],
+ }
+
+ # Overwrite default attributes.
+ router_attrs.update(attrs)
+
+ # Set default methods.
+ router_methods = {
+ 'keys': ['id', 'name', 'admin_state_up', 'distributed', 'ha',
+ 'tenant_id'],
+ }
+
+ # Overwrite default methods.
+ router_methods.update(methods)
+
+ router = fakes.FakeResource(info=copy.deepcopy(router_attrs),
+ methods=copy.deepcopy(router_methods),
+ loaded=True)
+ return router
+
+ @staticmethod
+ def create_routers(attrs={}, methods={}, count=2):
+ """Create multiple fake routers.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :param int count:
+ The number of routers to fake
+ :return:
+ A list of FakeResource objects faking the routers
+ """
+ routers = []
+ for i in range(0, count):
+ routers.append(FakeRouter.create_one_router(attrs, methods))
+
+ return routers
+
+ @staticmethod
+ def get_routers(routers=None, count=2):
+ """Get an iterable MagicMock object with a list of faked routers.
+
+ If routers list is provided, then initialize the Mock object with the
+ list. Otherwise create one.
+
+ :param List routers:
+ A list of FakeResource objects faking routers
+ :param int count:
+ The number of routers to fake
+ :return:
+ An iterable Mock object with side_effect set to a list of faked
+ routers
+ """
+ if routers is None:
+ routers = FakeRouter.create_routers(count)
+ return mock.MagicMock(side_effect=routers)
+
+
+class FakeSecurityGroup(object):
+ """Fake one or more security groups."""
+
+ @staticmethod
+ def create_one_security_group(attrs={}, methods={}):
+ """Create a fake security group.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :return:
+ A FakeResource object, with id, name, etc.
+ """
+ # Set default attributes.
+ security_group_attrs = {
+ 'id': 'security-group-id-' + uuid.uuid4().hex,
+ 'name': 'security-group-name-' + uuid.uuid4().hex,
+ 'description': 'security-group-description-' + uuid.uuid4().hex,
+ 'tenant_id': 'project-id-' + uuid.uuid4().hex,
+ 'security_group_rules': [],
+ }
+
+ # Overwrite default attributes.
+ security_group_attrs.update(attrs)
+
+ # Set default methods.
+ security_group_methods = {}
+
+ # Overwrite default methods.
+ security_group_methods.update(methods)
+
+ security_group = fakes.FakeResource(
+ info=copy.deepcopy(security_group_attrs),
+ methods=copy.deepcopy(security_group_methods),
+ loaded=True)
+ return security_group
+
+ @staticmethod
+ def create_security_groups(attrs={}, methods={}, count=2):
+ """Create multiple fake security groups.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :param int count:
+ The number of security groups to fake
+ :return:
+ A list of FakeResource objects faking the security groups
+ """
+ security_groups = []
+ for i in range(0, count):
+ security_groups.append(
+ FakeRouter.create_one_security_group(attrs, methods))
+
+ return security_groups
+
+ @staticmethod
+ def get_security_groups(security_groups=None, count=2):
+ """Get an iterable MagicMock object with a list of faked security groups.
+
+ If security group list is provided, then initialize the Mock object
+ with the list. Otherwise create one.
+
+ :param List security groups:
+ A list of FakeResource objects faking security groups
+ :param int count:
+ The number of security groups to fake
+ :return:
+ An iterable Mock object with side_effect set to a list of faked
+ security groups
+ """
+ if security_groups is None:
+ security_groups = FakeRouter.create_security_groups(count)
+ return mock.MagicMock(side_effect=security_groups)
+
+
+class FakeSubnet(object):
+ """Fake one or more subnets."""
+
+ @staticmethod
+ def create_one_subnet(attrs={}, methods={}):
+ """Create a fake subnet.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :return:
+ A FakeResource object faking the subnet
+ """
+ # Set default attributes.
+ subnet_attrs = {
+ 'id': 'subnet-id-' + uuid.uuid4().hex,
+ 'name': 'subnet-name-' + uuid.uuid4().hex,
+ 'network_id': 'network-id-' + uuid.uuid4().hex,
+ 'cidr': '10.10.10.0/24',
+ 'tenant_id': 'project-id-' + uuid.uuid4().hex,
+ 'enable_dhcp': True,
+ 'dns_nameservers': [],
+ 'allocation_pools': [],
+ 'host_routes': [],
+ 'ip_version': '4',
+ 'gateway_ip': '10.10.10.1',
+ }
+
+ # Overwrite default attributes.
+ subnet_attrs.update(attrs)
+
+ # Set default methods.
+ subnet_methods = {
+ 'keys': ['id', 'name', 'network_id', 'cidr', 'enable_dhcp',
+ 'allocation_pools', 'dns_nameservers', 'gateway_ip',
+ 'host_routes', 'ip_version', 'tenant_id']
+ }
+
+ # Overwrite default methods.
+ subnet_methods.update(methods)
+
+ subnet = fakes.FakeResource(info=copy.deepcopy(subnet_attrs),
+ methods=copy.deepcopy(subnet_methods),
+ loaded=True)
+
+ return subnet
+
+ @staticmethod
+ def create_subnets(attrs={}, methods={}, count=2):
+ """Create multiple fake subnets.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :param int count:
+ The number of subnets to fake
+ :return:
+ A list of FakeResource objects faking the subnets
+ """
+ subnets = []
+ for i in range(0, count):
+ subnets.append(FakeSubnet.create_one_subnet(attrs, methods))
+
+ return subnets
diff --git a/openstackclient/tests/network/v2/test_network.py b/openstackclient/tests/network/v2/test_network.py
index 5506259..f96497a 100644
--- a/openstackclient/tests/network/v2/test_network.py
+++ b/openstackclient/tests/network/v2/test_network.py
@@ -15,75 +15,120 @@ import copy
import mock
from openstackclient.common import exceptions
+from openstackclient.common import utils
from openstackclient.network.v2 import network
from openstackclient.tests import fakes
from openstackclient.tests.identity.v2_0 import fakes as identity_fakes_v2
from openstackclient.tests.identity.v3 import fakes as identity_fakes_v3
-from openstackclient.tests.network import common
-
-RESOURCE = 'network'
-RESOURCES = 'networks'
-FAKE_ID = 'iditty'
-FAKE_NAME = 'noo'
-FAKE_PROJECT = 'yaa'
-RECORD = {
- 'id': FAKE_ID,
- 'name': FAKE_NAME,
- 'admin_state_up': True,
- 'router:external': True,
- 'status': 'ACTIVE',
- 'subnets': ['a', 'b'],
- 'tenant_id': FAKE_PROJECT,
-}
-COLUMNS = ['ID', 'Name', 'Subnets']
-RESPONSE = {RESOURCE: copy.deepcopy(RECORD)}
-FILTERED = [
- (
+from openstackclient.tests.network.v2 import fakes as network_fakes
+from openstackclient.tests import utils as tests_utils
+
+
+class TestNetwork(network_fakes.TestNetworkV2):
+
+ def setUp(self):
+ super(TestNetwork, self).setUp()
+
+ # Get a shortcut to the network client
+ self.network = self.app.client_manager.network
+
+
+class TestCreateNetworkIdentityV3(TestNetwork):
+
+ # The new network created.
+ _network = network_fakes.FakeNetwork.create_one_network(
+ attrs={
+ 'tenant_id': identity_fakes_v3.project_id,
+ 'availability_zone_hints': ["nova"],
+ }
+ )
+
+ columns = (
+ 'admin_state_up',
+ 'availability_zone_hints',
+ 'availability_zones',
'id',
'name',
'project_id',
- 'router_type',
- 'state',
+ 'router_external',
'status',
'subnets',
- ),
- (
- FAKE_ID,
- FAKE_NAME,
- FAKE_PROJECT,
- 'External',
- 'UP',
- 'ACTIVE',
- 'a, b',
- ),
-]
-
-
-class TestCreateNetwork(common.TestNetworkBase):
+ )
+
+ data = (
+ network._format_admin_state(_network.admin_state_up),
+ utils.format_list(_network.availability_zone_hints),
+ utils.format_list(_network.availability_zones),
+ _network.id,
+ _network.name,
+ _network.project_id,
+ network._format_router_external(_network.router_external),
+ _network.status,
+ utils.format_list(_network.subnets),
+ )
+
+ def setUp(self):
+ super(TestCreateNetworkIdentityV3, self).setUp()
+
+ self.network.create_network = mock.Mock(return_value=self._network)
+
+ # Get the command object to test
+ self.cmd = network.CreateNetwork(self.app, self.namespace)
+
+ # Set identity client v3. And get a shortcut to Identity client.
+ identity_client = identity_fakes_v3.FakeIdentityv3Client(
+ endpoint=fakes.AUTH_URL,
+ token=fakes.AUTH_TOKEN,
+ )
+ self.app.client_manager.identity = identity_client
+ self.identity = self.app.client_manager.identity
+
+ # Get a shortcut to the ProjectManager Mock
+ self.projects_mock = self.identity.projects
+ self.projects_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes_v3.PROJECT),
+ loaded=True,
+ )
+
+ # Get a shortcut to the DomainManager Mock
+ self.domains_mock = self.identity.domains
+ self.domains_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes_v3.DOMAIN),
+ loaded=True,
+ )
+
def test_create_no_options(self):
+ arglist = []
+ verifylist = []
+
+ try:
+ # Missing required args should bail here
+ self.check_parser(self.cmd, arglist, verifylist)
+ except tests_utils.ParserException:
+ pass
+
+ def test_create_default_options(self):
arglist = [
- FAKE_NAME,
+ self._network.name,
]
verifylist = [
- ('name', FAKE_NAME),
+ ('name', self._network.name),
('admin_state', True),
('shared', None),
('project', None),
]
- mocker = mock.Mock(return_value=copy.deepcopy(RESPONSE))
- self.app.client_manager.network.create_network = mocker
- cmd = network.CreateNetwork(self.app, self.namespace)
-
- parsed_args = self.check_parser(cmd, arglist, verifylist)
- result = list(cmd.take_action(parsed_args))
-
- mocker.assert_called_with({
- RESOURCE: {
- 'admin_state_up': True,
- 'name': FAKE_NAME,
- }
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.create_network.assert_called_with(**{
+ 'admin_state_up': True,
+ 'name': self._network.name,
})
- self.assertEqual(FILTERED, result)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
def test_create_all_options(self):
arglist = [
@@ -91,175 +136,233 @@ class TestCreateNetwork(common.TestNetworkBase):
"--share",
"--project", identity_fakes_v3.project_name,
"--project-domain", identity_fakes_v3.domain_name,
- FAKE_NAME,
+ "--availability-zone-hint", "nova",
+ self._network.name,
]
verifylist = [
('admin_state', False),
('shared', True),
('project', identity_fakes_v3.project_name),
('project_domain', identity_fakes_v3.domain_name),
- ('name', FAKE_NAME),
+ ('availability_zone_hints', ["nova"]),
+ ('name', self._network.name),
]
- mocker = mock.Mock(return_value=copy.deepcopy(RESPONSE))
- self.app.client_manager.network.create_network = mocker
- identity_client = identity_fakes_v3.FakeIdentityv3Client(
- endpoint=fakes.AUTH_URL,
- token=fakes.AUTH_TOKEN,
- )
- self.app.client_manager.identity = identity_client
- self.projects_mock = self.app.client_manager.identity.projects
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes_v3.PROJECT),
- loaded=True,
- )
- self.domains_mock = self.app.client_manager.identity.domains
- self.domains_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes_v3.DOMAIN),
- loaded=True,
- )
- cmd = network.CreateNetwork(self.app, self.namespace)
-
- parsed_args = self.check_parser(cmd, arglist, verifylist)
- result = list(cmd.take_action(parsed_args))
-
- mocker.assert_called_with({
- RESOURCE: {
- 'admin_state_up': False,
- 'name': FAKE_NAME,
- 'shared': True,
- 'tenant_id': identity_fakes_v3.project_id,
- }
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = (self.cmd.take_action(parsed_args))
+
+ self.network.create_network.assert_called_with(**{
+ 'admin_state_up': False,
+ 'availability_zone_hints': ["nova"],
+ 'name': self._network.name,
+ 'shared': True,
+ 'tenant_id': identity_fakes_v3.project_id,
})
- self.assertEqual(FILTERED, result)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
def test_create_other_options(self):
arglist = [
"--enable",
"--no-share",
- FAKE_NAME,
+ self._network.name,
]
verifylist = [
('admin_state', True),
('shared', False),
- ('name', FAKE_NAME),
+ ('name', self._network.name),
]
- mocker = mock.Mock(return_value=copy.deepcopy(RESPONSE))
- self.app.client_manager.network.create_network = mocker
- cmd = network.CreateNetwork(self.app, self.namespace)
-
- parsed_args = self.check_parser(cmd, arglist, verifylist)
- result = list(cmd.take_action(parsed_args))
-
- mocker.assert_called_with({
- RESOURCE: {
- 'admin_state_up': True,
- 'name': FAKE_NAME,
- 'shared': False,
- }
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.create_network.assert_called_with(**{
+ 'admin_state_up': True,
+ 'name': self._network.name,
+ 'shared': False,
})
- self.assertEqual(FILTERED, result)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
- def test_create_with_project_identityv2(self):
- arglist = [
- "--project", identity_fakes_v2.project_name,
- FAKE_NAME,
- ]
- verifylist = [
- ('admin_state', True),
- ('shared', None),
- ('name', FAKE_NAME),
- ('project', identity_fakes_v2.project_name),
- ]
- mocker = mock.Mock(return_value=copy.deepcopy(RESPONSE))
- self.app.client_manager.network.create_network = mocker
+
+class TestCreateNetworkIdentityV2(TestNetwork):
+
+ # The new network created.
+ _network = network_fakes.FakeNetwork.create_one_network(
+ attrs={'tenant_id': identity_fakes_v2.project_id}
+ )
+
+ columns = (
+ 'admin_state_up',
+ 'availability_zone_hints',
+ 'availability_zones',
+ 'id',
+ 'name',
+ 'project_id',
+ 'router_external',
+ 'status',
+ 'subnets',
+ )
+
+ data = (
+ network._format_admin_state(_network.admin_state_up),
+ utils.format_list(_network.availability_zone_hints),
+ utils.format_list(_network.availability_zones),
+ _network.id,
+ _network.name,
+ _network.project_id,
+ network._format_router_external(_network.router_external),
+ _network.status,
+ utils.format_list(_network.subnets),
+ )
+
+ def setUp(self):
+ super(TestCreateNetworkIdentityV2, self).setUp()
+
+ self.network.create_network = mock.Mock(return_value=self._network)
+
+ # Get the command object to test
+ self.cmd = network.CreateNetwork(self.app, self.namespace)
+
+ # Set identity client v2. And get a shortcut to Identity client.
identity_client = identity_fakes_v2.FakeIdentityv2Client(
endpoint=fakes.AUTH_URL,
token=fakes.AUTH_TOKEN,
)
self.app.client_manager.identity = identity_client
- self.projects_mock = self.app.client_manager.identity.tenants
+ self.identity = self.app.client_manager.identity
+
+ # Get a shortcut to the ProjectManager Mock
+ self.projects_mock = self.identity.tenants
self.projects_mock.get.return_value = fakes.FakeResource(
None,
copy.deepcopy(identity_fakes_v2.PROJECT),
loaded=True,
)
- cmd = network.CreateNetwork(self.app, self.namespace)
- parsed_args = self.check_parser(cmd, arglist, verifylist)
- result = list(cmd.take_action(parsed_args))
+ # There is no DomainManager Mock in fake identity v2.
- mocker.assert_called_with({
- RESOURCE: {
- 'admin_state_up': True,
- 'name': FAKE_NAME,
- 'tenant_id': identity_fakes_v2.project_id,
- }
+ def test_create_with_project_identityv2(self):
+ arglist = [
+ "--project", identity_fakes_v2.project_name,
+ self._network.name,
+ ]
+ verifylist = [
+ ('admin_state', True),
+ ('shared', None),
+ ('name', self._network.name),
+ ('project', identity_fakes_v2.project_name),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.create_network.assert_called_with(**{
+ 'admin_state_up': True,
+ 'name': self._network.name,
+ 'tenant_id': identity_fakes_v2.project_id,
})
- self.assertEqual(FILTERED, result)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
def test_create_with_domain_identityv2(self):
arglist = [
"--project", identity_fakes_v3.project_name,
"--project-domain", identity_fakes_v3.domain_name,
- FAKE_NAME,
+ self._network.name,
]
verifylist = [
('admin_state', True),
('shared', None),
('project', identity_fakes_v3.project_name),
('project_domain', identity_fakes_v3.domain_name),
- ('name', FAKE_NAME),
+ ('name', self._network.name),
]
- mocker = mock.Mock(return_value=copy.deepcopy(RESPONSE))
- self.app.client_manager.network.create_network = mocker
- identity_client = identity_fakes_v2.FakeIdentityv2Client(
- endpoint=fakes.AUTH_URL,
- token=fakes.AUTH_TOKEN,
- )
- self.app.client_manager.identity = identity_client
- self.projects_mock = self.app.client_manager.identity.tenants
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes_v2.PROJECT),
- loaded=True,
- )
- cmd = network.CreateNetwork(self.app, self.namespace)
- parsed_args = self.check_parser(cmd, arglist, verifylist)
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(
AttributeError,
- cmd.take_action,
+ self.cmd.take_action,
parsed_args,
)
-class TestDeleteNetwork(common.TestNetworkBase):
+class TestDeleteNetwork(TestNetwork):
+
+ # The network to delete.
+ _network = network_fakes.FakeNetwork.create_one_network()
+
+ def setUp(self):
+ super(TestDeleteNetwork, self).setUp()
+
+ self.network.delete_network = mock.Mock(return_value=None)
+
+ self.network.find_network = mock.Mock(return_value=self._network)
+
+ # Get the command object to test
+ self.cmd = network.DeleteNetwork(self.app, self.namespace)
+
def test_delete(self):
arglist = [
- FAKE_NAME,
+ self._network.name,
]
verifylist = [
- ('networks', [FAKE_NAME]),
+ ('network', [self._network.name]),
]
- lister = mock.Mock(return_value={RESOURCES: [copy.deepcopy(RECORD)]})
- self.app.client_manager.network.list_networks = lister
- mocker = mock.Mock(return_value=None)
- self.app.client_manager.network.delete_network = mocker
- cmd = network.DeleteNetwork(self.app, self.namespace)
-
- parsed_args = self.check_parser(cmd, arglist, verifylist)
- result = cmd.take_action(parsed_args)
-
- mocker.assert_called_with(FAKE_ID)
- self.assertEqual(None, result)
-
-@mock.patch(
- 'openstackclient.api.network_v2.APIv2.network_list'
-)
-class TestListNetwork(common.TestNetworkBase):
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ self.network.delete_network.assert_called_with(self._network)
+ self.assertIsNone(result)
+
+
+class TestListNetwork(TestNetwork):
+
+ # The networks going to be listed up.
+ _network = network_fakes.FakeNetwork.create_networks(count=3)
+
+ columns = (
+ 'ID',
+ 'Name',
+ 'Subnets',
+ )
+ columns_long = (
+ 'ID',
+ 'Name',
+ 'Status',
+ 'Project',
+ 'State',
+ 'Shared',
+ 'Subnets',
+ 'Network Type',
+ 'Router Type',
+ 'Availability Zones',
+ )
+
+ data = []
+ for net in _network:
+ data.append((
+ net.id,
+ net.name,
+ utils.format_list(net.subnets),
+ ))
+
+ data_long = []
+ for net in _network:
+ data_long.append((
+ net.id,
+ net.name,
+ net.status,
+ net.project_id,
+ network._format_admin_state(net.admin_state_up),
+ net.shared,
+ utils.format_list(net.subnets),
+ net.provider_network_type,
+ network._format_router_external(net.router_external),
+ utils.format_list(net.availability_zones),
+ ))
def setUp(self):
super(TestListNetwork, self).setUp()
@@ -267,14 +370,9 @@ class TestListNetwork(common.TestNetworkBase):
# Get the command object to test
self.cmd = network.ListNetwork(self.app, self.namespace)
- self.NETWORK_LIST = [
- copy.deepcopy(RECORD),
- copy.deepcopy(RECORD),
- ]
-
- def test_network_list_no_options(self, n_mock):
- n_mock.return_value = self.NETWORK_LIST
+ self.network.networks = mock.Mock(return_value=self._network)
+ def test_network_list_no_options(self):
arglist = []
verifylist = [
('external', False),
@@ -285,21 +383,11 @@ class TestListNetwork(common.TestNetworkBase):
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- # Set expected values
- n_mock.assert_called_with(
- external=False,
- )
-
- self.assertEqual(tuple(COLUMNS), columns)
- datalist = [
- (FAKE_ID, FAKE_NAME, 'a, b'),
- (FAKE_ID, FAKE_NAME, 'a, b'),
- ]
- self.assertEqual(datalist, list(data))
-
- def test_list_external(self, n_mock):
- n_mock.return_value = self.NETWORK_LIST
+ self.network.networks.assert_called_with()
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+ def test_list_external(self):
arglist = [
'--external',
]
@@ -312,21 +400,13 @@ class TestListNetwork(common.TestNetworkBase):
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- # Set expected values
- n_mock.assert_called_with(
- external=True,
+ self.network.networks.assert_called_with(
+ **{'router:external': True}
)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
- self.assertEqual(tuple(COLUMNS), columns)
- datalist = [
- (FAKE_ID, FAKE_NAME, 'a, b'),
- (FAKE_ID, FAKE_NAME, 'a, b'),
- ]
- self.assertEqual(datalist, list(data))
-
- def test_network_list_long(self, n_mock):
- n_mock.return_value = self.NETWORK_LIST
-
+ def test_network_list_long(self):
arglist = [
'--long',
]
@@ -339,145 +419,142 @@ class TestListNetwork(common.TestNetworkBase):
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- # Set expected values
- n_mock.assert_called_with(
- external=False,
- )
+ self.network.networks.assert_called_with()
+ self.assertEqual(self.columns_long, columns)
+ self.assertEqual(self.data_long, list(data))
- collist = (
- 'ID',
- 'Name',
- 'Status',
- 'Project',
- 'State',
- 'Shared',
- 'Subnets',
- 'Network Type',
- 'Router Type',
- )
- self.assertEqual(columns, collist)
- dataitem = (
- FAKE_ID,
- FAKE_NAME,
- 'ACTIVE',
- FAKE_PROJECT,
- 'UP',
- '',
- 'a, b',
- '',
- 'External',
- )
- datalist = [
- dataitem,
- dataitem,
- ]
- self.assertEqual(list(data), datalist)
+class TestSetNetwork(TestNetwork):
+
+ # The network to set.
+ _network = network_fakes.FakeNetwork.create_one_network()
+
+ def setUp(self):
+ super(TestSetNetwork, self).setUp()
+
+ self.network.update_network = mock.Mock(return_value=None)
+
+ self.network.find_network = mock.Mock(return_value=self._network)
+
+ # Get the command object to test
+ self.cmd = network.SetNetwork(self.app, self.namespace)
-class TestSetNetwork(common.TestNetworkBase):
def test_set_this(self):
arglist = [
- FAKE_NAME,
+ self._network.name,
'--enable',
'--name', 'noob',
'--share',
]
verifylist = [
- ('identifier', FAKE_NAME),
+ ('identifier', self._network.name),
('admin_state', True),
('name', 'noob'),
('shared', True),
]
- lister = mock.Mock(return_value={RESOURCES: [copy.deepcopy(RECORD)]})
- self.app.client_manager.network.list_networks = lister
- mocker = mock.Mock(return_value=None)
- self.app.client_manager.network.update_network = mocker
- cmd = network.SetNetwork(self.app, self.namespace)
- parsed_args = self.check_parser(cmd, arglist, verifylist)
- result = cmd.take_action(parsed_args)
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
- exp = {'admin_state_up': True, 'name': 'noob', 'shared': True}
- exp_record = {RESOURCE: exp}
- mocker.assert_called_with(FAKE_ID, exp_record)
- self.assertEqual(None, result)
+ attrs = {
+ 'name': 'noob',
+ 'admin_state_up': True,
+ 'shared': True,
+ }
+ self.network.update_network.assert_called_with(self._network, **attrs)
+ self.assertIsNone(result)
def test_set_that(self):
arglist = [
- FAKE_NAME,
+ self._network.name,
'--disable',
'--no-share',
]
verifylist = [
- ('identifier', FAKE_NAME),
+ ('identifier', self._network.name),
('admin_state', False),
('shared', False),
]
- lister = mock.Mock(return_value={RESOURCES: [copy.deepcopy(RECORD)]})
- self.app.client_manager.network.list_networks = lister
- mocker = mock.Mock(return_value=None)
- self.app.client_manager.network.update_network = mocker
- cmd = network.SetNetwork(self.app, self.namespace)
- parsed_args = self.check_parser(cmd, arglist, verifylist)
- result = cmd.take_action(parsed_args)
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
- exp = {'admin_state_up': False, 'shared': False}
- exp_record = {RESOURCE: exp}
- mocker.assert_called_with(FAKE_ID, exp_record)
- self.assertEqual(None, result)
+ attrs = {
+ 'admin_state_up': False,
+ 'shared': False,
+ }
+ self.network.update_network.assert_called_with(self._network, **attrs)
+ self.assertIsNone(result)
def test_set_nothing(self):
- arglist = [FAKE_NAME, ]
- verifylist = [('identifier', FAKE_NAME), ]
- lister = mock.Mock(return_value={RESOURCES: [copy.deepcopy(RECORD)]})
- self.app.client_manager.network.list_networks = lister
- mocker = mock.Mock(return_value=None)
- self.app.client_manager.network.update_network = mocker
- cmd = network.SetNetwork(self.app, self.namespace)
-
- parsed_args = self.check_parser(cmd, arglist, verifylist)
- self.assertRaises(exceptions.CommandError, cmd.take_action,
+ arglist = [self._network.name, ]
+ verifylist = [('identifier', self._network.name), ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ self.assertRaises(exceptions.CommandError, self.cmd.take_action,
parsed_args)
-@mock.patch(
- 'openstackclient.api.network_v2.APIv2.find_attr'
-)
-class TestShowNetwork(common.TestNetworkBase):
+class TestShowNetwork(TestNetwork):
+
+ # The network to set.
+ _network = network_fakes.FakeNetwork.create_one_network()
+
+ columns = (
+ 'admin_state_up',
+ 'availability_zone_hints',
+ 'availability_zones',
+ 'id',
+ 'name',
+ 'project_id',
+ 'router_external',
+ 'status',
+ 'subnets',
+ )
+
+ data = (
+ network._format_admin_state(_network.admin_state_up),
+ utils.format_list(_network.availability_zone_hints),
+ utils.format_list(_network.availability_zones),
+ _network.id,
+ _network.name,
+ _network.project_id,
+ network._format_router_external(_network.router_external),
+ _network.status,
+ utils.format_list(_network.subnets),
+ )
def setUp(self):
super(TestShowNetwork, self).setUp()
+ self.network.find_network = mock.Mock(return_value=self._network)
+
# Get the command object to test
self.cmd = network.ShowNetwork(self.app, self.namespace)
- self.NETWORK_ITEM = copy.deepcopy(RECORD)
+ def test_show_no_options(self):
+ arglist = []
+ verifylist = []
- def test_show_no_options(self, n_mock):
+ try:
+ # Missing required args should bail here
+ self.check_parser(self.cmd, arglist, verifylist)
+ except tests_utils.ParserException:
+ pass
+
+ def test_show_all_options(self):
arglist = [
- FAKE_NAME,
+ self._network.name,
]
verifylist = [
- ('identifier', FAKE_NAME),
+ ('identifier', self._network.name),
]
- n_mock.return_value = copy.deepcopy(RECORD)
- self.cmd = network.ShowNetwork(self.app, self.namespace)
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- result = list(self.cmd.take_action(parsed_args))
-
- n_mock.assert_called_with('networks', FAKE_NAME)
- self.assertEqual(FILTERED, result)
-
- def test_show_all_options(self, n_mock):
- arglist = [FAKE_NAME]
- verifylist = [('identifier', FAKE_NAME)]
- n_mock.return_value = copy.deepcopy(RECORD)
- self.cmd = network.ShowNetwork(self.app, self.namespace)
+ columns, data = self.cmd.take_action(parsed_args)
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- result = list(self.cmd.take_action(parsed_args))
+ self.network.find_network.assert_called_with(self._network.name,
+ ignore_missing=False)
- n_mock.assert_called_with('networks', FAKE_NAME)
- self.assertEqual(FILTERED, result)
+ self.assertEqual(tuple(self.columns), columns)
+ self.assertEqual(list(self.data), list(data))
diff --git a/openstackclient/tests/network/v2/test_port.py b/openstackclient/tests/network/v2/test_port.py
new file mode 100644
index 0000000..bc246bd
--- /dev/null
+++ b/openstackclient/tests/network/v2/test_port.py
@@ -0,0 +1,140 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+import mock
+
+from openstackclient.common import utils
+from openstackclient.network.v2 import port
+from openstackclient.tests.network.v2 import fakes as network_fakes
+from openstackclient.tests import utils as tests_utils
+
+
+class TestPort(network_fakes.TestNetworkV2):
+
+ def setUp(self):
+ super(TestPort, self).setUp()
+
+ # Get a shortcut to the network client
+ self.network = self.app.client_manager.network
+
+
+class TestDeletePort(TestPort):
+
+ # The port to delete.
+ _port = network_fakes.FakePort.create_one_port()
+
+ def setUp(self):
+ super(TestDeletePort, self).setUp()
+
+ self.network.delete_port = mock.Mock(return_value=None)
+ self.network.find_port = mock.Mock(return_value=self._port)
+ # Get the command object to test
+ self.cmd = port.DeletePort(self.app, self.namespace)
+
+ def test_delete(self):
+ arglist = [
+ self._port.name,
+ ]
+ verifylist = [
+ ('port', [self._port.name]),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.network.delete_port.assert_called_with(self._port)
+ self.assertIsNone(result)
+
+
+class TestShowPort(TestPort):
+
+ # The port to show.
+ _port = network_fakes.FakePort.create_one_port()
+
+ columns = (
+ 'admin_state_up',
+ 'allowed_address_pairs',
+ 'binding_host_id',
+ 'binding_profile',
+ 'binding_vif_details',
+ 'binding_vif_type',
+ 'binding_vnic_type',
+ 'device_id',
+ 'device_owner',
+ 'dns_assignment',
+ 'dns_name',
+ 'extra_dhcp_opts',
+ 'fixed_ips',
+ 'id',
+ 'mac_address',
+ 'name',
+ 'network_id',
+ 'port_security_enabled',
+ 'project_id',
+ 'security_groups',
+ 'status',
+ )
+
+ data = (
+ port._format_admin_state(_port.admin_state_up),
+ utils.format_list_of_dicts(_port.allowed_address_pairs),
+ _port.binding_host_id,
+ utils.format_dict(_port.binding_profile),
+ utils.format_dict(_port.binding_vif_details),
+ _port.binding_vif_type,
+ _port.binding_vnic_type,
+ _port.device_id,
+ _port.device_owner,
+ utils.format_list_of_dicts(_port.dns_assignment),
+ _port.dns_name,
+ utils.format_list_of_dicts(_port.extra_dhcp_opts),
+ utils.format_list_of_dicts(_port.fixed_ips),
+ _port.id,
+ _port.mac_address,
+ _port.name,
+ _port.network_id,
+ _port.port_security_enabled,
+ _port.project_id,
+ utils.format_list(_port.security_groups),
+ _port.status,
+ )
+
+ def setUp(self):
+ super(TestShowPort, self).setUp()
+
+ self.network.find_port = mock.Mock(return_value=self._port)
+
+ # Get the command object to test
+ self.cmd = port.ShowPort(self.app, self.namespace)
+
+ def test_show_no_options(self):
+ arglist = []
+ verifylist = []
+
+ self.assertRaises(tests_utils.ParserException,
+ self.check_parser, self.cmd, arglist, verifylist)
+
+ def test_show_all_options(self):
+ arglist = [
+ self._port.name,
+ ]
+ verifylist = [
+ ('port', self._port.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.find_port.assert_called_with(self._port.name,
+ ignore_missing=False)
+ self.assertEqual(tuple(self.columns), columns)
+ self.assertEqual(self.data, data)
diff --git a/openstackclient/tests/network/v2/test_router.py b/openstackclient/tests/network/v2/test_router.py
new file mode 100644
index 0000000..98e9f17
--- /dev/null
+++ b/openstackclient/tests/network/v2/test_router.py
@@ -0,0 +1,372 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+import mock
+
+from openstackclient.common import exceptions
+from openstackclient.common import utils as osc_utils
+from openstackclient.network.v2 import router
+from openstackclient.tests.network.v2 import fakes as network_fakes
+from openstackclient.tests import utils as tests_utils
+
+
+class TestRouter(network_fakes.TestNetworkV2):
+
+ def setUp(self):
+ super(TestRouter, self).setUp()
+
+ # Get a shortcut to the network client
+ self.network = self.app.client_manager.network
+
+
+class TestCreateRouter(TestRouter):
+
+ # The new router created.
+ new_router = network_fakes.FakeRouter.create_one_router()
+
+ columns = (
+ 'admin_state_up',
+ 'distributed',
+ 'ha',
+ 'id',
+ 'name',
+ 'project_id',
+ )
+ data = (
+ router._format_admin_state(new_router.admin_state_up),
+ new_router.distributed,
+ new_router.ha,
+ new_router.id,
+ new_router.name,
+ new_router.tenant_id,
+ )
+
+ def setUp(self):
+ super(TestCreateRouter, self).setUp()
+
+ self.network.create_router = mock.Mock(return_value=self.new_router)
+
+ # Get the command object to test
+ self.cmd = router.CreateRouter(self.app, self.namespace)
+
+ def test_create_no_options(self):
+ arglist = []
+ verifylist = []
+
+ try:
+ self.check_parser(self.cmd, arglist, verifylist)
+ except tests_utils.ParserException:
+ pass
+
+ def test_create_default_options(self):
+ arglist = [
+ self.new_router.name,
+ ]
+ verifylist = [
+ ('name', self.new_router.name),
+ ('admin_state_up', True),
+ ('distributed', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = (self.cmd.take_action(parsed_args))
+
+ self.network.create_router.assert_called_with(**{
+ 'admin_state_up': True,
+ 'name': self.new_router.name,
+ 'distributed': False,
+ })
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
+ def test_create_with_AZ_hints(self):
+ arglist = [
+ self.new_router.name,
+ '--availability-zone-hint', 'fake-az',
+ '--availability-zone-hint', 'fake-az2',
+ ]
+ verifylist = [
+ ('name', self.new_router.name),
+ ('availability_zone_hints', ['fake-az', 'fake-az2']),
+ ('admin_state_up', True),
+ ('distributed', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = (self.cmd.take_action(parsed_args))
+ self.network.create_router.assert_called_with(**{
+ 'admin_state_up': True,
+ 'name': self.new_router.name,
+ 'distributed': False,
+ 'availability_zone_hints': ['fake-az', 'fake-az2'],
+ })
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
+
+class TestDeleteRouter(TestRouter):
+
+ # The router to delete.
+ _router = network_fakes.FakeRouter.create_one_router()
+
+ def setUp(self):
+ super(TestDeleteRouter, self).setUp()
+
+ self.network.delete_router = mock.Mock(return_value=None)
+
+ self.network.find_router = mock.Mock(return_value=self._router)
+
+ # Get the command object to test
+ self.cmd = router.DeleteRouter(self.app, self.namespace)
+
+ def test_delete(self):
+ arglist = [
+ self._router.name,
+ ]
+ verifylist = [
+ ('router', [self._router.name]),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.network.delete_router.assert_called_with(self._router)
+ self.assertIsNone(result)
+
+
+class TestListRouter(TestRouter):
+
+ # The routers going to be listed up.
+ routers = network_fakes.FakeRouter.create_routers(count=3)
+
+ columns = (
+ 'ID',
+ 'Name',
+ 'Status',
+ 'State',
+ 'Distributed',
+ 'HA',
+ 'Project',
+ )
+ columns_long = columns + (
+ 'Routes',
+ 'External gateway info',
+ 'Availability zones'
+ )
+
+ data = []
+ for r in routers:
+ data.append((
+ r.id,
+ r.name,
+ r.status,
+ router._format_admin_state(r.admin_state_up),
+ r.distributed,
+ r.ha,
+ r.tenant_id,
+ ))
+ data_long = []
+ for i in range(0, len(routers)):
+ r = routers[i]
+ data_long.append(
+ data[i] + (
+ r.routes,
+ router._format_external_gateway_info(r.external_gateway_info),
+ osc_utils.format_list(r.availability_zones),
+ )
+ )
+
+ def setUp(self):
+ super(TestListRouter, self).setUp()
+
+ # Get the command object to test
+ self.cmd = router.ListRouter(self.app, self.namespace)
+
+ self.network.routers = mock.Mock(return_value=self.routers)
+
+ def test_router_list_no_options(self):
+ arglist = []
+ verifylist = [
+ ('long', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.routers.assert_called_with()
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_router_list_long(self):
+ arglist = [
+ '--long',
+ ]
+ verifylist = [
+ ('long', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.routers.assert_called_with()
+ self.assertEqual(self.columns_long, columns)
+ self.assertEqual(self.data_long, list(data))
+
+
+class TestSetRouter(TestRouter):
+
+ # The router to set.
+ _router = network_fakes.FakeRouter.create_one_router()
+
+ def setUp(self):
+ super(TestSetRouter, self).setUp()
+
+ self.network.update_router = mock.Mock(return_value=None)
+
+ self.network.find_router = mock.Mock(return_value=self._router)
+
+ # Get the command object to test
+ self.cmd = router.SetRouter(self.app, self.namespace)
+
+ def test_set_this(self):
+ arglist = [
+ self._router.name,
+ '--enable',
+ '--distributed',
+ '--name', 'noob',
+ ]
+ verifylist = [
+ ('router', self._router.name),
+ ('admin_state_up', True),
+ ('distributed', True),
+ ('name', 'noob'),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ attrs = {
+ 'admin_state_up': True,
+ 'distributed': True,
+ 'name': 'noob',
+ }
+ self.network.update_router.assert_called_with(self._router, **attrs)
+ self.assertIsNone(result)
+
+ def test_set_that(self):
+ arglist = [
+ self._router.name,
+ '--disable',
+ '--centralized',
+ ]
+ verifylist = [
+ ('router', self._router.name),
+ ('admin_state_up', False),
+ ('distributed', False),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ attrs = {
+ 'admin_state_up': False,
+ 'distributed': False,
+ }
+ self.network.update_router.assert_called_with(self._router, **attrs)
+ self.assertIsNone(result)
+
+ def test_set_distributed_centralized(self):
+ arglist = [
+ self._router.name,
+ '--distributed',
+ '--centralized',
+ ]
+ verifylist = [
+ ('router', self._router.name),
+ ('distributed', True),
+ ('distributed', False),
+ ]
+
+ try:
+ # Argument parse failing should bail here
+ self.check_parser(self.cmd, arglist, verifylist)
+ except tests_utils.ParserException:
+ pass
+
+ def test_set_nothing(self):
+ arglist = [self._router.name, ]
+ verifylist = [('router', self._router.name), ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ self.assertRaises(exceptions.CommandError, self.cmd.take_action,
+ parsed_args)
+
+
+class TestShowRouter(TestRouter):
+
+ # The router to set.
+ _router = network_fakes.FakeRouter.create_one_router()
+
+ columns = (
+ 'admin_state_up',
+ 'distributed',
+ 'ha',
+ 'id',
+ 'name',
+ 'tenant_id',
+ )
+
+ data = (
+ router._format_admin_state(_router.admin_state_up),
+ _router.distributed,
+ _router.ha,
+ _router.id,
+ _router.name,
+ _router.tenant_id,
+ )
+
+ def setUp(self):
+ super(TestShowRouter, self).setUp()
+
+ self.network.find_router = mock.Mock(return_value=self._router)
+
+ # Get the command object to test
+ self.cmd = router.ShowRouter(self.app, self.namespace)
+
+ def test_show_no_options(self):
+ arglist = []
+ verifylist = []
+
+ try:
+ # Missing required args should bail here
+ self.check_parser(self.cmd, arglist, verifylist)
+ except tests_utils.ParserException:
+ pass
+
+ def test_show_all_options(self):
+ arglist = [
+ self._router.name,
+ ]
+ verifylist = [
+ ('router', self._router.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.find_router.assert_called_with(self._router.name,
+ ignore_missing=False)
+ self.assertEqual(tuple(self.columns), columns)
+ self.assertEqual(self.data, data)
diff --git a/openstackclient/tests/network/v2/test_security_group.py b/openstackclient/tests/network/v2/test_security_group.py
new file mode 100644
index 0000000..98388ec
--- /dev/null
+++ b/openstackclient/tests/network/v2/test_security_group.py
@@ -0,0 +1,99 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+import mock
+
+from openstackclient.network.v2 import security_group
+from openstackclient.tests.network.v2 import fakes as network_fakes
+
+
+class TestSecurityGroup(network_fakes.TestNetworkV2):
+
+ def setUp(self):
+ super(TestSecurityGroup, self).setUp()
+
+ # Get a shortcut to the network client
+ self.network = self.app.client_manager.network
+
+ # Create compute client mocks.
+ self.app.client_manager.compute = mock.Mock()
+ self.compute = self.app.client_manager.compute
+ self.compute.security_groups = mock.Mock()
+
+
+class TestDeleteSecurityGroupNetwork(TestSecurityGroup):
+
+ # The security group to be deleted.
+ _security_group = \
+ network_fakes.FakeSecurityGroup.create_one_security_group()
+
+ def setUp(self):
+ super(TestDeleteSecurityGroupNetwork, self).setUp()
+
+ self.network.delete_security_group = mock.Mock(return_value=None)
+
+ self.network.find_security_group = mock.Mock(
+ return_value=self._security_group)
+
+ # Get the command object to test
+ self.cmd = security_group.DeleteSecurityGroup(self.app, self.namespace)
+
+ def test_security_group_delete(self):
+ arglist = [
+ self._security_group.name,
+ ]
+ verifylist = [
+ ('group', self._security_group.name),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ self.network.delete_security_group.assert_called_with(
+ self._security_group)
+ self.assertEqual(None, result)
+
+
+class TestDeleteSecurityGroupCompute(TestSecurityGroup):
+
+ # The security group to be deleted.
+ _security_group = \
+ network_fakes.FakeSecurityGroup.create_one_security_group()
+
+ def setUp(self):
+ super(TestDeleteSecurityGroupCompute, self).setUp()
+
+ self.app.client_manager.network_endpoint_enabled = False
+
+ self.compute.security_groups.delete = mock.Mock(return_value=None)
+
+ self.compute.security_groups.get = mock.Mock(
+ return_value=self._security_group)
+
+ # Get the command object to test
+ self.cmd = security_group.DeleteSecurityGroup(self.app, self.namespace)
+
+ def test_security_group_delete(self):
+ arglist = [
+ self._security_group.name,
+ ]
+ verifylist = [
+ ('group', self._security_group.name),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ self.compute.security_groups.delete.assert_called_with(
+ self._security_group.id)
+ self.assertEqual(None, result)
diff --git a/openstackclient/tests/network/v2/test_subnet.py b/openstackclient/tests/network/v2/test_subnet.py
new file mode 100644
index 0000000..5fca5ed
--- /dev/null
+++ b/openstackclient/tests/network/v2/test_subnet.py
@@ -0,0 +1,108 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+import mock
+
+from openstackclient.common import utils
+from openstackclient.network.v2 import subnet as subnet_v2
+from openstackclient.tests.network.v2 import fakes as network_fakes
+
+
+class TestSubnet(network_fakes.TestNetworkV2):
+ def setUp(self):
+ super(TestSubnet, self).setUp()
+
+ # Get a shortcut to the network client
+ self.network = self.app.client_manager.network
+
+
+class TestListSubnet(TestSubnet):
+ # The subnets going to be listed up.
+ _subnet = network_fakes.FakeSubnet.create_subnets(count=3)
+
+ columns = (
+ 'ID',
+ 'Name',
+ 'Network',
+ 'Subnet'
+ )
+ columns_long = columns + (
+ 'Project',
+ 'DHCP',
+ 'Name Servers',
+ 'Allocation Pools',
+ 'Host Routes',
+ 'IP Version',
+ 'Gateway'
+ )
+
+ data = []
+ for subnet in _subnet:
+ data.append((
+ subnet.id,
+ subnet.name,
+ subnet.network_id,
+ subnet.cidr,
+ ))
+
+ data_long = []
+ for subnet in _subnet:
+ data_long.append((
+ subnet.id,
+ subnet.name,
+ subnet.network_id,
+ subnet.cidr,
+ subnet.tenant_id,
+ subnet.enable_dhcp,
+ utils.format_list(subnet.dns_nameservers),
+ subnet_v2._format_allocation_pools(subnet.allocation_pools),
+ utils.format_list(subnet.host_routes),
+ subnet.ip_version,
+ subnet.gateway_ip
+ ))
+
+ def setUp(self):
+ super(TestListSubnet, self).setUp()
+
+ # Get the command object to test
+ self.cmd = subnet_v2.ListSubnet(self.app, self.namespace)
+
+ self.network.subnets = mock.Mock(return_value=self._subnet)
+
+ def test_subnet_list_no_options(self):
+ arglist = []
+ verifylist = [
+ ('long', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.subnets.assert_called_with()
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_subnet_list_long(self):
+ arglist = [
+ '--long',
+ ]
+ verifylist = [
+ ('long', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.subnets.assert_called_with()
+ self.assertEqual(self.columns_long, columns)
+ self.assertEqual(self.data_long, list(data))
diff --git a/openstackclient/tests/object/v1/test_container.py b/openstackclient/tests/object/v1/test_container.py
index 2ef2f7b..afcb338 100644
--- a/openstackclient/tests/object/v1/test_container.py
+++ b/openstackclient/tests/object/v1/test_container.py
@@ -32,6 +32,9 @@ class FakeClient(object):
class TestContainer(object_fakes.TestObjectv1):
+
+ columns = ('Name',)
+
def setUp(self):
super(TestContainer, self).setUp()
self.app.client_manager.object_store = object_store.APIv1(
@@ -73,8 +76,7 @@ class TestContainerList(TestContainer):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(object_fakes.container_name, ),
(object_fakes.container_name_3, ),
@@ -107,8 +109,7 @@ class TestContainerList(TestContainer):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(object_fakes.container_name, ),
(object_fakes.container_name_3, ),
@@ -143,8 +144,7 @@ class TestContainerList(TestContainer):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(object_fakes.container_name, ),
(object_fakes.container_name_3, ),
@@ -176,8 +176,7 @@ class TestContainerList(TestContainer):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(object_fakes.container_name, ),
(object_fakes.container_name_3, ),
@@ -250,8 +249,7 @@ class TestContainerList(TestContainer):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(object_fakes.container_name, ),
(object_fakes.container_name_2, ),
diff --git a/openstackclient/tests/object/v1/test_container_all.py b/openstackclient/tests/object/v1/test_container_all.py
index 69fc0f3..c2dd02a 100644
--- a/openstackclient/tests/object/v1/test_container_all.py
+++ b/openstackclient/tests/object/v1/test_container_all.py
@@ -29,6 +29,12 @@ class TestContainerAll(object_fakes.TestObjectv1):
class TestContainerCreate(TestContainerAll):
+ columns = (
+ 'account',
+ 'container',
+ 'x-trans-id',
+ )
+
def setUp(self):
super(TestContainerCreate, self).setUp()
@@ -54,8 +60,7 @@ class TestContainerCreate(TestContainerAll):
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- collist = ('account', 'container', 'x-trans-id')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = [(
object_fakes.ACCOUNT_ID,
'ernie',
@@ -89,8 +94,7 @@ class TestContainerCreate(TestContainerAll):
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- collist = ('account', 'container', 'x-trans-id')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = [
(
object_fakes.ACCOUNT_ID,
@@ -161,6 +165,8 @@ class TestContainerDelete(TestContainerAll):
class TestContainerList(TestContainerAll):
+ columns = ('Name',)
+
def setUp(self):
super(TestContainerList, self).setUp()
@@ -187,8 +193,7 @@ class TestContainerList(TestContainerAll):
# Lister.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = [
(object_fakes.container_name, ),
(object_fakes.container_name_3, ),
@@ -219,8 +224,7 @@ class TestContainerList(TestContainerAll):
# Lister.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = [
(object_fakes.container_name, ),
(object_fakes.container_name_3, ),
diff --git a/openstackclient/tests/object/v1/test_object.py b/openstackclient/tests/object/v1/test_object.py
index 305fe8f..f0d62f6 100644
--- a/openstackclient/tests/object/v1/test_object.py
+++ b/openstackclient/tests/object/v1/test_object.py
@@ -40,6 +40,13 @@ class TestObject(object_fakes.TestObjectv1):
)
class TestObjectList(TestObject):
+ columns = ('Name',)
+ datalist = (
+ (
+ object_fakes.object_name_2,
+ ),
+ )
+
def setUp(self):
super(TestObjectList, self).setUp()
@@ -67,8 +74,7 @@ class TestObjectList(TestObject):
container=object_fakes.container_name,
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(object_fakes.object_name_1, ),
(object_fakes.object_name_2, ),
@@ -102,12 +108,8 @@ class TestObjectList(TestObject):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
- datalist = (
- (object_fakes.object_name_2, ),
- )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_object_list_objects_delimiter(self, o_mock):
o_mock.return_value = [
@@ -136,12 +138,8 @@ class TestObjectList(TestObject):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
- datalist = (
- (object_fakes.object_name_2, ),
- )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_object_list_objects_marker(self, o_mock):
o_mock.return_value = [
@@ -170,12 +168,8 @@ class TestObjectList(TestObject):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
- datalist = (
- (object_fakes.object_name_2, ),
- )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_object_list_objects_end_marker(self, o_mock):
o_mock.return_value = [
@@ -204,12 +198,8 @@ class TestObjectList(TestObject):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
- datalist = (
- (object_fakes.object_name_2, ),
- )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_object_list_objects_limit(self, o_mock):
o_mock.return_value = [
@@ -238,12 +228,8 @@ class TestObjectList(TestObject):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
- datalist = (
- (object_fakes.object_name_2, ),
- )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_object_list_objects_long(self, o_mock):
o_mock.return_value = [
@@ -320,8 +306,7 @@ class TestObjectList(TestObject):
**kwargs
)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(object_fakes.object_name_1, ),
(object_fakes.object_name_2, ),
diff --git a/openstackclient/tests/object/v1/test_object_all.py b/openstackclient/tests/object/v1/test_object_all.py
index 7a76ab7..a90e5b6 100644
--- a/openstackclient/tests/object/v1/test_object_all.py
+++ b/openstackclient/tests/object/v1/test_object_all.py
@@ -37,6 +37,8 @@ class TestObjectCreate(TestObjectAll):
class TestObjectList(TestObjectAll):
+ columns = ('Name',)
+
def setUp(self):
super(TestObjectList, self).setUp()
@@ -69,8 +71,7 @@ class TestObjectList(TestObjectAll):
# Lister.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = [
(object_fakes.object_name_1, ),
(object_fakes.object_name_2, ),
@@ -104,8 +105,7 @@ class TestObjectList(TestObjectAll):
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- collist = ('Name',)
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
(object_fakes.object_name_2, ),
)
diff --git a/openstackclient/tests/test_shell.py b/openstackclient/tests/test_shell.py
index c548d89..c4546d8 100644
--- a/openstackclient/tests/test_shell.py
+++ b/openstackclient/tests/test_shell.py
@@ -76,7 +76,7 @@ CLOUD_2 = {
'project_name': 'heart-o-gold',
'username': 'zaphod',
},
- 'region_name': 'occ-cloud',
+ 'region_name': 'occ-cloud,krikkit,occ-env',
'log_file': '/tmp/test_log_file',
'log_level': 'debug',
}
diff --git a/openstackclient/tests/volume/v1/test_qos_specs.py b/openstackclient/tests/volume/v1/test_qos_specs.py
index c2e6c0a..7ecc8ee 100644
--- a/openstackclient/tests/volume/v1/test_qos_specs.py
+++ b/openstackclient/tests/volume/v1/test_qos_specs.py
@@ -69,6 +69,18 @@ class TestQosAssociate(TestQos):
class TestQosCreate(TestQos):
+
+ columns = (
+ 'consumer',
+ 'id',
+ 'name',
+ )
+ datalist = (
+ volume_fakes.qos_consumer,
+ volume_fakes.qos_id,
+ volume_fakes.qos_name
+ )
+
def setUp(self):
super(TestQosCreate, self).setUp()
@@ -97,12 +109,7 @@ class TestQosCreate(TestQos):
{'consumer': volume_fakes.qos_default_consumer}
)
- collist = (
- 'consumer',
- 'id',
- 'name'
- )
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
volume_fakes.qos_default_consumer,
volume_fakes.qos_id,
@@ -133,19 +140,8 @@ class TestQosCreate(TestQos):
volume_fakes.qos_name,
{'consumer': volume_fakes.qos_consumer}
)
-
- collist = (
- 'consumer',
- 'id',
- 'name'
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.qos_consumer,
- volume_fakes.qos_id,
- volume_fakes.qos_name
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_qos_create_with_properties(self):
self.qos_mock.create.return_value = fakes.FakeResource(
@@ -176,17 +172,11 @@ class TestQosCreate(TestQos):
specs
)
- collist = (
- 'consumer',
- 'id',
- 'name',
+ columns = self.columns + (
'specs',
)
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.qos_consumer,
- volume_fakes.qos_id,
- volume_fakes.qos_name,
+ self.assertEqual(columns, columns)
+ datalist = self.datalist + (
volume_fakes.qos_specs,
)
self.assertEqual(datalist, data)
diff --git a/openstackclient/tests/volume/v1/test_volume.py b/openstackclient/tests/volume/v1/test_volume.py
index 70ff50d..33255aa 100644
--- a/openstackclient/tests/volume/v1/test_volume.py
+++ b/openstackclient/tests/volume/v1/test_volume.py
@@ -49,6 +49,29 @@ class TestVolume(volume_fakes.TestVolumev1):
class TestVolumeCreate(TestVolume):
+ columns = (
+ 'attach_status',
+ 'availability_zone',
+ 'display_description',
+ 'display_name',
+ 'id',
+ 'properties',
+ 'size',
+ 'status',
+ 'type',
+ )
+ datalist = (
+ 'detached',
+ volume_fakes.volume_zone,
+ volume_fakes.volume_description,
+ volume_fakes.volume_name,
+ volume_fakes.volume_id,
+ volume_fakes.volume_metadata_str,
+ volume_fakes.volume_size,
+ volume_fakes.volume_status,
+ volume_fakes.volume_type,
+ )
+
def setUp(self):
super(TestVolumeCreate, self).setUp()
@@ -93,31 +116,8 @@ class TestVolumeCreate(TestVolume):
None,
None,
)
-
- collist = (
- 'attach_status',
- 'availability_zone',
- 'display_description',
- 'display_name',
- 'id',
- 'properties',
- 'size',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- 'detached',
- volume_fakes.volume_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_name,
- volume_fakes.volume_id,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_options(self):
arglist = [
@@ -158,30 +158,8 @@ class TestVolumeCreate(TestVolume):
None,
)
- collist = (
- 'attach_status',
- 'availability_zone',
- 'display_description',
- 'display_name',
- 'id',
- 'properties',
- 'size',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- 'detached',
- volume_fakes.volume_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_name,
- volume_fakes.volume_id,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_user_project_id(self):
# Return a project
@@ -233,30 +211,8 @@ class TestVolumeCreate(TestVolume):
None,
)
- collist = (
- 'attach_status',
- 'availability_zone',
- 'display_description',
- 'display_name',
- 'id',
- 'properties',
- 'size',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- 'detached',
- volume_fakes.volume_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_name,
- volume_fakes.volume_id,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_user_project_name(self):
# Return a project
@@ -308,30 +264,8 @@ class TestVolumeCreate(TestVolume):
None,
)
- collist = (
- 'attach_status',
- 'availability_zone',
- 'display_description',
- 'display_name',
- 'id',
- 'properties',
- 'size',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- 'detached',
- volume_fakes.volume_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_name,
- volume_fakes.volume_id,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_properties(self):
arglist = [
@@ -369,30 +303,8 @@ class TestVolumeCreate(TestVolume):
None,
)
- collist = (
- 'attach_status',
- 'availability_zone',
- 'display_description',
- 'display_name',
- 'id',
- 'properties',
- 'size',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- 'detached',
- volume_fakes.volume_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_name,
- volume_fakes.volume_id,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_image_id(self):
self.images_mock.get.return_value = fakes.FakeResource(
@@ -435,30 +347,8 @@ class TestVolumeCreate(TestVolume):
volume_fakes.image_id,
)
- collist = (
- 'attach_status',
- 'availability_zone',
- 'display_description',
- 'display_name',
- 'id',
- 'properties',
- 'size',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- 'detached',
- volume_fakes.volume_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_name,
- volume_fakes.volume_id,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_image_name(self):
self.images_mock.get.return_value = fakes.FakeResource(
@@ -501,34 +391,29 @@ class TestVolumeCreate(TestVolume):
volume_fakes.image_id,
)
- collist = (
- 'attach_status',
- 'availability_zone',
- 'display_description',
- 'display_name',
- 'id',
- 'properties',
- 'size',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- 'detached',
- volume_fakes.volume_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_name,
- volume_fakes.volume_id,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
class TestVolumeList(TestVolume):
+ columns = (
+ 'ID',
+ 'Display Name',
+ 'Status',
+ 'Size',
+ 'Attached to',
+ )
+ datalist = (
+ (
+ volume_fakes.volume_id,
+ volume_fakes.volume_name,
+ volume_fakes.volume_status,
+ volume_fakes.volume_size,
+ '',
+ ),
+ )
+
def setUp(self):
super(TestVolumeList, self).setUp()
@@ -555,23 +440,8 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, columns)
-
- datalist = ((
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_status,
- volume_fakes.volume_size,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_volume_list_name(self):
arglist = [
@@ -586,24 +456,8 @@ class TestVolumeList(TestVolume):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
-
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, tuple(columns))
-
- datalist = ((
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_status,
- volume_fakes.volume_size,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, tuple(columns))
+ self.assertEqual(self.datalist, tuple(data))
def test_volume_list_status(self):
arglist = [
@@ -618,24 +472,8 @@ class TestVolumeList(TestVolume):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
-
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, tuple(columns))
-
- datalist = ((
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_status,
- volume_fakes.volume_size,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, tuple(columns))
+ self.assertEqual(self.datalist, tuple(data))
def test_volume_list_all_projects(self):
arglist = [
@@ -650,24 +488,8 @@ class TestVolumeList(TestVolume):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
-
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, columns)
-
- datalist = ((
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_status,
- volume_fakes.volume_size,
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, tuple(columns))
+ self.assertEqual(self.datalist, tuple(data))
def test_volume_list_long(self):
arglist = [
diff --git a/openstackclient/tests/volume/v2/fakes.py b/openstackclient/tests/volume/v2/fakes.py
index 60cec33..2fc5c8f 100644
--- a/openstackclient/tests/volume/v2/fakes.py
+++ b/openstackclient/tests/volume/v2/fakes.py
@@ -202,6 +202,8 @@ class FakeVolumeClient(object):
self.restores.resource_class = fakes.FakeResource(None, {})
self.qos_specs = mock.Mock()
self.qos_specs.resource_class = fakes.FakeResource(None, {})
+ self.availability_zones = mock.Mock()
+ self.availability_zones.resource_class = fakes.FakeResource(None, {})
self.auth_token = kwargs['token']
self.management_url = kwargs['endpoint']
@@ -254,9 +256,10 @@ class FakeVolume(object):
'key' + uuid.uuid4().hex: 'val' + uuid.uuid4().hex},
'snapshot_id': random.randint(1, 5),
'availability_zone': 'zone' + uuid.uuid4().hex,
- 'attachments': {
+ 'attachments': [{
'device': '/dev/' + uuid.uuid4().hex,
- 'server_id': uuid.uuid4().hex},
+ 'server_id': uuid.uuid4().hex,
+ }, ],
}
# Overwrite default attributes if there are some attributes set
@@ -304,3 +307,55 @@ class FakeVolume(object):
volumes = FakeVolume.create_volumes(count)
return mock.MagicMock(side_effect=volumes)
+
+
+class FakeAvailabilityZone(object):
+ """Fake one or more volume availability zones (AZs)."""
+
+ @staticmethod
+ def create_one_availability_zone(attrs={}, methods={}):
+ """Create a fake AZ.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :return:
+ A FakeResource object with zoneName, zoneState, etc.
+ """
+ # Set default attributes.
+ availability_zone = {
+ 'zoneName': uuid.uuid4().hex,
+ 'zoneState': {'available': True},
+ }
+
+ # Overwrite default attributes.
+ availability_zone.update(attrs)
+
+ availability_zone = fakes.FakeResource(
+ info=copy.deepcopy(availability_zone),
+ methods=methods,
+ loaded=True)
+ return availability_zone
+
+ @staticmethod
+ def create_availability_zones(attrs={}, methods={}, count=2):
+ """Create multiple fake AZs.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param Dictionary methods:
+ A dictionary with all methods
+ :param int count:
+ The number of AZs to fake
+ :return:
+ A list of FakeResource objects faking the AZs
+ """
+ availability_zones = []
+ for i in range(0, count):
+ availability_zone = \
+ FakeAvailabilityZone.create_one_availability_zone(
+ attrs, methods)
+ availability_zones.append(availability_zone)
+
+ return availability_zones
diff --git a/openstackclient/tests/volume/v2/test_backup.py b/openstackclient/tests/volume/v2/test_backup.py
index 7af22e8..dc1d787 100644
--- a/openstackclient/tests/volume/v2/test_backup.py
+++ b/openstackclient/tests/volume/v2/test_backup.py
@@ -166,6 +166,24 @@ class TestBackupRestore(TestBackup):
class TestBackupList(TestBackup):
+
+ columns = [
+ 'ID',
+ 'Name',
+ 'Description',
+ 'Status',
+ 'Size',
+ ]
+ datalist = (
+ (
+ volume_fakes.backup_id,
+ volume_fakes.backup_name,
+ volume_fakes.backup_description,
+ volume_fakes.backup_status,
+ volume_fakes.backup_size
+ ),
+ )
+
def setUp(self):
super(TestBackupList, self).setUp()
@@ -193,17 +211,8 @@ class TestBackupList(TestBackup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- collist = ['ID', 'Name', 'Description', 'Status', 'Size']
- self.assertEqual(collist, columns)
-
- datalist = ((
- volume_fakes.backup_id,
- volume_fakes.backup_name,
- volume_fakes.backup_description,
- volume_fakes.backup_status,
- volume_fakes.backup_size
- ),)
- self.assertEqual(datalist, tuple(data))
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, tuple(data))
def test_backup_list_with_options(self):
arglist = ["--long"]
@@ -212,9 +221,13 @@ class TestBackupList(TestBackup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- collist = ['ID', 'Name', 'Description', 'Status', 'Size',
- 'Availability Zone', 'Volume', 'Container']
- self.assertEqual(collist, columns)
+ columns = self.columns + [
+ 'Availability Zone',
+ 'Volume',
+ 'Container',
+ ]
+
+ self.assertEqual(columns, columns)
datalist = ((
volume_fakes.backup_id,
diff --git a/openstackclient/tests/volume/v2/test_qos_specs.py b/openstackclient/tests/volume/v2/test_qos_specs.py
index 4222ed0..403634a 100644
--- a/openstackclient/tests/volume/v2/test_qos_specs.py
+++ b/openstackclient/tests/volume/v2/test_qos_specs.py
@@ -69,6 +69,18 @@ class TestQosAssociate(TestQos):
class TestQosCreate(TestQos):
+
+ columns = (
+ 'consumer',
+ 'id',
+ 'name'
+ )
+ datalist = (
+ volume_fakes.qos_consumer,
+ volume_fakes.qos_id,
+ volume_fakes.qos_name
+ )
+
def setUp(self):
super(TestQosCreate, self).setUp()
@@ -97,12 +109,7 @@ class TestQosCreate(TestQos):
{'consumer': volume_fakes.qos_default_consumer}
)
- collist = (
- 'consumer',
- 'id',
- 'name'
- )
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = (
volume_fakes.qos_default_consumer,
volume_fakes.qos_id,
@@ -134,18 +141,8 @@ class TestQosCreate(TestQos):
{'consumer': volume_fakes.qos_consumer}
)
- collist = (
- 'consumer',
- 'id',
- 'name'
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.qos_consumer,
- volume_fakes.qos_id,
- volume_fakes.qos_name
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_qos_create_with_properties(self):
self.qos_mock.create.return_value = fakes.FakeResource(
@@ -176,17 +173,11 @@ class TestQosCreate(TestQos):
specs
)
- collist = (
- 'consumer',
- 'id',
- 'name',
+ columns = self.columns + (
'specs',
)
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.qos_consumer,
- volume_fakes.qos_id,
- volume_fakes.qos_name,
+ self.assertEqual(columns, columns)
+ datalist = self.datalist + (
volume_fakes.qos_specs,
)
self.assertEqual(datalist, data)
diff --git a/openstackclient/tests/volume/v2/test_snapshot.py b/openstackclient/tests/volume/v2/test_snapshot.py
index 3b30d4e..1c1dd43 100644
--- a/openstackclient/tests/volume/v2/test_snapshot.py
+++ b/openstackclient/tests/volume/v2/test_snapshot.py
@@ -202,6 +202,15 @@ class TestSnapshotUnset(TestSnapshot):
class TestSnapshotList(TestSnapshot):
+
+ columns = [
+ "ID",
+ "Name",
+ "Description",
+ "Status",
+ "Size"
+ ]
+
def setUp(self):
super(TestSnapshotList, self).setUp()
@@ -231,8 +240,7 @@ class TestSnapshotList(TestSnapshot):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- collist = ["ID", "Name", "Description", "Status", "Size"]
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = ((
volume_fakes.snapshot_id,
volume_fakes.snapshot_name,
@@ -249,9 +257,12 @@ class TestSnapshotList(TestSnapshot):
columns, data = self.cmd.take_action(parsed_args)
- collist = ["ID", "Name", "Description", "Status", "Size", "Created At",
- "Volume", "Properties"]
- self.assertEqual(collist, columns)
+ columns = self.columns + [
+ "Created At",
+ "Volume",
+ "Properties"
+ ]
+ self.assertEqual(columns, columns)
datalist = ((
volume_fakes.snapshot_id,
@@ -277,14 +288,7 @@ class TestSnapshotList(TestSnapshot):
columns, data = self.cmd.take_action(parsed_args)
- collist = [
- "ID",
- "Name",
- "Description",
- "Status",
- "Size"
- ]
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = ((
volume_fakes.snapshot_id,
diff --git a/openstackclient/tests/volume/v2/test_type.py b/openstackclient/tests/volume/v2/test_type.py
index c63cd1f..9bf6036 100644
--- a/openstackclient/tests/volume/v2/test_type.py
+++ b/openstackclient/tests/volume/v2/test_type.py
@@ -44,6 +44,17 @@ class TestType(volume_fakes.TestVolume):
class TestTypeCreate(TestType):
+ columns = (
+ 'description',
+ 'id',
+ 'name',
+ )
+ datalist = (
+ volume_fakes.type_description,
+ volume_fakes.type_id,
+ volume_fakes.type_name,
+ )
+
def setUp(self):
super(TestTypeCreate, self).setUp()
@@ -76,18 +87,8 @@ class TestTypeCreate(TestType):
is_public=True,
)
- collist = (
- 'description',
- 'id',
- 'name',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.type_description,
- volume_fakes.type_id,
- volume_fakes.type_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_type_create_private(self):
arglist = [
@@ -110,21 +111,17 @@ class TestTypeCreate(TestType):
is_public=False,
)
- collist = (
- 'description',
- 'id',
- 'name',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.type_description,
- volume_fakes.type_id,
- volume_fakes.type_name,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
class TestTypeList(TestType):
+
+ columns = [
+ "ID",
+ "Name"
+ ]
+
def setUp(self):
super(TestTypeList, self).setUp()
@@ -146,8 +143,7 @@ class TestTypeList(TestType):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- collist = ["ID", "Name"]
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
datalist = ((
volume_fakes.type_id,
volume_fakes.type_name,
@@ -160,8 +156,11 @@ class TestTypeList(TestType):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- collist = ["ID", "Name", "Description", "Properties"]
- self.assertEqual(collist, columns)
+ columns = self.columns + [
+ "Description",
+ "Properties"
+ ]
+ self.assertEqual(columns, columns)
datalist = ((
volume_fakes.type_id,
volume_fakes.type_name,
diff --git a/openstackclient/tests/volume/v2/test_volume.py b/openstackclient/tests/volume/v2/test_volume.py
index 70324b6..76c7a27 100644
--- a/openstackclient/tests/volume/v2/test_volume.py
+++ b/openstackclient/tests/volume/v2/test_volume.py
@@ -14,6 +14,9 @@
import copy
+from mock import call
+
+from openstackclient.common import utils
from openstackclient.tests import fakes
from openstackclient.tests.identity.v3 import fakes as identity_fakes
from openstackclient.tests.volume.v2 import fakes as volume_fakes
@@ -36,15 +39,47 @@ class TestVolume(volume_fakes.TestVolume):
self.images_mock = self.app.client_manager.image.images
self.images_mock.reset_mock()
+ def setup_volumes_mock(self, count):
+ volumes = volume_fakes.FakeVolume.create_volumes(count=count)
+
+ self.volumes_mock.get = volume_fakes.FakeVolume.get_volumes(
+ volumes,
+ 0)
+ return volumes
+
class TestVolumeCreate(TestVolume):
+
+ columns = (
+ 'attachments',
+ 'availability_zone',
+ 'description',
+ 'id',
+ 'name',
+ 'properties',
+ 'size',
+ 'snapshot_id',
+ 'status',
+ 'type',
+ )
+
def setUp(self):
super(TestVolumeCreate, self).setUp()
- self.volumes_mock.create.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(volume_fakes.VOLUME),
- loaded=True,
+ self.new_volume = volume_fakes.FakeVolume.create_one_volume()
+ self.volumes_mock.create.return_value = self.new_volume
+
+ self.datalist = (
+ self.new_volume.attachments,
+ self.new_volume.availability_zone,
+ self.new_volume.description,
+ self.new_volume.id,
+ self.new_volume.name,
+ utils.format_dict(self.new_volume.metadata),
+ self.new_volume.size,
+ self.new_volume.snapshot_id,
+ self.new_volume.status,
+ self.new_volume.volume_type,
)
# Get the command object to test
@@ -52,12 +87,12 @@ class TestVolumeCreate(TestVolume):
def test_volume_create_min_options(self):
arglist = [
- '--size', str(volume_fakes.volume_size),
- volume_fakes.volume_name,
+ '--size', str(self.new_volume.size),
+ self.new_volume.name,
]
verifylist = [
- ('size', volume_fakes.volume_size),
- ('name', volume_fakes.volume_name),
+ ('size', self.new_volume.size),
+ ('name', self.new_volume.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -65,9 +100,9 @@ class TestVolumeCreate(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
self.volumes_mock.create.assert_called_with(
- size=volume_fakes.volume_size,
+ size=self.new_volume.size,
snapshot_id=None,
- name=volume_fakes.volume_name,
+ name=self.new_volume.name,
description=None,
volume_type=None,
user_id=None,
@@ -78,47 +113,23 @@ class TestVolumeCreate(TestVolume):
source_volid=None
)
- collist = (
- 'attachments',
- 'availability_zone',
- 'description',
- 'id',
- 'name',
- 'properties',
- 'size',
- 'snapshot_id',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.volume_attachments,
- volume_fakes.volume_availability_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_snapshot_id,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_options(self):
arglist = [
- '--size', str(volume_fakes.volume_size),
- '--description', volume_fakes.volume_description,
- '--type', volume_fakes.volume_type,
- '--availability-zone', volume_fakes.volume_availability_zone,
- volume_fakes.volume_name,
+ '--size', str(self.new_volume.size),
+ '--description', self.new_volume.description,
+ '--type', self.new_volume.volume_type,
+ '--availability-zone', self.new_volume.availability_zone,
+ self.new_volume.name,
]
verifylist = [
- ('size', volume_fakes.volume_size),
- ('description', volume_fakes.volume_description),
- ('type', volume_fakes.volume_type),
- ('availability_zone', volume_fakes.volume_availability_zone),
- ('name', volume_fakes.volume_name),
+ ('size', self.new_volume.size),
+ ('description', self.new_volume.description),
+ ('type', self.new_volume.volume_type),
+ ('availability_zone', self.new_volume.availability_zone),
+ ('name', self.new_volume.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -126,45 +137,21 @@ class TestVolumeCreate(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
self.volumes_mock.create.assert_called_with(
- size=volume_fakes.volume_size,
+ size=self.new_volume.size,
snapshot_id=None,
- name=volume_fakes.volume_name,
- description=volume_fakes.volume_description,
- volume_type=volume_fakes.volume_type,
+ name=self.new_volume.name,
+ description=self.new_volume.description,
+ volume_type=self.new_volume.volume_type,
user_id=None,
project_id=None,
- availability_zone=volume_fakes.volume_availability_zone,
+ availability_zone=self.new_volume.availability_zone,
metadata=None,
imageRef=None,
source_volid=None
)
- collist = (
- 'attachments',
- 'availability_zone',
- 'description',
- 'id',
- 'name',
- 'properties',
- 'size',
- 'snapshot_id',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.volume_attachments,
- volume_fakes.volume_availability_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_snapshot_id,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_user_project_id(self):
# Return a project
@@ -181,16 +168,16 @@ class TestVolumeCreate(TestVolume):
)
arglist = [
- '--size', str(volume_fakes.volume_size),
+ '--size', str(self.new_volume.size),
'--project', identity_fakes.project_id,
'--user', identity_fakes.user_id,
- volume_fakes.volume_name,
+ self.new_volume.name,
]
verifylist = [
- ('size', volume_fakes.volume_size),
+ ('size', self.new_volume.size),
('project', identity_fakes.project_id),
('user', identity_fakes.user_id),
- ('name', volume_fakes.volume_name),
+ ('name', self.new_volume.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -198,9 +185,9 @@ class TestVolumeCreate(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
self.volumes_mock.create.assert_called_with(
- size=volume_fakes.volume_size,
+ size=self.new_volume.size,
snapshot_id=None,
- name=volume_fakes.volume_name,
+ name=self.new_volume.name,
description=None,
volume_type=None,
user_id=identity_fakes.user_id,
@@ -211,32 +198,8 @@ class TestVolumeCreate(TestVolume):
source_volid=None
)
- collist = (
- 'attachments',
- 'availability_zone',
- 'description',
- 'id',
- 'name',
- 'properties',
- 'size',
- 'snapshot_id',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.volume_attachments,
- volume_fakes.volume_availability_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_snapshot_id,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_user_project_name(self):
# Return a project
@@ -253,16 +216,16 @@ class TestVolumeCreate(TestVolume):
)
arglist = [
- '--size', str(volume_fakes.volume_size),
+ '--size', str(self.new_volume.size),
'--project', identity_fakes.project_name,
'--user', identity_fakes.user_name,
- volume_fakes.volume_name,
+ self.new_volume.name,
]
verifylist = [
- ('size', volume_fakes.volume_size),
+ ('size', self.new_volume.size),
('project', identity_fakes.project_name),
('user', identity_fakes.user_name),
- ('name', volume_fakes.volume_name),
+ ('name', self.new_volume.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -270,9 +233,9 @@ class TestVolumeCreate(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
self.volumes_mock.create.assert_called_with(
- size=volume_fakes.volume_size,
+ size=self.new_volume.size,
snapshot_id=None,
- name=volume_fakes.volume_name,
+ name=self.new_volume.name,
description=None,
volume_type=None,
user_id=identity_fakes.user_id,
@@ -283,44 +246,20 @@ class TestVolumeCreate(TestVolume):
source_volid=None
)
- collist = (
- 'attachments',
- 'availability_zone',
- 'description',
- 'id',
- 'name',
- 'properties',
- 'size',
- 'snapshot_id',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.volume_attachments,
- volume_fakes.volume_availability_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_snapshot_id,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_properties(self):
arglist = [
'--property', 'Alpha=a',
'--property', 'Beta=b',
- '--size', str(volume_fakes.volume_size),
- volume_fakes.volume_name,
+ '--size', str(self.new_volume.size),
+ self.new_volume.name,
]
verifylist = [
('property', {'Alpha': 'a', 'Beta': 'b'}),
- ('size', volume_fakes.volume_size),
- ('name', volume_fakes.volume_name),
+ ('size', self.new_volume.size),
+ ('name', self.new_volume.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -328,9 +267,9 @@ class TestVolumeCreate(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
self.volumes_mock.create.assert_called_with(
- size=volume_fakes.volume_size,
+ size=self.new_volume.size,
snapshot_id=None,
- name=volume_fakes.volume_name,
+ name=self.new_volume.name,
description=None,
volume_type=None,
user_id=None,
@@ -341,32 +280,8 @@ class TestVolumeCreate(TestVolume):
source_volid=None
)
- collist = (
- 'attachments',
- 'availability_zone',
- 'description',
- 'id',
- 'name',
- 'properties',
- 'size',
- 'snapshot_id',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.volume_attachments,
- volume_fakes.volume_availability_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_snapshot_id,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_image_id(self):
self.images_mock.get.return_value = fakes.FakeResource(
@@ -377,13 +292,13 @@ class TestVolumeCreate(TestVolume):
arglist = [
'--image', volume_fakes.image_id,
- '--size', str(volume_fakes.volume_size),
- volume_fakes.volume_name,
+ '--size', str(self.new_volume.size),
+ self.new_volume.name,
]
verifylist = [
('image', volume_fakes.image_id),
- ('size', volume_fakes.volume_size),
- ('name', volume_fakes.volume_name),
+ ('size', self.new_volume.size),
+ ('name', self.new_volume.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -391,9 +306,9 @@ class TestVolumeCreate(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
self.volumes_mock.create.assert_called_with(
- size=volume_fakes.volume_size,
+ size=self.new_volume.size,
snapshot_id=None,
- name=volume_fakes.volume_name,
+ name=self.new_volume.name,
description=None,
volume_type=None,
user_id=None,
@@ -401,35 +316,11 @@ class TestVolumeCreate(TestVolume):
availability_zone=None,
metadata=None,
imageRef=volume_fakes.image_id,
- source_volid=None
+ source_volid=None,
)
- collist = (
- 'attachments',
- 'availability_zone',
- 'description',
- 'id',
- 'name',
- 'properties',
- 'size',
- 'snapshot_id',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.volume_attachments,
- volume_fakes.volume_availability_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_snapshot_id,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
def test_volume_create_image_name(self):
self.images_mock.get.return_value = fakes.FakeResource(
@@ -440,13 +331,13 @@ class TestVolumeCreate(TestVolume):
arglist = [
'--image', volume_fakes.image_name,
- '--size', str(volume_fakes.volume_size),
- volume_fakes.volume_name,
+ '--size', str(self.new_volume.size),
+ self.new_volume.name,
]
verifylist = [
('image', volume_fakes.image_name),
- ('size', volume_fakes.volume_size),
- ('name', volume_fakes.volume_name),
+ ('size', self.new_volume.size),
+ ('name', self.new_volume.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -454,9 +345,9 @@ class TestVolumeCreate(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
self.volumes_mock.create.assert_called_with(
- size=volume_fakes.volume_size,
+ size=self.new_volume.size,
snapshot_id=None,
- name=volume_fakes.volume_name,
+ name=self.new_volume.name,
description=None,
volume_type=None,
user_id=None,
@@ -467,36 +358,61 @@ class TestVolumeCreate(TestVolume):
source_volid=None
)
- collist = (
- 'attachments',
- 'availability_zone',
- 'description',
- 'id',
- 'name',
- 'properties',
- 'size',
- 'snapshot_id',
- 'status',
- 'type',
- )
- self.assertEqual(collist, columns)
- datalist = (
- volume_fakes.volume_attachments,
- volume_fakes.volume_availability_zone,
- volume_fakes.volume_description,
- volume_fakes.volume_id,
- volume_fakes.volume_name,
- volume_fakes.volume_metadata_str,
- volume_fakes.volume_size,
- volume_fakes.volume_snapshot_id,
- volume_fakes.volume_status,
- volume_fakes.volume_type,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
+
+class TestVolumeDelete(TestVolume):
+ def setUp(self):
+ super(TestVolumeDelete, self).setUp()
+
+ self.volumes_mock.delete.return_value = None
+
+ # Get the command object to mock
+ self.cmd = volume.DeleteVolume(self.app, None)
+
+ def test_volume_delete_one_volume(self):
+ volumes = self.setup_volumes_mock(count=1)
+
+ arglist = [
+ volumes[0].id
+ ]
+ verifylist = [
+ ("volumes", [volumes[0].id])
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.cmd.take_action(parsed_args)
+ self.volumes_mock.delete.assert_called_with(volumes[0].id)
+
+ def test_volume_delete_multi_volumes(self):
+ volumes = self.setup_volumes_mock(count=3)
+
+ arglist = [v.id for v in volumes]
+ verifylist = [
+ ('volumes', arglist),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.cmd.take_action(parsed_args)
+
+ calls = [call(v.id) for v in volumes]
+
+ self.volumes_mock.delete.assert_has_calls(calls)
class TestVolumeList(TestVolume):
+ columns = [
+ 'ID',
+ 'Display Name',
+ 'Status',
+ 'Size',
+ 'Attached to',
+ ]
+
def setUp(self):
super(TestVolumeList, self).setUp()
@@ -539,14 +455,7 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = [
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- ]
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
@@ -574,19 +483,11 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, tuple(columns))
+ self.assertEqual(self.columns, columns)
server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
-
datalist = ((
volume_fakes.volume_id,
volume_fakes.volume_name,
@@ -612,19 +513,11 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, tuple(columns))
+ self.assertEqual(self.columns, columns)
server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
-
datalist = ((
volume_fakes.volume_id,
volume_fakes.volume_name,
@@ -648,19 +541,10 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, tuple(columns))
-
+ self.assertEqual(self.columns, columns)
server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
-
datalist = ((
volume_fakes.volume_id,
volume_fakes.volume_name,
@@ -686,19 +570,11 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, tuple(columns))
+ self.assertEqual(self.columns, columns)
server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
-
datalist = ((
volume_fakes.volume_id,
volume_fakes.volume_name,
@@ -722,19 +598,11 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, tuple(columns))
+ self.assertEqual(self.columns, columns)
server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
-
datalist = ((
volume_fakes.volume_id,
volume_fakes.volume_name,
@@ -758,14 +626,7 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = (
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- )
- self.assertEqual(collist, tuple(columns))
+ self.assertEqual(self.columns, columns)
server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
@@ -793,14 +654,7 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
- collist = [
- 'ID',
- 'Display Name',
- 'Status',
- 'Size',
- 'Attached to',
- ]
- self.assertEqual(collist, columns)
+ self.assertEqual(self.columns, columns)
server = volume_fakes.volume_attachment_server['server_id']
device = volume_fakes.volume_attachment_server['device']
@@ -882,30 +736,3 @@ class TestVolumeShow(TestVolume):
self.assertEqual(volume_fakes.VOLUME_columns, columns)
self.assertEqual(volume_fakes.VOLUME_data, data)
-
-
-class TestVolumeDelete(TestVolume):
- def setUp(self):
- super(TestVolumeDelete, self).setUp()
-
- self.volumes_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(volume_fakes.VOLUME),
- loaded=True)
- self.volumes_mock.delete.return_value = None
-
- # Get the command object to mock
- self.cmd = volume.DeleteVolume(self.app, None)
-
- def test_volume_delete(self):
- arglist = [
- volume_fakes.volume_id
- ]
- verifylist = [
- ("volumes", [volume_fakes.volume_id])
- ]
-
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- self.cmd.take_action(parsed_args)
- self.volumes_mock.delete.assert_called_with(volume_fakes.volume_id)
diff --git a/openstackclient/volume/v1/backup.py b/openstackclient/volume/v1/backup.py
index c668e36..32f39fb 100644
--- a/openstackclient/volume/v1/backup.py
+++ b/openstackclient/volume/v1/backup.py
@@ -16,21 +16,15 @@
"""Volume v1 Backup action implementations"""
import copy
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import utils
-class CreateBackup(show.ShowOne):
+class CreateBackup(command.ShowOne):
"""Create new backup"""
- log = logging.getLogger(__name__ + '.CreateBackup')
-
def get_parser(self, prog_name):
parser = super(CreateBackup, self).get_parser(prog_name)
parser.add_argument(
@@ -57,7 +51,6 @@ class CreateBackup(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
volume_id = utils.find_resource(volume_client.volumes,
@@ -76,8 +69,6 @@ class CreateBackup(show.ShowOne):
class DeleteBackup(command.Command):
"""Delete backup(s)"""
- log = logging.getLogger(__name__ + '.DeleteBackup')
-
def get_parser(self, prog_name):
parser = super(DeleteBackup, self).get_parser(prog_name)
parser.add_argument(
@@ -88,21 +79,17 @@ class DeleteBackup(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
for backup in parsed_args.backups:
backup_id = utils.find_resource(volume_client.backups,
backup).id
volume_client.backups.delete(backup_id)
- return
-class ListBackup(lister.Lister):
+class ListBackup(command.Lister):
"""List backups"""
- log = logging.getLogger(__name__ + '.ListBackup')
-
def get_parser(self, prog_name):
parser = super(ListBackup, self).get_parser(prog_name)
parser.add_argument(
@@ -113,7 +100,6 @@ class ListBackup(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
def _format_volume_id(volume_id):
@@ -158,8 +144,6 @@ class ListBackup(lister.Lister):
class RestoreBackup(command.Command):
"""Restore backup"""
- log = logging.getLogger(__name__ + '.RestoreBackup')
-
def get_parser(self, prog_name):
parser = super(RestoreBackup, self).get_parser(prog_name)
parser.add_argument(
@@ -172,7 +156,6 @@ class RestoreBackup(command.Command):
help='Volume to restore to (name or ID)')
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
backup = utils.find_resource(volume_client.backups,
@@ -183,11 +166,9 @@ class RestoreBackup(command.Command):
destination_volume.id)
-class ShowBackup(show.ShowOne):
+class ShowBackup(command.ShowOne):
"""Display backup details"""
- log = logging.getLogger(__name__ + '.ShowBackup')
-
def get_parser(self, prog_name):
parser = super(ShowBackup, self).get_parser(prog_name)
parser.add_argument(
@@ -196,7 +177,6 @@ class ShowBackup(show.ShowOne):
help='Backup to display (ID only)')
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
backup = utils.find_resource(volume_client.backups,
diff --git a/openstackclient/volume/v1/qos_specs.py b/openstackclient/volume/v1/qos_specs.py
index d1c7011..826e5c4 100644
--- a/openstackclient/volume/v1/qos_specs.py
+++ b/openstackclient/volume/v1/qos_specs.py
@@ -15,13 +15,9 @@
"""Volume v1 QoS action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import parseractions
from openstackclient.common import utils
@@ -29,8 +25,6 @@ from openstackclient.common import utils
class AssociateQos(command.Command):
"""Associate a QoS specification to a volume type"""
- log = logging.getLogger(__name__ + '.AssociateQos')
-
def get_parser(self, prog_name):
parser = super(AssociateQos, self).get_parser(prog_name)
parser.add_argument(
@@ -45,7 +39,6 @@ class AssociateQos(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
@@ -55,14 +48,10 @@ class AssociateQos(command.Command):
volume_client.qos_specs.associate(qos_spec.id, volume_type.id)
- return
-
-class CreateQos(show.ShowOne):
+class CreateQos(command.ShowOne):
"""Create new QoS specification"""
- log = logging.getLogger(__name__ + '.CreateQos')
-
def get_parser(self, prog_name):
parser = super(CreateQos, self).get_parser(prog_name)
parser.add_argument(
@@ -88,7 +77,6 @@ class CreateQos(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
specs = {}
@@ -105,8 +93,6 @@ class CreateQos(show.ShowOne):
class DeleteQos(command.Command):
"""Delete QoS specification"""
- log = logging.getLogger(__name__ + '.DeleteQos')
-
def get_parser(self, prog_name):
parser = super(DeleteQos, self).get_parser(prog_name)
parser.add_argument(
@@ -117,20 +103,16 @@ class DeleteQos(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, 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)
volume_client.qos_specs.delete(qos_spec.id)
- return
class DisassociateQos(command.Command):
"""Disassociate a QoS specification from a volume type"""
- log = logging.getLogger(__name__ + '.DisassociateQos')
-
def get_parser(self, prog_name):
parser = super(DisassociateQos, self).get_parser(prog_name)
parser.add_argument(
@@ -153,7 +135,6 @@ class DisassociateQos(command.Command):
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
@@ -166,15 +147,10 @@ class DisassociateQos(command.Command):
elif parsed_args.all:
volume_client.qos_specs.disassociate_all(qos_spec.id)
- return
-
-class ListQos(lister.Lister):
+class ListQos(command.Lister):
"""List QoS specifications"""
- log = logging.getLogger(__name__ + '.ListQos')
-
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
qos_specs_list = volume_client.qos_specs.list()
@@ -200,8 +176,6 @@ class ListQos(lister.Lister):
class SetQos(command.Command):
"""Set QoS specification properties"""
- log = logging.getLogger(__name__ + '.SetQos')
-
def get_parser(self, prog_name):
parser = super(SetQos, self).get_parser(prog_name)
parser.add_argument(
@@ -218,7 +192,6 @@ class SetQos(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
@@ -230,14 +203,10 @@ class SetQos(command.Command):
else:
self.app.log.error("No changes requested\n")
- return
-
-class ShowQos(show.ShowOne):
+class ShowQos(command.ShowOne):
"""Display QoS specification details"""
- log = logging.getLogger(__name__ + '.ShowQos')
-
def get_parser(self, prog_name):
parser = super(ShowQos, self).get_parser(prog_name)
parser.add_argument(
@@ -247,7 +216,6 @@ class ShowQos(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
@@ -268,8 +236,6 @@ class ShowQos(show.ShowOne):
class UnsetQos(command.Command):
"""Unset QoS specification properties"""
- log = logging.getLogger(__name__ + '.SetQos')
-
def get_parser(self, prog_name):
parser = super(UnsetQos, self).get_parser(prog_name)
parser.add_argument(
@@ -287,7 +253,6 @@ class UnsetQos(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
@@ -298,5 +263,3 @@ class UnsetQos(command.Command):
parsed_args.property)
else:
self.app.log.error("No changes requested\n")
-
- return
diff --git a/openstackclient/volume/v1/snapshot.py b/openstackclient/volume/v1/snapshot.py
index 93e17eb..95200e4 100644
--- a/openstackclient/volume/v1/snapshot.py
+++ b/openstackclient/volume/v1/snapshot.py
@@ -16,22 +16,16 @@
"""Volume v1 Snapshot action implementations"""
import copy
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import parseractions
from openstackclient.common import utils
-class CreateSnapshot(show.ShowOne):
+class CreateSnapshot(command.ShowOne):
"""Create new snapshot"""
- log = logging.getLogger(__name__ + '.CreateSnapshot')
-
def get_parser(self, prog_name):
parser = super(CreateSnapshot, self).get_parser(prog_name)
parser.add_argument(
@@ -59,7 +53,6 @@ class CreateSnapshot(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
volume_id = utils.find_resource(volume_client.volumes,
@@ -81,8 +74,6 @@ class CreateSnapshot(show.ShowOne):
class DeleteSnapshot(command.Command):
"""Delete snapshot(s)"""
- log = logging.getLogger(__name__ + '.DeleteSnapshot')
-
def get_parser(self, prog_name):
parser = super(DeleteSnapshot, self).get_parser(prog_name)
parser.add_argument(
@@ -93,21 +84,17 @@ class DeleteSnapshot(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
for snapshot in parsed_args.snapshots:
snapshot_id = utils.find_resource(volume_client.volume_snapshots,
snapshot).id
volume_client.volume_snapshots.delete(snapshot_id)
- return
-class ListSnapshot(lister.Lister):
+class ListSnapshot(command.Lister):
"""List snapshots"""
- log = logging.getLogger(__name__ + '.ListSnapshot')
-
def get_parser(self, prog_name):
parser = super(ListSnapshot, self).get_parser(prog_name)
parser.add_argument(
@@ -124,7 +111,6 @@ class ListSnapshot(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
def _format_volume_id(volume_id):
@@ -180,8 +166,6 @@ class ListSnapshot(lister.Lister):
class SetSnapshot(command.Command):
"""Set snapshot properties"""
- log = logging.getLogger(__name__ + '.SetSnapshot')
-
def get_parser(self, prog_name):
parser = super(SetSnapshot, self).get_parser(prog_name)
parser.add_argument(
@@ -205,7 +189,6 @@ class SetSnapshot(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
snapshot = utils.find_resource(volume_client.volume_snapshots,
@@ -226,14 +209,11 @@ class SetSnapshot(command.Command):
return
snapshot.update(**kwargs)
- return
-class ShowSnapshot(show.ShowOne):
+class ShowSnapshot(command.ShowOne):
"""Display snapshot details"""
- log = logging.getLogger(__name__ + '.ShowSnapshot')
-
def get_parser(self, prog_name):
parser = super(ShowSnapshot, self).get_parser(prog_name)
parser.add_argument(
@@ -242,7 +222,6 @@ class ShowSnapshot(show.ShowOne):
help='Snapshot to display (name or ID)')
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
snapshot = utils.find_resource(volume_client.volume_snapshots,
@@ -258,8 +237,6 @@ class ShowSnapshot(show.ShowOne):
class UnsetSnapshot(command.Command):
"""Unset snapshot properties"""
- log = logging.getLogger(__name__ + '.UnsetSnapshot')
-
def get_parser(self, prog_name):
parser = super(UnsetSnapshot, self).get_parser(prog_name)
parser.add_argument(
@@ -278,7 +255,6 @@ class UnsetSnapshot(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
snapshot = utils.find_resource(
@@ -291,4 +267,3 @@ class UnsetSnapshot(command.Command):
)
else:
self.app.log.error("No changes requested\n")
- return
diff --git a/openstackclient/volume/v1/volume.py b/openstackclient/volume/v1/volume.py
index 0691d88..90827d2 100644
--- a/openstackclient/volume/v1/volume.py
+++ b/openstackclient/volume/v1/volume.py
@@ -16,22 +16,16 @@
"""Volume v1 Volume action implementations"""
import argparse
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import parseractions
from openstackclient.common import utils
-class CreateVolume(show.ShowOne):
+class CreateVolume(command.ShowOne):
"""Create new volume"""
- log = logging.getLogger(__name__ + '.CreateVolume')
-
def get_parser(self, prog_name):
parser = super(CreateVolume, self).get_parser(prog_name)
parser.add_argument(
@@ -102,7 +96,6 @@ class CreateVolume(show.ShowOne):
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
@@ -166,8 +159,6 @@ class CreateVolume(show.ShowOne):
class DeleteVolume(command.Command):
"""Delete volume(s)"""
- log = logging.getLogger(__name__ + '.DeleteVolume')
-
def get_parser(self, prog_name):
parser = super(DeleteVolume, self).get_parser(prog_name)
parser.add_argument(
@@ -186,7 +177,6 @@ class DeleteVolume(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
for volume in parsed_args.volumes:
@@ -196,14 +186,11 @@ class DeleteVolume(command.Command):
volume_client.volumes.force_delete(volume_obj.id)
else:
volume_client.volumes.delete(volume_obj.id)
- return
-class ListVolume(lister.Lister):
+class ListVolume(command.Lister):
"""List volumes"""
- log = logging.getLogger(__name__ + '.ListVolume')
-
def get_parser(self, prog_name):
parser = super(ListVolume, self).get_parser(prog_name)
parser.add_argument(
@@ -230,7 +217,6 @@ class ListVolume(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
@@ -317,8 +303,6 @@ class ListVolume(lister.Lister):
class SetVolume(command.Command):
"""Set volume properties"""
- log = logging.getLogger(__name__ + '.SetVolume')
-
def get_parser(self, prog_name):
parser = super(SetVolume, self).get_parser(prog_name)
parser.add_argument(
@@ -351,7 +335,6 @@ class SetVolume(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
@@ -382,14 +365,10 @@ class SetVolume(command.Command):
if not kwargs and not parsed_args.property and not parsed_args.size:
self.app.log.error("No changes requested\n")
- return
-
-class ShowVolume(show.ShowOne):
+class ShowVolume(command.ShowOne):
"""Show volume details"""
- log = logging.getLogger(__name__ + '.ShowVolume')
-
def get_parser(self, prog_name):
parser = super(ShowVolume, self).get_parser(prog_name)
parser.add_argument(
@@ -399,7 +378,6 @@ class ShowVolume(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
@@ -421,8 +399,6 @@ class ShowVolume(show.ShowOne):
class UnsetVolume(command.Command):
"""Unset volume properties"""
- log = logging.getLogger(__name__ + '.UnsetVolume')
-
def get_parser(self, prog_name):
parser = super(UnsetVolume, self).get_parser(prog_name)
parser.add_argument(
@@ -441,7 +417,6 @@ class UnsetVolume(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
volume = utils.find_resource(
@@ -454,4 +429,3 @@ class UnsetVolume(command.Command):
)
else:
self.app.log.error("No changes requested\n")
- return
diff --git a/openstackclient/volume/v1/volume_type.py b/openstackclient/volume/v1/volume_type.py
index d7765c7..24d0b23 100644
--- a/openstackclient/volume/v1/volume_type.py
+++ b/openstackclient/volume/v1/volume_type.py
@@ -15,22 +15,16 @@
"""Volume v1 Type action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import parseractions
from openstackclient.common import utils
-class CreateVolumeType(show.ShowOne):
+class CreateVolumeType(command.ShowOne):
"""Create new volume type"""
- log = logging.getLogger(__name__ + '.CreateVolumeType')
-
def get_parser(self, prog_name):
parser = super(CreateVolumeType, self).get_parser(prog_name)
parser.add_argument(
@@ -47,7 +41,6 @@ class CreateVolumeType(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
volume_type = volume_client.volume_types.create(parsed_args.name)
@@ -64,8 +57,6 @@ class CreateVolumeType(show.ShowOne):
class DeleteVolumeType(command.Command):
"""Delete volume type"""
- log = logging.getLogger(__name__ + '.DeleteVolumeType')
-
def get_parser(self, prog_name):
parser = super(DeleteVolumeType, self).get_parser(prog_name)
parser.add_argument(
@@ -75,20 +66,16 @@ class DeleteVolumeType(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
volume_type_id = utils.find_resource(
volume_client.volume_types, parsed_args.volume_type).id
volume_client.volume_types.delete(volume_type_id)
- return
-class ListVolumeType(lister.Lister):
+class ListVolumeType(command.Lister):
"""List volume types"""
- log = logging.getLogger(__name__ + '.ListVolumeType')
-
def get_parser(self, prog_name):
parser = super(ListVolumeType, self).get_parser(prog_name)
parser.add_argument(
@@ -98,7 +85,6 @@ class ListVolumeType(lister.Lister):
help='List additional fields in output')
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
if parsed_args.long:
columns = ('ID', 'Name', 'Extra Specs')
@@ -117,8 +103,6 @@ class ListVolumeType(lister.Lister):
class SetVolumeType(command.Command):
"""Set volume type properties"""
- log = logging.getLogger(__name__ + '.SetVolumeType')
-
def get_parser(self, prog_name):
parser = super(SetVolumeType, self).get_parser(prog_name)
parser.add_argument(
@@ -135,7 +119,6 @@ class SetVolumeType(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
volume_type = utils.find_resource(
@@ -144,14 +127,10 @@ class SetVolumeType(command.Command):
if parsed_args.property:
volume_type.set_keys(parsed_args.property)
- return
-
class UnsetVolumeType(command.Command):
"""Unset volume type properties"""
- log = logging.getLogger(__name__ + '.UnsetVolumeType')
-
def get_parser(self, prog_name):
parser = super(UnsetVolumeType, self).get_parser(prog_name)
parser.add_argument(
@@ -170,7 +149,6 @@ class UnsetVolumeType(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
volume_type = utils.find_resource(
@@ -182,14 +160,11 @@ class UnsetVolumeType(command.Command):
volume_type.unset_keys(parsed_args.property)
else:
self.app.log.error("No changes requested\n")
- return
-class ShowVolumeType(show.ShowOne):
+class ShowVolumeType(command.ShowOne):
"""Display volume type details"""
- log = logging.getLogger(__name__ + ".ShowVolumeType")
-
def get_parser(self, prog_name):
parser = super(ShowVolumeType, self).get_parser(prog_name)
parser.add_argument(
@@ -200,7 +175,6 @@ class ShowVolumeType(show.ShowOne):
return parser
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)
diff --git a/openstackclient/volume/v2/backup.py b/openstackclient/volume/v2/backup.py
index 3525e70..64ca97a 100644
--- a/openstackclient/volume/v2/backup.py
+++ b/openstackclient/volume/v2/backup.py
@@ -15,21 +15,16 @@
"""Volume v2 Backup action implementations"""
import copy
-import logging
-from cliff import command
-from cliff import lister
-from cliff import show
import six
+from openstackclient.common import command
from openstackclient.common import utils
-class CreateBackup(show.ShowOne):
+class CreateBackup(command.ShowOne):
"""Create new backup"""
- log = logging.getLogger(__name__ + ".CreateBackup")
-
def get_parser(self, prog_name):
parser = super(CreateBackup, self).get_parser(prog_name)
parser.add_argument(
@@ -56,7 +51,6 @@ class CreateBackup(show.ShowOne):
return parser
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
@@ -73,8 +67,6 @@ class CreateBackup(show.ShowOne):
class DeleteBackup(command.Command):
"""Delete backup(s)"""
- log = logging.getLogger(__name__ + ".DeleteBackup")
-
def get_parser(self, prog_name):
parser = super(DeleteBackup, self).get_parser(prog_name)
parser.add_argument(
@@ -86,20 +78,16 @@ class DeleteBackup(command.Command):
return parser
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, backup).id
volume_client.backups.delete(backup_id)
- return
-class ListBackup(lister.Lister):
+class ListBackup(command.Lister):
"""List backups"""
- log = logging.getLogger(__name__ + ".ListBackup")
-
def get_parser(self, prog_name):
parser = super(ListBackup, self).get_parser(prog_name)
parser.add_argument(
@@ -111,7 +99,6 @@ class ListBackup(lister.Lister):
return parser
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
@@ -152,11 +139,9 @@ class ListBackup(lister.Lister):
) for s in data))
-class RestoreBackup(show.ShowOne):
+class RestoreBackup(command.ShowOne):
"""Restore backup"""
- log = logging.getLogger(__name__ + ".RestoreBackup")
-
def get_parser(self, prog_name):
parser = super(RestoreBackup, self).get_parser(prog_name)
parser.add_argument(
@@ -172,7 +157,6 @@ class RestoreBackup(show.ShowOne):
return parser
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)
destination_volume = utils.find_resource(volume_client.volumes,
@@ -180,11 +164,9 @@ class RestoreBackup(show.ShowOne):
return volume_client.restores.restore(backup.id, destination_volume.id)
-class ShowBackup(show.ShowOne):
+class ShowBackup(command.ShowOne):
"""Display backup details"""
- log = logging.getLogger(__name__ + ".ShowBackup")
-
def get_parser(self, prog_name):
parser = super(ShowBackup, self).get_parser(prog_name)
parser.add_argument(
@@ -194,7 +176,6 @@ class ShowBackup(show.ShowOne):
return parser
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/v2/qos_specs.py b/openstackclient/volume/v2/qos_specs.py
index b3a34ca..961cc27 100644
--- a/openstackclient/volume/v2/qos_specs.py
+++ b/openstackclient/volume/v2/qos_specs.py
@@ -15,13 +15,9 @@
"""Volume v2 QoS action implementations"""
-import logging
import six
-from cliff import command
-from cliff import lister
-from cliff import show
-
+from openstackclient.common import command
from openstackclient.common import parseractions
from openstackclient.common import utils
@@ -29,8 +25,6 @@ from openstackclient.common import utils
class AssociateQos(command.Command):
"""Associate a QoS specification to a volume type"""
- log = logging.getLogger(__name__ + '.AssociateQos')
-
def get_parser(self, prog_name):
parser = super(AssociateQos, self).get_parser(prog_name)
parser.add_argument(
@@ -45,7 +39,6 @@ class AssociateQos(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
@@ -55,14 +48,10 @@ class AssociateQos(command.Command):
volume_client.qos_specs.associate(qos_spec.id, volume_type.id)
- return
-
-class CreateQos(show.ShowOne):
+class CreateQos(command.ShowOne):
"""Create new QoS specification"""
- log = logging.getLogger(__name__ + '.CreateQos')
-
def get_parser(self, prog_name):
parser = super(CreateQos, self).get_parser(prog_name)
parser.add_argument(
@@ -88,7 +77,6 @@ class CreateQos(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
specs = {}
@@ -105,8 +93,6 @@ class CreateQos(show.ShowOne):
class DeleteQos(command.Command):
"""Delete QoS specification"""
- log = logging.getLogger(__name__ + '.DeleteQos')
-
def get_parser(self, prog_name):
parser = super(DeleteQos, self).get_parser(prog_name)
parser.add_argument(
@@ -117,20 +103,16 @@ class DeleteQos(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, 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)
volume_client.qos_specs.delete(qos_spec.id)
- return
class DisassociateQos(command.Command):
"""Disassociate a QoS specification from a volume type"""
- log = logging.getLogger(__name__ + '.DisassociateQos')
-
def get_parser(self, prog_name):
parser = super(DisassociateQos, self).get_parser(prog_name)
parser.add_argument(
@@ -153,7 +135,6 @@ class DisassociateQos(command.Command):
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
@@ -166,15 +147,10 @@ class DisassociateQos(command.Command):
elif parsed_args.all:
volume_client.qos_specs.disassociate_all(qos_spec.id)
- return
-
-class ListQos(lister.Lister):
+class ListQos(command.Lister):
"""List QoS specifications"""
- log = logging.getLogger(__name__ + '.ListQos')
-
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
qos_specs_list = volume_client.qos_specs.list()
@@ -200,8 +176,6 @@ class ListQos(lister.Lister):
class SetQos(command.Command):
"""Set QoS specification properties"""
- log = logging.getLogger(__name__ + '.SetQos')
-
def get_parser(self, prog_name):
parser = super(SetQos, self).get_parser(prog_name)
parser.add_argument(
@@ -218,7 +192,6 @@ class SetQos(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
@@ -230,14 +203,10 @@ class SetQos(command.Command):
else:
self.app.log.error("No changes requested\n")
- return
-
-class ShowQos(show.ShowOne):
+class ShowQos(command.ShowOne):
"""Display QoS specification details"""
- log = logging.getLogger(__name__ + '.ShowQos')
-
def get_parser(self, prog_name):
parser = super(ShowQos, self).get_parser(prog_name)
parser.add_argument(
@@ -247,7 +216,6 @@ class ShowQos(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
@@ -268,8 +236,6 @@ class ShowQos(show.ShowOne):
class UnsetQos(command.Command):
"""Unset QoS specification properties"""
- log = logging.getLogger(__name__ + '.SetQos')
-
def get_parser(self, prog_name):
parser = super(UnsetQos, self).get_parser(prog_name)
parser.add_argument(
@@ -287,7 +253,6 @@ class UnsetQos(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs,
@@ -298,5 +263,3 @@ class UnsetQos(command.Command):
parsed_args.property)
else:
self.app.log.error("No changes requested\n")
-
- return
diff --git a/openstackclient/volume/v2/snapshot.py b/openstackclient/volume/v2/snapshot.py
index aa7630a..4d00b72 100644
--- a/openstackclient/volume/v2/snapshot.py
+++ b/openstackclient/volume/v2/snapshot.py
@@ -15,22 +15,17 @@
"""Volume v2 snapshot action implementations"""
import copy
-import logging
-from cliff import command
-from cliff import lister
-from cliff import show
import six
+from openstackclient.common import command
from openstackclient.common import parseractions
from openstackclient.common import utils
-class CreateSnapshot(show.ShowOne):
+class CreateSnapshot(command.ShowOne):
"""Create new snapshot"""
- log = logging.getLogger(__name__ + ".CreateSnapshot")
-
def get_parser(self, prog_name):
parser = super(CreateSnapshot, self).get_parser(prog_name)
parser.add_argument(
@@ -59,7 +54,6 @@ class CreateSnapshot(show.ShowOne):
return parser
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
@@ -78,8 +72,6 @@ class CreateSnapshot(show.ShowOne):
class DeleteSnapshot(command.Command):
"""Delete volume snapshot(s)"""
- log = logging.getLogger(__name__ + ".DeleteSnapshot")
-
def get_parser(self, prog_name):
parser = super(DeleteSnapshot, self).get_parser(prog_name)
parser.add_argument(
@@ -91,20 +83,16 @@ class DeleteSnapshot(command.Command):
return parser
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, snapshot).id
volume_client.volume_snapshots.delete(snapshot_id)
- return
-class ListSnapshot(lister.Lister):
+class ListSnapshot(command.Lister):
"""List snapshots"""
- log = logging.getLogger(__name__ + ".ListSnapshot")
-
def get_parser(self, prog_name):
parser = super(ListSnapshot, self).get_parser(prog_name)
parser.add_argument(
@@ -122,7 +110,6 @@ class ListSnapshot(lister.Lister):
return parser
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 +159,6 @@ class ListSnapshot(lister.Lister):
class SetSnapshot(command.Command):
"""Set snapshot properties"""
- log = logging.getLogger(__name__ + '.SetSnapshot')
-
def get_parser(self, prog_name):
parser = super(SetSnapshot, self).get_parser(prog_name)
parser.add_argument(
@@ -197,7 +182,6 @@ class SetSnapshot(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
snapshot = utils.find_resource(volume_client.volume_snapshots,
@@ -217,14 +201,11 @@ class SetSnapshot(command.Command):
volume_client.volume_snapshots.set_metadata(snapshot.id,
parsed_args.property)
volume_client.volume_snapshots.update(snapshot.id, **kwargs)
- return
-class ShowSnapshot(show.ShowOne):
+class ShowSnapshot(command.ShowOne):
"""Display snapshot details"""
- log = logging.getLogger(__name__ + ".ShowSnapshot")
-
def get_parser(self, prog_name):
parser = super(ShowSnapshot, self).get_parser(prog_name)
parser.add_argument(
@@ -235,7 +216,6 @@ class ShowSnapshot(show.ShowOne):
return parser
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)
@@ -248,8 +228,6 @@ class ShowSnapshot(show.ShowOne):
class UnsetSnapshot(command.Command):
"""Unset snapshot properties"""
- log = logging.getLogger(__name__ + '.UnsetSnapshot')
-
def get_parser(self, prog_name):
parser = super(UnsetSnapshot, self).get_parser(prog_name)
parser.add_argument(
@@ -267,7 +245,6 @@ class UnsetSnapshot(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
snapshot = utils.find_resource(
@@ -280,4 +257,3 @@ class UnsetSnapshot(command.Command):
)
else:
self.app.log.error("No changes requested\n")
- return
diff --git a/openstackclient/volume/v2/volume.py b/openstackclient/volume/v2/volume.py
index 925b01d..436ec68 100644
--- a/openstackclient/volume/v2/volume.py
+++ b/openstackclient/volume/v2/volume.py
@@ -15,23 +15,18 @@
"""Volume V2 Volume action implementations"""
import copy
-import logging
-from cliff import command
-from cliff import lister
-from cliff import show
import six
+from openstackclient.common import command
from openstackclient.common import parseractions
from openstackclient.common import utils
from openstackclient.identity import common as identity_common
-class CreateVolume(show.ShowOne):
+class CreateVolume(command.ShowOne):
"""Create new volume"""
- log = logging.getLogger(__name__ + ".CreateVolume")
-
def get_parser(self, prog_name):
parser = super(CreateVolume, self).get_parser(prog_name)
parser.add_argument(
@@ -96,8 +91,6 @@ class CreateVolume(show.ShowOne):
return parser
def take_action(self, parsed_args):
- self.log.debug("take_action: (%s)", parsed_args)
-
identity_client = self.app.client_manager.identity
volume_client = self.app.client_manager.volume
image_client = self.app.client_manager.image
@@ -159,8 +152,6 @@ class CreateVolume(show.ShowOne):
class DeleteVolume(command.Command):
"""Delete volume(s)"""
- log = logging.getLogger(__name__ + ".DeleteVolume")
-
def get_parser(self, prog_name):
parser = super(DeleteVolume, self).get_parser(prog_name)
parser.add_argument(
@@ -180,7 +171,6 @@ class DeleteVolume(command.Command):
return parser
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(
@@ -189,14 +179,11 @@ class DeleteVolume(command.Command):
volume_client.volumes.force_delete(volume_obj.id)
else:
volume_client.volumes.delete(volume_obj.id)
- return
-class ListVolume(lister.Lister):
+class ListVolume(command.Lister):
"""List volumes"""
- log = logging.getLogger(__name__ + '.ListVolume')
-
def get_parser(self, prog_name):
parser = super(ListVolume, self).get_parser(prog_name)
parser.add_argument(
@@ -235,7 +222,6 @@ class ListVolume(lister.Lister):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
@@ -326,11 +312,9 @@ class ListVolume(lister.Lister):
) for s in data))
-class SetVolume(show.ShowOne):
+class SetVolume(command.Command):
"""Set volume properties"""
- log = logging.getLogger(__name__ + '.SetVolume')
-
def get_parser(self, prog_name):
parser = super(SetVolume, self).get_parser(prog_name)
parser.add_argument(
@@ -363,7 +347,6 @@ class SetVolume(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
@@ -394,14 +377,10 @@ class SetVolume(show.ShowOne):
if not kwargs and not parsed_args.property and not parsed_args.size:
self.app.log.error("No changes requested\n")
- return
-
-class ShowVolume(show.ShowOne):
+class ShowVolume(command.ShowOne):
"""Display volume details"""
- log = logging.getLogger(__name__ + '.ShowVolume')
-
def get_parser(self, prog_name):
parser = super(ShowVolume, self).get_parser(prog_name)
parser.add_argument(
@@ -411,7 +390,6 @@ class ShowVolume(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
@@ -424,8 +402,6 @@ class ShowVolume(show.ShowOne):
class UnsetVolume(command.Command):
"""Unset volume properties"""
- log = logging.getLogger(__name__ + '.UnsetVolume')
-
def get_parser(self, prog_name):
parser = super(UnsetVolume, self).get_parser(prog_name)
parser.add_argument(
@@ -444,7 +420,6 @@ class UnsetVolume(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
volume = utils.find_resource(
@@ -452,4 +427,3 @@ class UnsetVolume(command.Command):
volume_client.volumes.delete_metadata(
volume.id, parsed_args.property)
- return
diff --git a/openstackclient/volume/v2/volume_type.py b/openstackclient/volume/v2/volume_type.py
index 583e6ed..d2b3ed6 100644
--- a/openstackclient/volume/v2/volume_type.py
+++ b/openstackclient/volume/v2/volume_type.py
@@ -14,22 +14,16 @@
"""Volume v2 Type action implementations"""
-import logging
-
-from cliff import command
-from cliff import lister
-from cliff import show
import six
+from openstackclient.common import command
from openstackclient.common import parseractions
from openstackclient.common import utils
-class CreateVolumeType(show.ShowOne):
+class CreateVolumeType(command.ShowOne):
"""Create new volume type"""
- log = logging.getLogger(__name__ + ".CreateVolumeType")
-
def get_parser(self, prog_name):
parser = super(CreateVolumeType, self).get_parser(prog_name)
parser.add_argument(
@@ -66,7 +60,6 @@ class CreateVolumeType(show.ShowOne):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
@@ -93,8 +86,6 @@ class CreateVolumeType(show.ShowOne):
class DeleteVolumeType(command.Command):
"""Delete volume type"""
- log = logging.getLogger(__name__ + ".DeleteVolumeType")
-
def get_parser(self, prog_name):
parser = super(DeleteVolumeType, self).get_parser(prog_name)
parser.add_argument(
@@ -105,19 +96,15 @@ class DeleteVolumeType(command.Command):
return parser
def take_action(self, parsed_args):
- self.log.info("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)
volume_client.volume_types.delete(volume_type.id)
- return
-class ListVolumeType(lister.Lister):
+class ListVolumeType(command.Lister):
"""List volume types"""
- log = logging.getLogger(__name__ + '.ListVolumeType')
-
def get_parser(self, prog_name):
parser = super(ListVolumeType, self).get_parser(prog_name)
parser.add_argument(
@@ -127,7 +114,6 @@ class ListVolumeType(lister.Lister):
help='List additional fields in output')
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
if parsed_args.long:
columns = ['ID', 'Name', 'Description', 'Extra Specs']
@@ -146,8 +132,6 @@ class ListVolumeType(lister.Lister):
class SetVolumeType(command.Command):
"""Set volume type properties"""
- log = logging.getLogger(__name__ + '.SetVolumeType')
-
def get_parser(self, prog_name):
parser = super(SetVolumeType, self).get_parser(prog_name)
parser.add_argument(
@@ -174,7 +158,6 @@ class SetVolumeType(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
volume_type = utils.find_resource(
@@ -201,14 +184,10 @@ class SetVolumeType(command.Command):
if parsed_args.property:
volume_type.set_keys(parsed_args.property)
- return
-
-class ShowVolumeType(show.ShowOne):
+class ShowVolumeType(command.ShowOne):
"""Display volume type details"""
- log = logging.getLogger(__name__ + ".ShowVolumeType")
-
def get_parser(self, prog_name):
parser = super(ShowVolumeType, self).get_parser(prog_name)
parser.add_argument(
@@ -219,7 +198,6 @@ class ShowVolumeType(show.ShowOne):
return parser
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)
@@ -231,8 +209,6 @@ class ShowVolumeType(show.ShowOne):
class UnsetVolumeType(command.Command):
"""Unset volume type properties"""
- log = logging.getLogger(__name__ + '.UnsetVolumeType')
-
def get_parser(self, prog_name):
parser = super(UnsetVolumeType, self).get_parser(prog_name)
parser.add_argument(
@@ -250,7 +226,6 @@ class UnsetVolumeType(command.Command):
)
return parser
- @utils.log_method(log)
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
volume_type = utils.find_resource(
@@ -258,4 +233,3 @@ class UnsetVolumeType(command.Command):
parsed_args.volume_type,
)
volume_type.unset_keys(parsed_args.property)
- return
diff --git a/releasenotes/notes/add-port-delete-command-4789d3881b186cfc.yaml b/releasenotes/notes/add-port-delete-command-4789d3881b186cfc.yaml
new file mode 100644
index 0000000..dd1e703
--- /dev/null
+++ b/releasenotes/notes/add-port-delete-command-4789d3881b186cfc.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ Add support for the ``port delete`` command.
+ [Bug `1519909 <https://bugs.launchpad.net/python-openstackclient/+bug/1519909>`_]
diff --git a/releasenotes/notes/add-port-show-command-de0a599017189a21.yaml b/releasenotes/notes/add-port-show-command-de0a599017189a21.yaml
new file mode 100644
index 0000000..cb65266
--- /dev/null
+++ b/releasenotes/notes/add-port-show-command-de0a599017189a21.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ Add support for the ``port show`` command.
+ [Bug `1519909 <https://bugs.launchpad.net/python-openstackclient/+bug/1519909>`_]
diff --git a/releasenotes/notes/add-subnet-list-command-970f4b397469bdc6.yaml b/releasenotes/notes/add-subnet-list-command-970f4b397469bdc6.yaml
new file mode 100644
index 0000000..ec1b7a2
--- /dev/null
+++ b/releasenotes/notes/add-subnet-list-command-970f4b397469bdc6.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ Add support for the ``subnet list`` command.
+ [Bug `1523258 <https://bugs.launchpad.net/python-openstackclient/+bug/1523258>`_]
diff --git a/releasenotes/notes/bug-1486597-857e20262c038514.yaml b/releasenotes/notes/bug-1486597-857e20262c038514.yaml
new file mode 100644
index 0000000..45eebd4
--- /dev/null
+++ b/releasenotes/notes/bug-1486597-857e20262c038514.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ Add ``project unset`` command for Identity v2
+ [Bug `1486597 <https://bugs.launchpad.net/bugs/1486597>`_]
diff --git a/releasenotes/notes/bug-1516661-757ef629f899cca3.yaml b/releasenotes/notes/bug-1516661-757ef629f899cca3.yaml
new file mode 100644
index 0000000..21c4fb4
--- /dev/null
+++ b/releasenotes/notes/bug-1516661-757ef629f899cca3.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ Add ``image set --activate|--deactivate`` options (Image v2 only)
+ [Bug `1516661 <https://bugs.launchpad.net/bugs/1516661>`_]
diff --git a/releasenotes/notes/bug-1517134-9efecb257910989c.yaml b/releasenotes/notes/bug-1517134-9efecb257910989c.yaml
new file mode 100644
index 0000000..f6b254b
--- /dev/null
+++ b/releasenotes/notes/bug-1517134-9efecb257910989c.yaml
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ Add ``--project-domain`` option to ``image create`` and ``image set`` commands
+ (Image v2 only)
+ [Bug `1517134 <https://bugs.launchpad.net/bugs/1517134>`_]
diff --git a/releasenotes/notes/bug-1519503-978a68a54819dbbc.yaml b/releasenotes/notes/bug-1519503-978a68a54819dbbc.yaml
new file mode 100644
index 0000000..89c4023
--- /dev/null
+++ b/releasenotes/notes/bug-1519503-978a68a54819dbbc.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ Add ``router`` commands ``create``, ``delete``, ``list``, ``set``, ``show``
+ [Bug `1519503 <https://bugs.launchpad.net/bugs/1519503>`_]
diff --git a/releasenotes/notes/bug-1519512-d20f44aca1f9e9b9.yaml b/releasenotes/notes/bug-1519512-d20f44aca1f9e9b9.yaml
new file mode 100644
index 0000000..ae0f1b5
--- /dev/null
+++ b/releasenotes/notes/bug-1519512-d20f44aca1f9e9b9.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+ - |
+ Make ``security group rule list`` group argument optional to list all
+ security groups
+ [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
diff --git a/releasenotes/notes/bug-1520003-505af921c8afffc9.yaml b/releasenotes/notes/bug-1520003-505af921c8afffc9.yaml
new file mode 100644
index 0000000..ca94b95
--- /dev/null
+++ b/releasenotes/notes/bug-1520003-505af921c8afffc9.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+ - |
+ Add remote security group to `os security group rule list`
+ [Bug `1520003 <https://bugs.launchpad.net/bugs/1520003>`_]
diff --git a/releasenotes/notes/bug-1521492-89b972c6362940a5.yaml b/releasenotes/notes/bug-1521492-89b972c6362940a5.yaml
new file mode 100644
index 0000000..6f4766e
--- /dev/null
+++ b/releasenotes/notes/bug-1521492-89b972c6362940a5.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+ - |
+ Change ``server list --flavor`` to now accept flavor ID or name
+ [Bug `1521492 <https://bugs.launchpad.net/bugs/1521492>`_]
diff --git a/releasenotes/notes/bug-1521492-8cde2601591a8c78.yaml b/releasenotes/notes/bug-1521492-8cde2601591a8c78.yaml
new file mode 100644
index 0000000..8d86b35
--- /dev/null
+++ b/releasenotes/notes/bug-1521492-8cde2601591a8c78.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+ - |
+ Change ``server list --image`` to now accept image ID or name
+ [Bug `1521492 <https://bugs.launchpad.net/bugs/1521492>`_]
diff --git a/releasenotes/notes/bug-1522969-63abf273c6e71a07.yaml b/releasenotes/notes/bug-1522969-63abf273c6e71a07.yaml
new file mode 100644
index 0000000..98452db
--- /dev/null
+++ b/releasenotes/notes/bug-1522969-63abf273c6e71a07.yaml
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ Add ``--src-group`` option to ``security group rule create`` to include a
+ 'remote' security group rule.
+ [Bug `1522969 <https://bugs.launchpad.net/bugs/1522969>`_]
diff --git a/releasenotes/notes/bug-1524456-9967fac653c91cb2.yaml b/releasenotes/notes/bug-1524456-9967fac653c91cb2.yaml
new file mode 100644
index 0000000..37eb950
--- /dev/null
+++ b/releasenotes/notes/bug-1524456-9967fac653c91cb2.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+ - |
+ Change the ``project set --domain`` option to use the argument as a lookup
+ for locating projects in non-default domains.
+ [Bug `1524456 <https://bugs.launchpad.net/bugs/1524456>`_]
diff --git a/releasenotes/notes/bug-1525805-122e6ce0c3cd4945.yaml b/releasenotes/notes/bug-1525805-122e6ce0c3cd4945.yaml
new file mode 100644
index 0000000..444b637
--- /dev/null
+++ b/releasenotes/notes/bug-1525805-122e6ce0c3cd4945.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+ - |
+ Fix case sensitivity when showing object-store properties.
+ [Bug `1525805 <https://bugs.launchpad.net/bugs/1525805>`_]
diff --git a/releasenotes/notes/bug-1527833-42cde11d28b09ac3.yaml b/releasenotes/notes/bug-1527833-42cde11d28b09ac3.yaml
new file mode 100644
index 0000000..21f748b
--- /dev/null
+++ b/releasenotes/notes/bug-1527833-42cde11d28b09ac3.yaml
@@ -0,0 +1,7 @@
+---
+other:
+ - Change the `--owner` option to `--project` in `image create`
+ and `image set` commands. `--owner` is deprecated and no longer
+ documented but is still accepted; a warning message will be shown
+ if it is used.
+ [Bug `1527833 <https://bugs.launchpad.net/bugs/1527833>`_]
diff --git a/releasenotes/notes/bug-1531360-0f5c62d18088e5b5.yaml b/releasenotes/notes/bug-1531360-0f5c62d18088e5b5.yaml
new file mode 100644
index 0000000..992f265
--- /dev/null
+++ b/releasenotes/notes/bug-1531360-0f5c62d18088e5b5.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+ - |
+ Support non-interactive user password update
+ [Bug `1531360 <https://bugs.launchpad.net/bugs/1531360>`_]
diff --git a/releasenotes/notes/bug-1532945-1a5485b8d0ebddb8.yaml b/releasenotes/notes/bug-1532945-1a5485b8d0ebddb8.yaml
new file mode 100644
index 0000000..bee8102
--- /dev/null
+++ b/releasenotes/notes/bug-1532945-1a5485b8d0ebddb8.yaml
@@ -0,0 +1,8 @@
+---
+features:
+ - |
+ Add volume support to `os availability zone list`
+ [Bug `1532945 <https://bugs.launchpad.net/bugs/1532945>`_]
+
+ * New `--compute` option to only list compute availability zones.
+ * New `--volume` option to only list volume availability zones.
diff --git a/releasenotes/notes/bug-1534202-1ba78f0bb744961f.yaml b/releasenotes/notes/bug-1534202-1ba78f0bb744961f.yaml
new file mode 100644
index 0000000..36c0a3d
--- /dev/null
+++ b/releasenotes/notes/bug-1534202-1ba78f0bb744961f.yaml
@@ -0,0 +1,7 @@
+---
+features:
+ - |
+ Add network support to `os availability zone list`
+ [Bug `1534202 <https://bugs.launchpad.net/bugs/1534202>`_]
+
+ * New `--network` option to only list network availability zones.
diff --git a/releasenotes/notes/bug-1540988-17841cfd5accf7f5.yaml b/releasenotes/notes/bug-1540988-17841cfd5accf7f5.yaml
new file mode 100644
index 0000000..eabe420
--- /dev/null
+++ b/releasenotes/notes/bug-1540988-17841cfd5accf7f5.yaml
@@ -0,0 +1,9 @@
+---
+features:
+ - |
+ Add ``--limit`` option to ``image list`` to limit the number of images
+ in output.
+ [Bug `1540988 <https://bugs.launchpad.net/bugs/1540988>`_]
+ - |
+ Add ``--marker`` option to ``image list`` to handle paginate requests.
+ [Bug `1540988 <https://bugs.launchpad.net/bugs/1540988>`_]
diff --git a/requirements.txt b/requirements.txt
index fbe3b8d..cc189ba 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>=1.6
-six>=1.9.0
+pbr>=1.6 # Apache-2.0
+six>=1.9.0 # MIT
-Babel>=1.3
+Babel>=1.3 # BSD
cliff>=1.15.0 # Apache-2.0
-keystoneauth1>=1.0.0
-os-client-config!=1.6.2,>=1.4.0
-oslo.config>=2.7.0 # Apache-2.0
-oslo.i18n>=1.5.0 # Apache-2.0
-oslo.utils>=2.8.0 # Apache-2.0
-python-glanceclient>=0.18.0
-python-keystoneclient!=1.8.0,>=1.6.0
-python-novaclient!=2.33.0,>=2.29.0
-python-cinderclient>=1.3.1
-python-neutronclient>=2.6.0
-requests>=2.8.1
+keystoneauth1>=2.1.0 # Apache-2.0
+openstacksdk>=0.7.4 # Apache-2.0
+os-client-config>=1.13.1 # Apache-2.0
+oslo.config>=3.4.0 # Apache-2.0
+oslo.i18n>=2.1.0 # Apache-2.0
+oslo.utils>=3.4.0 # Apache-2.0
+python-glanceclient>=1.2.0 # Apache-2.0
+python-keystoneclient!=1.8.0,!=2.1.0,>=1.6.0 # Apache-2.0
+python-novaclient!=2.33.0,>=2.29.0 # Apache-2.0
+python-cinderclient>=1.3.1 # Apache-2.0
+requests!=2.9.0,>=2.8.1 # Apache-2.0
stevedore>=1.5.0 # Apache-2.0
diff --git a/setup.cfg b/setup.cfg
index 27b00d4..c4d1000 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -43,6 +43,7 @@ openstack.cli.base =
volume = openstackclient.volume.client
openstack.common =
+ availability_zone_list = openstackclient.common.availability_zone:ListAvailabilityZone
configuration_show = openstackclient.common.configuration:ShowConfiguration
extension_list = openstackclient.common.extension:ListExtension
limits_show = openstackclient.common.limits:ShowLimits
@@ -50,8 +51,6 @@ openstack.common =
quota_show = openstackclient.common.quota:ShowQuota
openstack.compute.v2 =
- availability_zone_list = openstackclient.compute.v2.availability_zone:ListAvailabilityZone
-
compute_agent_create = openstackclient.compute.v2.agent:CreateAgent
compute_agent_delete = openstackclient.compute.v2.agent:DeleteAgent
compute_agent_list = openstackclient.compute.v2.agent:ListAgent
@@ -104,7 +103,6 @@ openstack.compute.v2 =
keypair_show = openstackclient.compute.v2.keypair:ShowKeypair
security_group_create = openstackclient.compute.v2.security_group:CreateSecurityGroup
- security_group_delete = openstackclient.compute.v2.security_group:DeleteSecurityGroup
security_group_list = openstackclient.compute.v2.security_group:ListSecurityGroup
security_group_set = openstackclient.compute.v2.security_group:SetSecurityGroup
security_group_show = openstackclient.compute.v2.security_group:ShowSecurityGroup
@@ -163,6 +161,7 @@ openstack.identity.v2 =
project_list = openstackclient.identity.v2_0.project:ListProject
project_set = openstackclient.identity.v2_0.project:SetProject
project_show = openstackclient.identity.v2_0.project:ShowProject
+ project_unset = openstackclient.identity.v2_0.project:UnsetProject
role_add = openstackclient.identity.v2_0.role:AddRole
role_create = openstackclient.identity.v2_0.role:CreateRole
@@ -332,6 +331,15 @@ openstack.network.v2 =
network_list = openstackclient.network.v2.network:ListNetwork
network_set = openstackclient.network.v2.network:SetNetwork
network_show = openstackclient.network.v2.network:ShowNetwork
+ port_delete = openstackclient.network.v2.port:DeletePort
+ port_show = openstackclient.network.v2.port:ShowPort
+ router_create = openstackclient.network.v2.router:CreateRouter
+ router_delete = openstackclient.network.v2.router:DeleteRouter
+ router_list = openstackclient.network.v2.router:ListRouter
+ router_set = openstackclient.network.v2.router:SetRouter
+ router_show = openstackclient.network.v2.router:ShowRouter
+ security_group_delete = openstackclient.network.v2.security_group:DeleteSecurityGroup
+ subnet_list = openstackclient.network.v2.subnet:ListSubnet
openstack.object_store.v1 =
object_store_account_set = openstackclient.object.v1.account:SetAccount
@@ -440,13 +448,13 @@ universal = 1
[extract_messages]
keywords = _ gettext ngettext l_ lazy_gettext
mapping_file = babel.cfg
-output_file = python-openstackclient/locale/python-openstackclient.pot
+output_file = openstackclient/locale/openstackclient.pot
[update_catalog]
-domain = python-openstackclient
-output_dir = python-openstackclient/locale
-input_file = python-openstackclient/locale/python-openstackclient.pot
+domain = openstackclient
+output_dir = openstackclient/locale
+input_file = openstackclient/locale/openstackclient.pot
[compile_catalog]
-directory = python-openstackclient/locale
-domain = python-openstackclient
+directory = openstackclient/locale
+domain = openstackclient
diff --git a/test-requirements.txt b/test-requirements.txt
index 7322c84..6a73cd9 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -3,28 +3,27 @@
# process, which may cause wedges in the gate later.
hacking<0.11,>=0.10.0
-coverage>=3.6
-discover
-fixtures>=1.3.1
-mock>=1.2
+coverage>=3.6 # Apache-2.0
+discover # BSD
+fixtures>=1.3.1 # Apache-2.0/BSD
+mock>=1.2 # BSD
oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
oslotest>=1.10.0 # Apache-2.0
-reno>=0.1.1 # Apache2
-requests-mock>=0.6.0 # Apache-2.0
-sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2
-os-testr>=0.4.1
-testrepository>=0.0.18
-testtools>=1.4.0
-WebOb>=1.2.3
-tempest-lib>=0.10.0
+reno>=0.1.1 # Apache2
+requests-mock>=0.7.0 # Apache-2.0
+sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
+os-testr>=0.4.1 # Apache-2.0
+testrepository>=0.0.18 # Apache-2.0/BSD
+testtools>=1.4.0 # MIT
+WebOb>=1.2.3 # MIT
+tempest-lib>=0.13.0 # Apache-2.0
# Install these to generate sphinx autodocs
-python-barbicanclient>=3.3.0
-python-congressclient>=1.0.0
-python-designateclient>=1.5.0
-python-heatclient>=0.6.0
-python-ironicclient>=0.8.0
-python-mistralclient>=1.0.0
-python-saharaclient>=0.10.0
-python-tuskarclient>=0.1.17
-python-zaqarclient>=0.3.0
+python-barbicanclient>=3.3.0 # Apache-2.0
+python-congressclient>=1.0.0 # Apache-2.0
+python-designateclient>=1.5.0 # Apache-2.0
+python-heatclient>=0.6.0 # Apache-2.0
+python-ironicclient>=1.1.0 # Apache-2.0
+python-mistralclient>=1.0.0 # Apache-2.0
+python-saharaclient>=0.10.0 # Apache-2.0
+python-zaqarclient>=0.3.0 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index dd2b7b5..cc1407f 100644
--- a/tox.ini
+++ b/tox.ini
@@ -27,9 +27,6 @@ commands = python setup.py test --coverage --testr-args='{posargs}'
[testenv:debug]
commands = oslo_debug_helper -t openstackclient/tests {posargs}
-[tox:jenkins]
-downloadcache = ~/cache/pip
-
[testenv:docs]
commands = python setup.py build_sphinx