summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorey Bryant <corey.bryant@canonical.com>2020-07-28 20:33:41 -0400
committergit-ubuntu importer <ubuntu-devel-discuss@lists.ubuntu.com>2020-07-29 12:50:08 +0000
commitb4a4c2922e520d08a8c14bba5f2d906a8cd3baef (patch)
tree409fcdf4b919f9536dbcf979ef15ce46f6a7ba67
parent08904a8f95cae556393bbee628ac021ea9ff8c07 (diff)
5.3.1-0ubuntu1 (patches unapplied)import/5.3.1-0ubuntu1
Imported using git-ubuntu import.
Notes
Notes: * New upstream release for OpenStack Victoria. * d/control: Align (Build-)Depends with upstream. * d/control, d/rules: Switch to debhelper compat 12 and pybuild. * d/control: Update Standards-Version to 4.5.0.
-rw-r--r--.zuul.yaml17
-rw-r--r--AUTHORS13
-rw-r--r--ChangeLog50
-rw-r--r--Dockerfile7
-rw-r--r--PKG-INFO6
-rw-r--r--babel.cfg1
-rw-r--r--bindep.txt1
-rw-r--r--debian/changelog9
-rw-r--r--debian/compat1
-rw-r--r--debian/control45
-rw-r--r--debian/copyright2
-rwxr-xr-xdebian/rules6
-rw-r--r--doc/requirements.txt8
-rw-r--r--doc/source/_extra/.htaccess5
-rw-r--r--doc/source/cli/_hidden/ec2-credentials.rst13
-rw-r--r--doc/source/cli/_hidden/endpoint.rst13
-rw-r--r--doc/source/cli/_hidden/image.rst13
-rw-r--r--doc/source/cli/_hidden/project.rst13
-rw-r--r--doc/source/cli/_hidden/role.rst13
-rw-r--r--doc/source/cli/_hidden/service.rst13
-rw-r--r--doc/source/cli/_hidden/token.rst13
-rw-r--r--doc/source/cli/_hidden/user.rst13
-rw-r--r--doc/source/cli/command-objects/application-credentials.rst107
-rw-r--r--doc/source/cli/command-objects/catalog.rst5
-rw-r--r--doc/source/cli/command-objects/consumer.rst14
-rw-r--r--doc/source/cli/command-objects/credential.rst124
-rw-r--r--doc/source/cli/command-objects/ec2-credentials-v2.rst6
-rw-r--r--doc/source/cli/command-objects/ec2-credentials-v3.rst6
-rw-r--r--doc/source/cli/command-objects/ec2-credentials.rst138
-rw-r--r--doc/source/cli/command-objects/endpoint-v2.rst6
-rw-r--r--doc/source/cli/command-objects/endpoint-v3.rst24
-rw-r--r--doc/source/cli/command-objects/endpoint.rst275
-rw-r--r--doc/source/cli/command-objects/endpoint_group.rst20
-rw-r--r--doc/source/cli/command-objects/federation-domain-project.rst11
-rw-r--r--doc/source/cli/command-objects/federation-protocol.rst14
-rw-r--r--doc/source/cli/command-objects/group.rst245
-rw-r--r--doc/source/cli/command-objects/identity-provider.rst14
-rw-r--r--doc/source/cli/command-objects/image-v1.rst6
-rw-r--r--doc/source/cli/command-objects/image-v2.rst6
-rw-r--r--doc/source/cli/command-objects/image.rst650
-rw-r--r--doc/source/cli/command-objects/implied_role.rst53
-rw-r--r--doc/source/cli/command-objects/limit.rst127
-rw-r--r--doc/source/cli/command-objects/mapping.rst14
-rw-r--r--doc/source/cli/command-objects/policy.rst14
-rw-r--r--doc/source/cli/command-objects/project-v2.rst6
-rw-r--r--doc/source/cli/command-objects/project-v3.rst6
-rw-r--r--doc/source/cli/command-objects/project.rst277
-rw-r--r--doc/source/cli/command-objects/region.rst14
-rw-r--r--doc/source/cli/command-objects/registered-limit.rst133
-rw-r--r--doc/source/cli/command-objects/request-token.rst5
-rw-r--r--doc/source/cli/command-objects/role-v2.rst6
-rw-r--r--doc/source/cli/command-objects/role-v3.rst6
-rw-r--r--doc/source/cli/command-objects/role.rst292
-rw-r--r--doc/source/cli/command-objects/service-provider.rst14
-rw-r--r--doc/source/cli/command-objects/service-v2.rst6
-rw-r--r--doc/source/cli/command-objects/service-v3.rst18
-rw-r--r--doc/source/cli/command-objects/service.rst143
-rw-r--r--doc/source/cli/command-objects/token-v2.rst7
-rw-r--r--doc/source/cli/command-objects/token-v3.rst7
-rw-r--r--doc/source/cli/command-objects/token.rst30
-rw-r--r--doc/source/cli/command-objects/trust.rst11
-rw-r--r--doc/source/cli/command-objects/user-v2.rst7
-rw-r--r--doc/source/cli/command-objects/user-v3.rst7
-rw-r--r--doc/source/cli/command-objects/user.rst223
-rw-r--r--doc/source/cli/commands.rst4
-rw-r--r--doc/source/cli/index.rst9
-rw-r--r--doc/source/cli/plugin-commands/congress.rst4
-rw-r--r--doc/source/cli/plugin-commands/index.rst2
-rw-r--r--doc/source/cli/plugin-commands/manila.rst4
-rw-r--r--doc/source/conf.py27
-rw-r--r--doc/source/contributor/plugins.rst1
-rw-r--r--doc/test/redirect-tests.txt8
-rw-r--r--lower-constraints.txt17
-rw-r--r--openstackclient/api/object_store_v1.py14
-rw-r--r--openstackclient/common/clientmanager.py26
-rw-r--r--openstackclient/common/quota.py21
-rw-r--r--openstackclient/compute/v2/server.py9
-rw-r--r--openstackclient/identity/common.py24
-rw-r--r--openstackclient/identity/v3/domain.py9
-rw-r--r--openstackclient/identity/v3/project.py17
-rw-r--r--openstackclient/identity/v3/role.py10
-rw-r--r--openstackclient/identity/v3/user.py120
-rw-r--r--openstackclient/image/v2/image.py17
-rw-r--r--openstackclient/network/sdk_utils.py5
-rw-r--r--openstackclient/network/v2/address_scope.py10
-rw-r--r--openstackclient/network/v2/floating_ip.py2
-rw-r--r--openstackclient/network/v2/floating_ip_port_forwarding.py20
-rw-r--r--openstackclient/network/v2/ip_availability.py2
-rw-r--r--openstackclient/network/v2/network.py8
-rw-r--r--openstackclient/network/v2/network_agent.py1
-rw-r--r--openstackclient/network/v2/network_auto_allocated_topology.py17
-rw-r--r--openstackclient/network/v2/network_flavor.py10
-rw-r--r--openstackclient/network/v2/network_flavor_profile.py10
-rw-r--r--openstackclient/network/v2/network_meter.py10
-rw-r--r--openstackclient/network/v2/network_meter_rule.py10
-rw-r--r--openstackclient/network/v2/network_qos_policy.py10
-rw-r--r--openstackclient/network/v2/network_qos_rule.py10
-rw-r--r--openstackclient/network/v2/network_qos_rule_type.py8
-rw-r--r--openstackclient/network/v2/network_rbac.py32
-rw-r--r--openstackclient/network/v2/network_segment.py10
-rw-r--r--openstackclient/network/v2/network_segment_range.py9
-rw-r--r--openstackclient/network/v2/port.py7
-rw-r--r--openstackclient/network/v2/router.py98
-rw-r--r--openstackclient/network/v2/security_group.py37
-rw-r--r--openstackclient/network/v2/security_group_rule.py10
-rw-r--r--openstackclient/network/v2/subnet.py1
-rw-r--r--openstackclient/network/v2/subnet_pool.py1
-rw-r--r--openstackclient/tests/functional/common/test_quota.py44
-rw-r--r--openstackclient/tests/functional/identity/v3/test_project.py1
-rw-r--r--openstackclient/tests/functional/network/v2/test_router.py43
-rw-r--r--openstackclient/tests/functional/network/v2/test_security_group.py4
-rw-r--r--openstackclient/tests/unit/api/test_object_store_v1.py60
-rw-r--r--openstackclient/tests/unit/common/test_parseractions.py4
-rw-r--r--openstackclient/tests/unit/common/test_quota.py119
-rw-r--r--openstackclient/tests/unit/compute/v2/test_server.py36
-rw-r--r--openstackclient/tests/unit/identity/v3/fakes.py3
-rw-r--r--openstackclient/tests/unit/identity/v3/test_access_rule.py2
-rw-r--r--openstackclient/tests/unit/identity/v3/test_domain.py110
-rw-r--r--openstackclient/tests/unit/identity/v3/test_project.py281
-rw-r--r--openstackclient/tests/unit/identity/v3/test_role.py162
-rw-r--r--openstackclient/tests/unit/identity/v3/test_user.py852
-rw-r--r--openstackclient/tests/unit/image/v2/test_image.py22
-rw-r--r--openstackclient/tests/unit/integ/cli/test_shell.py20
-rw-r--r--openstackclient/tests/unit/network/v2/fakes.py4
-rw-r--r--openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py15
-rw-r--r--openstackclient/tests/unit/network/v2/test_network.py33
-rw-r--r--openstackclient/tests/unit/network/v2/test_network_rbac.py74
-rw-r--r--openstackclient/tests/unit/network/v2/test_port.py16
-rw-r--r--openstackclient/tests/unit/network/v2/test_router.py140
-rw-r--r--openstackclient/tests/unit/network/v2/test_security_group_network.py10
-rw-r--r--python_openstackclient.egg-info/PKG-INFO6
-rw-r--r--python_openstackclient.egg-info/SOURCES.txt51
-rw-r--r--python_openstackclient.egg-info/entry_points.txt4
-rw-r--r--python_openstackclient.egg-info/pbr.json2
-rw-r--r--python_openstackclient.egg-info/requires.txt10
-rw-r--r--releasenotes/notes/add-description-field-in-port-forwarding-c536e077b243d517.yaml6
-rw-r--r--releasenotes/notes/add-image-import-flag-899869dc5a92aea7.yaml5
-rw-r--r--releasenotes/notes/add_options_to_user_create_and_set-302401520f36d153.yaml19
-rw-r--r--releasenotes/notes/add_resource_option_immutable-efed6e1ebdc69591.yaml9
-rw-r--r--releasenotes/notes/bug-2005246-3fb70206bafc5444.yaml5
-rw-r--r--releasenotes/notes/disallow-setting-default-on-internal-network-824fdea1a900891c.yaml9
-rw-r--r--releasenotes/notes/entrypoint-3.8-0597d159889042f7.yaml6
-rw-r--r--releasenotes/notes/fix-story-2007890-0974f3e69f26801e.yaml7
-rw-r--r--releasenotes/notes/force-flag-openstackclient-c172de2717e5cfac.yaml6
-rw-r--r--releasenotes/notes/rbac-add-address-scope-7f6409ab70d36306.yaml4
-rw-r--r--releasenotes/notes/rbac-add-subnetpool-f1fc0e728ff61654.yaml4
-rw-r--r--releasenotes/notes/router-extraroute-atomic-d6d406ffb15695f2.yaml12
-rw-r--r--releasenotes/notes/stateful-security-group-a21fa8498e866b90.yaml6
-rw-r--r--releasenotes/notes/task-40279-eb0d718ac1959c50.yaml5
-rw-r--r--releasenotes/source/conf.py12
-rw-r--r--releasenotes/source/index.rst1
-rw-r--r--releasenotes/source/ussuri.rst6
-rw-r--r--requirements.txt4
-rw-r--r--setup.cfg42
-rw-r--r--setup.py9
-rw-r--r--test-requirements.txt4
-rw-r--r--tox.ini2
157 files changed, 2977 insertions, 3387 deletions
diff --git a/.zuul.yaml b/.zuul.yaml
index 7a7e264..e566ceb 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -9,7 +9,6 @@
- openstack/cliff
- openstack/keystoneauth
- openstack/openstacksdk
- - openstack/os-client-config
- openstack/osc-lib
- openstack/python-openstackclient
vars:
@@ -30,7 +29,6 @@
- openstack/cliff
- openstack/keystoneauth
- openstack/openstacksdk
- - openstack/os-client-config
- openstack/osc-lib
- openstack/python-openstackclient
vars:
@@ -53,8 +51,6 @@
vars:
devstack_localrc:
LIBS_FROM_GIT: python-openstackclient
- # NOTE(dtroyer): OSC needs to support Image v1 for a while yet so re-enable
- GLANCE_V1_ENABLED: true
# NOTE(dtroyer): Functional tests need a bit more volume headroom
VOLUME_BACKING_FILE_SIZE: 20G
devstack_local_conf:
@@ -127,12 +123,11 @@
- openstack/cliff
- openstack/keystoneauth
- openstack/openstacksdk
- - openstack/os-client-config
- openstack/osc-lib
- openstack/python-openstackclient
vars:
devstack_localrc:
- LIBS_FROM_GIT: python-openstackclient,openstacksdk,osc-lib,os-client-config
+ LIBS_FROM_GIT: python-openstackclient,openstacksdk,osc-lib,cliff
# This is insufficient, but leaving it here as a reminder of what may
# someday be all we need to make this work
# disable_python3_package swift
@@ -174,8 +169,8 @@
description: Build Docker images.
allowed-projects: openstack/python-openstackclient
requires:
- - python-builder-container-image
- - python-base-container-image
+ - python-builder-3.7-container-image
+ - python-base-3.7-container-image
provides: osc-container-image
vars: &osc_image_vars
docker_images:
@@ -188,8 +183,8 @@
description: Build Docker images and upload to Docker Hub.
allowed-projects: openstack/python-openstackclient
requires:
- - python-builder-container-image
- - python-base-container-image
+ - python-builder-3.7-container-image
+ - python-base-3.7-container-image
provides: osc-container-image
secrets:
- name: docker_credentials
@@ -225,7 +220,7 @@
- osc-tox-unit-tips
- openstack-cover-jobs
- openstack-lower-constraints-jobs
- - openstack-python3-ussuri-jobs
+ - openstack-python3-victoria-jobs
- publish-openstack-docs-pti
- check-requirements
- release-notes-jobs-python3
diff --git a/AUTHORS b/AUTHORS
index 788e405..fa123d4 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -14,7 +14,9 @@ Alex Gaynor <alex.gaynor@gmail.com>
Alex Holden <alex@alexjonasholden.com>
Alex Katz <akatz@akatz.tlv.csb>
Alex Schultz <aschultz@mirantis.com>
+Alexander Gräb <alexander.graeb@secustack.com>
Alexander Ignatov <aignatov@mirantis.com>
+Alfredo Moralejo <amoralej@redhat.com>
Allain Legacy <Allain.legacy@windriver.com>
Alvaro Lopez Garcia <aloga@ifca.unican.es>
Amey Bhide <abhide@vmware.com>
@@ -91,6 +93,7 @@ Dean Troyer <dtroyer@gmail.com>
Dina Belova <dbelova@mirantis.com>
Dirk Mueller <dirk@dmllr.de>
Dmitriy Rabotyagov <drabotyagov@vexxhost.com>
+Dmitry Tantsur <dtantsur@protonmail.com>
Dolph Mathews <dolph.mathews@gmail.com>
Dongcan Ye <hellochosen@gmail.com>
Doug Hellmann <doug.hellmann@dreamhost.com>
@@ -105,6 +108,7 @@ Eric Fried <openstack@fried.cc>
Fan Zhang <zh.f@outlook.com>
Fang Zhen <zhen.fang@easystack.cn>
Fei Long Wang <flwang@catalyst.net.nz>
+Felix Yan <felixonmars@archlinux.org>
Flavio Percoco <flaper87@gmail.com>
Florent Flament <florent.flament-ext@cloudwatt.com>
Gage Hugo <gagehugo@gmail.com>
@@ -138,6 +142,7 @@ Huang Cheng <huang.cheng@h3c.com>
Huanxuan Ao <huanxuan.ao@easystack.cn>
Hugh Saunders <hugh@wherenow.org>
Ian Wienand <iwienand@redhat.com>
+Igor Malinovskiy <u.glide@gmail.com>
Igor_Bolotin <Igor_Bolotin@symantec.com>
Igor_Bolotin <igor_bolotin@symantec.com>
Ilya Persky <ipersky@yahoo-inc.com>
@@ -156,6 +161,7 @@ Jas <singhj@us.ibm.com>
Jaspreet Singh Rawel <jaspreetsinghrawel@gmail.com>
Javier Pena <jpena@redhat.com>
Jean-Philippe Evrard <jean-philippe@evrard.me>
+Jens Harbott (frickler) <j.harbott@x-ion.de>
Jens Harbott <j.harbott@x-ion.de>
Jens Rosenboom <j.rosenboom@x-ion.de>
Jeremy Houser <jh629g@att.com>
@@ -202,6 +208,7 @@ Lorin Hochstein <lorin@nimbisservices.com>
Lu lei <lei.lu@easystack.cn>
Léo GEORGEL <leo.georgel@osones.com>
M V P Nitesh <m.nitesh@nectechnologies.in>
+Maari Tamm <tamm.maari@gmail.com>
Madhu Mohan Nelemane <mmnelemane@suse.com>
Major Hayden <major@mhtx.net>
Manjeet Singh Bhatia <manjeet.s.bhatia@intel.com>
@@ -253,11 +260,13 @@ Paul Belanger <paul.belanger@polybeacon.com>
Paul Bourke <paul.bourke@oracle.com>
Pavlo Shchelokovskyy <shchelokovskyy@gmail.com>
Pedro Navarro <pednape@gmail.com>
+Pete Zaitcev <zaitcev@kotori.zaitcev.us>
Petr Blaho <pblaho@redhat.com>
Pierre Hanselmann <pierre.hanselmann@gmail.com>
Pierre Prinetti <pierreprinetti@redhat.com>
Qiu Yu <qiuyu@ebaysf.com>
Radoslaw Smigielski <radoslaw.smigielski@nokia.com>
+Radosław Piliszek <radoslaw.piliszek@gmail.com>
Radu Mateescu <mateescu@ca.ibm.com>
Rajasi Kulkarni <rajasikulkarni18@gmail.com>
Ramaraja <ramaraja.r@hcl.com>
@@ -322,6 +331,7 @@ Thomas Goirand <zigo@debian.org>
Tim Burke <tim.burke@gmail.com>
Tom Cocozzello <tjcocozz@us.ibm.com>
Tom Jose Kalapura <tomjosekal@gmail.com>
+Tom Stappaerts <tom.stappaerts@nuagenetworks.net>
Tovin Seven <vinhnt@vn.fujitsu.com>
Travis Tripp <travis.tripp@hpe.com>
Trevor McCasland <TM2086@att.com>
@@ -366,6 +376,7 @@ guang-yee <guang.yee@hpe.com>
guangpei.liu <guangpei.liu@easystack.cn>
guiyanxing <guiyanxing@cmss.chinamobile.com>
gvrangan <venkatrangang@hcl.com>
+hackertron <jayadityagupta11@gmail.com>
heha <zhanghanqun@unitedstack.com>
henriquetruta <henrique@lsd.ufcg.edu.br>
huangshan <huangshan@fiberhome.com>
@@ -395,6 +406,7 @@ melanie witt <melwittt@gmail.com>
melissaml <ma.lei@99cloud.net>
nidhimittalhada <nidhimittal19@gmail.com>
npraveen35 <npraveen35@gmail.com>
+pedro <phpm13@gmail.com>
pengyuesheng <pengyuesheng@gohighsec.com>
phil-hopkins-a <phil.hopkins@rackspace.com>
qinchunhua <qin.chunhua@zte.com.cn>
@@ -433,6 +445,7 @@ yushangbin <yushb@gohighsec.com>
zhang.lei <zhang.lei@99cloud.net>
zhang.xiuhua <zhang.xiuhua@99cloud.net>
zhangbailin <zhangbailin@inspur.com>
+zhangboye <zhangboye@inspur.com>
zhanghongtao <zhanghongtao0826@126.com>
zheng yin <yin.zheng@easystack.cn>
zhengsenyan <zhengsy_sean@126.com>
diff --git a/ChangeLog b/ChangeLog
index 07e9b7f..bf4523d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,55 @@
CHANGES
=======
+5.3.1
+-----
+
+* Fix compatibility issue in 5.3
+
+5.3.0
+-----
+
+* Fix uploading an signed image does not work if private signing key is encrypted
+* Add a command to trigger entrypoint cache creation
+* switch to stevedore for entry points
+* Make volume backup record commands available in v3
+* Remove enabling of glance v1 API
+* Expose flag for forcing use of import for images
+* Remove translation sections from setup.cfg
+* port: add --host to list command
+* Don't display Munch objects in the output
+* Revert "Format location columns in network commands"
+* image: autogenerate docs
+* identity: autogenerate docs
+* Remove os-client-config references
+* Add cliff to libs-from-git for devstack functional tips
+* Add OpenStack Client for Manila docs
+* Remove congress
+* Replace assertItemsEqual with assertCountEqual
+* Client should parse string to boolean for value 'is\_domain'
+* Add py38 package metadata
+* Switch to newer openstackdocstheme and reno versions
+* Make container list --all work
+* Cleanup: remove a useless reference to "object"
+* Resolve PEP8
+* Correct image lookup during server rebuild
+* Add Python3 victoria unit tests
+* Update master for stable/ussuri
+* Remove Babel from requirements
+* Add '--force; parameter to 'openstack quota set'
+* Add 'subnetpool' type support to rbac commands
+* Add resource option immutable
+* Revert "Disallow setting default on internal network"
+* Use unittest.mock instead of third party mock
+* Add description field to portforwarding NAT rules
+* Support for stateless security groups
+* Cleanup Python 2.7 support
+* Add command: router add/remove route --route
+* Adding options to user cli
+* Be explicit about python version in image
+* Add libc6-dev to bindep
+* Add 'address\_scope' type support to network rbac commands
+
5.2.0
-----
@@ -20,6 +69,7 @@ CHANGES
* Allow setting floating IP description
* Stop configuring install\_command in tox and stop use pip
* Build utility image for using osc
+* Allow os quota list query to filter by project
* Add "fields" parameter to ListSecurityGroup query
* Update http links in docs
* Disallow setting default on internal network
diff --git a/Dockerfile b/Dockerfile
index 9ff8084..bf5de3c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -13,14 +13,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-FROM docker.io/opendevorg/python-builder as builder
+FROM docker.io/opendevorg/python-builder:3.7 as builder
COPY . /tmp/src
RUN assemble
-FROM docker.io/opendevorg/python-base
+FROM docker.io/opendevorg/python-base:3.7
COPY --from=builder /output/ /output
RUN /output/install-from-bindep
+# Trigger entrypoint loading to trigger stevedore entrypoint caching
+RUN openstack --help >/dev/null 2>&1
+
CMD ["/usr/local/bin/openstack"]
diff --git a/PKG-INFO b/PKG-INFO
index a8ec03d..8e0a1bd 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
-Metadata-Version: 1.1
+Metadata-Version: 1.2
Name: python-openstackclient
-Version: 5.2.0
+Version: 5.3.1
Summary: OpenStack Command-line Client
Home-page: https://docs.openstack.org/python-openstackclient/latest/
Author: OpenStack
@@ -118,3 +118,5 @@ Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Requires-Python: >=3.6
diff --git a/babel.cfg b/babel.cfg
deleted file mode 100644
index efceab8..0000000
--- a/babel.cfg
+++ /dev/null
@@ -1 +0,0 @@
-[python: **.py]
diff --git a/bindep.txt b/bindep.txt
index c5ae6c6..cf94d2a 100644
--- a/bindep.txt
+++ b/bindep.txt
@@ -2,6 +2,7 @@
# see https://docs.openstack.org/infra/bindep/ for additional information.
gcc [compile test]
+libc6-dev [compile test platform:dpkg]
libffi-devel [platform:rpm]
libffi-dev [compile test platform:dpkg]
libffi6 [platform:dpkg]
diff --git a/debian/changelog b/debian/changelog
index a224293..a97af9f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+python-openstackclient (5.3.1-0ubuntu1) groovy; urgency=medium
+
+ * New upstream release for OpenStack Victoria.
+ * d/control: Align (Build-)Depends with upstream.
+ * d/control, d/rules: Switch to debhelper compat 12 and pybuild.
+ * d/control: Update Standards-Version to 4.5.0.
+
+ -- Corey Bryant <corey.bryant@canonical.com> Tue, 28 Jul 2020 20:33:41 -0400
+
python-openstackclient (5.2.0-0ubuntu1) focal; urgency=medium
* New upstream release for OpenStack Ussuri.
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index f599e28..0000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-10
diff --git a/debian/control b/debian/control
index 6c196a6..6fd01da 100644
--- a/debian/control
+++ b/debian/control
@@ -7,52 +7,70 @@ Uploaders:
gustavo panizzo <gfa@zumbi.com.ar>,
Thomas Goirand <zigo@debian.org>,
Build-Depends:
- debhelper (>= 10),
+ debhelper-compat (= 12),
dh-python,
- openstack-pkg-tools (>= 71),
- python-all,
- python-pbr (>= 2.0.0),
- python-setuptools,
+ openstack-pkg-tools,
python3-all,
python3-pbr (>= 2.0.0),
python3-setuptools,
- python3-sphinx (>= 1.6.5),
+ python3-sphinx (>= 2.0.0),
Build-Depends-Indep:
+ python3-aodhclient (>= 0.9.0),
python3-babel (>= 2.3.4),
+ python3-barbicanclient (>= 4.5.2),
python3-cinderclient (>= 1:3.3.0),
python3-cliff (>= 2.8.0),
python3-coverage (>= 4.0),
python3-crypto,
+ python3-designateclient (>= 2.7.0),
+ python3-ddt (>= 1.0.1),
python3-fixtures (>= 3.0.0),
+ python3-gnocchiclient (>= 3.3.1),
python3-hacking (>= 1.1.0),
+ python3-heatclient (>= 1.10.0),
+ python3-ironic-inspector-client (>= 1.5.0),
+ python3-ironicclient (>= 2.3.0),
+ python3-karborclient (>= 0.6.0),
python3-keystoneclient (>= 1:3.22.0),
+ python3-manilaclient (>= 2.0.0),
+ python3-mistralclient (>= 1:3.1.0),
python3-mock (>= 2.0.0),
+ python3-muranoclient (>= 0.8.2),
+ python3-neutronclient (>= 1:6.7.0),
python3-novaclient (>= 2:15.1.0),
- python3-openstackdocstheme (>= 1.23.2),
- python3-openstacksdk (>= 0.36.0),
+ python3-octaviaclient (>= 1.11.0),
+ python3-openstackdocstheme (>= 2.2.1),
+ python3-openstacksdk (>= 0.48.0),
python3-os-client-config (>= 1.28.0),
python3-osc-lib (>= 2.0.0),
+ python3-osc-placement (>= 1.7.0),
python3-oslo.i18n (>= 3.15.3),
python3-oslo.serialization (>= 1.2.0),
python3-oslo.utils (>= 3.33.0),
python3-oslotest (>= 1:3.2.0),
python3-osprofiler (>= 1.4.0),
- python3-reno (>= 2.5.0),
python3-requests (>= 2.14.2),
python3-requests-mock (>= 1.2.0),
+ python3-saharaclient (>= 1.4.0),
+ python3-searchlightclient (>= 1.0.0),
+ python3-senlinclient (>= 1.1.0),
python3-six (>= 1.10.0),
python3-sphinxcontrib.apidoc (>= 0.2.0),
python3-stestr (>= 1.0.0),
- python3-stevedore (>= 1:1.20.0),
+ python3-stevedore (>= 1:2.0.1),
python3-subunit,
python3-tempest (>= 1:17.1.0),
python3-testtools (>= 2.2.0),
+ python3-troveclient (>= 1:3.1.0),
+ python3-watcherclient (>= 2.5.0),
python3-wrapt (>= 1.7.0),
+ python3-zaqarclient (>= 1.0.0),
+ python3-zunclient (>= 3.6.0),
subunit,
-Standards-Version: 4.1.3
+Standards-Version: 4.5.0
Vcs-Browser: https://git.launchpad.net/~ubuntu-server-dev/ubuntu/+source/python-openstackclient
Vcs-Git: https://git.launchpad.net/~ubuntu-server-dev/ubuntu/+source/python-openstackclient
-Homepage: http://wiki.openstack.org/OpenStackClient
+Homepage: https://opendev.org/openstack/python-openstackclient
Testsuite: autopkgtest-pkg-python
Package: python-openstackclient-doc
@@ -83,13 +101,14 @@ Depends:
python3-crypto,
python3-keystoneclient (>= 1:3.22.0),
python3-novaclient (>= 2:15.1.0),
- python3-openstacksdk (>= 0.36.0),
+ python3-openstacksdk (>= 0.48.0),
python3-osc-lib (>= 2.0.0),
python3-oslo.i18n (>= 3.15.3),
python3-oslo.serialization (>= 1.2.0),
python3-oslo.utils (>= 3.33.0),
python3-pbr (>= 2.0.0),
python3-six (>= 1.10.0),
+ python3-stevedore (>= 1:2.0.1),
${misc:Depends},
${python3:Depends},
Recommends:
diff --git a/debian/copyright b/debian/copyright
index 9bbab65..8b9181e 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -1,6 +1,6 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: python-openstackclient
-Source: http://wiki.openstack.org/OpenStackClient
+Source: https://opendev.org/openstack/python-openstackclient
Files: *
Copyright: (c) 2013-2014, OpenStack Foundation <openstack-dev@lists.openstack.org>
diff --git a/debian/rules b/debian/rules
index 19a9125..efa4900 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,9 +1,11 @@
#!/usr/bin/make -f
+export PYBUILD_NAME=openstackclient
+
include /usr/share/openstack-pkg-tools/pkgos.make
%:
- dh $@ --with python3,sphinxdoc
+ dh $@ --buildsystem=pybuild --with python3,sphinxdoc
override_dh_auto_install:
pkgos-dh_auto_install --no-py2
@@ -24,7 +26,7 @@ override_dh_sphinxdoc:
ifeq (,$(findstring nodoc, $(DEB_BUILD_OPTIONS)))
sphinx-build -b man doc/source doc/build/man
PYTHONPATH=. sphinx-build -b html doc/source $(CURDIR)/debian/python-openstackclient-doc/usr/share/doc/python-openstackclient-doc/html
- dh_sphinxdoc -O--buildsystem=python3
+ dh_sphinxdoc -O--buildsystem=pybuild
endif
override_dh_installman:
diff --git a/doc/requirements.txt b/doc/requirements.txt
index 5cfc337..962b0e2 100644
--- a/doc/requirements.txt
+++ b/doc/requirements.txt
@@ -1,9 +1,9 @@
# 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.
-openstackdocstheme>=1.23.2 # Apache-2.0
-reno>=2.5.0 # Apache-2.0
-sphinx!=1.6.6,!=1.6.7,>=1.6.5 # BSD
+openstackdocstheme>=2.2.1 # Apache-2.0
+reno>=3.1.0 # Apache-2.0
+sphinx>=2.0.0,!=2.1.0 # BSD
sphinxcontrib-apidoc>=0.2.0 # BSD
# redirect tests in docs
@@ -14,12 +14,12 @@ aodhclient>=0.9.0 # Apache-2.0
gnocchiclient>=3.3.1 # Apache-2.0
osc-placement>=1.7.0 # Apache-2.0
python-barbicanclient>=4.5.2 # Apache-2.0
-python-congressclient<2000,>=1.9.0 # Apache-2.0
python-designateclient>=2.7.0 # Apache-2.0
python-heatclient>=1.10.0 # Apache-2.0
python-ironicclient>=2.3.0 # Apache-2.0
python-ironic-inspector-client>=1.5.0 # Apache-2.0
python-karborclient>=0.6.0 # Apache-2.0
+python-manilaclient>=2.0.0 # Apache-2.0
python-mistralclient!=3.2.0,>=3.1.0 # Apache-2.0
python-muranoclient>=0.8.2 # Apache-2.0
python-neutronclient>=6.7.0 # Apache-2.0
diff --git a/doc/source/_extra/.htaccess b/doc/source/_extra/.htaccess
index 513dedd..8c0a005 100644
--- a/doc/source/_extra/.htaccess
+++ b/doc/source/_extra/.htaccess
@@ -9,3 +9,8 @@ redirectmatch 301 ^/python-openstackclient/([^/]+)/specs/([^/.]+).html$ /python-
redirectmatch 301 ^/python-openstackclient/([^/]+)/(command-(beta|errors|logs|options|wrappers)|developing|humaninterfaceguide|plugins).html$ /python-openstackclient/$1/contributor/$2.html
redirectmatch 301 ^/python-openstackclient/([^/]+)/cli/plugin-commands.html$ /python-openstackclient/$1/cli/plugin-commands/index.html
+# For common subcommand names:
+# - identity pages were split into -v2 and -v3
+# - image pages were split into -v1 and -v2
+# The unversioned page is hidden but contains links to the versioned pages so links in the wild redirect somewhere sane.
+redirectmatch 301 ^/python-openstackclient/([^/]+)/cli/command-objects/(ec2-credentials|endpoint|image|project|role|service|token|user).html$ /python-openstackclient/$1/cli/_hidden/$2.html
diff --git a/doc/source/cli/_hidden/ec2-credentials.rst b/doc/source/cli/_hidden/ec2-credentials.rst
new file mode 100644
index 0000000..c54459d
--- /dev/null
+++ b/doc/source/cli/_hidden/ec2-credentials.rst
@@ -0,0 +1,13 @@
+===============
+ec2 credentials
+===============
+
+.. NOTE(efried): This page is hidden from the main TOC; it's here so links in
+ the wild redirect somewhere sane, because previously identity v2 and v3 were
+ combined in a single page.
+
+.. toctree::
+ :maxdepth: 2
+
+ ../command-objects/ec2-credentials-v2
+ ../command-objects/ec2-credentials-v3
diff --git a/doc/source/cli/_hidden/endpoint.rst b/doc/source/cli/_hidden/endpoint.rst
new file mode 100644
index 0000000..744e3ba
--- /dev/null
+++ b/doc/source/cli/_hidden/endpoint.rst
@@ -0,0 +1,13 @@
+========
+endpoint
+========
+
+.. NOTE(efried): This page is hidden from the main TOC; it's here so links in
+ the wild redirect somewhere sane, because previously identity v2 and v3 were
+ combined in a single page.
+
+.. toctree::
+ :maxdepth: 2
+
+ ../command-objects/endpoint-v2
+ ../command-objects/endpoint-v3
diff --git a/doc/source/cli/_hidden/image.rst b/doc/source/cli/_hidden/image.rst
new file mode 100644
index 0000000..85ffde6
--- /dev/null
+++ b/doc/source/cli/_hidden/image.rst
@@ -0,0 +1,13 @@
+=====
+image
+=====
+
+.. NOTE(efried): This page is hidden from the main TOC; it's here so links in
+ the wild redirect somewhere sane, because previously identity v2 and v3 were
+ combined in a single page.
+
+.. toctree::
+ :maxdepth: 2
+
+ ../command-objects/image-v1
+ ../command-objects/image-v2
diff --git a/doc/source/cli/_hidden/project.rst b/doc/source/cli/_hidden/project.rst
new file mode 100644
index 0000000..209a312
--- /dev/null
+++ b/doc/source/cli/_hidden/project.rst
@@ -0,0 +1,13 @@
+=======
+project
+=======
+
+.. NOTE(efried): This page is hidden from the main TOC; it's here so links in
+ the wild redirect somewhere sane, because previously identity v2 and v3 were
+ combined in a single page.
+
+.. toctree::
+ :maxdepth: 2
+
+ ../command-objects/project-v2
+ ../command-objects/project-v3
diff --git a/doc/source/cli/_hidden/role.rst b/doc/source/cli/_hidden/role.rst
new file mode 100644
index 0000000..c85f481
--- /dev/null
+++ b/doc/source/cli/_hidden/role.rst
@@ -0,0 +1,13 @@
+====
+role
+====
+
+.. NOTE(efried): This page is hidden from the main TOC; it's here so links in
+ the wild redirect somewhere sane, because previously identity v2 and v3 were
+ combined in a single page.
+
+.. toctree::
+ :maxdepth: 2
+
+ ../command-objects/role-v2
+ ../command-objects/role-v3
diff --git a/doc/source/cli/_hidden/service.rst b/doc/source/cli/_hidden/service.rst
new file mode 100644
index 0000000..8b33638
--- /dev/null
+++ b/doc/source/cli/_hidden/service.rst
@@ -0,0 +1,13 @@
+=======
+service
+=======
+
+.. NOTE(efried): This page is hidden from the main TOC; it's here so links in
+ the wild redirect somewhere sane, because previously identity v2 and v3 were
+ combined in a single page.
+
+.. toctree::
+ :maxdepth: 2
+
+ ../command-objects/service-v2
+ ../command-objects/service-v3
diff --git a/doc/source/cli/_hidden/token.rst b/doc/source/cli/_hidden/token.rst
new file mode 100644
index 0000000..6ebf801
--- /dev/null
+++ b/doc/source/cli/_hidden/token.rst
@@ -0,0 +1,13 @@
+=====
+token
+=====
+
+.. NOTE(efried): This page is hidden from the main TOC; it's here so links in
+ the wild redirect somewhere sane, because previously identity v2 and v3 were
+ combined in a single page.
+
+.. toctree::
+ :maxdepth: 2
+
+ ../command-objects/token-v2
+ ../command-objects/token-v3
diff --git a/doc/source/cli/_hidden/user.rst b/doc/source/cli/_hidden/user.rst
new file mode 100644
index 0000000..34eb599
--- /dev/null
+++ b/doc/source/cli/_hidden/user.rst
@@ -0,0 +1,13 @@
+====
+user
+====
+
+.. NOTE(efried): This page is hidden from the main TOC; it's here so links in
+ the wild redirect somewhere sane, because previously identity v2 and v3 were
+ combined in a single page.
+
+.. toctree::
+ :maxdepth: 2
+
+ ../command-objects/user-v2
+ ../command-objects/user-v3
diff --git a/doc/source/cli/command-objects/application-credentials.rst b/doc/source/cli/command-objects/application-credentials.rst
index 047f5ab..cef3ef0 100644
--- a/doc/source/cli/command-objects/application-credentials.rst
+++ b/doc/source/cli/command-objects/application-credentials.rst
@@ -8,109 +8,6 @@ With application credentials, a user can grant their applications limited
access to their cloud resources. Once created, users can authenticate with an
application credential by using the ``v3applicationcredential`` auth type.
-application credential create
------------------------------
-Create new application credential
-
-.. program:: application credential create
-.. code:: bash
-
- openstack application credential create
- [--secret <secret>]
- [--role <role>]
- [--expiration <expiration>]
- [--description <description>]
- [--restricted|--unrestricted]
- [--access-rules <access-rules>]
- <name>
-
-.. option:: --secret <secret>
-
- Secret to use for authentication (if not provided, one will be generated)
-
-.. option:: --role <role>
-
- Roles to authorize (name or ID) (repeat option to set multiple values)
-
-.. option:: --expiration <expiration>
-
- Sets an expiration date for the application credential (format of
- YYYY-mm-ddTHH:MM:SS)
-
-.. option:: --description <description>
-
- Application credential description
-
-.. option:: --unrestricted
-
- Enable application credential to create and delete other application
- credentials and trusts (this is potentially dangerous behavior and is
- disabled by default)
-
-.. option:: --restricted
-
- Prohibit application credential from creating and deleting other
- application credentials and trusts (this is the default behavior)
-
-.. option:: --access-rules
-
- Either a string or file path containing a JSON-formatted list of access
- rules, each containing a request method, path, and service, for example
- '[{"method": "GET", "path": "/v2.1/servers", "service": "compute"}]'
-
-.. describe:: <name>
-
- Name of the application credential
-
-
-application credential delete
------------------------------
-
-Delete application credential(s)
-
-.. program:: application credential delete
-.. code:: bash
-
- openstack application credential delete
- <application-credential> [<application-credential> ...]
-
-.. describe:: <application-credential>
-
- Application credential(s) to delete (name or ID)
-
-application credential list
----------------------------
-
-List application credentials
-
-.. program:: application credential list
-.. code:: bash
-
- openstack application credential list
- [--user <user>]
- [--user-domain <user-domain>]
-
-.. option:: --user
-
- User whose application credentials to list (name or ID)
-
-.. option:: --user-domain
-
- Domain the user belongs to (name or ID). This can be
- used in case collisions between user names exist.
-
-application credential show
----------------------------
-
-Display application credential details
-
-.. program:: application credential show
-.. code:: bash
-
- openstack application credential show
- <application-credential>
-
-.. describe:: <application-credential>
-
- Application credential to display (name or ID)
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: application credential *
diff --git a/doc/source/cli/command-objects/catalog.rst b/doc/source/cli/command-objects/catalog.rst
index 6db8227..84cd160 100644
--- a/doc/source/cli/command-objects/catalog.rst
+++ b/doc/source/cli/command-objects/catalog.rst
@@ -6,7 +6,4 @@ A **catalog** lists OpenStack services that are available on the cloud.
Applicable to Identity v2 and v3
.. autoprogram-cliff:: openstack.identity.v3
- :command: catalog list
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: catalog show
+ :command: catalog *
diff --git a/doc/source/cli/command-objects/consumer.rst b/doc/source/cli/command-objects/consumer.rst
index 8f6dda0..17cfc0c 100644
--- a/doc/source/cli/command-objects/consumer.rst
+++ b/doc/source/cli/command-objects/consumer.rst
@@ -7,16 +7,4 @@ is used to create a **request token** and **access token**. Applicable to
Identity v3.
.. autoprogram-cliff:: openstack.identity.v3
- :command: consumer create
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: consumer delete
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: consumer list
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: consumer set
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: consumer show
+ :command: consumer *
diff --git a/doc/source/cli/command-objects/credential.rst b/doc/source/cli/command-objects/credential.rst
index 7fe5731..f490f1c 100644
--- a/doc/source/cli/command-objects/credential.rst
+++ b/doc/source/cli/command-objects/credential.rst
@@ -4,125 +4,5 @@ credential
Identity v3
-credential create
------------------
-
-Create new credential
-
-.. program:: credential create
-.. code:: bash
-
- openstack credential create
- [--type <type>]
- [--project <project>]
- <user> <data>
-
-.. option:: --type <type>
-
- New credential type: cert, ec2, totp and so on
-
-.. option:: --project <project>
-
- Project which limits the scope of the credential (name or ID)
-
-.. _credential_create:
-.. describe:: <user>
-
- User that owns the credential (name or ID)
-
-.. describe:: <data>
-
- New credential data
-
-credential delete
------------------
-
-Delete credential(s)
-
-.. program:: credential delete
-.. code:: bash
-
- openstack credential delete
- <credential-id> [<credential-id> ...]
-
-.. _credential_delete:
-.. describe:: <credential-id>
-
- ID(s) of credential to delete
-
-credential list
----------------
-
-List credentials
-
-.. program:: credential list
-.. code:: bash
-
- openstack credential list
- [--user <user> [--user-domain <user-domain>]]
- [--type <type>]
-
-.. option:: --user <user>
-
- Filter credentials by <user> (name or ID)
-
-.. option:: --user-domain <user-domain>
-
- Domain the user belongs to (name or ID). This can be
- used in case collisions between user names exist.
-
-.. option:: --type <type>
-
- Filter credentials by type: cert, ec2, totp and so on
-
-credential set
---------------
-
-Set credential properties
-
-.. program:: credential set
-.. code:: bash
-
- openstack credential set
- [--user <user>]
- [--type <type>]
- [--data <data>]
- [--project <project>]
- <credential-id>
-
-.. option:: --user <user>
-
- User that owns the credential (name or ID)
-
-.. option:: --type <type>
-
- New credential type: cert, ec2, totp and so on.
-
-.. option:: --data <data>
-
- New credential data
-
-.. option:: --project <project>
-
- Project which limits the scope of the credential (name or ID)
-
-.. _credential_set:
-.. describe:: <credential-id>
-
- ID of credential to change
-
-credential show
----------------
-
-Display credential details
-
-.. program:: credential show
-.. code:: bash
-
- openstack credential show
- <credential-id>
-
-.. _credential_show:
-.. describe:: <credential-id>
-
- ID of credential to display
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: credential *
diff --git a/doc/source/cli/command-objects/ec2-credentials-v2.rst b/doc/source/cli/command-objects/ec2-credentials-v2.rst
new file mode 100644
index 0000000..ace3d84
--- /dev/null
+++ b/doc/source/cli/command-objects/ec2-credentials-v2.rst
@@ -0,0 +1,6 @@
+=============================
+ec2 credentials (Identity v2)
+=============================
+
+.. autoprogram-cliff:: openstack.identity.v2
+ :command: ec2 credentials *
diff --git a/doc/source/cli/command-objects/ec2-credentials-v3.rst b/doc/source/cli/command-objects/ec2-credentials-v3.rst
new file mode 100644
index 0000000..761d428
--- /dev/null
+++ b/doc/source/cli/command-objects/ec2-credentials-v3.rst
@@ -0,0 +1,6 @@
+=============================
+ec2 credentials (Identity v3)
+=============================
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: ec2 credentials *
diff --git a/doc/source/cli/command-objects/ec2-credentials.rst b/doc/source/cli/command-objects/ec2-credentials.rst
deleted file mode 100644
index 9174b04..0000000
--- a/doc/source/cli/command-objects/ec2-credentials.rst
+++ /dev/null
@@ -1,138 +0,0 @@
-===============
-ec2 credentials
-===============
-
-Identity v2
-
-ec2 credentials create
-----------------------
-
-Create EC2 credentials
-
-.. program:: ec2 credentials create
-.. code-block:: bash
-
- openstack ec2 credentials create
- [--project <project>]
- [--user <user>]
- [--user-domain <user-domain>]
- [--project-domain <project-domain>]
-
-.. option:: --project <project>
-
- Create credentials in project (name or ID; default: current authenticated project)
-
-.. option:: --user <user>
-
- Create credentials for user (name or ID; default: current authenticated user)
-
-.. option:: --user-domain <user-domain>
-
- Domain the user belongs to (name or ID). This can be
- used in case collisions between user names exist.
-
- .. versionadded:: 3
-
-.. option:: --project-domain <project-domain>
-
- Domain the project belongs to (name or ID). This can be
- used in case collisions between user names exist.
-
- .. versionadded:: 3
-
-The :option:`--project` and :option:`--user` options are typically only
-useful for admin users, but may be allowed for other users depending on
-the policy of the cloud and the roles granted to the user.
-
-ec2 credentials delete
-----------------------
-
-Delete EC2 credentials
-
-.. program:: ec2 credentials delete
-.. code-block:: bash
-
- openstack ec2 credentials delete
- [--user <user>]
- [--user-domain <user-domain>]
- <access-key> [<access-key> ...]
-
-.. option:: --user <user>
-
- Delete credentials for user (name or ID)
-
-.. option:: --user-domain <user-domain>
-
- Select user from a specific domain (name or ID)
- This can be used in case collisions between user names exist.
-
- .. versionadded:: 3
-
-.. _ec2_credentials_delete-access-key:
-.. describe:: access-key
-
- Credentials access key(s)
-
-The :option:`--user` option is typically only useful for admin users, but
-may be allowed for other users depending on the policy of the cloud and
-the roles granted to the user.
-
-ec2 credentials list
---------------------
-
-List EC2 credentials
-
-.. program:: ec2 credentials list
-.. code-block:: bash
-
- openstack ec2 credentials list
- [--user <user>]
- [--user-domain <user-domain>]
-
-.. option:: --user <user>
-
- Filter list by <user> (name or ID)
-
-.. option:: --user-domain <user-domain>
-
- Select user from a specific domain (name or ID)
- This can be used in case collisions between user names exist.
-
- .. versionadded:: 3
-
-The :option:`--user` option is typically only useful for admin users, but
-may be allowed for other users depending on the policy of the cloud and
-the roles granted to the user.
-
-ec2 credentials show
---------------------
-
-Display EC2 credentials details
-
-.. program:: ec2 credentials show
-.. code-block:: bash
-
- openstack ec2 credentials show
- [--user <user>]
- [--user-domain <user-domain>]
- <access-key>
-
-.. option:: --user <user>
-
- Show credentials for user (name or ID)
-
-.. option:: --user-domain <user-domain>
-
- Select user from a specific domain (name or ID)
- This can be used in case collisions between user names exist.
-
- .. versionadded:: 3
-
-.. _ec2_credentials_show-access-key:
-.. describe:: access-key
-
- Credentials access key
-
-The :option:`--user` option is typically only useful for admin users, but
-may be allowed for other users depending on the policy of the cloud and
-the roles granted to the user.
diff --git a/doc/source/cli/command-objects/endpoint-v2.rst b/doc/source/cli/command-objects/endpoint-v2.rst
new file mode 100644
index 0000000..7badfd4
--- /dev/null
+++ b/doc/source/cli/command-objects/endpoint-v2.rst
@@ -0,0 +1,6 @@
+======================
+endpoint (Identity v2)
+======================
+
+.. autoprogram-cliff:: openstack.identity.v2
+ :command: endpoint *
diff --git a/doc/source/cli/command-objects/endpoint-v3.rst b/doc/source/cli/command-objects/endpoint-v3.rst
new file mode 100644
index 0000000..f12063f
--- /dev/null
+++ b/doc/source/cli/command-objects/endpoint-v3.rst
@@ -0,0 +1,24 @@
+======================
+endpoint (Identity v3)
+======================
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: endpoint add project
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: endpoint create
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: endpoint delete
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: endpoint list
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: endpoint remove project
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: endpoint set
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: endpoint show
diff --git a/doc/source/cli/command-objects/endpoint.rst b/doc/source/cli/command-objects/endpoint.rst
deleted file mode 100644
index 6d02532..0000000
--- a/doc/source/cli/command-objects/endpoint.rst
+++ /dev/null
@@ -1,275 +0,0 @@
-========
-endpoint
-========
-
-Identity v2, v3
-
-endpoint add project
---------------------
-
-Associate a project to an endpoint for endpoint filtering
-
-.. program:: endpoint add project
-.. code:: bash
-
- openstack endpoint add project
- [--project-domain <project-domain>]
- <endpoint>
- <project>
-
-.. option:: --project-domain <project-domain>
-
- Domain the project belongs to (name or ID).
- This can be used in case collisions between project names exist.
-
-.. _endpoint_add_project-endpoint:
-.. describe:: <endpoint>
-
- Endpoint to associate with specified project (name or ID)
-
-.. _endpoint_add_project-project:
-.. describe:: <project>
-
- Project to associate with specified endpoint (name or ID)
-
-endpoint create
----------------
-
-Create new endpoint
-
-*Identity version 2 only*
-
-.. program:: endpoint create (v2)
-.. code:: bash
-
- openstack endpoint create
- --publicurl <url>
- [--adminurl <url>]
- [--internalurl <url>]
- [--region <region-id>]
- <service>
-
-.. option:: --publicurl <url>
-
- New endpoint public URL (required)
-
-.. option:: --adminurl <url>
-
- New endpoint admin URL
-
-.. option:: --internalurl <url>
-
- New endpoint internal URL
-
-.. option:: --region <region-id>
-
- New endpoint region ID
-
-.. _endpoint_create-endpoint:
-.. describe:: <service>
-
- Service to be associated with new endpoint (name or ID)
-
-*Identity version 3 only*
-
-.. program:: endpoint create (v3)
-.. code:: bash
-
- openstack endpoint create
- [--region <region-id>]
- [--enable | --disable]
- <service>
- <interface>
- <url>
-
-.. option:: --region <region-id>
-
- New endpoint region ID
-
-.. option:: --enable
-
- Enable endpoint (default)
-
-.. option:: --disable
-
- Disable endpoint
-
-.. describe:: <service>
-
- Service to be associated with new endpoint(name or ID)
-
-.. describe:: <interface>
-
- New endpoint interface type (admin, public or internal)
-
-.. describe:: <url>
-
- New endpoint URL
-
-endpoint delete
----------------
-
-Delete endpoint(s)
-
-.. program:: endpoint delete
-.. code:: bash
-
- openstack endpoint delete
- <endpoint-id> [<endpoint-id> ...]
-
-.. _endpoint_delete-endpoint:
-.. describe:: <endpoint-id>
-
- Endpoint(s) to delete (ID only)
-
-endpoint list
--------------
-
-List endpoints
-
-.. program:: endpoint list
-.. code:: bash
-
- openstack endpoint list
- [--service <service>]
- [--interface <interface>]
- [--region <region-id>]
- [--long]
- [--endpoint <endpoint> |
- --project <project> [--project-domain <project-domain>]]
-
-.. option:: --service <service>
-
- Filter by service (type, name or ID)
-
- *Identity version 3 only*
-
-.. option:: --interface <interface>
-
- Filter by interface type (admin, public or internal)
-
- *Identity version 3 only*
-
-.. option:: --region <region-id>
-
- Filter by region ID
-
- *Identity version 3 only*
-
-.. option:: --long
-
- List additional fields in output
-
- *Identity version 2 only*
-
-.. option:: --endpoint
-
- List projects that have access to that endpoint using
- endpoint filtering
-
- *Identity version 3 only*
-
-.. option:: --project
-
- List endpoints available for the project using
- endpoint filtering
-
- *Identity version 3 only*
-
-.. option:: --project-domain
-
- Domain the project belongs to (name or ID).
- This can be used in case collisions between project names exist.
-
- *Identity version 3 only*
-
-endpoint remove project
------------------------
-
-Dissociate a project from an endpoint.
-
-.. program:: endpoint remove project
-.. code:: bash
-
- openstack endpoint remove project
- [--project-domain <project-domain>]
- <endpoint>
- <project>
-
-.. option:: --project-domain <project-domain>
-
- Domain the project belongs to (name or ID).
- This can be used in case collisions between project names exist.
-
-.. _endpoint_remove_project-endpoint:
-.. describe:: <endpoint>
-
- Endpoint to dissociate with specified project (name or ID)
-
-.. _endpoint_remove_project-project:
-.. describe:: <project>
-
- Project to dissociate with specified endpoint (name or ID)
-
-endpoint set
-------------
-
-Set endpoint properties
-
-*Identity version 3 only*
-
-.. program:: endpoint set
-.. code:: bash
-
- openstack endpoint set
- [--region <region-id>]
- [--interface <interface>]
- [--url <url>]
- [--service <service>]
- [--enable | --disable]
- <endpoint-id>
-
-.. option:: --region <region-id>
-
- New endpoint region ID
-
-.. option:: --interface <interface>
-
- New endpoint interface type (admin, public or internal)
-
-.. option:: --url <url>
-
- New endpoint URL
-
-.. option:: --service <service>
-
- New endpoint service (name or ID)
-
-.. option:: --enable
-
- Enable endpoint
-
-.. option:: --disable
-
- Disable endpoint
-
-.. _endpoint_set-endpoint:
-.. describe:: <endpoint-id>
-
- Endpoint to modify (ID only)
-
-endpoint show
--------------
-
-Display endpoint details
-
-.. program:: endpoint show
-.. code:: bash
-
- openstack endpoint show
- <endpoint>
-
-.. _endpoint_show-endpoint:
-.. describe:: <endpoint>
-
- Endpoint to display (endpoint ID, service ID, service name, service type)
diff --git a/doc/source/cli/command-objects/endpoint_group.rst b/doc/source/cli/command-objects/endpoint_group.rst
index ccfe5f6..b0d988e 100644
--- a/doc/source/cli/command-objects/endpoint_group.rst
+++ b/doc/source/cli/command-objects/endpoint_group.rst
@@ -7,22 +7,4 @@ can be used to filter the endpoints that are available to a project.
Applicable to Identity v3
.. autoprogram-cliff:: openstack.identity.v3
- :command: endpoint group add project
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: endpoint group create
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: endpoint group delete
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: endpoint group list
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: endpoint group remove project
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: endpoint group set
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: endpoint group show
+ :command: endpoint group *
diff --git a/doc/source/cli/command-objects/federation-domain-project.rst b/doc/source/cli/command-objects/federation-domain-project.rst
new file mode 100644
index 0000000..68db570
--- /dev/null
+++ b/doc/source/cli/command-objects/federation-domain-project.rst
@@ -0,0 +1,11 @@
+=========================
+federation domain/project
+=========================
+
+Identity v3
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: federation domain *
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: federation project *
diff --git a/doc/source/cli/command-objects/federation-protocol.rst b/doc/source/cli/command-objects/federation-protocol.rst
index 3a99fd7..81b3f9f 100644
--- a/doc/source/cli/command-objects/federation-protocol.rst
+++ b/doc/source/cli/command-objects/federation-protocol.rst
@@ -7,16 +7,4 @@ extension. It is used by **identity providers** and **mappings**. Applicable to
Identity v3.
.. autoprogram-cliff:: openstack.identity.v3
- :command: federation protocol create
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: federation protocol delete
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: federation protocol list
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: federation protocol set
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: federation protocol show
+ :command: federation protocol *
diff --git a/doc/source/cli/command-objects/group.rst b/doc/source/cli/command-objects/group.rst
index ac938ef..a107106 100644
--- a/doc/source/cli/command-objects/group.rst
+++ b/doc/source/cli/command-objects/group.rst
@@ -4,246 +4,5 @@ group
Identity v3
-group add user
---------------
-
-Add user to group
-
-.. program:: group add user
-.. code:: bash
-
- openstack group add user
- [--group-domain <group-domain>]
- [--user-domain <user-domain>]
- <group>
- <user> [<user> ...]
-
-.. option:: --group-domain <group-domain>
-
- Domain the group belongs to (name or ID). This can be
- used in case collisions between group names exist.
-
- .. versionadded:: 3
-
-.. option:: --user-domain <user-domain>
-
- Domain the user belongs to (name or ID). This can be
- used in case collisions between user names exist.
-
- .. versionadded:: 3
-
-.. describe:: <group>
-
- Group to contain <user> (name or ID)
-
-.. describe:: <user>
-
- User(s) to add to <group> (name or ID)
- (repeat option to add multiple users)
-
-group contains user
--------------------
-
-Check user membership in group
-
-.. program:: group contains user
-.. code:: bash
-
- openstack group contains user
- [--group-domain <group-domain>]
- [--user-domain <user-domain>]
- <group>
- <user>
-
-.. option:: --group-domain <group-domain>
-
- Domain the group belongs to (name or ID). This can be
- used in case collisions between group names exist.
-
- .. versionadded:: 3
-
-.. option:: --user-domain <user-domain>
-
- Domain the user belongs to (name or ID). This can be
- used in case collisions between user names exist.
-
- .. versionadded:: 3
-
-.. describe:: <group>
-
- Group to check (name or ID)
-
-.. describe:: <user>
-
- User to check (name or ID)
-
-group create
-------------
-
-Create new group
-
-.. program:: group create
-.. code:: bash
-
- openstack group create
- [--domain <domain>]
- [--description <description>]
- [--or-show]
- <group-name>
-
-.. option:: --domain <domain>
-
- Domain to contain new group (name or ID)
-
-.. option:: --description <description>
-
- New group description
-
-.. option:: --or-show
-
- Return existing group
-
- If the group already exists, return the existing group data and do not fail.
-
-.. describe:: <group-name>
-
- New group name
-
-group delete
-------------
-
-Delete group
-
-.. program:: group delete
-.. code:: bash
-
- openstack group delete
- [--domain <domain>]
- <group> [<group> ...]
-
-.. option:: --domain <domain>
-
- Domain containing group(s) (name or ID)
-
-.. describe:: <group>
-
- Group(s) to delete (name or ID)
-
-group list
-----------
-
-List groups
-
-.. program:: group list
-.. code:: bash
-
- openstack group list
- [--domain <domain>]
- [--user <user> [--user-domain <user-domain>]]
- [--long]
-
-.. option:: --domain <domain>
-
- Filter group list by <domain> (name or ID)
-
-.. option:: --user <user>
-
- Filter group list by <user> (name or ID)
-
-.. option:: --user-domain <user-domain>
-
- Domain the user belongs to (name or ID). This can be
- used in case collisions between user names exist.
-
- .. versionadded:: 3
-
-.. option:: --long
-
- List additional fields in output
-
-group remove user
------------------
-
-Remove user from group
-
-.. program:: group remove user
-.. code:: bash
-
- openstack group remove user
- [--group-domain <group-domain>]
- [--user-domain <user-domain>]
- <group>
- <user> [<user> ...]
-
-.. option:: --group-domain <group-domain>
-
- Domain the group belongs to (name or ID). This can be
- used in case collisions between group names exist.
-
- .. versionadded:: 3
-
-.. option:: --user-domain <user-domain>
-
- Domain the user belongs to (name or ID). This can be
- used in case collisions between user names exist.
-
- .. versionadded:: 3
-
-.. describe:: <group>
-
- Group containing <user> (name or ID)
-
-.. describe:: <user>
-
- User(s) to remove from <group> (name or ID)
- (repeat option to remove multiple users)
-
-group set
----------
-
-Set group properties
-
-.. program:: group set
-.. code:: bash
-
- openstack group set
- [--domain <domain>]
- [--name <name>]
- [--description <description>]
- <group>
-
-.. option:: --domain <domain>
-
- Domain containing <group> (name or ID)
-
-.. option:: --name <name>
-
- New group name
-
-.. option:: --description <description>
-
- New group description
-
-.. describe:: <group>
-
- Group to modify (name or ID)
-
-group show
-----------
-
-Display group details
-
-.. program:: group show
-.. code:: bash
-
- openstack group show
- [--domain <domain>]
- <group>
-
-.. option:: --domain <domain>
-
- Domain containing <group> (name or ID)
-
-.. describe:: <group>
-
- Group to display (name or ID)
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: group *
diff --git a/doc/source/cli/command-objects/identity-provider.rst b/doc/source/cli/command-objects/identity-provider.rst
index 36c9264..ed85cb7 100644
--- a/doc/source/cli/command-objects/identity-provider.rst
+++ b/doc/source/cli/command-objects/identity-provider.rst
@@ -7,16 +7,4 @@ extension. It is used by **federation protocols** and **mappings**. Applicable
to Identity v3.
.. autoprogram-cliff:: openstack.identity.v3
- :command: identity provider create
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: identity provider delete
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: identity provider list
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: identity provider set
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: identity provider show
+ :command: identity provider *
diff --git a/doc/source/cli/command-objects/image-v1.rst b/doc/source/cli/command-objects/image-v1.rst
new file mode 100644
index 0000000..4f7edc4
--- /dev/null
+++ b/doc/source/cli/command-objects/image-v1.rst
@@ -0,0 +1,6 @@
+========
+image v1
+========
+
+.. autoprogram-cliff:: openstack.image.v1
+ :command: image *
diff --git a/doc/source/cli/command-objects/image-v2.rst b/doc/source/cli/command-objects/image-v2.rst
new file mode 100644
index 0000000..473b26d
--- /dev/null
+++ b/doc/source/cli/command-objects/image-v2.rst
@@ -0,0 +1,6 @@
+========
+image v2
+========
+
+.. autoprogram-cliff:: openstack.image.v2
+ :command: image *
diff --git a/doc/source/cli/command-objects/image.rst b/doc/source/cli/command-objects/image.rst
deleted file mode 100644
index 459a077..0000000
--- a/doc/source/cli/command-objects/image.rst
+++ /dev/null
@@ -1,650 +0,0 @@
-=====
-image
-=====
-
-Image v1, v2
-
-image add project
------------------
-
-*Only supported for Image v2*
-
-Associate project with image
-
-.. program:: image add project
-.. code:: bash
-
- openstack image add project
- [--project-domain <project-domain>]
- <image>
- <project>
-
-.. option:: --project-domain <project-domain>
-
- Domain the project belongs to (name or ID).
- This can be used in case collisions between project names exist.
-
-.. _image_add_project-image:
-.. describe:: <image>
-
- Image to share (name or ID).
-
-.. _image_add_project-project:
-.. describe:: <project>
-
- Project to associate with image (ID)
-
-image create
-------------
-
-*Image v1, v2*
-
-Create/upload an image
-
-.. program:: image create
-.. code:: bash
-
- openstack image create
- [--id <id>]
- [--store <store>]
- [--container-format <container-format>]
- [--disk-format <disk-format>]
- [--size <size>]
- [--min-disk <disk-gb>]
- [--min-ram <ram-mb>]
- [--location <image-url>]
- [--copy-from <image-url>]
- [--file <file> | --volume <volume>]
- [--force]
- [--checksum <checksum>]
- [--protected | --unprotected]
- [--public | --private | --community | --shared]
- [--property <key=value> [...] ]
- [--tag <tag> [...] ]
- [--project <project>]
- [--project-domain <project-domain>]
- <image-name>
-
-.. option:: --id <id>
-
- Image ID to reserve
-
-.. option:: --store <store>
-
- Upload image to this store
-
- *Image version 1 only.*
-
-.. option:: --container-format <container-format>
-
- Image container format. The supported options are: ami, ari, aki,
- bare, docker, ova, ovf. The default format is: bare
-
-.. option:: --disk-format <disk-format>
-
- Image disk format. The supported options are: ami, ari, aki, vhd, vmdk,
- raw, qcow2, vhdx, vdi, iso, and ploop. The default format is: raw
-
-.. option:: --size <size>
-
- Image size, in bytes (only used with :option:`--location` and :option:`--copy-from`)
-
- *Image version 1 only.*
-
-.. option:: --min-disk <disk-gb>
-
- Minimum disk size needed to boot image, in gigabytes
-
-.. option:: --min-ram <ram-mb>
-
- Minimum RAM size needed to boot image, in megabytes
-
-.. option:: --location <image-url>
-
- Download image from an existing URL
-
- *Image version 1 only.*
-
-.. option:: --copy-from <image-url>
-
- Copy image from the data store (similar to :option:`--location`)
-
- *Image version 1 only.*
-
-.. option:: --file <file>
-
- Upload image from local file
-
-.. option:: --volume <volume>
-
- Create image from a volume
-
-.. option:: --force
-
- Force image creation if volume is in use (only meaningful with :option:`--volume`)
-
-.. option:: --checksum <checksum>
-
- Image hash used for verification
-
- *Image version 1 only.*
-
-.. option:: --protected
-
- Prevent image from being deleted
-
-.. option:: --unprotected
-
- Allow image to be deleted (default)
-
-.. option:: --public
-
- Image is accessible to the public
-
-.. option:: --private
-
- Image is inaccessible to the public (default)
-
-.. option:: --community
-
- Image is accessible to the community
-
-.. option:: --shared
-
- Image can be shared
-
-.. option:: --property <key=value>
-
- Set a property on this image (repeat option to set multiple properties)
-
-.. option:: --tag <tag>
-
- Set a tag on this image (repeat option to set multiple tags)
-
- .. 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
-
-.. _image_create-image-name:
-.. describe:: <image-name>
-
- New image name
-
-image delete
-------------
-
-Delete image(s)
-
-.. program:: image delete
-.. code:: bash
-
- openstack image delete
- <image>
-
-.. _image_delete-image:
-.. describe:: <image>
-
- Image(s) to delete (name or ID)
-
-image list
-----------
-
-List available images
-
-.. program:: image list
-.. code:: bash
-
- openstack image list
- [--public | --private | --community | --shared]
- [--property <key=value>]
- [--name <name>]
- [--status <status>]
- [--member-status <member-status>]
- [--tag <tag>]
- [--long]
- [--sort <key>[:<direction>]]
- [--limit <num-images>]
- [--marker <image>]
-
-.. option:: --public
-
- List only public images
-
-.. option:: --private
-
- List only private images
-
-.. option:: --community
-
- List only community images
-
- *Image version 2 only.*
-
-.. option:: --shared
-
- List only shared images
-
- *Image version 2 only.*
-
-.. option:: --property <key=value>
-
- Filter output based on property
-
-.. option:: --name <name>
-
- Filter images based on name
-
- *Image version 2 only.*
-
-.. option:: --status <status>
-
- Filter images based on status
-
- *Image version 2 only*
-
-.. option:: --member-status <member-status>
-
- Filter images based on member status
-
- *Image version 2 only*
-
-.. option:: --tag <tag>
-
- Filter images based on tag
-
- *Image version 2 only*
-
-.. option:: --long
-
- List additional fields in output
-
-.. option:: --sort <key>[:<direction>]
-
- Sort output by selected keys and directions(asc or desc) (default: name:asc),
- multiple keys and directions can be specified separated by comma
-
-.. option:: --limit <num-images>
-
- Maximum number of images to display.
-
- *Image version 2 only*
-
-.. option:: --marker <image>
-
- The last image of the previous page. Display list of images
- after marker. Display all images if not specified. (name or ID)
-
- *Image version 2 only*
-
-image member list
------------------
-
-List projects associated with image
-
-.. program:: image member list
-.. code:: bash
-
- openstack image member list
- <image>
-
-.. _image_member_list-image:
-.. describe:: <image>
-
- Image(s) to view members for (name or ID)
-
-image remove project
---------------------
-
-*Only supported for Image v2*
-
-Disassociate project with image
-
-.. program:: image remove project
-.. code:: bash
-
- openstack image remove project
- [--project-domain <project-domain>]
- <image>
- <project>
-
-.. option:: --project-domain <project-domain>
-
- Domain the project belongs to (name or ID).
- This can be used in case collisions between project names exist.
-
-.. _image_remove_project:
-.. describe:: <image>
-
- Image to unshare (name or ID).
-
-.. describe:: <project>
-
- Project to disassociate with image (name or ID)
-
-image save
-----------
-
-Save an image locally
-
-.. program:: image save
-.. code:: bash
-
- openstack image save
- --file <filename>
- <image>
-
-.. option:: --file <filename>
-
- Downloaded image save filename (default: stdout)
-
-.. _image_save-image:
-.. describe:: <image>
-
- Image to save (name or ID)
-
-image set
----------
-
-*Image v1, v2*
-
-Set image properties
-
-.. program:: image set
-.. code:: bash
-
- openstack image set
- [--name <name>]
- [--min-disk <disk-gb>]
- [--min-ram <ram-mb>]
- [--container-format <container-format>]
- [--disk-format <disk-format>]
- [--size <size>]
- [--protected | --unprotected]
- [--public | --private | --community | --shared]
- [--store <store>]
- [--location <image-url>]
- [--copy-from <image-url>]
- [--file <file>]
- [--volume <volume>]
- [--force]
- [--checksum <checksum>]
- [--stdin]
- [--property <key=value> [...] ]
- [--tag <tag> [...] ]
- [--architecture <architecture>]
- [--instance-id <instance-id>]
- [--kernel-id <kernel-id>]
- [--os-distro <os-distro>]
- [--os-version <os-version>]
- [--ramdisk-id <ramdisk-id>]
- [--deactivate | --activate]
- [--project <project>]
- [--project-domain <project-domain>]
- [--accept | --reject | --pending]
- <image>
-
-.. option:: --name <name>
-
- New image name
-
-.. option:: --min-disk <disk-gb>
-
- Minimum disk size needed to boot image, in gigabytes
-
-.. option:: --min-ram <ram-mb>
-
- Minimum RAM size needed to boot image, in megabytes
-
-.. option:: --container-format <container-format>
-
- Image container format. The supported options are: ami, ari, aki,
- bare, docker, ova, ovf.
-
-.. option:: --disk-format <disk-format>
-
- Image disk format. The supported options are: ami, ari, aki, vhd, vmdk,
- raw, qcow2, vhdx, vdi, iso, and ploop.
-
-.. option:: --size <size>
-
- Size of image data (in bytes)
-
- *Image version 1 only.*
-
-.. option:: --protected
-
- Prevent image from being deleted
-
-.. option:: --unprotected
-
- Allow image to be deleted (default)
-
-.. option:: --public
-
- Image is accessible to the public
-
-.. option:: --private
-
- Image is inaccessible to the public (default)
-
-.. option:: --community
-
- Image is accessible to the community
-
-.. option:: --shared
-
- Image can be shared
-
-.. option:: --store <store>
-
- Upload image to this store
-
- *Image version 1 only.*
-
-.. option:: --location <image-url>
-
- Download image from an existing URL
-
- *Image version 1 only.*
-
-.. option:: --copy-from <image-url>
-
- Copy image from the data store (similar to :option:`--location`)
-
- *Image version 1 only.*
-
-.. option:: --file <file>
-
- Upload image from local file
-
- *Image version 1 only.*
-
-.. option:: --volume <volume>
-
- Update image with a volume
-
- *Image version 1 only.*
-
-.. option:: --force
-
- Force image update if volume is in use (only meaningful with :option:`--volume`)
-
- *Image version 1 only.*
-
-.. option:: --checksum <checksum>
-
- Image hash used for verification
-
- *Image version 1 only.*
-
-.. option:: --stdin
-
- Allow to read image data from standard input
-
- *Image version 1 only.*
-
-.. option:: --property <key=value>
-
- Set a property on this image (repeat option to set multiple properties)
-
- .. versionadded:: 2
-
-.. option:: --tag <tag>
-
- Set a tag on this image (repeat option to set multiple tags)
-
- .. versionadded:: 2
-
-.. option:: --architecture <architecture>
-
- Operating system architecture
-
- .. versionadded:: 2
-
-.. option:: --instance-id <instance-id>
-
- ID of server instance used to create this image
-
- .. versionadded:: 2
-
-.. option:: --kernel-id <kernel-id>
-
- ID of kernel image used to boot this disk image
-
- .. versionadded:: 2
-
-.. option:: --os-distro <os-distro>
-
- Operating system distribution name
-
- .. versionadded:: 2
-
-.. option:: --os-version <os-version>
-
- Operating system distribution version
-
- .. versionadded:: 2
-
-.. option:: --ramdisk-id <ramdisk-id>
-
- ID of ramdisk image used to boot this disk image
-
- .. versionadded:: 2
-
-.. option:: --deactivate
-
- Deactivate the image.
-
- .. versionadded:: 2
-
-.. option:: --activate
-
- Activate 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
-
-.. option:: --accept
-
- Accept the image membership.
-
- If `--project` is passed, this will update the membership status for the
- given project, otherwise `--project` will default to the project the user
- is authenticated to.
-
- .. versionadded:: 2
-
-.. option:: --reject
-
- Reject the image membership.
-
- If `--project` is passed, this will update the membership status for the
- given project, otherwise `--project` will default to the project the user
- is authenticated to.
-
- .. versionadded:: 2
-
-.. option:: --pending
-
- Reset the image membership to 'pending'.
-
- If `--project` is passed, this will update the membership status for the
- given project, otherwise `--project` will default to the project the user
- is authenticated to.
-
- .. versionadded:: 2
-
-.. _image_set-image:
-.. describe:: <image>
-
- Image to modify (name or ID)
-
-image show
-----------
-
-Display image details
-
-.. program:: image show
-.. code:: bash
-
- openstack image show
- [--human-readable]
- <image>
-
-.. option:: --human-readable
-
- Print image size in a human-friendly format.
-
-.. _image_show-image:
-.. describe:: <image>
-
- Image to display (name or ID)
-
-image unset
------------
-
-*Only supported for Image v2*
-
-Unset image tags or properties
-
-.. program:: image unset
-.. code:: bash
-
- openstack image unset
- [--tag <tag>]
- [--property <property-key>]
- <image>
-
-.. option:: --tag <tag>
-
- Unset a tag on this image (repeat option to unset multiple tags)
-
-.. option:: --property <property-key>
-
- Unset a property on this image (repeat option to unset multiple properties)
-
-.. _image_unset-image:
-.. describe:: <image>
-
- Image to modify (name or ID)
diff --git a/doc/source/cli/command-objects/implied_role.rst b/doc/source/cli/command-objects/implied_role.rst
index e43c9ea..09532c0 100644
--- a/doc/source/cli/command-objects/implied_role.rst
+++ b/doc/source/cli/command-objects/implied_role.rst
@@ -4,54 +4,5 @@ implied role
Identity v3
-
-implied role create
--------------------
-
-Creates an association between prior and implied roles
-
-.. program:: implied role create
-.. code:: bash
-
- openstack implied role create
- <role>
- --implied-role <role>
-
-.. option:: <role>
-
- Prior role <role> (name or ID) implies another role
-
-.. option:: --implied-role <role>
-
- <role> (name or ID) implied by another role
-
-
-implied role delete
--------------------
-
-Deletes an association between prior and implied roles
-
-.. program:: implied role delete
-.. code:: bash
-
- openstack implied role delete
- <role>
- --implied-role <role>
-
-.. option:: <role>
-
- Prior role <role> (name or ID) implies another role
-
-.. option:: --implied-role <role>
-
- <role> (name or ID) implied by another role
-
-implied role list
------------------
-
-List implied roles
-
-.. program:: implied role list
-.. code:: bash
-
- openstack implied role list
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: implied role *
diff --git a/doc/source/cli/command-objects/limit.rst b/doc/source/cli/command-objects/limit.rst
index 46da6c1..784d0cb 100644
--- a/doc/source/cli/command-objects/limit.rst
+++ b/doc/source/cli/command-objects/limit.rst
@@ -6,128 +6,5 @@ Identity v3
Limits are used to specify project-specific limits thresholds of resources.
-limit create
-------------
-
-Create a new limit
-
-.. program:: limit create
-.. code:: bash
-
- openstack limit create
- [--description <description>]
- [--region <region>]
- --project <project>
- --service <service>
- --resource-limit <resource-limit>
- <resource-name>
-
-.. option:: --description <description>
-
- Useful description of the limit or its purpose
-
-.. option:: --region <region>
-
- Region that the limit should be applied to
-
-.. describe:: --project <project>
-
- The project that the limit applies to (required)
-
-.. describe:: --service <service>
-
- The service that is responsible for the resource being limited (required)
-
-.. describe:: --resource-limit <resource-limit>
-
- The limit to apply to the project (required)
-
-.. describe:: <resource-name>
-
- The name of the resource to limit (e.g. cores or volumes)
-
-limit delete
-------------
-
-Delete project-specific limit(s)
-
-.. program:: limit delete
-.. code:: bash
-
- openstack limit delete
- <limit-id> [<limit-id> ...]
-
-.. describe:: <limit-id>
-
- Limit(s) to delete (ID)
-
-limit list
-----------
-
-List project-specific limits
-
-.. program:: limit list
-.. code:: bash
-
- openstack limit list
- [--service <service>]
- [--resource-name <resource-name>]
- [--region <region>]
- [--project <project>]
-
-.. option:: --service <service>
-
- The service to filter the response by (name or ID)
-
-.. option:: --resource-name <resource-name>
-
- The name of the resource to filter the response by
-
-.. option:: --region <region>
-
- The region name to filter the response by
-
-.. option:: --project <project>
-
- List resource limits associated with project
-
-limit show
-----------
-
-Display details about a limit
-
-.. program:: limit show
-.. code:: bash
-
- openstack limit show
- <limit-id>
-
-.. describe:: <limit-id>
-
- Limit to display (ID)
-
-limit set
----------
-
-Update a limit
-
-.. program:: limit show
-.. code:: bash
-
- openstack limit set
- [--description <description>]
- [--resource-limit <resource-limit>]
- <limit-id>
-
-
-.. option:: --description <description>
-
- Useful description of the limit or its purpose
-
-.. option:: --resource-limit <resource-limit>
-
- The limit to apply to the project
-
-.. describe:: <limit-id>
-
- Limit to update (ID)
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: limit *
diff --git a/doc/source/cli/command-objects/mapping.rst b/doc/source/cli/command-objects/mapping.rst
index 73dbbc8..5653b52 100644
--- a/doc/source/cli/command-objects/mapping.rst
+++ b/doc/source/cli/command-objects/mapping.rst
@@ -7,16 +7,4 @@ extension. It is used by **federation protocols** and **identity providers**.
Applicable to Identity v3.
.. autoprogram-cliff:: openstack.identity.v3
- :command: mapping create
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: mapping delete
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: mapping list
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: mapping set
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: mapping show
+ :command: mapping * \ No newline at end of file
diff --git a/doc/source/cli/command-objects/policy.rst b/doc/source/cli/command-objects/policy.rst
index 0fe104c..66bc254 100644
--- a/doc/source/cli/command-objects/policy.rst
+++ b/doc/source/cli/command-objects/policy.rst
@@ -6,16 +6,4 @@ A **policy** is an arbitrarily serialized policy engine rule set to be consumed
by a remote service. Applies to Identity v3.
.. autoprogram-cliff:: openstack.identity.v3
- :command: policy create
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: policy delete
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: policy list
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: policy set
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: policy show
+ :command: policy *
diff --git a/doc/source/cli/command-objects/project-v2.rst b/doc/source/cli/command-objects/project-v2.rst
new file mode 100644
index 0000000..502154d
--- /dev/null
+++ b/doc/source/cli/command-objects/project-v2.rst
@@ -0,0 +1,6 @@
+=====================
+project (Identity v2)
+=====================
+
+.. autoprogram-cliff:: openstack.identity.v2
+ :command: project *
diff --git a/doc/source/cli/command-objects/project-v3.rst b/doc/source/cli/command-objects/project-v3.rst
new file mode 100644
index 0000000..9bee6ae
--- /dev/null
+++ b/doc/source/cli/command-objects/project-v3.rst
@@ -0,0 +1,6 @@
+=====================
+project (Identity v3)
+=====================
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: project *
diff --git a/doc/source/cli/command-objects/project.rst b/doc/source/cli/command-objects/project.rst
deleted file mode 100644
index ac7e8cd..0000000
--- a/doc/source/cli/command-objects/project.rst
+++ /dev/null
@@ -1,277 +0,0 @@
-=======
-project
-=======
-
-Identity v2, v3
-
-project create
---------------
-
-Create new project
-
-.. program:: project create
-.. code:: bash
-
- openstack project create
- [--domain <domain>]
- [--parent <project>]
- [--description <description>]
- [--enable | --disable]
- [--property <key=value>]
- [--or-show]
- [--tag <tag>]
- <name>
-
-.. option:: --domain <domain>
-
- Domain owning the project (name or ID)
-
- .. versionadded:: 3
-
-.. option:: --parent <project>
-
- Parent of the project (name or ID)
-
- .. versionadded:: 3
-
-.. option:: --description <description>
-
- Project description
-
-.. option:: --enable
-
- Enable project (default)
-
-.. option:: --disable
-
- Disable project
-
-.. option:: --property <key=value>
-
- Add a property to :ref:`\<name\> <project_create-name>`
- (repeat option to set multiple properties)
-
-.. option:: --or-show
-
- Return existing project
-
- If the project already exists return the existing project data and do not fail.
-
-.. option:: --tag
-
- Add a tag to the project
- (repeat option to set multiple tags)
-
- .. versionadded:: 3
-
-.. _project_create-name:
-.. describe:: <name>
-
- New project name
-
-project delete
---------------
-
-Delete project(s)
-
-.. program:: project delete
-.. code:: bash
-
- openstack project delete
- [--domain <domain>]
- <project> [<project> ...]
-
-.. option:: --domain <domain>
-
- Domain owning :ref:`\<project\> <project_delete-project>` (name or ID)
-
- .. versionadded:: 3
-
-.. _project_delete-project:
-.. describe:: <project>
-
- Project to delete (name or ID)
-
-project list
-------------
-
-List projects
-
-.. program:: project list
-.. code:: bash
-
- openstack project list
- [--domain <domain>]
- [--parent <parent>]
- [--user <user>]
- [--my-projects]
- [--long]
- [--sort <key>[:<direction>,<key>:<direction>,..]]
- [--tags <tag>[,<tag>,...]] [--tags-any <tag>[,<tag>,...]]
- [--not-tags <tag>[,<tag>,...]] [--not-tags-any <tag>[,<tag>,...]]
-
-.. option:: --domain <domain>
-
- Filter projects by :option:`\<domain\> <--domain>` (name or ID)
-
- .. versionadded:: 3
-
-.. option:: --parent <parent>
-
- Filter projects whose parent is :option:`\<parent\> <--parent>` (name or ID)
-
- .. versionadded:: 3
-
-.. option:: --user <user>
-
- Filter projects by :option:`\<user\> <--user>` (name or ID)
-
- .. versionadded:: 3
-
-.. option:: --my-projects
-
- List projects for the authenticated user. Supersedes other filters.
-
- .. versionadded:: 3
-
-.. option:: --long
-
- List additional fields in output
-
-.. option:: --sort <key>[:<direction>,<key>:<direction>,..]
-
- Sort output by selected keys and directions (asc or desc) (default: asc),
- multiple keys and directions can be specified --sort
- <key>[:<direction>,<key>:<direction>,..]
-
-.. option:: --tags <tag>[,<tag>,...]
-
- List projects which have all given tag(s)
-
- .. versionadded:: 3
-
-.. option:: --tags-any <tag>[,<tag>,...]
-
- List projects which have any given tag(s)
-
- .. versionadded:: 3
-
-.. option:: --not-tags <tag>[,<tag>,...]
-
- Exclude projects which have all given tag(s)
-
- .. versionadded:: 3
-
-.. option:: --not-tags-any <tag>[,<tag>,...]
-
- Exclude projects which have any given tag(s)
-
- .. versionadded:: 3
-
-project set
------------
-
-Set project properties
-
-.. program:: project set
-.. code:: bash
-
- openstack project set
- [--name <name>]
- [--domain <domain>]
- [--description <description>]
- [--enable | --disable]
- [--property <key=value>]
- [--tag <tag> | --clear-tags | --remove-tags <tag>]
- <project>
-
-.. option:: --name <name>
-
- Set project name
-
-.. option:: --domain <domain>
-
- Domain owning :ref:`\<project\> <project_set-project>` (name or ID)
-
- .. versionadded:: 3
-
-.. option:: --description <description>
-
- Set project description
-
-.. option:: --enable
-
- Enable project (default)
-
-.. option:: --disable
-
- Disable project
-
-.. option:: --property <key=value>
-
- Set a property on :ref:`\<project\> <project_set-project>`
- (repeat option to set multiple properties)
-
- *Identity version 2 only*
-
-.. _project_set-project:
-.. describe:: <project>
-
- Project to modify (name or ID)
-
-project show
-------------
-
-Display project details
-
-.. program:: project show
-.. code:: bash
-
- openstack project show
- [--domain <domain>]
- <project>
-
-.. option:: --domain <domain>
-
- Domain owning :ref:`\<project\> <project_show-project>` (name or ID)
-
- .. versionadded:: 3
-
-.. option:: --parents
-
- Show the project\'s parents as a list
-
- .. versionadded:: 3
-
-.. option:: --children
-
- Show project\'s subtree (children) as a list
-
- .. versionadded:: 3
-
-.. _project_show-project:
-.. describe:: <project>
-
- Project to display (name or ID)
-
-project unset
--------------
-
-Unset project properties
-
-*Identity version 2 only*
-
-.. program:: project unset
-.. code:: bash
-
- openstack 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/cli/command-objects/region.rst b/doc/source/cli/command-objects/region.rst
index 58cc341..86e7ca8 100644
--- a/doc/source/cli/command-objects/region.rst
+++ b/doc/source/cli/command-objects/region.rst
@@ -7,16 +7,4 @@ zero or more sub-regions with a region to create a tree-like structured
hierarchy. Applies to Identity v3.
.. autoprogram-cliff:: openstack.identity.v3
- :command: region create
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: region delete
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: region list
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: region set
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: region show
+ :command: region *
diff --git a/doc/source/cli/command-objects/registered-limit.rst b/doc/source/cli/command-objects/registered-limit.rst
index 586fd1f..98a5efb 100644
--- a/doc/source/cli/command-objects/registered-limit.rst
+++ b/doc/source/cli/command-objects/registered-limit.rst
@@ -7,134 +7,5 @@ Identity v3
Registered limits are used to define default limits for resources within a
deployment.
-registered limit create
------------------------
-
-Create a new registered limit
-
-.. program:: registered limit create
-.. code:: bash
-
- openstack registered limit create
- [--description <description>]
- [--region <region>]
- --service <service>
- --default-limit <default-limit>
- <resource-name>
-
-.. option:: --description <description>
-
- Useful description of the registered limit or its purpose
-
-.. option:: --region <region>
-
- Region that the limit should be applied to
-
-.. describe:: --service <service>
-
- The service that is responsible for the resource being limited (required)
-
-.. describe:: --default-limit <default-limit>
-
- The default limit for projects to assume unless explicitly overridden
- (required)
-
-.. describe:: <resource-name>
-
- The name of the resource to limit (e.g. cores or volumes)
-
-registered limit delete
------------------------
-
-Delete registered limit(s)
-
-.. program:: registered limit delete
-.. code:: bash
-
- openstack registered limit delete
- <registered-limit-id> [<registered-limit-id> ...]
-
-
-.. describe:: <registered-limit-id>
-
- Registered limit(s) to delete (ID)
-
-registered limit list
----------------------
-
-List registered limits
-
-.. program:: registered limit list
-.. code:: bash
-
- openstack registered limit list
- [--service <service>]
- [--resource-name <resource-name>]
- [--region <region>]
-
-.. option:: --service <service>
-
- The service to filter the response by (name or ID)
-
-.. option:: --resource-name <resource-name>
-
- The name of the resource to filter the response by
-
-.. option:: --region <region>
-
- The region name to filter the response by
-
-registered limit show
----------------------
-
-Display details about a registered limit
-
-.. program:: registered limit show
-.. code:: bash
-
- openstack registered limit show
- <registered-limit-id>
-
-.. describe:: <registered-limit-id>
-
- Registered limit to display (ID)
-
-registered limit set
---------------------
-
-Update a registered limit
-
-.. program:: registered limit set
-.. code:: bash
-
- openstack registered limit set
- [--service <service>]
- [--resource-name <resource-name>]
- [--default-limit <default-limit>]
- [--description <description>]
- [--region <region>]
- <registered-limit-id>
-
-.. option:: --service <service>
-
- The service of the registered limit to update (ID or name)
-
-.. option:: --resource-name <resource-name>
-
- The name of the resource for the limit
-
-.. option:: --default-limit <default-limit>
-
- The default limit for projects to assume for a given resource
-
-.. option:: --description <description>
-
- A useful description of the limit or its purpose
-
-.. option:: --region <region>
-
- The region the limit should apply to
-
-.. describe:: <registered-limit-id>
-
- Registered limit to display (ID)
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: registered limit *
diff --git a/doc/source/cli/command-objects/request-token.rst b/doc/source/cli/command-objects/request-token.rst
index e10f664..ea333c4 100644
--- a/doc/source/cli/command-objects/request-token.rst
+++ b/doc/source/cli/command-objects/request-token.rst
@@ -7,7 +7,4 @@ is used by the **consumer** to request **access tokens**. Applicable to
Identity v3.
.. autoprogram-cliff:: openstack.identity.v3
- :command: request token authorize
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: request token create
+ :command: request token *
diff --git a/doc/source/cli/command-objects/role-v2.rst b/doc/source/cli/command-objects/role-v2.rst
new file mode 100644
index 0000000..dc5bac6
--- /dev/null
+++ b/doc/source/cli/command-objects/role-v2.rst
@@ -0,0 +1,6 @@
+==================
+role (Identity v2)
+==================
+
+.. autoprogram-cliff:: openstack.identity.v2
+ :command: role *
diff --git a/doc/source/cli/command-objects/role-v3.rst b/doc/source/cli/command-objects/role-v3.rst
new file mode 100644
index 0000000..e36bef7
--- /dev/null
+++ b/doc/source/cli/command-objects/role-v3.rst
@@ -0,0 +1,6 @@
+==================
+role (Identity v3)
+==================
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: role *
diff --git a/doc/source/cli/command-objects/role.rst b/doc/source/cli/command-objects/role.rst
deleted file mode 100644
index 752dc4e..0000000
--- a/doc/source/cli/command-objects/role.rst
+++ /dev/null
@@ -1,292 +0,0 @@
-====
-role
-====
-
-Identity v2, v3
-
-role add
---------
-
-Add role assignment to a user or group in a project or domain
-
-.. program:: role add
-.. code:: bash
-
- openstack role add
- --system <system> | --domain <domain> | --project <project> [--project-domain <project-domain>]
- --user <user> [--user-domain <user-domain>] | --group <group> [--group-domain <group-domain>]
- --role-domain <role-domain>
- --inherited
- <role>
-
-.. option:: --system <system>
-
- Include <system>
-
- System or service to grant authorization to. Currently only ``all`` is
- supported which encompasses the entire deployment system.
-
- .. versionadded:: 3
-
-.. option:: --domain <domain>
-
- Include <domain> (name or ID)
-
- .. versionadded:: 3
-
-.. option:: --project <project>
-
- Include <project> (name or ID)
-
-.. option:: --user <user>
-
- Include <user> (name or ID)
-
-.. option:: --group <group>
-
- Include <group> (name or ID)
-
- .. versionadded:: 3
-
-.. option:: --user-domain <user-domain>
-
- Domain the user belongs to (name or ID).
- This can be used in case collisions between user names exist.
-
- .. versionadded:: 3
-
-.. option:: --group-domain <group-domain>
-
- Domain the group belongs to (name or ID).
- This can be used in case collisions between group names exist.
-
- .. versionadded:: 3
-
-.. 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:: 3
-
-.. option:: --inherited
-
- Specifies if the role grant is inheritable to the sub projects.
-
- .. versionadded:: 3
-
-.. option:: --role-domain <role-domain>
-
- Domain the role belongs to (name or ID).
- This must be specified when the name of a domain specific role is used.
-
- .. versionadded:: 3
-
-.. describe:: <role>
-
- Role to add to <project>:<user> (name or ID)
-
-role create
------------
-
-Create new role
-
-.. program:: role create
-.. code:: bash
-
- openstack role create
- [--or-show]
- [--domain <domain>]
- <name>
-
-.. option:: --domain <domain>
-
- Domain the role belongs to (name or ID).
-
- .. versionadded:: 3
-
-.. option:: --or-show
-
- Return existing role
-
- If the role already exists return the existing role data and do not fail.
-
-.. describe:: <name>
-
- New role name
-
-.. option:: --description <description>
-
- Add description about the role
-
-role delete
------------
-
-Delete role(s)
-
-.. program:: role delete
-.. code:: bash
-
- openstack role delete
- <role> [<role> ...]
- [--domain <domain>]
-
-.. describe:: <role>
-
- Role to delete (name or ID)
-
-.. option:: --domain <domain>
-
- Domain the role belongs to (name or ID).
-
- .. versionadded:: 3
-
-role list
----------
-
-List roles
-
-.. program:: role list
-.. code:: bash
-
- openstack role list
- [--domain <domain>]
-
-.. option:: --domain <domain>
-
- Filter roles by <domain> (name or ID)
-
- .. versionadded:: 3
-
-role remove
------------
-
-Remove role assignment from domain/project : user/group
-
-.. program:: role remove
-.. code:: bash
-
- openstack role remove
- --system <system> | --domain <domain> | --project <project> [--project-domain <project-domain>]
- --user <user> [--user-domain <user-domain>] | --group <group> [--group-domain <group-domain>]
- --role-domain <role-domain>
- --inherited
- <role>
-
-.. option:: --system <system>
-
- Include <system>
-
- System or service to remove authorization from. Currently only ``all`` is
- supported which encompasses the entire deployment system.
-
- .. versionadded:: 3
-
-.. option:: --domain <domain>
-
- Include <domain> (name or ID)
-
- .. versionadded:: 3
-
-.. option:: --project <project>
-
- Include <project> (name or ID)
-
-.. option:: --user <user>
-
- Include <user> (name or ID)
-
-.. option:: --group <group>
-
- Include <group> (name or ID)
-
- .. versionadded:: 3
-
-.. option:: --user-domain <user-domain>
-
- Domain the user belongs to (name or ID).
- This can be used in case collisions between user names exist.
-
- .. versionadded:: 3
-
-.. option:: --group-domain <group-domain>
-
- Domain the group belongs to (name or ID).
- This can be used in case collisions between group names exist.
-
- .. versionadded:: 3
-
-.. 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:: 3
-
-.. option:: --inherited
-
- Specifies if the role grant is inheritable to the sub projects.
-
- .. versionadded:: 3
-
-.. option:: --role-domain <role-domain>
-
- Domain the role belongs to (name or ID).
- This must be specified when the name of a domain specific role is used.
-
- .. versionadded:: 3
-
-.. describe:: <role>
-
- Role to remove (name or ID)
-
-role set
---------
-
-Set role properties
-
-.. versionadded:: 3
-
-.. program:: role set
-.. code:: bash
-
- openstack role set
- [--name <name>]
- [--domain <domain>]
- <role>
-
-.. option:: --name <name>
-
- Set role name
-
-.. option:: --domain <domain>
-
- Domain the role belongs to (name or ID).
-
- .. versionadded:: 3
-
-.. describe:: <role>
-
- Role to modify (name or ID)
-
-role show
----------
-
-Display role details
-
-.. program:: role show
-.. code:: bash
-
- openstack role show
- [--domain <domain>]
- <role>
-
-.. option:: --domain <domain>
-
- Domain the role belongs to (name or ID).
-
- .. versionadded:: 3
-
-.. describe:: <role>
-
- Role to display (name or ID)
diff --git a/doc/source/cli/command-objects/service-provider.rst b/doc/source/cli/command-objects/service-provider.rst
index b7a282c..47a5032 100644
--- a/doc/source/cli/command-objects/service-provider.rst
+++ b/doc/source/cli/command-objects/service-provider.rst
@@ -7,16 +7,4 @@ extension. It is used by to register another OpenStack Identity service.
Applicable to Identity v3.
.. autoprogram-cliff:: openstack.identity.v3
- :command: service provider create
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: service provider delete
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: service provider list
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: service provider set
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: service provider show
+ :command: service provider *
diff --git a/doc/source/cli/command-objects/service-v2.rst b/doc/source/cli/command-objects/service-v2.rst
new file mode 100644
index 0000000..6b22b7e
--- /dev/null
+++ b/doc/source/cli/command-objects/service-v2.rst
@@ -0,0 +1,6 @@
+=====================
+service (Identity v2)
+=====================
+
+.. autoprogram-cliff:: openstack.identity.v2
+ :command: service *
diff --git a/doc/source/cli/command-objects/service-v3.rst b/doc/source/cli/command-objects/service-v3.rst
new file mode 100644
index 0000000..d4b7020
--- /dev/null
+++ b/doc/source/cli/command-objects/service-v3.rst
@@ -0,0 +1,18 @@
+=====================
+service (Identity v3)
+=====================
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: service create
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: service delete
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: service list
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: service show
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: service set
diff --git a/doc/source/cli/command-objects/service.rst b/doc/source/cli/command-objects/service.rst
deleted file mode 100644
index a69c695..0000000
--- a/doc/source/cli/command-objects/service.rst
+++ /dev/null
@@ -1,143 +0,0 @@
-=======
-service
-=======
-
-Identity v2, v3
-
-service create
---------------
-
-Create new service
-
-.. program:: service create
-.. code-block:: bash
-
- openstack service create
- [--name <name>]
- [--description <description>]
- [--enable | --disable]
- <type>
-
-.. option:: --name <name>
-
- New service name
-
-.. option:: --description <description>
-
- New service description
-
-.. option:: --enable
-
- Enable service (default)
-
- *Identity version 3 only*
-
-.. option:: --disable
-
- Disable service
-
- *Identity version 3 only*
-
-.. _service_create-type:
-.. describe:: <type>
-
- New service type (compute, image, identity, volume, etc)
-
-service delete
---------------
-
-Delete service(s)
-
-.. program:: service delete
-.. code-block:: bash
-
- openstack service delete
- <service> [<service> ...]
-
-.. _service_delete-service:
-.. describe:: <service>
-
- Service(s) to delete (type, name or ID)
-
-service list
-------------
-
-List services
-
-.. program:: service list
-.. code-block:: bash
-
- openstack service list
- [--long]
-
-.. option:: --long
-
- List additional fields in output
-
-Returns service fields ID, Name and Type. :option:`--long` adds Description
-and Enabled (*Identity version 3 only*) to the output.
-
-service set
------------
-
-Set service properties
-
-* Identity version 3 only*
-
-.. program:: service set
-.. code-block:: bash
-
- openstack service set
- [--type <type>]
- [--name <name>]
- [--description <description>]
- [--enable | --disable]
- <service>
-
-.. option:: --type <type>
-
- New service type (compute, image, identity, volume, etc)
-
-.. option:: --name <name>
-
- New service name
-
-.. option:: --description <description>
-
- New service description
-
-.. option:: --enable
-
- Enable service
-
-.. option:: --disable
-
- Disable service
-
-.. _service_set-service:
-.. describe:: <service>
-
- Service to modify (type, name or ID)
-
-service show
-------------
-
-Display service details
-
-.. program:: service show
-.. code-block:: bash
-
- openstack service show
- [--catalog]
- <service>
-
-.. option:: --catalog
-
- Show service catalog information
-
- *Identity version 2 only*
-
-.. _service_show-service:
-.. describe:: <service>
-
- Service to display (type, name or ID)
diff --git a/doc/source/cli/command-objects/token-v2.rst b/doc/source/cli/command-objects/token-v2.rst
new file mode 100644
index 0000000..c66302b
--- /dev/null
+++ b/doc/source/cli/command-objects/token-v2.rst
@@ -0,0 +1,7 @@
+===================
+token (Identity v2)
+===================
+
+
+.. autoprogram-cliff:: openstack.identity.v2
+ :command: token *
diff --git a/doc/source/cli/command-objects/token-v3.rst b/doc/source/cli/command-objects/token-v3.rst
new file mode 100644
index 0000000..6b2d87a
--- /dev/null
+++ b/doc/source/cli/command-objects/token-v3.rst
@@ -0,0 +1,7 @@
+===================
+token (Identity v3)
+===================
+
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: token *
diff --git a/doc/source/cli/command-objects/token.rst b/doc/source/cli/command-objects/token.rst
deleted file mode 100644
index b4b14cd..0000000
--- a/doc/source/cli/command-objects/token.rst
+++ /dev/null
@@ -1,30 +0,0 @@
-=====
-token
-=====
-
-Identity v2, v3
-
-token issue
------------
-
-Issue new token
-
-.. program:: token issue
-.. code:: bash
-
- openstack token issue
-
-token revoke
-------------
-
-Revoke existing token
-
-.. program:: token revoke
-.. code:: bash
-
- openstack token revoke
- <token>
-
-.. describe:: <token>
-
- Token to be deleted
diff --git a/doc/source/cli/command-objects/trust.rst b/doc/source/cli/command-objects/trust.rst
index febef1c..738c640 100644
--- a/doc/source/cli/command-objects/trust.rst
+++ b/doc/source/cli/command-objects/trust.rst
@@ -6,13 +6,4 @@ A **trust** provide project-specific role delegation between users, with
optional impersonation. Requires the OS-TRUST extension. Applies to Identity v3.
.. autoprogram-cliff:: openstack.identity.v3
- :command: trust create
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: trust delete
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: trust list
-
-.. autoprogram-cliff:: openstack.identity.v3
- :command: trust show
+ :command: trust *
diff --git a/doc/source/cli/command-objects/user-v2.rst b/doc/source/cli/command-objects/user-v2.rst
new file mode 100644
index 0000000..966bd37
--- /dev/null
+++ b/doc/source/cli/command-objects/user-v2.rst
@@ -0,0 +1,7 @@
+==================
+user (Identity v2)
+==================
+
+
+.. autoprogram-cliff:: openstack.identity.v2
+ :command: user *
diff --git a/doc/source/cli/command-objects/user-v3.rst b/doc/source/cli/command-objects/user-v3.rst
new file mode 100644
index 0000000..c11ff9a
--- /dev/null
+++ b/doc/source/cli/command-objects/user-v3.rst
@@ -0,0 +1,7 @@
+==================
+user (Identity v3)
+==================
+
+
+.. autoprogram-cliff:: openstack.identity.v3
+ :command: user *
diff --git a/doc/source/cli/command-objects/user.rst b/doc/source/cli/command-objects/user.rst
deleted file mode 100644
index 632d0e2..0000000
--- a/doc/source/cli/command-objects/user.rst
+++ /dev/null
@@ -1,223 +0,0 @@
-====
-user
-====
-
-Identity v2, v3
-
-user create
------------
-
-Create new user
-
-.. program:: user create
-.. code:: bash
-
- openstack user create
- [--domain <domain>]
- [--project <project> [--project-domain <project-domain>]]
- [--password <password>]
- [--password-prompt]
- [--email <email-address>]
- [--description <description>]
- [--enable | --disable]
- [--or-show]
- <user-name>
-
-.. option:: --domain <domain>
-
- Default domain (name or ID)
-
- .. versionadded:: 3
-
-.. option:: --project <project>
-
- Default 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:: --password <password>
-
- Set user password
-
-.. option:: --password-prompt
-
- Prompt interactively for password
-
-.. option:: --email <email-address>
-
- Set user email address
-
-.. option:: --description <description>
-
- User description
-
- .. versionadded:: 3
-
-.. option:: --enable
-
- Enable user (default)
-
-.. option:: --disable
-
- Disable user
-
-.. option:: --or-show
-
- Return existing user
-
- If the username already exist return the existing user data and do not fail.
-
-.. describe:: <user-name>
-
- New user name
-
-user delete
------------
-
-Delete user(s)
-
-.. program:: user delete
-.. code:: bash
-
- openstack user delete
- [--domain <domain>]
- <user> [<user> ...]
-
-.. option:: --domain <domain>
-
- Domain owning :ref:`\<user\> <user_delete-user>` (name or ID)
-
- .. versionadded:: 3
-
-.. _user_delete-user:
-.. describe:: <user>
-
- User(s) to delete (name or ID)
-
-user list
----------
-
-List users
-
-.. program:: user list
-.. code:: bash
-
- openstack user list
- [--project <project>]
- [--domain <domain>]
- [--group <group> | --project <project>]
- [--long]
-
-.. option:: --project <project>
-
- Filter users by `<project>` (name or ID)
-
-.. option:: --domain <domain>
-
- Filter users by `<domain>` (name or ID)
-
- *Identity version 3 only*
-
-.. option:: --group <group>
-
- Filter users by `<group>` membership (name or ID)
-
- *Identity version 3 only*
-
-.. option:: --long
-
- List additional fields in output
-
-user set
---------
-
-Set user properties
-
-.. program:: user set
-.. code:: bash
-
- openstack user set
- [--name <name>]
- [--project <project> [--project-domain <project-domain>]]
- [--password <password>]
- [--password-prompt]
- [--email <email-address>]
- [--description <description>]
- [--enable|--disable]
- <user>
-
-.. option:: --name <name>
-
- Set user name
-
-.. option:: --domain <domain>
-
- Domain the user belongs to (name or ID).
- This can be used in case collisions between user names exist.
-
- .. versionadded:: 3
-
-.. option:: --project <project>
-
- Set default 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:: --password <password>
-
- Set user password
-
-.. option:: --password-prompt
-
- Prompt interactively for password
-
-.. option:: --email <email-address>
-
- Set user email address
-
-.. option:: --description <description>
-
- Set user description
-
- .. versionadded:: 3
-
-.. option:: --enable
-
- Enable user (default)
-
-.. option:: --disable
-
- Disable user
-
-.. describe:: <user>
-
- User to modify (name or ID)
-
-user show
----------
-
-Display user details
-
-.. program:: user show
-.. code:: bash
-
- openstack user show
- [--domain <domain>]
- <user>
-
-.. option:: --domain <domain>
-
- Domain owning :ref:`\<user\> <user_show-user>` (name or ID)
-
- .. versionadded:: 3
-
-.. _user_show-user:
-.. describe:: <user>
-
- User to display (name or ID)
diff --git a/doc/source/cli/commands.rst b/doc/source/cli/commands.rst
index 7c38aa5..97a829b 100644
--- a/doc/source/cli/commands.rst
+++ b/doc/source/cli/commands.rst
@@ -195,10 +195,6 @@ conflicts when creating new plugins. For a complete list check out
* ``cluster profile``: (**Clustering (Senlin)**)
* ``cluster profile type``: (**Clustering (Senlin)**)
* ``cluster receiver``: (**Clustering (Senlin)**)
-* ``congress datasource``: (**Policy (Congress)**)
-* ``congress driver``: (**Policy (Congress)**)
-* ``congress policy``: (**Policy (Congress)**)
-* ``congress policy rule``: (**Policy (Congress)**)
* ``cron trigger``: (**Workflow Engine (Mistral)**)
* ``database flavor``: (**Database (Trove)**)
* ``dataprocessing data source``: (**Data Processing (Sahara)**)
diff --git a/doc/source/cli/index.rst b/doc/source/cli/index.rst
index 17e50a0..9cb3b33 100644
--- a/doc/source/cli/index.rst
+++ b/doc/source/cli/index.rst
@@ -13,3 +13,12 @@
interactive
decoder
backwards-incompatible
+
+.. NOTE(efried): Everything must be in a toctree but we don't want these to
+ show up to the reader.
+
+.. toctree::
+ :glob:
+ :hidden:
+
+ _hidden/*
diff --git a/doc/source/cli/plugin-commands/congress.rst b/doc/source/cli/plugin-commands/congress.rst
deleted file mode 100644
index 7a1e63b..0000000
--- a/doc/source/cli/plugin-commands/congress.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-congress
---------
-
-.. autoprogram-cliff:: openstack.congressclient.v1
diff --git a/doc/source/cli/plugin-commands/index.rst b/doc/source/cli/plugin-commands/index.rst
index 2c3bda3..33a8fe0 100644
--- a/doc/source/cli/plugin-commands/index.rst
+++ b/doc/source/cli/plugin-commands/index.rst
@@ -9,13 +9,13 @@ Plugin Commands
aodh
barbican
- congress
designate
gnocchi
heat
ironic
ironic-inspector
karbor
+ manila
mistral
neutron
octavia
diff --git a/doc/source/cli/plugin-commands/manila.rst b/doc/source/cli/plugin-commands/manila.rst
new file mode 100644
index 0000000..c42d606
--- /dev/null
+++ b/doc/source/cli/plugin-commands/manila.rst
@@ -0,0 +1,4 @@
+manila
+------
+
+.. autoprogram-cliff:: openstack.share.v2
diff --git a/doc/source/conf.py b/doc/source/conf.py
index ff37783..2216ddd 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -12,8 +12,6 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
-import pbr.version
-
# -- General configuration ----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
@@ -31,11 +29,12 @@ extensions = ['sphinx.ext.autodoc',
]
# openstackdocstheme options
-repository_name = 'openstack/python-openstackclient'
-use_storyboard = True
+openstackdocs_repo_name = 'openstack/python-openstackclient'
+openstackdocs_use_storyboard = True
+openstackdocs_auto_name = False
# Add project 'foo' to this list to enable the :foo-doc: role
-openstack_projects = [
+openstackdocs_projects = [
'neutron',
]
@@ -55,17 +54,6 @@ master_doc = 'index'
project = u'OpenStack Command Line Client'
copyright = u'2012-2013 OpenStack Foundation'
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-version_info = pbr.version.VersionInfo('python-openstackclient')
-#
-# The short X.Y version.
-version = version_info.version_string()
-# The full version, including alpha/beta/rc tags.
-release = version_info.release_string()
-
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
@@ -96,7 +84,7 @@ exclude_patterns = ['**tests**']
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = 'native'
# A list of ignored prefixes for module index sorting.
modindex_common_prefix = ['openstackclient.']
@@ -139,11 +127,6 @@ html_theme = 'openstackdocs'
# so a file named "default.css" will overwrite the builtin "default.css".
#html_static_path = ['_static']
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-html_last_updated_fmt = '%Y-%m-%d %H:%M'
-
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
diff --git a/doc/source/contributor/plugins.rst b/doc/source/contributor/plugins.rst
index d6bcbee..374b274 100644
--- a/doc/source/contributor/plugins.rst
+++ b/doc/source/contributor/plugins.rst
@@ -27,7 +27,6 @@ The following is a list of projects that are an OpenStackClient plugin.
- gnocchiclient
- osc-placement
- python-barbicanclient
-- python-congressclient
- python-designateclient
- python-heatclient
- python-ironicclient
diff --git a/doc/test/redirect-tests.txt b/doc/test/redirect-tests.txt
index ef3a48d..5ed7c19 100644
--- a/doc/test/redirect-tests.txt
+++ b/doc/test/redirect-tests.txt
@@ -16,3 +16,11 @@
/python-openstackclient/latest/humaninterfaceguide.html 301 /python-openstackclient/latest/contributor/humaninterfaceguide.html
/python-openstackclient/latest/plugins.html 301 /python-openstackclient/latest/contributor/plugins.html
/python-openstackclient/latest/cli/plugin-commands.html 301 /python-openstackclient/latest/cli/plugin-commands/index.html
+/python-openstackclient/latest/cli/command-objects/ec2-credentials.html 301 /python-openstackclient/latest/cli/_hidden/ec2-credentials.html
+/python-openstackclient/latest/cli/command-objects/endpoint.html 301 /python-openstackclient/latest/cli/_hidden/endpoint.html
+/python-openstackclient/latest/cli/command-objects/image.html 301 /python-openstackclient/latest/cli/_hidden/image.html
+/python-openstackclient/latest/cli/command-objects/project.html 301 /python-openstackclient/latest/cli/_hidden/project.html
+/python-openstackclient/latest/cli/command-objects/role.html 301 /python-openstackclient/latest/cli/_hidden/role.html
+/python-openstackclient/latest/cli/command-objects/service.html 301 /python-openstackclient/latest/cli/_hidden/service.html
+/python-openstackclient/latest/cli/command-objects/token.html 301 /python-openstackclient/latest/cli/_hidden/token.html
+/python-openstackclient/latest/cli/command-objects/user.html 301 /python-openstackclient/latest/cli/_hidden/user.html
diff --git a/lower-constraints.txt b/lower-constraints.txt
index 1fa3067..0a453da 100644
--- a/lower-constraints.txt
+++ b/lower-constraints.txt
@@ -2,7 +2,6 @@ amqp==2.1.1
aodhclient==0.9.0
appdirs==1.3.0
asn1crypto==0.23.0
-Babel==2.3.4
bandit==1.1.0
cachetools==2.0.0
cffi==1.7.0
@@ -11,12 +10,13 @@ cmd2==0.8.0
contextlib2==0.4.0
coverage==4.0
cryptography==2.1
+ddt==1.0.1
debtcollector==1.2.0
-decorator==3.4.0
+decorator==4.4.1
deprecation==1.0
docker-pycreds==0.2.1
docker==2.4.2
-dogpile.cache==0.6.2
+dogpile.cache==0.6.5
eventlet==0.18.2
extras==1.0.0
fasteners==0.7.0
@@ -24,7 +24,7 @@ fixtures==3.0.0
flake8-import-order==0.13
flake8==2.6.2
future==0.16.0
-futurist==1.2.0
+futurist==2.1.0
gitdb==0.6.4
GitPython==1.0.1
gnocchiclient==3.3.1
@@ -38,20 +38,18 @@ jmespath==0.9.0
jsonpatch==1.16
jsonpointer==1.13
jsonschema==2.6.0
-keystoneauth1==3.16.0
+keystoneauth1==3.18.0
kombu==4.0.0
linecache2==1.0.0
MarkupSafe==1.1.0
mccabe==0.2.1
-mock==2.0.0
monotonic==0.6
mox3==0.20.0
msgpack-python==0.4.0
munch==2.1.0
netaddr==0.7.18
netifaces==0.10.4
-openstacksdk==0.36.0
-os-client-config==1.28.0
+openstacksdk==0.48.0
os-service-types==1.7.0
os-testr==1.0.0
osc-lib==2.0.0
@@ -87,7 +85,6 @@ pyparsing==2.1.0
pyperclip==1.5.27
python-barbicanclient==4.5.2
python-cinderclient==3.3.0
-python-congressclient==1.9.0
python-dateutil==2.5.3
python-designateclient==2.7.0
python-glanceclient==2.8.0
@@ -126,7 +123,7 @@ six==1.10.0
smmap==0.9.0
statsd==3.2.1
stestr==1.0.0
-stevedore==1.20.0
+stevedore==2.0.1
sushy==0.1.0
tempest==17.1.0
tenacity==3.2.1
diff --git a/openstackclient/api/object_store_v1.py b/openstackclient/api/object_store_v1.py
index c8514a5..8092abd 100644
--- a/openstackclient/api/object_store_v1.py
+++ b/openstackclient/api/object_store_v1.py
@@ -87,7 +87,7 @@ class APIv1(api.BaseAPI):
def container_list(
self,
- all_data=False,
+ full_listing=False,
limit=None,
marker=None,
end_marker=None,
@@ -96,7 +96,7 @@ class APIv1(api.BaseAPI):
):
"""Get containers in an account
- :param boolean all_data:
+ :param boolean full_listing:
if True, return a full listing, else returns a max of
10000 listings
:param integer limit:
@@ -113,7 +113,7 @@ class APIv1(api.BaseAPI):
params['format'] = 'json'
- if all_data:
+ if full_listing:
data = listing = self.container_list(
limit=limit,
marker=marker,
@@ -299,7 +299,7 @@ class APIv1(api.BaseAPI):
def object_list(
self,
container=None,
- all_data=False,
+ full_listing=False,
limit=None,
marker=None,
end_marker=None,
@@ -311,7 +311,7 @@ class APIv1(api.BaseAPI):
:param string container:
container name to get a listing for
- :param boolean all_data:
+ :param boolean full_listing:
if True, return a full listing, else returns a max of
10000 listings
:param integer limit:
@@ -328,11 +328,11 @@ class APIv1(api.BaseAPI):
headers will be a dict and all header names will be lowercase.
"""
- if container is None or object is None:
+ if container is None:
return None
params['format'] = 'json'
- if all_data:
+ if full_listing:
data = listing = self.object_list(
container=container,
limit=limit,
diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py
index c1118ad..36c3ce2 100644
--- a/openstackclient/common/clientmanager.py
+++ b/openstackclient/common/clientmanager.py
@@ -15,12 +15,13 @@
"""Manage access to the clients, including authenticating when needed."""
+import importlib
import logging
import sys
from osc_lib import clientmanager
from osc_lib import shell
-import pkg_resources
+import stevedore
LOG = logging.getLogger(__name__)
@@ -143,17 +144,28 @@ class ClientManager(clientmanager.ClientManager):
def get_plugin_modules(group):
"""Find plugin entry points"""
mod_list = []
- for ep in pkg_resources.iter_entry_points(group):
+ mgr = stevedore.ExtensionManager(group)
+ for ep in mgr:
LOG.debug('Found plugin %s', ep.name)
+ # Different versions of stevedore use different
+ # implementations of EntryPoint from other libraries, which
+ # are not API-compatible.
try:
- __import__(ep.module_name)
- except Exception:
+ module_name = ep.entry_point.module_name
+ except AttributeError:
+ try:
+ module_name = ep.entry_point.module
+ except AttributeError:
+ module_name = ep.entry_point.value
+
+ try:
+ module = importlib.import_module(module_name)
+ except Exception as err:
sys.stderr.write(
- "WARNING: Failed to import plugin %s.\n" % ep.name)
+ "WARNING: Failed to import plugin %s: %s.\n" % (ep.name, err))
continue
- module = sys.modules[ep.module_name]
mod_list.append(module)
init_func = getattr(module, 'Initialize', None)
if init_func:
@@ -164,7 +176,7 @@ def get_plugin_modules(group):
clientmanager.ClientManager,
module.API_NAME,
clientmanager.ClientCache(
- getattr(sys.modules[ep.module_name], 'make_client', None)
+ getattr(sys.modules[module_name], 'make_client', None)
),
)
return mod_list
diff --git a/openstackclient/common/quota.py b/openstackclient/common/quota.py
index 3743734..11de986 100644
--- a/openstackclient/common/quota.py
+++ b/openstackclient/common/quota.py
@@ -274,9 +274,18 @@ class ListQuota(command.Lister, BaseQuota):
return parser
def take_action(self, parsed_args):
- projects = self.app.client_manager.identity.projects.list()
result = []
- project_ids = [getattr(p, 'id', '') for p in projects]
+ project_ids = []
+ if parsed_args.project is None:
+ for p in self.app.client_manager.identity.projects.list():
+ project_ids.append(getattr(p, 'id', ''))
+ else:
+ identity_client = self.app.client_manager.identity
+ project = utils.find_resource(
+ identity_client.projects,
+ parsed_args.project,
+ )
+ project_ids.append(getattr(project, 'id', ''))
if parsed_args.compute:
if parsed_args.detail:
@@ -516,6 +525,11 @@ class SetQuota(common.NetDetectionMixin, command.Command):
metavar='<volume-type>',
help=_('Set quotas for a specific <volume-type>'),
)
+ parser.add_argument(
+ '--force',
+ action='store_true',
+ help=_('Force quota update (only supported by compute)')
+ )
return parser
def take_action(self, parsed_args):
@@ -529,6 +543,9 @@ class SetQuota(common.NetDetectionMixin, command.Command):
if value is not None:
compute_kwargs[k] = value
+ if parsed_args.force:
+ compute_kwargs['force'] = True
+
volume_kwargs = {}
for k, v in VOLUME_QUOTAS.items():
value = getattr(parsed_args, k, None)
diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index 8be7804..93e9f96 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -1921,9 +1921,12 @@ class RebuildServer(command.ShowOne):
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.to_dict().get(
- 'image', {}).get('id')
- image = image_client.get_image(image_id)
+ if parsed_args.image:
+ image = image_client.find_image(
+ parsed_args.image, ignore_missing=False)
+ else:
+ image_id = server.to_dict().get('image', {}).get('id')
+ image = image_client.get_image(image_id)
kwargs = {}
if parsed_args.property:
diff --git a/openstackclient/identity/common.py b/openstackclient/identity/common.py
index 7be2a17..e70d87d 100644
--- a/openstackclient/identity/common.py
+++ b/openstackclient/identity/common.py
@@ -213,6 +213,15 @@ def _find_identity_resource(identity_client_manager, name_or_id,
return resource_type(None, {'id': name_or_id, 'name': name_or_id})
+def get_immutable_options(parsed_args):
+ options = {}
+ if parsed_args.immutable:
+ options['immutable'] = True
+ if parsed_args.no_immutable:
+ options['immutable'] = False
+ return options
+
+
def add_user_domain_option_to_parser(parser):
parser.add_argument(
'--user-domain',
@@ -261,3 +270,18 @@ def add_inherited_option_to_parser(parser):
help=_('Specifies if the role grant is inheritable to the sub '
'projects'),
)
+
+
+def add_resource_option_to_parser(parser):
+ enable_group = parser.add_mutually_exclusive_group()
+ enable_group.add_argument(
+ '--immutable',
+ action='store_true',
+ help=_('Make resource immutable. An immutable project may not '
+ 'be deleted or modified except to remove the immutable flag'),
+ )
+ enable_group.add_argument(
+ '--no-immutable',
+ action='store_true',
+ help=_('Make resource mutable (default)'),
+ )
diff --git a/openstackclient/identity/v3/domain.py b/openstackclient/identity/v3/domain.py
index dbcc97f..e33fce0 100644
--- a/openstackclient/identity/v3/domain.py
+++ b/openstackclient/identity/v3/domain.py
@@ -60,6 +60,7 @@ class CreateDomain(command.ShowOne):
action='store_true',
help=_('Return existing domain'),
)
+ common.add_resource_option_to_parser(parser)
return parser
def take_action(self, parsed_args):
@@ -69,10 +70,13 @@ class CreateDomain(command.ShowOne):
if parsed_args.disable:
enabled = False
+ options = common.get_immutable_options(parsed_args)
+
try:
domain = identity_client.domains.create(
name=parsed_args.name,
description=parsed_args.description,
+ options=options,
enabled=enabled,
)
except ks_exc.Conflict:
@@ -163,6 +167,7 @@ class SetDomain(command.Command):
action='store_true',
help=_('Disable domain'),
)
+ common.add_resource_option_to_parser(parser)
return parser
def take_action(self, parsed_args):
@@ -180,6 +185,10 @@ class SetDomain(command.Command):
if parsed_args.disable:
kwargs['enabled'] = False
+ options = common.get_immutable_options(parsed_args)
+ if options:
+ kwargs['options'] = options
+
identity_client.domains.update(domain.id, **kwargs)
diff --git a/openstackclient/identity/v3/project.py b/openstackclient/identity/v3/project.py
index 9ecc70e..5e8ce82 100644
--- a/openstackclient/identity/v3/project.py
+++ b/openstackclient/identity/v3/project.py
@@ -78,6 +78,7 @@ class CreateProject(command.ShowOne):
action='store_true',
help=_('Return existing project'),
)
+ common.add_resource_option_to_parser(parser)
tag.add_tag_option_to_parser_for_create(parser, _('project'))
return parser
@@ -99,9 +100,20 @@ class CreateProject(command.ShowOne):
enabled = True
if parsed_args.disable:
enabled = False
+
+ options = common.get_immutable_options(parsed_args)
+
kwargs = {}
if parsed_args.property:
kwargs = parsed_args.property.copy()
+ if 'is_domain' in kwargs.keys():
+ if kwargs['is_domain'].lower() == "true":
+ kwargs['is_domain'] = True
+ elif kwargs['is_domain'].lower() == "false":
+ kwargs['is_domain'] = False
+ elif kwargs['is_domain'].lower() == "none":
+ kwargs['is_domain'] = None
+
kwargs['tags'] = list(set(parsed_args.tags))
try:
@@ -111,6 +123,7 @@ class CreateProject(command.ShowOne):
parent=parent,
description=parsed_args.description,
enabled=enabled,
+ options=options,
**kwargs
)
except ks_exc.Conflict:
@@ -317,6 +330,7 @@ class SetProject(command.Command):
help=_('Set a property on <project> '
'(repeat option to set multiple properties)'),
)
+ common.add_resource_option_to_parser(parser)
tag.add_tag_option_to_parser_for_set(parser, _('project'))
return parser
@@ -336,6 +350,9 @@ class SetProject(command.Command):
kwargs['enabled'] = True
if parsed_args.disable:
kwargs['enabled'] = False
+ options = common.get_immutable_options(parsed_args)
+ if options:
+ kwargs['options'] = options
if parsed_args.property:
kwargs.update(parsed_args.property)
tag.update_tags_in_args(parsed_args, project, kwargs)
diff --git a/openstackclient/identity/v3/role.py b/openstackclient/identity/v3/role.py
index 36f3f93..980ebf1 100644
--- a/openstackclient/identity/v3/role.py
+++ b/openstackclient/identity/v3/role.py
@@ -191,6 +191,7 @@ class CreateRole(command.ShowOne):
action='store_true',
help=_('Return existing role'),
)
+ common.add_resource_option_to_parser(parser)
return parser
def take_action(self, parsed_args):
@@ -201,10 +202,12 @@ class CreateRole(command.ShowOne):
domain_id = common.find_domain(identity_client,
parsed_args.domain).id
+ options = common.get_immutable_options(parsed_args)
+
try:
role = identity_client.roles.create(
name=parsed_args.name, domain=domain_id,
- description=parsed_args.description)
+ description=parsed_args.description, options=options)
except ks_exc.Conflict:
if parsed_args.or_show:
@@ -366,6 +369,7 @@ class SetRole(command.Command):
metavar='<name>',
help=_('Set role name'),
)
+ common.add_resource_option_to_parser(parser)
return parser
def take_action(self, parsed_args):
@@ -376,12 +380,14 @@ class SetRole(command.Command):
domain_id = common.find_domain(identity_client,
parsed_args.domain).id
+ options = common.get_immutable_options(parsed_args)
role = utils.find_resource(identity_client.roles,
parsed_args.role,
domain_id=domain_id)
identity_client.roles.update(role.id, name=parsed_args.name,
- description=parsed_args.description)
+ description=parsed_args.description,
+ options=options)
class ShowRole(command.ShowOne):
diff --git a/openstackclient/identity/v3/user.py b/openstackclient/identity/v3/user.py
index ca85c5d..cbc112a 100644
--- a/openstackclient/identity/v3/user.py
+++ b/openstackclient/identity/v3/user.py
@@ -30,6 +30,114 @@ from openstackclient.identity import common
LOG = logging.getLogger(__name__)
+def _get_options_for_user(identity_client, parsed_args):
+ options = {}
+ if parsed_args.ignore_lockout_failure_attempts:
+ options['ignore_lockout_failure_attempts'] = True
+ if parsed_args.no_ignore_lockout_failure_attempts:
+ options['ignore_lockout_failure_attempts'] = False
+ if parsed_args.ignore_password_expiry:
+ options['ignore_password_expiry'] = True
+ if parsed_args.no_ignore_password_expiry:
+ options['ignore_password_expiry'] = False
+ if parsed_args.ignore_change_password_upon_first_use:
+ options['ignore_change_password_upon_first_use'] = True
+ if parsed_args.no_ignore_change_password_upon_first_use:
+ options['ignore_change_password_upon_first_use'] = False
+ if parsed_args.enable_lock_password:
+ options['lock_password'] = True
+ if parsed_args.disable_lock_password:
+ options['lock_password'] = False
+ if parsed_args.enable_multi_factor_auth:
+ options['multi_factor_auth_enabled'] = True
+ if parsed_args.disable_multi_factor_auth:
+ options['multi_factor_auth_enabled'] = False
+ if parsed_args.multi_factor_auth_rule:
+ auth_rules = [rule.split(",") for rule in
+ parsed_args.multi_factor_auth_rule]
+ if auth_rules:
+ options['multi_factor_auth_rules'] = auth_rules
+ return options
+
+
+def _add_user_options(parser):
+ # Add additional user options
+
+ parser.add_argument(
+ '--ignore-lockout-failure-attempts',
+ action="store_true",
+ help=_('Opt into ignoring the number of times a user has '
+ 'authenticated and locking out the user as a result'),
+ )
+ parser.add_argument(
+ '--no-ignore-lockout-failure-attempts',
+ action="store_true",
+ help=_('Opt out of ignoring the number of times a user has '
+ 'authenticated and locking out the user as a result'),
+ )
+ parser.add_argument(
+ '--ignore-password-expiry',
+ action="store_true",
+ help=_('Opt into allowing user to continue using passwords that '
+ 'may be expired'),
+ )
+ parser.add_argument(
+ '--no-ignore-password-expiry',
+ action="store_true",
+ help=_('Opt out of allowing user to continue using passwords '
+ 'that may be expired'),
+ )
+ parser.add_argument(
+ '--ignore-change-password-upon-first-use',
+ action="store_true",
+ help=_('Control if a user should be forced to change their password '
+ 'immediately after they log into keystone for the first time. '
+ 'Opt into ignoring the user to change their password during '
+ 'first time login in keystone'),
+ )
+ parser.add_argument(
+ '--no-ignore-change-password-upon-first-use',
+ action="store_true",
+ help=_('Control if a user should be forced to change their password '
+ 'immediately after they log into keystone for the first time. '
+ 'Opt out of ignoring the user to change their password during '
+ 'first time login in keystone'),
+ )
+ parser.add_argument(
+ '--enable-lock-password',
+ action="store_true",
+ help=_('Disables the ability for a user to change its password '
+ 'through self-service APIs'),
+ )
+ parser.add_argument(
+ '--disable-lock-password',
+ action="store_true",
+ help=_('Enables the ability for a user to change its password '
+ 'through self-service APIs'),
+ )
+ parser.add_argument(
+ '--enable-multi-factor-auth',
+ action="store_true",
+ help=_('Enables the MFA (Multi Factor Auth)'),
+ )
+ parser.add_argument(
+ '--disable-multi-factor-auth',
+ action="store_true",
+ help=_('Disables the MFA (Multi Factor Auth)'),
+ )
+ parser.add_argument(
+ '--multi-factor-auth-rule',
+ metavar='<rule>',
+ action="append",
+ default=[],
+ help=_('Set multi-factor auth rules. For example, to set a rule '
+ 'requiring the "password" and "totp" auth methods to be '
+ 'provided, use: "--multi-factor-auth-rule password,totp". '
+ 'May be provided multiple times to set different rule '
+ 'combinations.')
+ )
+
+
class CreateUser(command.ShowOne):
_description = _("Create new user")
@@ -72,6 +180,8 @@ class CreateUser(command.ShowOne):
metavar='<description>',
help=_('User description'),
)
+ _add_user_options(parser)
+
enable_group = parser.add_mutually_exclusive_group()
enable_group.add_argument(
'--enable',
@@ -113,6 +223,7 @@ class CreateUser(command.ShowOne):
if not parsed_args.password:
LOG.warning(_("No password was supplied, authentication will fail "
"when a user does not have a password."))
+ options = _get_options_for_user(identity_client, parsed_args)
try:
user = identity_client.users.create(
@@ -122,7 +233,8 @@ class CreateUser(command.ShowOne):
password=parsed_args.password,
email=parsed_args.email,
description=parsed_args.description,
- enabled=enabled
+ enabled=enabled,
+ options=options,
)
except ks_exc.Conflict:
if parsed_args.or_show:
@@ -333,6 +445,8 @@ class SetUser(command.Command):
metavar='<description>',
help=_('Set user description'),
)
+ _add_user_options(parser)
+
enable_group = parser.add_mutually_exclusive_group()
enable_group.add_argument(
'--enable',
@@ -390,6 +504,10 @@ class SetUser(command.Command):
if parsed_args.disable:
kwargs['enabled'] = False
+ options = _get_options_for_user(identity_client, parsed_args)
+ if options:
+ kwargs['options'] = options
+
identity_client.users.update(user.id, **kwargs)
diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py
index 53ce560..029f57a 100644
--- a/openstackclient/image/v2/image.py
+++ b/openstackclient/image/v2/image.py
@@ -324,6 +324,14 @@ class CreateImage(command.ShowOne):
metavar="<project>",
help=_("Set an alternate project on this image (name or ID)"),
)
+ parser.add_argument(
+ "--import",
+ dest="use_import",
+ action="store_true",
+ help=_(
+ "Force the use of glance image import instead of"
+ " direct upload")
+ )
common.add_project_domain_option_to_parser(parser)
for deadopt in self.deadopts:
parser.add_argument(
@@ -388,6 +396,9 @@ class CreateImage(command.ShowOne):
parsed_args.project_domain,
).id
+ if parsed_args.use_import:
+ kwargs['use_import'] = True
+
# open the file first to ensure any failures are handled before the
# image is created. Get the file name (if it is file, and not stdin)
# for easier further handling.
@@ -429,8 +440,14 @@ class CreateImage(command.ShowOne):
prompt=("Please enter private key password, leave "
"empty if none: "),
confirm=False)
+
if not pw or len(pw) < 1:
pw = None
+ else:
+ # load_private_key() requires the password to be
+ # passed as bytes
+ pw = pw.encode()
+
signer.load_private_key(
sign_key_path,
password=pw)
diff --git a/openstackclient/network/sdk_utils.py b/openstackclient/network/sdk_utils.py
index af9c74f..cff3071 100644
--- a/openstackclient/network/sdk_utils.py
+++ b/openstackclient/network/sdk_utils.py
@@ -10,6 +10,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import munch
+
def get_osc_show_columns_for_sdk_resource(
sdk_resource,
@@ -38,6 +40,9 @@ def get_osc_show_columns_for_sdk_resource(
# Build the OSC column names to display for the SDK resource.
attr_map = {}
display_columns = list(resource_dict.keys())
+ for col_name in display_columns:
+ if isinstance(resource_dict[col_name], munch.Munch):
+ display_columns.remove(col_name)
invisible_columns = [] if invisible_columns is None else invisible_columns
for col_name in invisible_columns:
if col_name in display_columns:
diff --git a/openstackclient/network/v2/address_scope.py b/openstackclient/network/v2/address_scope.py
index 7efbb63..71c1a9a 100644
--- a/openstackclient/network/v2/address_scope.py
+++ b/openstackclient/network/v2/address_scope.py
@@ -15,7 +15,6 @@
import logging
-from osc_lib.cli import format_columns
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
@@ -28,11 +27,6 @@ from openstackclient.network import sdk_utils
LOG = logging.getLogger(__name__)
-_formatters = {
- 'location': format_columns.DictColumn,
-}
-
-
def _get_columns(item):
column_map = {
'is_shared': 'shared',
@@ -106,7 +100,7 @@ class CreateAddressScope(command.ShowOne):
attrs = _get_attrs(self.app.client_manager, parsed_args)
obj = client.create_address_scope(**attrs)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns, formatters={})
return (display_columns, data)
@@ -295,6 +289,6 @@ class ShowAddressScope(command.ShowOne):
parsed_args.address_scope,
ignore_missing=False)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns, formatters={})
return (display_columns, data)
diff --git a/openstackclient/network/v2/floating_ip.py b/openstackclient/network/v2/floating_ip.py
index f3e3e5c..a2765cd 100644
--- a/openstackclient/network/v2/floating_ip.py
+++ b/openstackclient/network/v2/floating_ip.py
@@ -13,7 +13,6 @@
"""IP Floating action implementations"""
-from osc_lib.cli import format_columns
from osc_lib.command import command
from osc_lib import utils
from osc_lib.utils import tags as _tag
@@ -25,7 +24,6 @@ from openstackclient.network import sdk_utils
_formatters = {
- 'location': format_columns.DictColumn,
'port_details': utils.format_dict,
}
diff --git a/openstackclient/network/v2/floating_ip_port_forwarding.py b/openstackclient/network/v2/floating_ip_port_forwarding.py
index f94bcc0..06b3df8 100644
--- a/openstackclient/network/v2/floating_ip_port_forwarding.py
+++ b/openstackclient/network/v2/floating_ip_port_forwarding.py
@@ -75,6 +75,12 @@ class CreateFloatingIPPortForwarding(command.ShowOne):
required=True,
help=_("The protocol used in the floating IP "
"port forwarding, for instance: TCP, UDP")
+ ),
+ parser.add_argument(
+ '--description',
+ metavar='<description>',
+ help=_("A text to describe/contextualize the use of the "
+ "port forwarding configuration")
)
parser.add_argument(
'floating_ip',
@@ -113,6 +119,9 @@ class CreateFloatingIPPortForwarding(command.ShowOne):
attrs['internal_ip_address'] = parsed_args.internal_ip_address
attrs['protocol'] = parsed_args.protocol
+ if parsed_args.description is not None:
+ attrs['description'] = parsed_args.description
+
obj = client.create_floating_ip_port_forwarding(
floating_ip.id,
**attrs
@@ -212,6 +221,7 @@ class ListFloatingIPPortForwarding(command.Lister):
'internal_port',
'external_port',
'protocol',
+ 'description',
)
headers = (
'ID',
@@ -220,6 +230,7 @@ class ListFloatingIPPortForwarding(command.Lister):
'Internal Port',
'External Port',
'Protocol',
+ 'Description',
)
query = {}
@@ -296,6 +307,12 @@ class SetFloatingIPPortForwarding(command.Command):
metavar='<protocol>',
choices=['tcp', 'udp'],
help=_("The IP protocol used in the floating IP port forwarding")
+ ),
+ parser.add_argument(
+ '--description',
+ metavar='<description>',
+ help=_("A text to describe/contextualize the use of "
+ "the port forwarding configuration")
)
return parser
@@ -332,6 +349,9 @@ class SetFloatingIPPortForwarding(command.Command):
if parsed_args.protocol:
attrs['protocol'] = parsed_args.protocol
+ if parsed_args.description is not None:
+ attrs['description'] = parsed_args.description
+
client.update_floating_ip_port_forwarding(
floating_ip.id, parsed_args.port_forwarding_id, **attrs)
diff --git a/openstackclient/network/v2/ip_availability.py b/openstackclient/network/v2/ip_availability.py
index c026baa..ddc88e5 100644
--- a/openstackclient/network/v2/ip_availability.py
+++ b/openstackclient/network/v2/ip_availability.py
@@ -21,9 +21,7 @@ from openstackclient.i18n import _
from openstackclient.identity import common as identity_common
from openstackclient.network import sdk_utils
-
_formatters = {
- 'location': format_columns.DictColumn,
'subnet_ip_availability': format_columns.ListDictColumn,
}
diff --git a/openstackclient/network/v2/network.py b/openstackclient/network/v2/network.py
index 3f579b6..7a12d52 100644
--- a/openstackclient/network/v2/network.py
+++ b/openstackclient/network/v2/network.py
@@ -16,7 +16,6 @@
from cliff import columns as cliff_columns
from osc_lib.cli import format_columns
from osc_lib.command import command
-from osc_lib import exceptions
from osc_lib import utils
from osc_lib.utils import tags as _tag
@@ -41,7 +40,6 @@ _formatters = {
'subnet_ids': format_columns.ListColumn,
'admin_state_up': AdminStateColumn,
'is_admin_state_up': AdminStateColumn,
- 'location': format_columns.DictColumn,
'router:external': RouterExternalColumn,
'is_router_external': RouterExternalColumn,
'availability_zones': format_columns.ListColumn,
@@ -126,9 +124,6 @@ def _get_attrs_network(client_manager, parsed_args):
attrs['is_default'] = False
if parsed_args.default:
attrs['is_default'] = True
- if attrs.get('is_default') and not attrs.get('router:external'):
- msg = _("Cannot set default for internal network")
- raise exceptions.CommandError(msg)
# Update Provider network options
if parsed_args.provider_network_type:
attrs['provider:network_type'] = parsed_args.provider_network_type
@@ -706,8 +701,7 @@ class SetNetwork(command.Command):
default_router_grp.add_argument(
'--default',
action='store_true',
- help=_("Set the network as the default external network "
- "(cannot be used with internal network).")
+ help=_("Set the network as the default external network")
)
default_router_grp.add_argument(
'--no-default',
diff --git a/openstackclient/network/v2/network_agent.py b/openstackclient/network/v2/network_agent.py
index a6ed362..1678485 100644
--- a/openstackclient/network/v2/network_agent.py
+++ b/openstackclient/network/v2/network_agent.py
@@ -43,7 +43,6 @@ _formatters = {
'alive': AliveColumn,
'admin_state_up': AdminStateColumn,
'is_admin_state_up': AdminStateColumn,
- 'location': format_columns.DictColumn,
'configurations': format_columns.DictColumn,
}
diff --git a/openstackclient/network/v2/network_auto_allocated_topology.py b/openstackclient/network/v2/network_auto_allocated_topology.py
index f6070a0..36f3920 100644
--- a/openstackclient/network/v2/network_auto_allocated_topology.py
+++ b/openstackclient/network/v2/network_auto_allocated_topology.py
@@ -15,7 +15,6 @@
import logging
-from osc_lib.cli import format_columns
from osc_lib.command import command
from osc_lib import utils
@@ -26,11 +25,6 @@ from openstackclient.network import sdk_utils
LOG = logging.getLogger(__name__)
-_formatters = {
- 'location': format_columns.DictColumn,
-}
-
-
def _get_columns(item):
column_map = {
'tenant_id': 'project_id',
@@ -99,17 +93,16 @@ class CreateAutoAllocatedTopology(command.ShowOne):
obj = client.validate_auto_allocated_topology(parsed_args.project)
columns = _format_check_resource_columns()
- data = utils.get_item_properties(
- _format_check_resource(obj),
- columns,
- formatters=_formatters,
- )
+ data = utils.get_item_properties(_format_check_resource(obj),
+ columns,
+ formatters={})
+
return (columns, data)
def get_topology(self, client, parsed_args):
obj = client.get_auto_allocated_topology(parsed_args.project)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns, formatters={})
return (display_columns, data)
def take_action(self, parsed_args):
diff --git a/openstackclient/network/v2/network_flavor.py b/openstackclient/network/v2/network_flavor.py
index 355d04c..c9d368b 100644
--- a/openstackclient/network/v2/network_flavor.py
+++ b/openstackclient/network/v2/network_flavor.py
@@ -15,7 +15,6 @@
import logging
-from osc_lib.cli import format_columns
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
@@ -28,11 +27,6 @@ from openstackclient.network import sdk_utils
LOG = logging.getLogger(__name__)
-_formatters = {
- 'location': format_columns.DictColumn,
-}
-
-
def _get_columns(item):
column_map = {
'is_enabled': 'enabled',
@@ -142,7 +136,7 @@ class CreateNetworkFlavor(command.ShowOne):
attrs = _get_attrs(self.app.client_manager, parsed_args)
obj = client.create_flavor(**attrs)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns, formatters={})
return (display_columns, data)
@@ -306,5 +300,5 @@ class ShowNetworkFlavor(command.ShowOne):
client = self.app.client_manager.network
obj = client.find_flavor(parsed_args.flavor, ignore_missing=False)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns)
return display_columns, data
diff --git a/openstackclient/network/v2/network_flavor_profile.py b/openstackclient/network/v2/network_flavor_profile.py
index 492fd43..6cf0c41 100644
--- a/openstackclient/network/v2/network_flavor_profile.py
+++ b/openstackclient/network/v2/network_flavor_profile.py
@@ -13,7 +13,6 @@
import logging
-from osc_lib.cli import format_columns
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
@@ -26,11 +25,6 @@ from openstackclient.network import sdk_utils
LOG = logging.getLogger(__name__)
-_formatters = {
- 'location': format_columns.DictColumn,
-}
-
-
def _get_columns(item):
column_map = {
'is_enabled': 'enabled',
@@ -116,7 +110,7 @@ class CreateNetworkFlavorProfile(command.ShowOne):
obj = client.create_service_profile(**attrs)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns, formatters={})
return (display_columns, data)
@@ -252,5 +246,5 @@ class ShowNetworkFlavorProfile(command.ShowOne):
obj = client.find_service_profile(parsed_args.flavor_profile,
ignore_missing=False)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns)
return (display_columns, data)
diff --git a/openstackclient/network/v2/network_meter.py b/openstackclient/network/v2/network_meter.py
index cde7a30..df0e1da 100644
--- a/openstackclient/network/v2/network_meter.py
+++ b/openstackclient/network/v2/network_meter.py
@@ -15,7 +15,6 @@
import logging
-from osc_lib.cli import format_columns
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
@@ -27,11 +26,6 @@ from openstackclient.network import sdk_utils
LOG = logging.getLogger(__name__)
-_formatters = {
- 'location': format_columns.DictColumn,
-}
-
-
def _get_columns(item):
column_map = {
'is_shared': 'shared',
@@ -108,7 +102,7 @@ class CreateMeter(command.ShowOne):
attrs = _get_attrs(self.app.client_manager, parsed_args)
obj = client.create_metering_label(**attrs)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns, formatters={})
return (display_columns, data)
@@ -192,5 +186,5 @@ class ShowMeter(command.ShowOne):
obj = client.find_metering_label(parsed_args.meter,
ignore_missing=False)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns)
return display_columns, data
diff --git a/openstackclient/network/v2/network_meter_rule.py b/openstackclient/network/v2/network_meter_rule.py
index 5f31255..49ff9e1 100644
--- a/openstackclient/network/v2/network_meter_rule.py
+++ b/openstackclient/network/v2/network_meter_rule.py
@@ -15,7 +15,6 @@
import logging
-from osc_lib.cli import format_columns
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
@@ -27,11 +26,6 @@ from openstackclient.network import sdk_utils
LOG = logging.getLogger(__name__)
-_formatters = {
- 'location': format_columns.DictColumn,
-}
-
-
def _get_columns(item):
column_map = {
'tenant_id': 'project_id',
@@ -122,7 +116,7 @@ class CreateMeterRule(command.ShowOne):
attrs = _get_attrs(self.app.client_manager, parsed_args)
obj = client.create_metering_label_rule(**attrs)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns, formatters={})
return (display_columns, data)
@@ -205,5 +199,5 @@ class ShowMeterRule(command.ShowOne):
obj = client.find_metering_label_rule(parsed_args.meter_rule_id,
ignore_missing=False)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns)
return display_columns, data
diff --git a/openstackclient/network/v2/network_qos_policy.py b/openstackclient/network/v2/network_qos_policy.py
index 1622de4..fd5ff93 100644
--- a/openstackclient/network/v2/network_qos_policy.py
+++ b/openstackclient/network/v2/network_qos_policy.py
@@ -15,7 +15,6 @@
import logging
-from osc_lib.cli import format_columns
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
@@ -28,11 +27,6 @@ from openstackclient.network import sdk_utils
LOG = logging.getLogger(__name__)
-_formatters = {
- 'location': format_columns.DictColumn,
-}
-
-
def _get_columns(item):
column_map = {
'is_shared': 'shared',
@@ -125,7 +119,7 @@ class CreateNetworkQosPolicy(command.ShowOne):
attrs = _get_attrs(self.app.client_manager, parsed_args)
obj = client.create_qos_policy(**attrs)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns, formatters={})
return (display_columns, data)
@@ -285,5 +279,5 @@ class ShowNetworkQosPolicy(command.ShowOne):
obj = client.find_qos_policy(parsed_args.policy,
ignore_missing=False)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns)
return (display_columns, data)
diff --git a/openstackclient/network/v2/network_qos_rule.py b/openstackclient/network/v2/network_qos_rule.py
index d74beda..28c5600 100644
--- a/openstackclient/network/v2/network_qos_rule.py
+++ b/openstackclient/network/v2/network_qos_rule.py
@@ -15,7 +15,6 @@
import itertools
-from osc_lib.cli import format_columns
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
@@ -47,11 +46,6 @@ ACTION_SET = 'update'
ACTION_SHOW = 'get'
-_formatters = {
- 'location': format_columns.DictColumn,
-}
-
-
def _get_columns(item):
column_map = {
'tenant_id': 'project_id',
@@ -214,7 +208,7 @@ class CreateNetworkQosRule(command.ShowOne):
msg = (_('Failed to create Network QoS rule: %(e)s') % {'e': e})
raise exceptions.CommandError(msg)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns)
return display_columns, data
@@ -364,5 +358,5 @@ class ShowNetworkQosRule(command.ShowOne):
{'rule': rule_id, 'e': e})
raise exceptions.CommandError(msg)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns)
return display_columns, data
diff --git a/openstackclient/network/v2/network_qos_rule_type.py b/openstackclient/network/v2/network_qos_rule_type.py
index e842944..7b92c8a 100644
--- a/openstackclient/network/v2/network_qos_rule_type.py
+++ b/openstackclient/network/v2/network_qos_rule_type.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from osc_lib.cli import format_columns
from osc_lib.command import command
from osc_lib import utils
@@ -21,11 +20,6 @@ from openstackclient.i18n import _
from openstackclient.network import sdk_utils
-_formatters = {
- 'location': format_columns.DictColumn,
-}
-
-
def _get_columns(item):
column_map = {
"type": "rule_type_name",
@@ -71,5 +65,5 @@ class ShowNetworkQosRuleType(command.ShowOne):
client = self.app.client_manager.network
obj = client.get_qos_rule_type(parsed_args.rule_type)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns)
return display_columns, data
diff --git a/openstackclient/network/v2/network_rbac.py b/openstackclient/network/v2/network_rbac.py
index 1781193..b88ef01 100644
--- a/openstackclient/network/v2/network_rbac.py
+++ b/openstackclient/network/v2/network_rbac.py
@@ -15,7 +15,6 @@
import logging
-from osc_lib.cli import format_columns
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
@@ -28,11 +27,6 @@ from openstackclient.network import sdk_utils
LOG = logging.getLogger(__name__)
-_formatters = {
- 'location': format_columns.DictColumn,
-}
-
-
def _get_columns(item):
column_map = {
'target_tenant': 'target_project_id',
@@ -58,6 +52,15 @@ def _get_attrs(client_manager, parsed_args):
object_id = network_client.find_security_group(
parsed_args.rbac_object,
ignore_missing=False).id
+ if parsed_args.type == 'address_scope':
+ object_id = network_client.find_address_scope(
+ parsed_args.rbac_object,
+ ignore_missing=False).id
+ if parsed_args.type == 'subnetpool':
+ object_id = network_client.find_subnet_pool(
+ parsed_args.rbac_object,
+ ignore_missing=False).id
+
attrs['object_id'] = object_id
identity_client = client_manager.identity
@@ -97,9 +100,11 @@ class CreateNetworkRBAC(command.ShowOne):
'--type',
metavar="<type>",
required=True,
- choices=['security_group', 'qos_policy', 'network'],
+ choices=['address_scope', 'security_group', 'subnetpool',
+ 'qos_policy', 'network'],
help=_('Type of the object that RBAC policy '
- 'affects ("security_group", "qos_policy" or "network")')
+ 'affects ("address_scope", "security_group", "subnetpool",'
+ ' "qos_policy" or "network")')
)
parser.add_argument(
'--action',
@@ -142,7 +147,7 @@ class CreateNetworkRBAC(command.ShowOne):
attrs = _get_attrs(self.app.client_manager, parsed_args)
obj = client.create_rbac_policy(**attrs)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns)
return display_columns, data
@@ -188,10 +193,11 @@ class ListNetworkRBAC(command.Lister):
parser.add_argument(
'--type',
metavar='<type>',
- choices=['security_group', 'qos_policy', 'network'],
+ choices=['address_scope', 'security_group', 'subnetpool',
+ 'qos_policy', 'network'],
help=_('List network RBAC policies according to '
- 'given object type ("security_group", "qos_policy" '
- 'or "network")')
+ 'given object type ("address_scope", "security_group", '
+ '"subnetpool", "qos_policy" or "network")')
)
parser.add_argument(
'--action',
@@ -299,5 +305,5 @@ class ShowNetworkRBAC(command.ShowOne):
obj = client.find_rbac_policy(parsed_args.rbac_policy,
ignore_missing=False)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns)
return display_columns, data
diff --git a/openstackclient/network/v2/network_segment.py b/openstackclient/network/v2/network_segment.py
index 5899dc6..c1a672e 100644
--- a/openstackclient/network/v2/network_segment.py
+++ b/openstackclient/network/v2/network_segment.py
@@ -15,7 +15,6 @@
import logging
-from osc_lib.cli import format_columns
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
@@ -27,11 +26,6 @@ from openstackclient.network import sdk_utils
LOG = logging.getLogger(__name__)
-_formatters = {
- 'location': format_columns.DictColumn,
-}
-
-
def _get_columns(item):
return sdk_utils.get_osc_show_columns_for_sdk_resource(item, {})
@@ -96,7 +90,7 @@ class CreateNetworkSegment(command.ShowOne):
attrs['segmentation_id'] = parsed_args.segment
obj = client.create_segment(**attrs)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns)
return (display_columns, data)
@@ -248,5 +242,5 @@ class ShowNetworkSegment(command.ShowOne):
ignore_missing=False
)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns)
return (display_columns, data)
diff --git a/openstackclient/network/v2/network_segment_range.py b/openstackclient/network/v2/network_segment_range.py
index b38c72c..6229995 100644
--- a/openstackclient/network/v2/network_segment_range.py
+++ b/openstackclient/network/v2/network_segment_range.py
@@ -19,7 +19,6 @@
import itertools
import logging
-from osc_lib.cli import format_columns
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
@@ -31,10 +30,6 @@ from openstackclient.network import sdk_utils
LOG = logging.getLogger(__name__)
-_formatters = {
- 'location': format_columns.DictColumn,
-}
-
def _get_columns(item):
return sdk_utils.get_osc_show_columns_for_sdk_resource(item, {})
@@ -216,7 +211,7 @@ class CreateNetworkSegmentRange(command.ShowOne):
attrs['physical_network'] = parsed_args.physical_network
obj = network_client.create_network_segment_range(**attrs)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns)
data = _update_additional_fields_from_props(columns, props=data)
return (display_columns, data)
@@ -455,6 +450,6 @@ class ShowNetworkSegmentRange(command.ShowOne):
ignore_missing=False
)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns)
data = _update_additional_fields_from_props(columns, props=data)
return (display_columns, data)
diff --git a/openstackclient/network/v2/port.py b/openstackclient/network/v2/port.py
index a22bcaf..a21324a 100644
--- a/openstackclient/network/v2/port.py
+++ b/openstackclient/network/v2/port.py
@@ -51,7 +51,6 @@ _formatters = {
'dns_assignment': format_columns.ListDictColumn,
'extra_dhcp_opts': format_columns.ListDictColumn,
'fixed_ips': format_columns.ListDictColumn,
- 'location': format_columns.DictColumn,
'security_group_ids': format_columns.ListColumn,
'tags': format_columns.ListColumn,
}
@@ -516,6 +515,10 @@ class ListPort(command.Lister):
"network:dhcp).")
)
parser.add_argument(
+ '--host',
+ metavar='<host-id>',
+ help=_("List only ports bound to this host ID"))
+ parser.add_argument(
'--network',
metavar='<network>',
help=_("List only ports connected to this network (name or ID)"))
@@ -603,6 +606,8 @@ class ListPort(command.Lister):
server = utils.find_resource(compute_client.servers,
parsed_args.server)
filters['device_id'] = server.id
+ if parsed_args.host:
+ filters['binding:host_id'] = parsed_args.host
if parsed_args.network:
network = network_client.find_network(parsed_args.network,
ignore_missing=False)
diff --git a/openstackclient/network/v2/router.py b/openstackclient/network/v2/router.py
index 464dbbe..e3e8acc 100644
--- a/openstackclient/network/v2/router.py
+++ b/openstackclient/network/v2/router.py
@@ -61,7 +61,6 @@ _formatters = {
'external_gateway_info': RouterInfoColumn,
'availability_zones': format_columns.ListColumn,
'availability_zone_hints': format_columns.ListColumn,
- 'location': format_columns.DictColumn,
'routes': RoutesColumn,
'tags': format_columns.ListColumn,
}
@@ -168,6 +167,93 @@ class AddSubnetToRouter(command.Command):
subnet_id=subnet.id)
+class AddExtraRoutesToRouter(command.ShowOne):
+ _description = _("Add extra static routes to a router's routing table.")
+
+ def get_parser(self, prog_name):
+ parser = super(AddExtraRoutesToRouter, self).get_parser(prog_name)
+ parser.add_argument(
+ 'router',
+ metavar='<router>',
+ help=_("Router to which extra static routes "
+ "will be added (name or ID).")
+ )
+ parser.add_argument(
+ '--route',
+ metavar='destination=<subnet>,gateway=<ip-address>',
+ action=parseractions.MultiKeyValueAction,
+ dest='routes',
+ default=[],
+ required_keys=['destination', 'gateway'],
+ help=_("Add extra static route to the router. "
+ "destination: destination subnet (in CIDR notation), "
+ "gateway: nexthop IP address. "
+ "Repeat option to add multiple routes. "
+ "Trying to add a route that's already present "
+ "(exactly, including destination and nexthop) "
+ "in the routing table is allowed and is considered "
+ "a successful operation.")
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ if parsed_args.routes is not None:
+ for route in parsed_args.routes:
+ route['nexthop'] = route.pop('gateway')
+ client = self.app.client_manager.network
+ router_obj = client.add_extra_routes_to_router(
+ client.find_router(parsed_args.router, ignore_missing=False),
+ body={'router': {'routes': parsed_args.routes}})
+ display_columns, columns = _get_columns(router_obj)
+ data = utils.get_item_properties(
+ router_obj, columns, formatters=_formatters)
+ return (display_columns, data)
+
+
+class RemoveExtraRoutesFromRouter(command.ShowOne):
+ _description = _(
+ "Remove extra static routes from a router's routing table.")
+
+ def get_parser(self, prog_name):
+ parser = super(RemoveExtraRoutesFromRouter, self).get_parser(prog_name)
+ parser.add_argument(
+ 'router',
+ metavar='<router>',
+ help=_("Router from which extra static routes "
+ "will be removed (name or ID).")
+ )
+ parser.add_argument(
+ '--route',
+ metavar='destination=<subnet>,gateway=<ip-address>',
+ action=parseractions.MultiKeyValueAction,
+ dest='routes',
+ default=[],
+ required_keys=['destination', 'gateway'],
+ help=_("Remove extra static route from the router. "
+ "destination: destination subnet (in CIDR notation), "
+ "gateway: nexthop IP address. "
+ "Repeat option to remove multiple routes. "
+ "Trying to remove a route that's already missing "
+ "(fully, including destination and nexthop) "
+ "from the routing table is allowed and is considered "
+ "a successful operation.")
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ if parsed_args.routes is not None:
+ for route in parsed_args.routes:
+ route['nexthop'] = route.pop('gateway')
+ client = self.app.client_manager.network
+ router_obj = client.remove_extra_routes_from_router(
+ client.find_router(parsed_args.router, ignore_missing=False),
+ body={'router': {'routes': parsed_args.routes}})
+ display_columns, columns = _get_columns(router_obj)
+ data = utils.get_item_properties(
+ router_obj, columns, formatters=_formatters)
+ return (display_columns, data)
+
+
# TODO(yanxing'an): Use the SDK resource mapped attribute names once the
# OSC minimum requirements include SDK 1.0.
class CreateRouter(command.ShowOne):
@@ -540,17 +626,21 @@ class SetRouter(command.Command):
dest='routes',
default=None,
required_keys=['destination', 'gateway'],
- help=_("Routes associated with the router "
+ help=_("Add routes to the router "
"destination: destination subnet (in CIDR notation) "
"gateway: nexthop IP address "
- "(repeat option to set multiple routes)")
+ "(repeat option to add multiple routes). "
+ "This is deprecated in favor of 'router add/remove route' "
+ "since it is prone to race conditions between concurrent "
+ "clients when not used together with --no-route to "
+ "overwrite the current value of 'routes'.")
)
parser.add_argument(
'--no-route',
action='store_true',
help=_("Clear routes associated with the router. "
"Specify both --route and --no-route to overwrite "
- "current value of route.")
+ "current value of routes.")
)
routes_ha = parser.add_mutually_exclusive_group()
routes_ha.add_argument(
diff --git a/openstackclient/network/v2/security_group.py b/openstackclient/network/v2/security_group.py
index 2033af1..0732c23 100644
--- a/openstackclient/network/v2/security_group.py
+++ b/openstackclient/network/v2/security_group.py
@@ -16,7 +16,6 @@
import argparse
from cliff import columns as cliff_columns
-from osc_lib.cli import format_columns
from osc_lib.command import command
from osc_lib import utils
from osc_lib.utils import tags as _tag
@@ -77,13 +76,11 @@ class ComputeSecurityGroupRulesColumn(cliff_columns.FormattableColumn):
_formatters_network = {
- 'location': format_columns.DictColumn,
'security_group_rules': NetworkSecurityGroupRulesColumn,
}
_formatters_compute = {
- 'location': format_columns.DictColumn,
'rules': ComputeSecurityGroupRulesColumn,
}
@@ -120,6 +117,19 @@ class CreateSecurityGroup(common.NetworkAndComputeShowOne):
metavar='<project>',
help=self.enhance_help_neutron(_("Owner's project (name or ID)"))
)
+ stateful_group = parser.add_mutually_exclusive_group()
+ stateful_group.add_argument(
+ "--stateful",
+ action='store_true',
+ default=None,
+ help=_("Security group is stateful (Default)")
+ )
+ stateful_group.add_argument(
+ "--stateless",
+ action='store_true',
+ default=None,
+ help=_("Security group is stateless")
+ )
identity_common.add_project_domain_option_to_parser(
parser, enhance_help=self.enhance_help_neutron)
_tag.add_tag_option_to_parser_for_create(
@@ -138,6 +148,10 @@ class CreateSecurityGroup(common.NetworkAndComputeShowOne):
attrs = {}
attrs['name'] = parsed_args.name
attrs['description'] = self._get_description(parsed_args)
+ if parsed_args.stateful:
+ attrs['stateful'] = True
+ if parsed_args.stateless:
+ attrs['stateful'] = False
if parsed_args.project is not None:
identity_client = self.app.client_manager.identity
project_id = identity_common.find_project(
@@ -315,6 +329,19 @@ class SetSecurityGroup(common.NetworkAndComputeCommand):
metavar="<description>",
help=_("New security group description")
)
+ stateful_group = parser.add_mutually_exclusive_group()
+ stateful_group.add_argument(
+ "--stateful",
+ action='store_true',
+ default=None,
+ help=_("Security group is stateful (Default)")
+ )
+ stateful_group.add_argument(
+ "--stateless",
+ action='store_true',
+ default=None,
+ help=_("Security group is stateless")
+ )
return parser
def update_parser_network(self, parser):
@@ -331,6 +358,10 @@ class SetSecurityGroup(common.NetworkAndComputeCommand):
attrs['name'] = parsed_args.name
if parsed_args.description is not None:
attrs['description'] = parsed_args.description
+ if parsed_args.stateful:
+ attrs['stateful'] = True
+ if parsed_args.stateless:
+ attrs['stateful'] = False
# NOTE(rtheis): Previous behavior did not raise a CommandError
# if there were no updates. Maintain this behavior and issue
# the update.
diff --git a/openstackclient/network/v2/security_group_rule.py b/openstackclient/network/v2/security_group_rule.py
index f48478e..1fbd97a 100644
--- a/openstackclient/network/v2/security_group_rule.py
+++ b/openstackclient/network/v2/security_group_rule.py
@@ -16,7 +16,6 @@
import argparse
import logging
-from osc_lib.cli import format_columns
from osc_lib.cli import parseractions
from osc_lib import exceptions
from osc_lib import utils
@@ -31,11 +30,6 @@ from openstackclient.network import utils as network_utils
LOG = logging.getLogger(__name__)
-_formatters = {
- 'location': format_columns.DictColumn,
-}
-
-
def _format_security_group_rule_show(obj):
data = network_utils.transform_compute_security_group_rule(obj)
return zip(*sorted(data.items()))
@@ -353,7 +347,7 @@ class CreateSecurityGroupRule(common.NetworkAndComputeShowOne):
# Create and show the security group rule.
obj = client.create_security_group_rule(**attrs)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns)
return (display_columns, data)
def take_action_compute(self, client, parsed_args):
@@ -620,7 +614,7 @@ class ShowSecurityGroupRule(common.NetworkAndComputeShowOne):
if not obj['remote_ip_prefix']:
obj['remote_ip_prefix'] = _format_remote_ip_prefix(obj)
display_columns, columns = _get_columns(obj)
- data = utils.get_item_properties(obj, columns, formatters=_formatters)
+ data = utils.get_item_properties(obj, columns)
return (display_columns, data)
def take_action_compute(self, client, parsed_args):
diff --git a/openstackclient/network/v2/subnet.py b/openstackclient/network/v2/subnet.py
index f684406..f87f7ab 100644
--- a/openstackclient/network/v2/subnet.py
+++ b/openstackclient/network/v2/subnet.py
@@ -61,7 +61,6 @@ _formatters = {
'allocation_pools': AllocationPoolsColumn,
'dns_nameservers': format_columns.ListColumn,
'host_routes': HostRoutesColumn,
- 'location': format_columns.DictColumn,
'service_types': format_columns.ListColumn,
'tags': format_columns.ListColumn,
}
diff --git a/openstackclient/network/v2/subnet_pool.py b/openstackclient/network/v2/subnet_pool.py
index 2750574..56cf615 100644
--- a/openstackclient/network/v2/subnet_pool.py
+++ b/openstackclient/network/v2/subnet_pool.py
@@ -42,7 +42,6 @@ def _get_columns(item):
_formatters = {
- 'location': format_columns.DictColumn,
'prefixes': format_columns.ListColumn,
'tags': format_columns.ListColumn,
}
diff --git a/openstackclient/tests/functional/common/test_quota.py b/openstackclient/tests/functional/common/test_quota.py
index 9c05746..4c2fc0e 100644
--- a/openstackclient/tests/functional/common/test_quota.py
+++ b/openstackclient/tests/functional/common/test_quota.py
@@ -165,3 +165,47 @@ class QuotaTests(base.TestCase):
# returned attributes
self.assertTrue(cmd_output["key-pairs"] >= 0)
self.assertTrue(cmd_output["snapshots"] >= 0)
+
+ def test_quota_set_force(self):
+ """Test to set instance value by force """
+ json_output = json.loads(self.openstack(
+ 'quota list -f json --detail --compute'
+ ))
+ in_use = limit = None
+ for j in json_output:
+ if j["Resource"] == "instances":
+ in_use = j["In Use"]
+ limit = j["Limit"]
+
+ # Reduce count of in_use
+ in_use = in_use - 1
+ # cannot have negative instances limit
+ if in_use < 0:
+ in_use = 0
+
+ # set the limit by force now
+ self.openstack(
+ 'quota set ' + self.PROJECT_NAME +
+ '--instances ' + str(in_use) + ' --force'
+ )
+ cmd_output = json.loads(self.openstack(
+ 'quota show -f json ' + self.PROJECT_NAME
+ ))
+ self.assertIsNotNone(cmd_output)
+ self.assertEqual(
+ in_use,
+ cmd_output["instances"]
+ )
+
+ # Set instances limit to original limit now
+ self.openstack(
+ 'quota set ' + self.PROJECT_NAME + '--instances ' + str(limit)
+ )
+ cmd_output = json.loads(self.openstack(
+ 'quota show -f json ' + self.PROJECT_NAME
+ ))
+ self.assertIsNotNone(cmd_output)
+ self.assertEqual(
+ limit,
+ cmd_output["instances"]
+ )
diff --git a/openstackclient/tests/functional/identity/v3/test_project.py b/openstackclient/tests/functional/identity/v3/test_project.py
index 96d41c3..27cf448 100644
--- a/openstackclient/tests/functional/identity/v3/test_project.py
+++ b/openstackclient/tests/functional/identity/v3/test_project.py
@@ -79,7 +79,6 @@ class ProjectTests(common.IdentityTests):
'--disable '
'--property k0=v0 '
'%(name)s' % {'new_name': new_project_name,
- 'domain': self.domain_name,
'name': project_name})
self.assertEqual(0, len(raw_output))
# check project details
diff --git a/openstackclient/tests/functional/network/v2/test_router.py b/openstackclient/tests/functional/network/v2/test_router.py
index 05aad7a..0769dca 100644
--- a/openstackclient/tests/functional/network/v2/test_router.py
+++ b/openstackclient/tests/functional/network/v2/test_router.py
@@ -261,3 +261,46 @@ class RouterTests(common.NetworkTagTests):
new_name
))
self.assertIsNone(cmd_output["external_gateway_info"])
+
+ def test_router_add_remove_route(self):
+ network_name = uuid.uuid4().hex
+ subnet_name = uuid.uuid4().hex
+ router_name = uuid.uuid4().hex
+
+ self.openstack('network create %s' % network_name)
+ self.addCleanup(self.openstack, 'network delete %s' % network_name)
+
+ self.openstack(
+ 'subnet create %s '
+ '--network %s --subnet-range 10.0.0.0/24' % (
+ subnet_name, network_name))
+
+ self.openstack('router create %s' % router_name)
+ self.addCleanup(self.openstack, 'router delete %s' % router_name)
+
+ self.openstack('router add subnet %s %s' % (router_name, subnet_name))
+ self.addCleanup(self.openstack, 'router remove subnet %s %s' % (
+ router_name, subnet_name))
+
+ out1 = json.loads(self.openstack(
+ 'router add route -f json %s '
+ '--route destination=10.0.10.0/24,gateway=10.0.0.10' %
+ router_name)),
+ self.assertEqual(1, len(out1[0]['routes']))
+
+ self.addCleanup(
+ self.openstack, 'router set %s --no-route' % router_name)
+
+ out2 = json.loads(self.openstack(
+ 'router add route -f json %s '
+ '--route destination=10.0.10.0/24,gateway=10.0.0.10 '
+ '--route destination=10.0.11.0/24,gateway=10.0.0.11' %
+ router_name)),
+ self.assertEqual(2, len(out2[0]['routes']))
+
+ out3 = json.loads(self.openstack(
+ 'router remove route -f json %s '
+ '--route destination=10.0.11.0/24,gateway=10.0.0.11 '
+ '--route destination=10.0.12.0/24,gateway=10.0.0.12' %
+ router_name)),
+ self.assertEqual(1, len(out3[0]['routes']))
diff --git a/openstackclient/tests/functional/network/v2/test_security_group.py b/openstackclient/tests/functional/network/v2/test_security_group.py
index 8ae24b7..d46f8db 100644
--- a/openstackclient/tests/functional/network/v2/test_security_group.py
+++ b/openstackclient/tests/functional/network/v2/test_security_group.py
@@ -42,7 +42,7 @@ class SecurityGroupTests(common.NetworkTests):
def test_security_group_set(self):
other_name = uuid.uuid4().hex
raw_output = self.openstack(
- 'security group set --description NSA --name ' +
+ 'security group set --description NSA --stateless --name ' +
other_name + ' ' + self.NAME
)
self.assertEqual('', raw_output)
@@ -50,8 +50,10 @@ class SecurityGroupTests(common.NetworkTests):
cmd_output = json.loads(self.openstack(
'security group show -f json ' + other_name))
self.assertEqual('NSA', cmd_output['description'])
+ self.assertFalse(cmd_output['stateful'])
def test_security_group_show(self):
cmd_output = json.loads(self.openstack(
'security group show -f json ' + self.NAME))
self.assertEqual(self.NAME, cmd_output['name'])
+ self.assertTrue(cmd_output['stateful'])
diff --git a/openstackclient/tests/unit/api/test_object_store_v1.py b/openstackclient/tests/unit/api/test_object_store_v1.py
index 96c68d5..b9e0740 100644
--- a/openstackclient/tests/unit/api/test_object_store_v1.py
+++ b/openstackclient/tests/unit/api/test_object_store_v1.py
@@ -30,8 +30,10 @@ FAKE_CONTAINER = 'rainbarrel'
FAKE_OBJECT = 'spigot'
LIST_CONTAINER_RESP = [
- 'qaz',
- 'fred',
+ {"name": "qaz", "count": 0, "bytes": 0,
+ "last_modified": "2020-05-16T05:52:07.377550"},
+ {"name": "fred", "count": 0, "bytes": 0,
+ "last_modified": "2020-05-16T05:55:07.377550"},
]
LIST_OBJECT_RESP = [
@@ -117,34 +119,32 @@ class TestContainer(TestObjectAPIv1):
)
self.assertEqual(LIST_CONTAINER_RESP, ret)
-# def test_container_list_full_listing(self):
-# sess = self.app.client_manager.session
-#
-# def side_effect(*args, **kwargs):
-# rv = sess.get().json.return_value
-# sess.get().json.return_value = []
-# sess.get().json.side_effect = None
-# return rv
-#
-# resp = [{'name': 'is-name'}]
-# sess.get().json.return_value = resp
-# sess.get().json.side_effect = side_effect
-#
-# data = lib_container.list_containers(
-# self.app.client_manager.session,
-# fake_url,
-# full_listing=True,
-# )
-#
-# # Check expected values
-# sess.get.assert_called_with(
-# fake_url,
-# params={
-# 'format': 'json',
-# 'marker': 'is-name',
-# }
-# )
-# self.assertEqual(resp, data)
+ def test_container_list_full_listing(self):
+ self.requests_mock.register_uri(
+ 'GET',
+ FAKE_URL + '?limit=1&format=json',
+ json=[LIST_CONTAINER_RESP[0]],
+ status_code=200,
+ )
+ self.requests_mock.register_uri(
+ 'GET',
+ FAKE_URL +
+ '?marker=%s&limit=1&format=json' % LIST_CONTAINER_RESP[0]['name'],
+ json=[LIST_CONTAINER_RESP[1]],
+ status_code=200,
+ )
+ self.requests_mock.register_uri(
+ 'GET',
+ FAKE_URL +
+ '?marker=%s&limit=1&format=json' % LIST_CONTAINER_RESP[1]['name'],
+ json=[],
+ status_code=200,
+ )
+ ret = self.api.container_list(
+ limit=1,
+ full_listing=True,
+ )
+ self.assertEqual(LIST_CONTAINER_RESP, ret)
def test_container_show(self):
headers = {
diff --git a/openstackclient/tests/unit/common/test_parseractions.py b/openstackclient/tests/unit/common/test_parseractions.py
index d015da4..736cd0b 100644
--- a/openstackclient/tests/unit/common/test_parseractions.py
+++ b/openstackclient/tests/unit/common/test_parseractions.py
@@ -92,7 +92,7 @@ class TestMultiKeyValueAction(utils.TestCase):
{'req1': 'aaa', 'req2': 'bbb'},
{'req1': '', 'req2': ''},
]
- self.assertItemsEqual(expect, actual)
+ self.assertCountEqual(expect, actual)
def test_empty_required_optional(self):
self.parser.add_argument(
@@ -116,7 +116,7 @@ class TestMultiKeyValueAction(utils.TestCase):
{'req1': 'aaa', 'req2': 'bbb'},
{'req1': '', 'req2': ''},
]
- self.assertItemsEqual(expect, actual)
+ self.assertCountEqual(expect, actual)
def test_error_values_with_comma(self):
self.assertRaises(
diff --git a/openstackclient/tests/unit/common/test_quota.py b/openstackclient/tests/unit/common/test_quota.py
index bd59ca7..6504c5b 100644
--- a/openstackclient/tests/unit/common/test_quota.py
+++ b/openstackclient/tests/unit/common/test_quota.py
@@ -392,6 +392,29 @@ class TestQuotaList(TestQuota):
parsed_args,
)
+ def test_quota_list_compute_by_project(self):
+ # Two projects with non-default quotas
+ self.compute.quotas.get = mock.Mock(
+ side_effect=self.compute_quotas,
+ )
+
+ arglist = [
+ '--compute',
+ '--project', self.projects[0].name,
+ ]
+ verifylist = [
+ ('compute', True),
+ ('project', self.projects[0].name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ ret_quotas = list(data)
+
+ self.assertEqual(self.compute_column_header, columns)
+ self.assertEqual(self.compute_reference_data, ret_quotas[0])
+ self.assertEqual(1, len(ret_quotas))
+
def test_quota_list_network(self):
# Two projects with non-default quotas
self.network.get_quota = mock.Mock(
@@ -461,6 +484,29 @@ class TestQuotaList(TestQuota):
self.assertEqual(self.network_reference_data, ret_quotas[0])
self.assertEqual(1, len(ret_quotas))
+ def test_quota_list_network_by_project(self):
+ # Two projects with non-default quotas
+ self.network.get_quota = mock.Mock(
+ side_effect=self.network_quotas,
+ )
+
+ arglist = [
+ '--network',
+ '--project', self.projects[0].name,
+ ]
+ verifylist = [
+ ('network', True),
+ ('project', self.projects[0].name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ ret_quotas = list(data)
+
+ self.assertEqual(self.network_column_header, columns)
+ self.assertEqual(self.network_reference_data, ret_quotas[0])
+ self.assertEqual(1, len(ret_quotas))
+
def test_quota_list_volume(self):
# Two projects with non-default quotas
self.volume.quotas.get = mock.Mock(
@@ -530,6 +576,29 @@ class TestQuotaList(TestQuota):
self.assertEqual(self.volume_reference_data, ret_quotas[0])
self.assertEqual(1, len(ret_quotas))
+ def test_quota_list_volume_by_project(self):
+ # Two projects with non-default quotas
+ self.volume.quotas.get = mock.Mock(
+ side_effect=self.volume_quotas,
+ )
+
+ arglist = [
+ '--volume',
+ '--project', self.projects[0].name,
+ ]
+ verifylist = [
+ ('volume', True),
+ ('project', self.projects[0].name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ ret_quotas = list(data)
+
+ self.assertEqual(self.volume_column_header, columns)
+ self.assertEqual(self.volume_reference_data, ret_quotas[0])
+ self.assertEqual(1, len(ret_quotas))
+
class TestQuotaSet(TestQuota):
@@ -831,6 +900,56 @@ class TestQuotaSet(TestQuota):
self.assertNotCalled(self.network_mock.update_quota)
self.assertIsNone(result)
+ def test_quota_set_with_force(self):
+ arglist = [
+ '--cores', str(compute_fakes.core_num),
+ '--ram', str(compute_fakes.ram_num),
+ '--instances', str(compute_fakes.instance_num),
+ '--volumes', str(volume_fakes.QUOTA['volumes']),
+ '--subnets', str(network_fakes.QUOTA['subnet']),
+ '--force',
+ self.projects[0].name,
+ ]
+ verifylist = [
+ ('cores', compute_fakes.core_num),
+ ('ram', compute_fakes.ram_num),
+ ('instances', compute_fakes.instance_num),
+ ('volumes', volume_fakes.QUOTA['volumes']),
+ ('subnet', network_fakes.QUOTA['subnet']),
+ ('force', True),
+ ('project', self.projects[0].name),
+ ]
+ self.app.client_manager.network_endpoint_enabled = True
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ kwargs_compute = {
+ 'cores': compute_fakes.core_num,
+ 'ram': compute_fakes.ram_num,
+ 'instances': compute_fakes.instance_num,
+ 'force': True,
+ }
+ kwargs_volume = {
+ 'volumes': volume_fakes.QUOTA['volumes'],
+ }
+ kwargs_network = {
+ 'subnet': network_fakes.QUOTA['subnet'],
+ }
+ self.compute_quotas_mock.update.assert_called_once_with(
+ self.projects[0].id,
+ **kwargs_compute
+ )
+ self.volume_quotas_mock.update.assert_called_once_with(
+ self.projects[0].id,
+ **kwargs_volume
+ )
+ self.network_mock.update_quota.assert_called_once_with(
+ self.projects[0].id,
+ **kwargs_network
+ )
+ self.assertIsNone(result)
+
class TestQuotaShow(TestQuota):
diff --git a/openstackclient/tests/unit/compute/v2/test_server.py b/openstackclient/tests/unit/compute/v2/test_server.py
index 8ec8217..7e4c71c 100644
--- a/openstackclient/tests/unit/compute/v2/test_server.py
+++ b/openstackclient/tests/unit/compute/v2/test_server.py
@@ -3577,6 +3577,41 @@ class TestServerRebuild(TestServer):
self.cmd = server.RebuildServer(self.app, None)
+ def test_rebuild_with_image_name(self):
+ image_name = 'my-custom-image'
+ user_image = image_fakes.FakeImage.create_one_image(
+ attrs={'name': image_name})
+ self.find_image_mock.return_value = user_image
+
+ attrs = {
+ 'image': {
+ 'id': user_image.id
+ },
+ 'networks': {},
+ 'adminPass': 'passw0rd',
+ }
+ new_server = compute_fakes.FakeServer.create_one_server(attrs=attrs)
+ self.server.rebuild.return_value = new_server
+
+ arglist = [
+ self.server.id,
+ '--image', image_name
+ ]
+ verifylist = [
+ ('server', self.server.id),
+ ('image', image_name)
+ ]
+ 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.find_image_mock.assert_called_with(
+ image_name, ignore_missing=False)
+ self.get_image_mock.assert_called_with(user_image.id)
+ self.server.rebuild.assert_called_with(user_image, None)
+
def test_rebuild_with_current_image(self):
arglist = [
self.server.id,
@@ -3590,6 +3625,7 @@ class TestServerRebuild(TestServer):
self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(self.server.id)
+ self.find_image_mock.assert_not_called()
self.get_image_mock.assert_called_with(self.image.id)
self.server.rebuild.assert_called_with(self.image, None)
diff --git a/openstackclient/tests/unit/identity/v3/fakes.py b/openstackclient/tests/unit/identity/v3/fakes.py
index eb3ce2a..58d5d14 100644
--- a/openstackclient/tests/unit/identity/v3/fakes.py
+++ b/openstackclient/tests/unit/identity/v3/fakes.py
@@ -108,6 +108,9 @@ MAPPING_RESPONSE_2 = {
"rules": MAPPING_RULES_2
}
+mfa_opt1 = 'password,totp'
+mfa_opt2 = 'password'
+
project_id = '8-9-64'
project_name = 'beatles'
project_description = 'Fab Four'
diff --git a/openstackclient/tests/unit/identity/v3/test_access_rule.py b/openstackclient/tests/unit/identity/v3/test_access_rule.py
index f8b6093..904fe32 100644
--- a/openstackclient/tests/unit/identity/v3/test_access_rule.py
+++ b/openstackclient/tests/unit/identity/v3/test_access_rule.py
@@ -14,8 +14,8 @@
#
import copy
+from unittest import mock
-import mock
from osc_lib import exceptions
from osc_lib import utils
diff --git a/openstackclient/tests/unit/identity/v3/test_domain.py b/openstackclient/tests/unit/identity/v3/test_domain.py
index 014986e..46f389e 100644
--- a/openstackclient/tests/unit/identity/v3/test_domain.py
+++ b/openstackclient/tests/unit/identity/v3/test_domain.py
@@ -68,6 +68,7 @@ class TestDomainCreate(TestDomain):
kwargs = {
'name': self.domain.name,
'description': None,
+ 'options': {},
'enabled': True,
}
self.domains_mock.create.assert_called_with(
@@ -97,6 +98,7 @@ class TestDomainCreate(TestDomain):
kwargs = {
'name': self.domain.name,
'description': 'new desc',
+ 'options': {},
'enabled': True,
}
self.domains_mock.create.assert_called_with(
@@ -126,6 +128,7 @@ class TestDomainCreate(TestDomain):
kwargs = {
'name': self.domain.name,
'description': None,
+ 'options': {},
'enabled': True,
}
self.domains_mock.create.assert_called_with(
@@ -155,6 +158,7 @@ class TestDomainCreate(TestDomain):
kwargs = {
'name': self.domain.name,
'description': None,
+ 'options': {},
'enabled': False,
}
self.domains_mock.create.assert_called_with(
@@ -164,6 +168,66 @@ class TestDomainCreate(TestDomain):
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, data)
+ def test_domain_create_with_immutable(self):
+ arglist = [
+ '--immutable',
+ self.domain.name,
+ ]
+ verifylist = [
+ ('immutable', True),
+ ('name', self.domain.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.domain.name,
+ 'description': None,
+ 'options': {'immutable': True},
+ 'enabled': True,
+ }
+ self.domains_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
+ def test_domain_create_with_no_immutable(self):
+ arglist = [
+ '--no-immutable',
+ self.domain.name,
+ ]
+ verifylist = [
+ ('no_immutable', True),
+ ('name', self.domain.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.domain.name,
+ 'description': None,
+ 'options': {'immutable': False},
+ 'enabled': True,
+ }
+ self.domains_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
class TestDomainDelete(TestDomain):
@@ -354,6 +418,52 @@ class TestDomainSet(TestDomain):
)
self.assertIsNone(result)
+ def test_domain_set_immutable_option(self):
+ arglist = [
+ '--immutable',
+ self.domain.id,
+ ]
+ verifylist = [
+ ('immutable', True),
+ ('domain', self.domain.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'options': {'immutable': True},
+ }
+ self.domains_mock.update.assert_called_with(
+ self.domain.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_domain_set_no_immutable_option(self):
+ arglist = [
+ '--no-immutable',
+ self.domain.id,
+ ]
+ verifylist = [
+ ('no_immutable', True),
+ ('domain', self.domain.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'options': {'immutable': False},
+ }
+ self.domains_mock.update.assert_called_with(
+ self.domain.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
class TestDomainShow(TestDomain):
diff --git a/openstackclient/tests/unit/identity/v3/test_project.py b/openstackclient/tests/unit/identity/v3/test_project.py
index 466bea1..dfd0805 100644
--- a/openstackclient/tests/unit/identity/v3/test_project.py
+++ b/openstackclient/tests/unit/identity/v3/test_project.py
@@ -98,7 +98,8 @@ class TestProjectCreate(TestProject):
'description': None,
'enabled': True,
'parent': None,
- 'tags': []
+ 'tags': [],
+ 'options': {},
}
# ProjectManager.create(name=, domain=, description=,
# enabled=, **kwargs)
@@ -156,7 +157,8 @@ class TestProjectCreate(TestProject):
'description': 'new desc',
'enabled': True,
'parent': None,
- 'tags': []
+ 'tags': [],
+ 'options': {},
}
# ProjectManager.create(name=, domain=, description=,
# enabled=, **kwargs)
@@ -194,7 +196,8 @@ class TestProjectCreate(TestProject):
'description': None,
'enabled': True,
'parent': None,
- 'tags': []
+ 'tags': [],
+ 'options': {},
}
# ProjectManager.create(name=, domain=, description=,
# enabled=, **kwargs)
@@ -232,7 +235,8 @@ class TestProjectCreate(TestProject):
'description': None,
'enabled': True,
'parent': None,
- 'tags': []
+ 'tags': [],
+ 'options': {},
}
self.projects_mock.create.assert_called_with(
**kwargs
@@ -266,7 +270,8 @@ class TestProjectCreate(TestProject):
'description': None,
'enabled': True,
'parent': None,
- 'tags': []
+ 'tags': [],
+ 'options': {},
}
# ProjectManager.create(name=, domain=, description=,
# enabled=, **kwargs)
@@ -302,7 +307,8 @@ class TestProjectCreate(TestProject):
'description': None,
'enabled': False,
'parent': None,
- 'tags': []
+ 'tags': [],
+ 'options': {},
}
# ProjectManager.create(name=, domain=,
# description=, enabled=, **kwargs)
@@ -339,7 +345,8 @@ class TestProjectCreate(TestProject):
'parent': None,
'fee': 'fi',
'fo': 'fum',
- 'tags': []
+ 'tags': [],
+ 'options': {},
}
# ProjectManager.create(name=, domain=, description=,
# enabled=, **kwargs)
@@ -350,6 +357,126 @@ class TestProjectCreate(TestProject):
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, data)
+ def test_project_create_is_domain_false_property(self):
+ arglist = [
+ '--property', 'is_domain=false',
+ self.project.name,
+ ]
+ verifylist = [
+ ('parent', None),
+ ('enable', False),
+ ('disable', False),
+ ('name', self.project.name),
+ ('tags', []),
+ ('property', {'is_domain': 'false'}),
+ ('name', self.project.name),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.project.name,
+ 'domain': None,
+ 'description': None,
+ 'enabled': True,
+ 'parent': None,
+ 'is_domain': False,
+ 'tags': [],
+ 'options': {},
+ }
+ self.projects_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
+ def test_project_create_is_domain_true_property(self):
+ arglist = [
+ '--property', 'is_domain=true',
+ self.project.name,
+ ]
+ verifylist = [
+ ('parent', None),
+ ('enable', False),
+ ('disable', False),
+ ('name', self.project.name),
+ ('tags', []),
+ ('property', {'is_domain': 'true'}),
+ ('name', self.project.name),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.project.name,
+ 'domain': None,
+ 'description': None,
+ 'enabled': True,
+ 'parent': None,
+ 'is_domain': True,
+ 'tags': [],
+ 'options': {},
+ }
+ self.projects_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
+ def test_project_create_is_domain_none_property(self):
+ arglist = [
+ '--property', 'is_domain=none',
+ self.project.name,
+ ]
+ verifylist = [
+ ('parent', None),
+ ('enable', False),
+ ('disable', False),
+ ('name', self.project.name),
+ ('tags', []),
+ ('property', {'is_domain': 'none'}),
+ ('name', self.project.name),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.project.name,
+ 'domain': None,
+ 'description': None,
+ 'enabled': True,
+ 'parent': None,
+ 'is_domain': None,
+ 'tags': [],
+ 'options': {},
+ }
+ self.projects_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
def test_project_create_parent(self):
self.parent = identity_fakes.FakeProject.create_one_project()
self.project = identity_fakes.FakeProject.create_one_project(
@@ -380,7 +507,8 @@ class TestProjectCreate(TestProject):
'parent': self.parent.id,
'description': None,
'enabled': True,
- 'tags': []
+ 'tags': [],
+ 'options': {},
}
self.projects_mock.create.assert_called_with(
@@ -465,8 +593,89 @@ class TestProjectCreate(TestProject):
'description': None,
'enabled': True,
'parent': None,
- 'tags': ['foo']
+ 'tags': ['foo'],
+ 'options': {},
+ }
+ self.projects_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
+ def test_project_create_with_immutable_option(self):
+ arglist = [
+ '--immutable',
+ self.project.name,
+ ]
+ verifylist = [
+ ('immutable', True),
+ ('description', None),
+ ('enable', False),
+ ('disable', False),
+ ('name', self.project.name),
+ ('parent', None),
+ ('tags', [])
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.project.name,
+ 'domain': None,
+ 'description': None,
+ 'enabled': True,
+ 'parent': None,
+ 'tags': [],
+ 'options': {'immutable': True},
}
+ # ProjectManager.create(name=, domain=, description=,
+ # enabled=, **kwargs)
+ self.projects_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
+ def test_project_create_with_no_immutable_option(self):
+ arglist = [
+ '--no-immutable',
+ self.project.name,
+ ]
+ verifylist = [
+ ('no_immutable', True),
+ ('description', None),
+ ('enable', False),
+ ('disable', False),
+ ('name', self.project.name),
+ ('parent', None),
+ ('tags', [])
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.project.name,
+ 'domain': None,
+ 'description': None,
+ 'enabled': True,
+ 'parent': None,
+ 'tags': [],
+ 'options': {'immutable': False},
+ }
+ # ProjectManager.create(name=, domain=, description=,
+ # enabled=, **kwargs)
self.projects_mock.create.assert_called_with(
**kwargs
)
@@ -927,6 +1136,60 @@ class TestProjectSet(TestProject):
)
self.assertIsNone(result)
+ def test_project_set_with_immutable_option(self):
+ arglist = [
+ '--domain', self.project.domain_id,
+ '--immutable',
+ self.project.name,
+ ]
+ verifylist = [
+ ('domain', self.project.domain_id),
+ ('immutable', True),
+ ('enable', False),
+ ('disable', False),
+ ('project', self.project.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'options': {'immutable': True},
+ }
+ self.projects_mock.update.assert_called_with(
+ self.project.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_project_set_with_no_immutable_option(self):
+ arglist = [
+ '--domain', self.project.domain_id,
+ '--no-immutable',
+ self.project.name,
+ ]
+ verifylist = [
+ ('domain', self.project.domain_id),
+ ('no_immutable', True),
+ ('enable', False),
+ ('disable', False),
+ ('project', self.project.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'options': {'immutable': False},
+ }
+ self.projects_mock.update.assert_called_with(
+ self.project.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
class TestProjectShow(TestProject):
diff --git a/openstackclient/tests/unit/identity/v3/test_role.py b/openstackclient/tests/unit/identity/v3/test_role.py
index 4278ab1..544da7c 100644
--- a/openstackclient/tests/unit/identity/v3/test_role.py
+++ b/openstackclient/tests/unit/identity/v3/test_role.py
@@ -333,6 +333,7 @@ class TestRoleCreate(TestRole):
'domain': None,
'name': identity_fakes.role_name,
'description': None,
+ 'options': {},
}
# RoleManager.create(name=, domain=)
@@ -377,6 +378,7 @@ class TestRoleCreate(TestRole):
'domain': identity_fakes.domain_id,
'name': identity_fakes.ROLE_2['name'],
'description': None,
+ 'options': {},
}
# RoleManager.create(name=, domain=)
@@ -420,6 +422,97 @@ class TestRoleCreate(TestRole):
'description': identity_fakes.role_description,
'name': identity_fakes.ROLE_2['name'],
'domain': None,
+ 'options': {},
+ }
+
+ # RoleManager.create(name=, domain=)
+ self.roles_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ collist = ('domain', 'id', 'name')
+ self.assertEqual(collist, columns)
+ datalist = (
+ 'd1',
+ identity_fakes.ROLE_2['id'],
+ identity_fakes.ROLE_2['name'],
+ )
+ self.assertEqual(datalist, data)
+
+ def test_role_create_with_immutable_option(self):
+
+ self.roles_mock.create.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes.ROLE_2),
+ loaded=True,
+ )
+ arglist = [
+ '--immutable',
+ identity_fakes.ROLE_2['name'],
+ ]
+ verifylist = [
+ ('immutable', True),
+ ('name', identity_fakes.ROLE_2['name']),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+
+ 'options': {'immutable': True},
+ 'description': None,
+ 'name': identity_fakes.ROLE_2['name'],
+ 'domain': None,
+ }
+
+ # RoleManager.create(name=, domain=)
+ self.roles_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ collist = ('domain', 'id', 'name')
+ self.assertEqual(collist, columns)
+ datalist = (
+ 'd1',
+ identity_fakes.ROLE_2['id'],
+ identity_fakes.ROLE_2['name'],
+ )
+ self.assertEqual(datalist, data)
+
+ def test_role_create_with_no_immutable_option(self):
+
+ self.roles_mock.create.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes.ROLE_2),
+ loaded=True,
+ )
+ arglist = [
+ '--no-immutable',
+ identity_fakes.ROLE_2['name'],
+ ]
+ verifylist = [
+ ('no_immutable', True),
+ ('name', identity_fakes.ROLE_2['name']),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+
+ 'options': {'immutable': False},
+ 'description': None,
+ 'name': identity_fakes.ROLE_2['name'],
+ 'domain': None,
}
# RoleManager.create(name=, domain=)
@@ -871,6 +964,7 @@ class TestRoleSet(TestRole):
kwargs = {
'name': 'over',
'description': None,
+ 'options': {},
}
# RoleManager.update(role, name=)
self.roles_mock.update.assert_called_with(
@@ -903,6 +997,7 @@ class TestRoleSet(TestRole):
kwargs = {
'name': 'over',
'description': None,
+ 'options': {},
}
# RoleManager.update(role, name=)
self.roles_mock.update.assert_called_with(
@@ -935,6 +1030,73 @@ class TestRoleSet(TestRole):
kwargs = {
'name': 'over',
'description': identity_fakes.role_description,
+ 'options': {},
+ }
+ # RoleManager.update(role, name=)
+ self.roles_mock.update.assert_called_with(
+ identity_fakes.ROLE_2['id'],
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_role_set_with_immutable(self):
+ self.roles_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes.ROLE_2),
+ loaded=True,
+ )
+ arglist = [
+ '--name', 'over',
+ '--immutable',
+ identity_fakes.ROLE_2['name'],
+ ]
+ verifylist = [
+ ('name', 'over'),
+ ('immutable', True),
+ ('role', identity_fakes.ROLE_2['name']),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': 'over',
+ 'description': None,
+ 'options': {'immutable': True},
+ }
+ # RoleManager.update(role, name=)
+ self.roles_mock.update.assert_called_with(
+ identity_fakes.ROLE_2['id'],
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_role_set_with_no_immutable(self):
+ self.roles_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes.ROLE_2),
+ loaded=True,
+ )
+ arglist = [
+ '--name', 'over',
+ '--no-immutable',
+ identity_fakes.ROLE_2['name'],
+ ]
+ verifylist = [
+ ('name', 'over'),
+ ('no_immutable', True),
+ ('role', identity_fakes.ROLE_2['name']),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': 'over',
+ 'description': None,
+ 'options': {'immutable': False},
}
# RoleManager.update(role, name=)
self.roles_mock.update.assert_called_with(
diff --git a/openstackclient/tests/unit/identity/v3/test_user.py b/openstackclient/tests/unit/identity/v3/test_user.py
index 4b14bca..c71435b 100644
--- a/openstackclient/tests/unit/identity/v3/test_user.py
+++ b/openstackclient/tests/unit/identity/v3/test_user.py
@@ -111,6 +111,7 @@ class TestUserCreate(TestUser):
'description': None,
'domain': None,
'email': None,
+ 'options': {},
'enabled': True,
'password': None,
}
@@ -150,6 +151,7 @@ class TestUserCreate(TestUser):
'description': None,
'domain': None,
'email': None,
+ 'options': {},
'enabled': True,
'password': 'secret',
}
@@ -190,6 +192,7 @@ class TestUserCreate(TestUser):
'description': None,
'domain': None,
'email': None,
+ 'options': {},
'enabled': True,
'password': 'abc123',
}
@@ -228,6 +231,7 @@ class TestUserCreate(TestUser):
'domain': None,
'email': 'barney@example.com',
'enabled': True,
+ 'options': {},
'password': None,
}
# UserManager.create(name=, domain=, project=, password=, email=,
@@ -265,6 +269,7 @@ class TestUserCreate(TestUser):
'domain': None,
'email': None,
'enabled': True,
+ 'options': {},
'password': None,
}
# UserManager.create(name=, domain=, project=, password=, email=,
@@ -311,6 +316,7 @@ class TestUserCreate(TestUser):
'description': None,
'domain': None,
'email': None,
+ 'options': {},
'enabled': True,
'password': None,
}
@@ -356,6 +362,7 @@ class TestUserCreate(TestUser):
'description': None,
'domain': self.domain.id,
'email': None,
+ 'options': {},
'enabled': True,
'password': None,
}
@@ -392,6 +399,7 @@ class TestUserCreate(TestUser):
'description': None,
'domain': None,
'email': None,
+ 'options': {},
'enabled': True,
'password': None,
}
@@ -428,6 +436,7 @@ class TestUserCreate(TestUser):
'description': None,
'domain': None,
'email': None,
+ 'options': {},
'enabled': False,
'password': None,
}
@@ -438,6 +447,471 @@ class TestUserCreate(TestUser):
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, data)
+ def test_user_create_ignore_lockout_failure_attempts(self):
+ arglist = [
+ '--ignore-lockout-failure-attempts',
+ self.user.name,
+ ]
+ verifylist = [
+ ('ignore_lockout_failure_attempts', True),
+ ('enable', False),
+ ('disable', False),
+ ('name', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.user.name,
+ 'default_project': None,
+ 'description': None,
+ 'domain': None,
+ 'email': None,
+ 'enabled': True,
+ 'options': {'ignore_lockout_failure_attempts': True},
+ 'password': None,
+ }
+ # UserManager.create(name=, domain=, project=, password=, email=,
+ # description=, enabled=, default_project=)
+ self.users_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
+ def test_user_create_no_ignore_lockout_failure_attempts(self):
+ arglist = [
+ '--no-ignore-lockout-failure-attempts',
+ self.user.name,
+ ]
+ verifylist = [
+ ('no_ignore_lockout_failure_attempts', True),
+ ('enable', False),
+ ('disable', False),
+ ('name', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.user.name,
+ 'default_project': None,
+ 'description': None,
+ 'domain': None,
+ 'email': None,
+ 'enabled': True,
+ 'options': {'ignore_lockout_failure_attempts': False},
+ 'password': None,
+ }
+ # UserManager.create(name=, domain=, project=, password=, email=,
+ # description=, enabled=, default_project=)
+ self.users_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
+ def test_user_create_ignore_password_expiry(self):
+ arglist = [
+ '--ignore-password-expiry',
+ self.user.name,
+ ]
+ verifylist = [
+ ('ignore_password_expiry', True),
+ ('enable', False),
+ ('disable', False),
+ ('name', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.user.name,
+ 'default_project': None,
+ 'description': None,
+ 'domain': None,
+ 'email': None,
+ 'enabled': True,
+ 'options': {'ignore_password_expiry': True},
+ 'password': None,
+ }
+ # UserManager.create(name=, domain=, project=, password=, email=,
+ # description=, enabled=, default_project=)
+ self.users_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
+ def test_user_create_no_ignore_password_expiry(self):
+ arglist = [
+ '--no-ignore-password-expiry',
+ self.user.name,
+ ]
+ verifylist = [
+ ('no_ignore_password_expiry', True),
+ ('enable', False),
+ ('disable', False),
+ ('name', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.user.name,
+ 'default_project': None,
+ 'description': None,
+ 'domain': None,
+ 'email': None,
+ 'enabled': True,
+ 'options': {'ignore_password_expiry': False},
+ 'password': None,
+ }
+ # UserManager.create(name=, domain=, project=, password=, email=,
+ # description=, enabled=, default_project=)
+ self.users_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
+ def test_user_create_ignore_change_password_upon_first_use(self):
+ arglist = [
+ '--ignore-change-password-upon-first-use',
+ self.user.name,
+ ]
+ verifylist = [
+ ('ignore_change_password_upon_first_use', True),
+ ('enable', False),
+ ('disable', False),
+ ('name', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.user.name,
+ 'default_project': None,
+ 'description': None,
+ 'domain': None,
+ 'email': None,
+ 'enabled': True,
+ 'options': {'ignore_change_password_upon_first_use': True},
+ 'password': None,
+ }
+ # UserManager.create(name=, domain=, project=, password=, email=,
+ # description=, enabled=, default_project=)
+ self.users_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
+ def test_user_create_no_ignore_change_password_upon_first_use(self):
+ arglist = [
+ '--no-ignore-change-password-upon-first-use',
+ self.user.name,
+ ]
+ verifylist = [
+ ('no_ignore_change_password_upon_first_use', True),
+ ('enable', False),
+ ('disable', False),
+ ('name', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.user.name,
+ 'default_project': None,
+ 'description': None,
+ 'domain': None,
+ 'email': None,
+ 'enabled': True,
+ 'options': {'ignore_change_password_upon_first_use': False},
+ 'password': None,
+ }
+ # UserManager.create(name=, domain=, project=, password=, email=,
+ # description=, enabled=, default_project=)
+ self.users_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
+ def test_user_create_enables_lock_password(self):
+ arglist = [
+ '--enable-lock-password',
+ self.user.name,
+ ]
+ verifylist = [
+ ('enable_lock_password', True),
+ ('enable', False),
+ ('disable', False),
+ ('name', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.user.name,
+ 'default_project': None,
+ 'description': None,
+ 'domain': None,
+ 'email': None,
+ 'enabled': True,
+ 'options': {'lock_password': True},
+ 'password': None,
+ }
+ # UserManager.create(name=, domain=, project=, password=, email=,
+ # description=, enabled=, default_project=)
+ self.users_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
+ def test_user_create_disables_lock_password(self):
+ arglist = [
+ '--disable-lock-password',
+ self.user.name,
+ ]
+ verifylist = [
+ ('disable_lock_password', True),
+ ('enable', False),
+ ('disable', False),
+ ('name', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.user.name,
+ 'default_project': None,
+ 'description': None,
+ 'domain': None,
+ 'email': None,
+ 'enabled': True,
+ 'options': {'lock_password': False},
+ 'password': None,
+ }
+ # UserManager.create(name=, domain=, project=, password=, email=,
+ # description=, enabled=, default_project=)
+ self.users_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
+ def test_user_create_enable_multi_factor_auth(self):
+ arglist = [
+ '--enable-multi-factor-auth',
+ self.user.name,
+ ]
+ verifylist = [
+ ('enable_multi_factor_auth', True),
+ ('enable', False),
+ ('disable', False),
+ ('name', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.user.name,
+ 'default_project': None,
+ 'description': None,
+ 'domain': None,
+ 'email': None,
+ 'enabled': True,
+ 'options': {'multi_factor_auth_enabled': True},
+ 'password': None,
+ }
+ # UserManager.create(name=, domain=, project=, password=, email=,
+ # description=, enabled=, default_project=)
+ self.users_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
+ def test_user_create_disable_multi_factor_auth(self):
+ arglist = [
+ '--disable-multi-factor-auth',
+ self.user.name,
+ ]
+ verifylist = [
+ ('disable_multi_factor_auth', True),
+ ('enable', False),
+ ('disable', False),
+ ('name', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.user.name,
+ 'default_project': None,
+ 'description': None,
+ 'domain': None,
+ 'email': None,
+ 'enabled': True,
+ 'options': {'multi_factor_auth_enabled': False},
+ 'password': None,
+ }
+ # UserManager.create(name=, domain=, project=, password=, email=,
+ # description=, enabled=, default_project=)
+ self.users_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
+ def test_user_create_option_with_multi_factor_auth_rule(self):
+ arglist = [
+ '--multi-factor-auth-rule', identity_fakes.mfa_opt1,
+ '--multi-factor-auth-rule', identity_fakes.mfa_opt2,
+ self.user.name,
+ ]
+ verifylist = [
+ ('multi_factor_auth_rule', [identity_fakes.mfa_opt1,
+ identity_fakes.mfa_opt2]),
+ ('enable', False),
+ ('disable', False),
+ ('name', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.user.name,
+ 'default_project': None,
+ 'description': None,
+ 'domain': None,
+ 'email': None,
+ 'enabled': True,
+ 'options': {'multi_factor_auth_rules': [["password", "totp"],
+ ["password"]]},
+ 'password': None,
+ }
+ # UserManager.create(name=, domain=, project=, password=, email=,
+ # description=, enabled=, default_project=)
+ self.users_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
+ def test_user_create_with_multiple_options(self):
+ arglist = [
+ '--ignore-password-expiry',
+ '--disable-multi-factor-auth',
+ '--multi-factor-auth-rule', identity_fakes.mfa_opt1,
+ self.user.name,
+ ]
+ verifylist = [
+ ('ignore_password_expiry', True),
+ ('disable_multi_factor_auth', True),
+ ('multi_factor_auth_rule', [identity_fakes.mfa_opt1]),
+ ('enable', False),
+ ('disable', False),
+ ('name', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class ShowOne in cliff, abstract method take_action()
+ # returns a two-part tuple with a tuple of column names and a tuple of
+ # data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.user.name,
+ 'default_project': None,
+ 'description': None,
+ 'domain': None,
+ 'email': None,
+ 'enabled': True,
+ 'options': {'ignore_password_expiry': True,
+ 'multi_factor_auth_enabled': False,
+ 'multi_factor_auth_rules': [["password", "totp"]]},
+ 'password': None,
+ }
+ # UserManager.create(name=, domain=, project=, password=, email=,
+ # description=, enabled=, default_project=)
+ self.users_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+
class TestUserDelete(TestUser):
@@ -1007,6 +1481,384 @@ class TestUserSet(TestUser):
)
self.assertIsNone(result)
+ def test_user_set_ignore_lockout_failure_attempts(self):
+ arglist = [
+ '--ignore-lockout-failure-attempts',
+ self.user.name,
+ ]
+ verifylist = [
+ ('name', None),
+ ('password', None),
+ ('email', None),
+ ('ignore_lockout_failure_attempts', True),
+ ('project', None),
+ ('enable', False),
+ ('disable', False),
+ ('user', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ # Set expected values
+ kwargs = {
+ 'enabled': True,
+ 'options': {'ignore_lockout_failure_attempts': True},
+ }
+ # UserManager.update(user, name=, domain=, project=, password=,
+ # email=, description=, enabled=, default_project=)
+ self.users_mock.update.assert_called_with(
+ self.user.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_user_set_no_ignore_lockout_failure_attempts(self):
+ arglist = [
+ '--no-ignore-lockout-failure-attempts',
+ self.user.name,
+ ]
+ verifylist = [
+ ('name', None),
+ ('password', None),
+ ('email', None),
+ ('no_ignore_lockout_failure_attempts', True),
+ ('project', None),
+ ('enable', False),
+ ('disable', False),
+ ('user', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ # Set expected values
+ kwargs = {
+ 'enabled': True,
+ 'options': {'ignore_lockout_failure_attempts': False},
+ }
+ # UserManager.update(user, name=, domain=, project=, password=,
+ # email=, description=, enabled=, default_project=)
+ self.users_mock.update.assert_called_with(
+ self.user.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_user_set_ignore_password_expiry(self):
+ arglist = [
+ '--ignore-password-expiry',
+ self.user.name,
+ ]
+ verifylist = [
+ ('name', None),
+ ('password', None),
+ ('email', None),
+ ('ignore_password_expiry', True),
+ ('project', None),
+ ('enable', False),
+ ('disable', False),
+ ('user', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ # Set expected values
+ kwargs = {
+ 'enabled': True,
+ 'options': {'ignore_password_expiry': True},
+ }
+ # UserManager.update(user, name=, domain=, project=, password=,
+ # email=, description=, enabled=, default_project=)
+ self.users_mock.update.assert_called_with(
+ self.user.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_user_set_no_ignore_password_expiry(self):
+ arglist = [
+ '--no-ignore-password-expiry',
+ self.user.name,
+ ]
+ verifylist = [
+ ('name', None),
+ ('password', None),
+ ('email', None),
+ ('no_ignore_password_expiry', True),
+ ('project', None),
+ ('enable', False),
+ ('disable', False),
+ ('user', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ # Set expected values
+ kwargs = {
+ 'enabled': True,
+ 'options': {'ignore_password_expiry': False},
+ }
+ # UserManager.update(user, name=, domain=, project=, password=,
+ # email=, description=, enabled=, default_project=)
+ self.users_mock.update.assert_called_with(
+ self.user.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_user_set_ignore_change_password_upon_first_use(self):
+ arglist = [
+ '--ignore-change-password-upon-first-use',
+ self.user.name,
+ ]
+ verifylist = [
+ ('name', None),
+ ('password', None),
+ ('email', None),
+ ('ignore_change_password_upon_first_use', True),
+ ('project', None),
+ ('enable', False),
+ ('disable', False),
+ ('user', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ # Set expected values
+ kwargs = {
+ 'enabled': True,
+ 'options': {'ignore_change_password_upon_first_use': True},
+ }
+ # UserManager.update(user, name=, domain=, project=, password=,
+ # email=, description=, enabled=, default_project=)
+ self.users_mock.update.assert_called_with(
+ self.user.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_user_set_no_ignore_change_password_upon_first_use(self):
+ arglist = [
+ '--no-ignore-change-password-upon-first-use',
+ self.user.name,
+ ]
+ verifylist = [
+ ('name', None),
+ ('password', None),
+ ('email', None),
+ ('no_ignore_change_password_upon_first_use', True),
+ ('project', None),
+ ('enable', False),
+ ('disable', False),
+ ('user', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ # Set expected values
+ kwargs = {
+ 'enabled': True,
+ 'options': {'ignore_change_password_upon_first_use': False},
+ }
+ # UserManager.update(user, name=, domain=, project=, password=,
+ # email=, description=, enabled=, default_project=)
+ self.users_mock.update.assert_called_with(
+ self.user.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_user_set_enable_lock_password(self):
+ arglist = [
+ '--enable-lock-password',
+ self.user.name,
+ ]
+ verifylist = [
+ ('name', None),
+ ('password', None),
+ ('email', None),
+ ('enable_lock_password', True),
+ ('project', None),
+ ('enable', False),
+ ('disable', False),
+ ('user', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ # Set expected values
+ kwargs = {
+ 'enabled': True,
+ 'options': {'lock_password': True},
+ }
+ # UserManager.update(user, name=, domain=, project=, password=,
+ # email=, description=, enabled=, default_project=)
+ self.users_mock.update.assert_called_with(
+ self.user.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_user_set_disable_lock_password(self):
+ arglist = [
+ '--disable-lock-password',
+ self.user.name,
+ ]
+ verifylist = [
+ ('name', None),
+ ('password', None),
+ ('email', None),
+ ('disable_lock_password', True),
+ ('project', None),
+ ('enable', False),
+ ('disable', False),
+ ('user', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ # Set expected values
+ kwargs = {
+ 'enabled': True,
+ 'options': {'lock_password': False},
+ }
+ # UserManager.update(user, name=, domain=, project=, password=,
+ # email=, description=, enabled=, default_project=)
+ self.users_mock.update.assert_called_with(
+ self.user.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_user_set_enable_multi_factor_auth(self):
+ arglist = [
+ '--enable-multi-factor-auth',
+ self.user.name,
+ ]
+ verifylist = [
+ ('name', None),
+ ('password', None),
+ ('email', None),
+ ('enable_multi_factor_auth', True),
+ ('project', None),
+ ('enable', False),
+ ('disable', False),
+ ('user', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ # Set expected values
+ kwargs = {
+ 'enabled': True,
+ 'options': {'multi_factor_auth_enabled': True},
+ }
+ # UserManager.update(user, name=, domain=, project=, password=,
+ # email=, description=, enabled=, default_project=)
+ self.users_mock.update.assert_called_with(
+ self.user.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_user_set_disable_multi_factor_auth(self):
+ arglist = [
+ '--disable-multi-factor-auth',
+ self.user.name,
+ ]
+ verifylist = [
+ ('name', None),
+ ('password', None),
+ ('email', None),
+ ('disable_multi_factor_auth', True),
+ ('project', None),
+ ('enable', False),
+ ('disable', False),
+ ('user', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ # Set expected values
+ kwargs = {
+ 'enabled': True,
+ 'options': {'multi_factor_auth_enabled': False},
+ }
+ # UserManager.update(user, name=, domain=, project=, password=,
+ # email=, description=, enabled=, default_project=)
+ self.users_mock.update.assert_called_with(
+ self.user.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_user_set_option_multi_factor_auth_rule(self):
+ arglist = [
+ '--multi-factor-auth-rule', identity_fakes.mfa_opt1,
+ self.user.name,
+ ]
+ verifylist = [
+ ('name', None),
+ ('password', None),
+ ('email', None),
+ ('multi_factor_auth_rule', [identity_fakes.mfa_opt1]),
+ ('project', None),
+ ('enable', False),
+ ('disable', False),
+ ('user', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ # Set expected values
+ kwargs = {
+ 'enabled': True,
+ 'options': {'multi_factor_auth_rules': [["password", "totp"]]}}
+
+ # UserManager.update(user, name=, domain=, project=, password=,
+ # email=, description=, enabled=, default_project=)
+ self.users_mock.update.assert_called_with(
+ self.user.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_user_set_with_multiple_options(self):
+ arglist = [
+ '--ignore-password-expiry',
+ '--enable-multi-factor-auth',
+ '--multi-factor-auth-rule', identity_fakes.mfa_opt1,
+ self.user.name,
+ ]
+ verifylist = [
+ ('name', None),
+ ('password', None),
+ ('email', None),
+ ('ignore_password_expiry', True),
+ ('enable_multi_factor_auth', True),
+ ('multi_factor_auth_rule', [identity_fakes.mfa_opt1]),
+ ('project', None),
+ ('enable', False),
+ ('disable', False),
+ ('user', self.user.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ # Set expected values
+ kwargs = {
+ 'enabled': True,
+ 'options': {'ignore_password_expiry': True,
+ 'multi_factor_auth_enabled': True,
+ 'multi_factor_auth_rules': [["password", "totp"]]}}
+
+ # UserManager.update(user, name=, domain=, project=, password=,
+ # email=, description=, enabled=, default_project=)
+ self.users_mock.update.assert_called_with(
+ self.user.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
class TestUserSetPassword(TestUser):
diff --git a/openstackclient/tests/unit/image/v2/test_image.py b/openstackclient/tests/unit/image/v2/test_image.py
index a021cfc..310f6b7 100644
--- a/openstackclient/tests/unit/image/v2/test_image.py
+++ b/openstackclient/tests/unit/image/v2/test_image.py
@@ -271,6 +271,28 @@ class TestImageCreate(TestImage):
exceptions.CommandError,
self.cmd.take_action, parsed_args)
+ @mock.patch('sys.stdin', side_effect=[None])
+ def test_image_create_import(self, raw_input):
+
+ arglist = [
+ '--import',
+ self.new_image.name,
+ ]
+ verifylist = [
+ ('name', self.new_image.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # ImageManager.create(name=, **)
+ self.client.create_image.assert_called_with(
+ name=self.new_image.name,
+ container_format=image.DEFAULT_CONTAINER_FORMAT,
+ disk_format=image.DEFAULT_DISK_FORMAT,
+ use_import=True
+ )
+
class TestAddProjectToImage(TestImage):
diff --git a/openstackclient/tests/unit/integ/cli/test_shell.py b/openstackclient/tests/unit/integ/cli/test_shell.py
index 0c98a12..5788b47 100644
--- a/openstackclient/tests/unit/integ/cli/test_shell.py
+++ b/openstackclient/tests/unit/integ/cli/test_shell.py
@@ -20,16 +20,6 @@ from openstackclient import shell
from openstackclient.tests.unit.integ import base as test_base
from openstackclient.tests.unit import test_shell
-# NOTE(dtroyer): Attempt the import to detect if the SDK installed is new
-# enough to contain the os_client_config code. If so, use
-# that path for mocks.
-CONFIG_MOCK_BASE = "openstack.config.loader"
-try:
- from openstack.config import defaults # noqa
-except ImportError:
- # Fall back to os-client-config
- CONFIG_MOCK_BASE = "os_client_config.config"
-
class TestIntegShellCliNoAuth(test_base.TestInteg):
@@ -455,8 +445,8 @@ class TestIntegShellCliPrecedenceOCC(test_base.TestInteg):
temp_dir = self.useFixture(fixtures.TempDir())
return temp_dir.join(filename)
- @mock.patch(CONFIG_MOCK_BASE + ".OpenStackConfig._load_vendor_file")
- @mock.patch(CONFIG_MOCK_BASE + ".OpenStackConfig._load_config_file")
+ @mock.patch("openstack.config.loader.OpenStackConfig._load_vendor_file")
+ @mock.patch("openstack.config.loader.OpenStackConfig._load_config_file")
def test_shell_args_precedence_1(self, config_mock, vendor_mock):
"""Precedence run 1
@@ -473,7 +463,6 @@ class TestIntegShellCliPrecedenceOCC(test_base.TestInteg):
return ('file.yaml', copy.deepcopy(test_shell.PUBLIC_1))
vendor_mock.side_effect = vendor_mock_return
- print("CONFIG_MOCK_BASE=%s" % CONFIG_MOCK_BASE)
_shell = shell.OpenStackShell()
_shell.run(
"--os-password qaz extension list".split(),
@@ -527,8 +516,8 @@ class TestIntegShellCliPrecedenceOCC(test_base.TestInteg):
# +env, +cli, +occ
# see test_shell_args_precedence_2()
- @mock.patch(CONFIG_MOCK_BASE + ".OpenStackConfig._load_vendor_file")
- @mock.patch(CONFIG_MOCK_BASE + ".OpenStackConfig._load_config_file")
+ @mock.patch("openstack.config.loader.OpenStackConfig._load_vendor_file")
+ @mock.patch("openstack.config.loader.OpenStackConfig._load_config_file")
def test_shell_args_precedence_2(self, config_mock, vendor_mock):
"""Precedence run 2
@@ -545,7 +534,6 @@ class TestIntegShellCliPrecedenceOCC(test_base.TestInteg):
return ('file.yaml', copy.deepcopy(test_shell.PUBLIC_1))
vendor_mock.side_effect = vendor_mock_return
- print("CONFIG_MOCK_BASE=%s" % CONFIG_MOCK_BASE)
_shell = shell.OpenStackShell()
_shell.run(
"--os-username zarquon --os-password qaz "
diff --git a/openstackclient/tests/unit/network/v2/fakes.py b/openstackclient/tests/unit/network/v2/fakes.py
index a553f50..cef0a11 100644
--- a/openstackclient/tests/unit/network/v2/fakes.py
+++ b/openstackclient/tests/unit/network/v2/fakes.py
@@ -1227,6 +1227,7 @@ class FakeSecurityGroup(object):
'id': 'security-group-id-' + uuid.uuid4().hex,
'name': 'security-group-name-' + uuid.uuid4().hex,
'description': 'security-group-description-' + uuid.uuid4().hex,
+ 'stateful': True,
'project_id': 'project-id-' + uuid.uuid4().hex,
'security_group_rules': [],
'tags': []
@@ -1832,7 +1833,7 @@ class FakeFloatingIPPortForwarding(object):
"""
attrs = attrs or {}
floatingip_id = (
- attrs.get('floatingip_id') or'floating-ip-id-' + uuid.uuid4().hex
+ attrs.get('floatingip_id') or 'floating-ip-id-' + uuid.uuid4().hex
)
# Set default attributes.
port_forwarding_attrs = {
@@ -1843,6 +1844,7 @@ class FakeFloatingIPPortForwarding(object):
'internal_port': randint(1, 65535),
'external_port': randint(1, 65535),
'protocol': 'tcp',
+ 'description': 'some description',
}
# Overwrite default attributes.
diff --git a/openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py b/openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py
index ea6cdd2..1028c18 100644
--- a/openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py
+++ b/openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py
@@ -62,6 +62,7 @@ class TestCreateFloatingIPPortForwarding(TestFloatingIPPortForwarding):
self.app, self.namespace)
self.columns = (
+ 'description',
'external_port',
'floatingip_id',
'id',
@@ -73,6 +74,7 @@ class TestCreateFloatingIPPortForwarding(TestFloatingIPPortForwarding):
)
self.data = (
+ self.new_port_forwarding.description,
self.new_port_forwarding.external_port,
self.new_port_forwarding.floatingip_id,
self.new_port_forwarding.id,
@@ -102,6 +104,8 @@ class TestCreateFloatingIPPortForwarding(TestFloatingIPPortForwarding):
self.new_port_forwarding.floatingip_id,
'--internal-ip-address',
self.new_port_forwarding.internal_ip_address,
+ '--description',
+ self.new_port_forwarding.description,
]
verifylist = [
('port', self.new_port_forwarding.internal_port_id),
@@ -111,6 +115,7 @@ class TestCreateFloatingIPPortForwarding(TestFloatingIPPortForwarding):
('floating_ip', self.new_port_forwarding.floatingip_id),
('internal_ip_address', self.new_port_forwarding.
internal_ip_address),
+ ('description', self.new_port_forwarding.description),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
@@ -126,6 +131,7 @@ class TestCreateFloatingIPPortForwarding(TestFloatingIPPortForwarding):
'internal_port_id': self.new_port_forwarding.
internal_port_id,
'protocol': self.new_port_forwarding.protocol,
+ 'description': self.new_port_forwarding.description,
})
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
@@ -251,7 +257,8 @@ class TestListFloatingIPPortForwarding(TestFloatingIPPortForwarding):
'Internal IP Address',
'Internal Port',
'External Port',
- 'Protocol'
+ 'Protocol',
+ 'Description',
)
def setUp(self):
@@ -273,6 +280,7 @@ class TestListFloatingIPPortForwarding(TestFloatingIPPortForwarding):
port_forwarding.internal_port,
port_forwarding.external_port,
port_forwarding.protocol,
+ port_forwarding.description,
))
self.network.floating_ip_port_forwardings = mock.Mock(
return_value=self.port_forwardings
@@ -393,6 +401,7 @@ class TestSetFloatingIPPortForwarding(TestFloatingIPPortForwarding):
'--internal-protocol-port', '100',
'--external-protocol-port', '200',
'--protocol', 'tcp',
+ '--description', 'some description',
self._port_forwarding.floatingip_id,
self._port_forwarding.id,
]
@@ -402,6 +411,7 @@ class TestSetFloatingIPPortForwarding(TestFloatingIPPortForwarding):
('internal_protocol_port', 100),
('external_protocol_port', 200),
('protocol', 'tcp'),
+ ('description', 'some description'),
('floating_ip', self._port_forwarding.floatingip_id),
('port_forwarding_id', self._port_forwarding.id),
]
@@ -415,6 +425,7 @@ class TestSetFloatingIPPortForwarding(TestFloatingIPPortForwarding):
'internal_port': 100,
'external_port': 200,
'protocol': 'tcp',
+ 'description': 'some description',
}
self.network.update_floating_ip_port_forwarding.assert_called_with(
self._port_forwarding.floatingip_id,
@@ -428,6 +439,7 @@ class TestShowFloatingIPPortForwarding(TestFloatingIPPortForwarding):
# The port forwarding to show.
columns = (
+ 'description',
'external_port',
'floatingip_id',
'id',
@@ -450,6 +462,7 @@ class TestShowFloatingIPPortForwarding(TestFloatingIPPortForwarding):
)
)
self.data = (
+ self._port_forwarding.description,
self._port_forwarding.external_port,
self._port_forwarding.floatingip_id,
self._port_forwarding.id,
diff --git a/openstackclient/tests/unit/network/v2/test_network.py b/openstackclient/tests/unit/network/v2/test_network.py
index 45d6008..5f8eed6 100644
--- a/openstackclient/tests/unit/network/v2/test_network.py
+++ b/openstackclient/tests/unit/network/v2/test_network.py
@@ -278,24 +278,6 @@ class TestCreateNetworkIdentityV3(TestNetwork):
def test_create_with_no_tag(self):
self._test_create_with_tag(add_tags=False)
- def test_create_default_internal(self):
- arglist = [
- self._network.name,
- "--default",
- ]
- verifylist = [
- ('name', self._network.name),
- ('enable', True),
- ('share', None),
- ('project', None),
- ('external', False),
- ('default', True),
- ]
-
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- self.assertRaises(exceptions.CommandError, self.cmd.take_action,
- parsed_args)
-
class TestCreateNetworkIdentityV2(TestNetwork):
@@ -1043,21 +1025,6 @@ class TestSetNetwork(TestNetwork):
def test_set_with_no_tag(self):
self._test_set_tags(with_tags=False)
- def test_set_default_internal(self):
- arglist = [
- self._network.name,
- '--internal',
- '--default',
- ]
- verifylist = [
- ('internal', True),
- ('default', True),
- ]
-
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- self.assertRaises(exceptions.CommandError, self.cmd.take_action,
- parsed_args)
-
class TestShowNetwork(TestNetwork):
diff --git a/openstackclient/tests/unit/network/v2/test_network_rbac.py b/openstackclient/tests/unit/network/v2/test_network_rbac.py
index 078188c..d7c71ea 100644
--- a/openstackclient/tests/unit/network/v2/test_network_rbac.py
+++ b/openstackclient/tests/unit/network/v2/test_network_rbac.py
@@ -14,6 +14,7 @@
from unittest import mock
from unittest.mock import call
+import ddt
from osc_lib import exceptions
from openstackclient.network.v2 import network_rbac
@@ -33,11 +34,14 @@ class TestNetworkRBAC(network_fakes.TestNetworkV2):
self.projects_mock = self.app.client_manager.identity.projects
+@ddt.ddt
class TestCreateNetworkRBAC(TestNetworkRBAC):
network_object = network_fakes.FakeNetwork.create_one_network()
qos_object = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
sg_object = network_fakes.FakeNetworkSecGroup.create_one_security_group()
+ as_object = network_fakes.FakeAddressScope.create_one_address_scope()
+ snp_object = network_fakes.FakeSubnetPool.create_one_subnet_pool()
project = identity_fakes_v3.FakeProject.create_one_project()
rbac_policy = network_fakes.FakeNetworkRBAC.create_one_network_rbac(
attrs={'tenant_id': project.id,
@@ -77,6 +81,10 @@ class TestCreateNetworkRBAC(TestNetworkRBAC):
return_value=self.qos_object)
self.network.find_security_group = mock.Mock(
return_value=self.sg_object)
+ self.network.find_address_scope = mock.Mock(
+ return_value=self.as_object)
+ self.network.find_subnet_pool = mock.Mock(
+ return_value=self.snp_object)
self.projects_mock.get.return_value = self.project
def test_network_rbac_create_no_type(self):
@@ -224,57 +232,29 @@ class TestCreateNetworkRBAC(TestNetworkRBAC):
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
- def test_network_rbac_create_qos_object(self):
- self.rbac_policy.object_type = 'qos_policy'
- self.rbac_policy.object_id = self.qos_object.id
- arglist = [
- '--type', 'qos_policy',
- '--action', self.rbac_policy.action,
- '--target-project', self.rbac_policy.target_tenant,
- self.qos_object.name,
- ]
- verifylist = [
- ('type', 'qos_policy'),
- ('action', self.rbac_policy.action),
- ('target_project', self.rbac_policy.target_tenant),
- ('rbac_object', self.qos_object.name),
- ]
- 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.create_rbac_policy.assert_called_with(**{
- 'object_id': self.qos_object.id,
- 'object_type': 'qos_policy',
- 'action': self.rbac_policy.action,
- 'target_tenant': self.rbac_policy.target_tenant,
- })
- self.data = [
- self.rbac_policy.action,
- self.rbac_policy.id,
- self.qos_object.id,
- 'qos_policy',
- self.rbac_policy.tenant_id,
- self.rbac_policy.target_tenant,
- ]
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, list(data))
+ @ddt.data(
+ ('qos_policy', "qos_object"),
+ ('security_group', "sg_object"),
+ ('subnetpool', "snp_object"),
+ ('address_scope', "as_object")
+ )
+ @ddt.unpack
+ def test_network_rbac_create_object(self, obj_type, obj_fake_attr):
+ obj_fake = getattr(self, obj_fake_attr)
- def test_network_rbac_create_security_group_object(self):
- self.rbac_policy.object_type = 'security_group'
- self.rbac_policy.object_id = self.sg_object.id
+ self.rbac_policy.object_type = obj_type
+ self.rbac_policy.object_id = obj_fake.id
arglist = [
- '--type', 'security_group',
+ '--type', obj_type,
'--action', self.rbac_policy.action,
'--target-project', self.rbac_policy.target_tenant,
- self.sg_object.name,
+ obj_fake.name,
]
verifylist = [
- ('type', 'security_group'),
+ ('type', obj_type),
('action', self.rbac_policy.action),
('target_project', self.rbac_policy.target_tenant),
- ('rbac_object', self.sg_object.name),
+ ('rbac_object', obj_fake.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -282,16 +262,16 @@ class TestCreateNetworkRBAC(TestNetworkRBAC):
columns, data = self.cmd.take_action(parsed_args)
self.network.create_rbac_policy.assert_called_with(**{
- 'object_id': self.sg_object.id,
- 'object_type': 'security_group',
+ 'object_id': obj_fake.id,
+ 'object_type': obj_type,
'action': self.rbac_policy.action,
'target_tenant': self.rbac_policy.target_tenant,
})
self.data = [
self.rbac_policy.action,
self.rbac_policy.id,
- self.sg_object.id,
- 'security_group',
+ obj_fake.id,
+ obj_type,
self.rbac_policy.tenant_id,
self.rbac_policy.target_tenant,
]
diff --git a/openstackclient/tests/unit/network/v2/test_port.py b/openstackclient/tests/unit/network/v2/test_port.py
index b1a18da..87aea61 100644
--- a/openstackclient/tests/unit/network/v2/test_port.py
+++ b/openstackclient/tests/unit/network/v2/test_port.py
@@ -1054,6 +1054,22 @@ class TestListPort(TestPort):
self.assertEqual(self.columns_long, columns)
self.assertListItemEqual(self.data_long, list(data))
+ def test_port_list_host(self):
+ arglist = [
+ '--host', 'foobar',
+ ]
+ verifylist = [
+ ('host', 'foobar'),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ filters = {'binding:host_id': 'foobar'}
+
+ self.network.ports.assert_called_once_with(**filters)
+ self.assertEqual(self.columns, columns)
+ self.assertListItemEqual(self.data, list(data))
+
def test_port_list_project(self):
project = identity_fakes.FakeProject.create_one_project()
self.projects_mock.get.return_value = project
diff --git a/openstackclient/tests/unit/network/v2/test_router.py b/openstackclient/tests/unit/network/v2/test_router.py
index 38861b0..09b4957 100644
--- a/openstackclient/tests/unit/network/v2/test_router.py
+++ b/openstackclient/tests/unit/network/v2/test_router.py
@@ -776,6 +776,146 @@ class TestRemoveSubnetFromRouter(TestRouter):
self.assertIsNone(result)
+class TestAddExtraRoutesToRouter(TestRouter):
+
+ _router = network_fakes.FakeRouter.create_one_router()
+
+ def setUp(self):
+ super(TestAddExtraRoutesToRouter, self).setUp()
+ self.network.add_extra_routes_to_router = mock.Mock(
+ return_value=self._router)
+ self.cmd = router.AddExtraRoutesToRouter(self.app, self.namespace)
+ self.network.find_router = mock.Mock(return_value=self._router)
+
+ def test_add_no_extra_route(self):
+ arglist = [
+ self._router.id,
+ ]
+ verifylist = [
+ ('router', self._router.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.network.add_extra_routes_to_router.assert_called_with(
+ self._router, body={'router': {'routes': []}})
+ self.assertEqual(2, len(result))
+
+ def test_add_one_extra_route(self):
+ arglist = [
+ self._router.id,
+ '--route', 'destination=dst1,gateway=gw1',
+ ]
+ verifylist = [
+ ('router', self._router.id),
+ ('routes', [{'destination': 'dst1', 'gateway': 'gw1'}]),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.network.add_extra_routes_to_router.assert_called_with(
+ self._router, body={'router': {'routes': [
+ {'destination': 'dst1', 'nexthop': 'gw1'},
+ ]}})
+ self.assertEqual(2, len(result))
+
+ def test_add_multiple_extra_routes(self):
+ arglist = [
+ self._router.id,
+ '--route', 'destination=dst1,gateway=gw1',
+ '--route', 'destination=dst2,gateway=gw2',
+ ]
+ verifylist = [
+ ('router', self._router.id),
+ ('routes', [
+ {'destination': 'dst1', 'gateway': 'gw1'},
+ {'destination': 'dst2', 'gateway': 'gw2'},
+ ]),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.network.add_extra_routes_to_router.assert_called_with(
+ self._router, body={'router': {'routes': [
+ {'destination': 'dst1', 'nexthop': 'gw1'},
+ {'destination': 'dst2', 'nexthop': 'gw2'},
+ ]}})
+ self.assertEqual(2, len(result))
+
+
+class TestRemoveExtraRoutesFromRouter(TestRouter):
+
+ _router = network_fakes.FakeRouter.create_one_router()
+
+ def setUp(self):
+ super(TestRemoveExtraRoutesFromRouter, self).setUp()
+ self.network.remove_extra_routes_from_router = mock.Mock(
+ return_value=self._router)
+ self.cmd = router.RemoveExtraRoutesFromRouter(self.app, self.namespace)
+ self.network.find_router = mock.Mock(return_value=self._router)
+
+ def test_remove_no_extra_route(self):
+ arglist = [
+ self._router.id,
+ ]
+ verifylist = [
+ ('router', self._router.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.network.remove_extra_routes_from_router.assert_called_with(
+ self._router, body={'router': {'routes': []}})
+ self.assertEqual(2, len(result))
+
+ def test_remove_one_extra_route(self):
+ arglist = [
+ self._router.id,
+ '--route', 'destination=dst1,gateway=gw1',
+ ]
+ verifylist = [
+ ('router', self._router.id),
+ ('routes', [{'destination': 'dst1', 'gateway': 'gw1'}]),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.network.remove_extra_routes_from_router.assert_called_with(
+ self._router, body={'router': {'routes': [
+ {'destination': 'dst1', 'nexthop': 'gw1'},
+ ]}})
+ self.assertEqual(2, len(result))
+
+ def test_remove_multiple_extra_routes(self):
+ arglist = [
+ self._router.id,
+ '--route', 'destination=dst1,gateway=gw1',
+ '--route', 'destination=dst2,gateway=gw2',
+ ]
+ verifylist = [
+ ('router', self._router.id),
+ ('routes', [
+ {'destination': 'dst1', 'gateway': 'gw1'},
+ {'destination': 'dst2', 'gateway': 'gw2'},
+ ]),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.network.remove_extra_routes_from_router.assert_called_with(
+ self._router, body={'router': {'routes': [
+ {'destination': 'dst1', 'nexthop': 'gw1'},
+ {'destination': 'dst2', 'nexthop': 'gw2'},
+ ]}})
+ self.assertEqual(2, len(result))
+
+
class TestSetRouter(TestRouter):
# The router to set.
diff --git a/openstackclient/tests/unit/network/v2/test_security_group_network.py b/openstackclient/tests/unit/network/v2/test_security_group_network.py
index 67908fa..7c1d7fb 100644
--- a/openstackclient/tests/unit/network/v2/test_security_group_network.py
+++ b/openstackclient/tests/unit/network/v2/test_security_group_network.py
@@ -49,6 +49,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
'name',
'project_id',
'rules',
+ 'stateful',
'tags',
)
@@ -58,6 +59,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
_security_group.name,
_security_group.project_id,
security_group.NetworkSecurityGroupRulesColumn([]),
+ _security_group.stateful,
_security_group.tags,
)
@@ -101,6 +103,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
'--description', self._security_group.description,
'--project', self.project.name,
'--project-domain', self.domain.name,
+ '--stateful',
self._security_group.name,
]
verifylist = [
@@ -108,6 +111,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
('name', self._security_group.name),
('project', self.project.name),
('project_domain', self.domain.name),
+ ('stateful', self._security_group.stateful),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -115,6 +119,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
self.network.create_security_group.assert_called_once_with(**{
'description': self._security_group.description,
+ 'stateful': self._security_group.stateful,
'name': self._security_group.name,
'tenant_id': self.project.id,
})
@@ -421,11 +426,13 @@ class TestSetSecurityGroupNetwork(TestSecurityGroupNetwork):
arglist = [
'--name', new_name,
'--description', new_description,
+ '--stateful',
self._security_group.name,
]
verifylist = [
('description', new_description),
('group', self._security_group.name),
+ ('stateful', self._security_group.stateful),
('name', new_name),
]
@@ -435,6 +442,7 @@ class TestSetSecurityGroupNetwork(TestSecurityGroupNetwork):
attrs = {
'description': new_description,
'name': new_name,
+ 'stateful': True,
}
self.network.update_security_group.assert_called_once_with(
self._security_group,
@@ -489,6 +497,7 @@ class TestShowSecurityGroupNetwork(TestSecurityGroupNetwork):
'name',
'project_id',
'rules',
+ 'stateful',
'tags',
)
@@ -499,6 +508,7 @@ class TestShowSecurityGroupNetwork(TestSecurityGroupNetwork):
_security_group.project_id,
security_group.NetworkSecurityGroupRulesColumn(
[_security_group_rule._info]),
+ _security_group.stateful,
_security_group.tags,
)
diff --git a/python_openstackclient.egg-info/PKG-INFO b/python_openstackclient.egg-info/PKG-INFO
index a8ec03d..8e0a1bd 100644
--- a/python_openstackclient.egg-info/PKG-INFO
+++ b/python_openstackclient.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
-Metadata-Version: 1.1
+Metadata-Version: 1.2
Name: python-openstackclient
-Version: 5.2.0
+Version: 5.3.1
Summary: OpenStack Command-line Client
Home-page: https://docs.openstack.org/python-openstackclient/latest/
Author: OpenStack
@@ -118,3 +118,5 @@ Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Requires-Python: >=3.6
diff --git a/python_openstackclient.egg-info/SOURCES.txt b/python_openstackclient.egg-info/SOURCES.txt
index 27db9e2..d9c2dc0 100644
--- a/python_openstackclient.egg-info/SOURCES.txt
+++ b/python_openstackclient.egg-info/SOURCES.txt
@@ -9,7 +9,6 @@ Dockerfile
HACKING.rst
LICENSE
README.rst
-babel.cfg
bindep.txt
lower-constraints.txt
requirements.txt
@@ -29,6 +28,14 @@ doc/source/cli/commands.rst
doc/source/cli/decoder.rst
doc/source/cli/index.rst
doc/source/cli/interactive.rst
+doc/source/cli/_hidden/ec2-credentials.rst
+doc/source/cli/_hidden/endpoint.rst
+doc/source/cli/_hidden/image.rst
+doc/source/cli/_hidden/project.rst
+doc/source/cli/_hidden/role.rst
+doc/source/cli/_hidden/service.rst
+doc/source/cli/_hidden/token.rst
+doc/source/cli/_hidden/user.rst
doc/source/cli/command-objects/access-rules.rst
doc/source/cli/command-objects/access-token.rst
doc/source/cli/command-objects/address-scope.rst
@@ -49,10 +56,13 @@ doc/source/cli/command-objects/consumer.rst
doc/source/cli/command-objects/container.rst
doc/source/cli/command-objects/credential.rst
doc/source/cli/command-objects/domain.rst
-doc/source/cli/command-objects/ec2-credentials.rst
-doc/source/cli/command-objects/endpoint.rst
+doc/source/cli/command-objects/ec2-credentials-v2.rst
+doc/source/cli/command-objects/ec2-credentials-v3.rst
+doc/source/cli/command-objects/endpoint-v2.rst
+doc/source/cli/command-objects/endpoint-v3.rst
doc/source/cli/command-objects/endpoint_group.rst
doc/source/cli/command-objects/extension.rst
+doc/source/cli/command-objects/federation-domain-project.rst
doc/source/cli/command-objects/federation-protocol.rst
doc/source/cli/command-objects/flavor.rst
doc/source/cli/command-objects/floating-ip-pool.rst
@@ -63,7 +73,8 @@ doc/source/cli/command-objects/host.rst
doc/source/cli/command-objects/hypervisor-stats.rst
doc/source/cli/command-objects/hypervisor.rst
doc/source/cli/command-objects/identity-provider.rst
-doc/source/cli/command-objects/image.rst
+doc/source/cli/command-objects/image-v1.rst
+doc/source/cli/command-objects/image-v2.rst
doc/source/cli/command-objects/implied_role.rst
doc/source/cli/command-objects/ip-availability.rst
doc/source/cli/command-objects/keypair.rst
@@ -90,13 +101,15 @@ doc/source/cli/command-objects/object.rst
doc/source/cli/command-objects/policy.rst
doc/source/cli/command-objects/port.rst
doc/source/cli/command-objects/project-purge.rst
-doc/source/cli/command-objects/project.rst
+doc/source/cli/command-objects/project-v2.rst
+doc/source/cli/command-objects/project-v3.rst
doc/source/cli/command-objects/quota.rst
doc/source/cli/command-objects/region.rst
doc/source/cli/command-objects/registered-limit.rst
doc/source/cli/command-objects/request-token.rst
doc/source/cli/command-objects/role-assignment.rst
-doc/source/cli/command-objects/role.rst
+doc/source/cli/command-objects/role-v2.rst
+doc/source/cli/command-objects/role-v3.rst
doc/source/cli/command-objects/router.rst
doc/source/cli/command-objects/security-group-rule.rst
doc/source/cli/command-objects/security-group.rst
@@ -106,13 +119,16 @@ doc/source/cli/command-objects/server-group.rst
doc/source/cli/command-objects/server-image.rst
doc/source/cli/command-objects/server.rst
doc/source/cli/command-objects/service-provider.rst
-doc/source/cli/command-objects/service.rst
+doc/source/cli/command-objects/service-v2.rst
+doc/source/cli/command-objects/service-v3.rst
doc/source/cli/command-objects/subnet-pool.rst
doc/source/cli/command-objects/subnet.rst
-doc/source/cli/command-objects/token.rst
+doc/source/cli/command-objects/token-v2.rst
+doc/source/cli/command-objects/token-v3.rst
doc/source/cli/command-objects/trust.rst
doc/source/cli/command-objects/usage.rst
-doc/source/cli/command-objects/user.rst
+doc/source/cli/command-objects/user-v2.rst
+doc/source/cli/command-objects/user-v3.rst
doc/source/cli/command-objects/versions.rst
doc/source/cli/command-objects/volume-backend.rst
doc/source/cli/command-objects/volume-backup.rst
@@ -132,7 +148,6 @@ doc/source/cli/data/swift.csv
doc/source/cli/man/openstack.rst
doc/source/cli/plugin-commands/aodh.rst
doc/source/cli/plugin-commands/barbican.rst
-doc/source/cli/plugin-commands/congress.rst
doc/source/cli/plugin-commands/designate.rst
doc/source/cli/plugin-commands/gnocchi.rst
doc/source/cli/plugin-commands/heat.rst
@@ -140,6 +155,7 @@ doc/source/cli/plugin-commands/index.rst
doc/source/cli/plugin-commands/ironic-inspector.rst
doc/source/cli/plugin-commands/ironic.rst
doc/source/cli/plugin-commands/karbor.rst
+doc/source/cli/plugin-commands/manila.rst
doc/source/cli/plugin-commands/mistral.rst
doc/source/cli/plugin-commands/neutron.rst
doc/source/cli/plugin-commands/octavia.rst
@@ -601,6 +617,7 @@ python_openstackclient.egg-info/top_level.txt
releasenotes/notes/.placeholder
releasenotes/notes/add-auto-and-none-as-nic-parameter-ed23a6e7f99f250d.yaml
releasenotes/notes/add-community-option-to-image-list-ac0651eb2e5d632f.yaml
+releasenotes/notes/add-description-field-in-port-forwarding-c536e077b243d517.yaml
releasenotes/notes/add-description-to-role-afe7b6ff668df261.yaml
releasenotes/notes/add-device_id-to-port-list-0c658db51ce43c9e.yaml
releasenotes/notes/add-disable-reason-6e0f28459a09a60d.yaml
@@ -608,6 +625,7 @@ releasenotes/notes/add-dns-nameserver-overwrite-option-b866baeae12f9460.yaml
releasenotes/notes/add-fip-portforwarding-commands-6e4d8ace698ee308.yaml
releasenotes/notes/add-ha-to-router-update-6a38a73cc112b2fc.yaml
releasenotes/notes/add-host-and-hypervisor-hostname-flag-to-create-server-cb8b39a9f9311d42.yaml
+releasenotes/notes/add-image-import-flag-899869dc5a92aea7.yaml
releasenotes/notes/add-image-member-list-1630ead5988348c2.yaml
releasenotes/notes/add-image-tag-filter-support-5cb039416b07caab.yaml
releasenotes/notes/add-implied-role-0cdafb131fbd7453.yaml
@@ -646,6 +664,8 @@ releasenotes/notes/add-server-resize-confirm-revert-commands-98854ca98965432a.ya
releasenotes/notes/add-subnet-list-command-970f4b397469bdc6.yaml
releasenotes/notes/add-virtio-forwarder-vnic-type-bad939c6a868b9e9.yaml
releasenotes/notes/add-volume-host-failover-8fc77b24533b7fed.yaml
+releasenotes/notes/add_options_to_user_create_and_set-302401520f36d153.yaml
+releasenotes/notes/add_resource_option_immutable-efed6e1ebdc69591.yaml
releasenotes/notes/address-scope-delete-multi-31c3af73feb31265.yaml
releasenotes/notes/allow-custom-logging-12d55f8ed859ff8e.yaml
releasenotes/notes/allow-port-create-with-extra-dhcp-options-c2c40e4002b52e2a.yaml
@@ -942,6 +962,7 @@ releasenotes/notes/bug-1777153-750e6044aa28d5d8.yaml
releasenotes/notes/bug-1784879-9b632174d4af853f.yaml
releasenotes/notes/bug-1798744-5512256baf4dc633.yaml
releasenotes/notes/bug-1827844-8f1de120087c6a22.yaml
+releasenotes/notes/bug-2005246-3fb70206bafc5444.yaml
releasenotes/notes/bug-2005521-0274fc26bd9b3842.yaml
releasenotes/notes/bug-2006761-9041d1b25e845cfb.yaml
releasenotes/notes/bug-27882-402ced7ffe930058.yaml
@@ -952,14 +973,16 @@ releasenotes/notes/complete_image_switch-203e0b3105a54674.yaml
releasenotes/notes/compute-agent-deff48988e81b30e.yaml
releasenotes/notes/config-show-00512dc60882e5c0.yaml
releasenotes/notes/credential_list_user_type-c809e5b8014d6275.yaml
-releasenotes/notes/disallow-setting-default-on-internal-network-824fdea1a900891c.yaml
releasenotes/notes/drop-py2-421c90fbdf18dbc2.yaml
+releasenotes/notes/entrypoint-3.8-0597d159889042f7.yaml
releasenotes/notes/fix-network-rbac-create-d1f4de77ad2dd421.yaml
+releasenotes/notes/fix-story-2007890-0974f3e69f26801e.yaml
releasenotes/notes/flavor-add-description-b618abd4a7fb6545.yaml
releasenotes/notes/flavor-create-with-project-19d41bfa93e3c6d0.yaml
releasenotes/notes/floating-ip-multi-port-9779e88f590cae23.yaml
releasenotes/notes/floating-ip-set-unset-port-28e33875937b69cf.yaml
releasenotes/notes/floatingip_dns_integration-f26c7575694d098d.yaml
+releasenotes/notes/force-flag-openstackclient-c172de2717e5cfac.yaml
releasenotes/notes/image-list-filter-multiple-properties-03c51d43131ee3b6.yaml
releasenotes/notes/image-set-to-update-image-membership-68221f226ca3b6e0.yaml
releasenotes/notes/image_set_visibility-babf4ff2f687d465.yaml
@@ -987,12 +1010,15 @@ releasenotes/notes/osc4-identity-6564257c67d43106.yaml
releasenotes/notes/osc4-image-e922ee6f8e028648.yaml
releasenotes/notes/osc4-network-db2aed696d964ca6.yaml
releasenotes/notes/osc4-volume-470422e5a453310e.yaml
+releasenotes/notes/rbac-add-address-scope-7f6409ab70d36306.yaml
releasenotes/notes/rbac-add-security-group-35370701a06ac906.yaml
+releasenotes/notes/rbac-add-subnetpool-f1fc0e728ff61654.yaml
releasenotes/notes/recursive-container-delete-983361aa9c35ffed.yaml
releasenotes/notes/remove-ip-floating-commands-d5363f313e09249a.yaml
releasenotes/notes/remove-osc_password-0767ac78267ef114.yaml
releasenotes/notes/remove-unsupported-set-vlan-transparent-eeff412264ae7c09.yaml
releasenotes/notes/rename-snapshot-commands-e0937f7143a4ef55.yaml
+releasenotes/notes/router-extraroute-atomic-d6d406ffb15695f2.yaml
releasenotes/notes/router-gateway-IP-QoS-c8ba95e180bca05f.yaml
releasenotes/notes/router-gateway-set-01d9c7ffe4461daf.yaml
releasenotes/notes/router-port-add-0afe7392c080bcb8.yaml
@@ -1006,6 +1032,7 @@ releasenotes/notes/server-set-state-214b12ec2161de4d.yaml
releasenotes/notes/service-set-option-61772a8940ad0778.yaml
releasenotes/notes/skip-name-lookups-9f499927173c1eee.yaml
releasenotes/notes/speedup-object-save-6bd59e678a31c3e8.yaml
+releasenotes/notes/stateful-security-group-a21fa8498e866b90.yaml
releasenotes/notes/story-2005349-compute-service-set-2.53-3d2db875154e633a.yaml
releasenotes/notes/story-2006302-add-boot-from-volume-cd411b1ca776bb3c.yaml
releasenotes/notes/story-2006302-support-bdm-type-image-0becfb63bd4fb969.yaml
@@ -1017,6 +1044,7 @@ releasenotes/notes/support-icmp-type-code-zero-cbef0a36db2b8123.yaml
releasenotes/notes/support-no-property-in-volume-811e67ff4a199eb6.yaml
releasenotes/notes/support-no-property-in-volume-snapshot-0af3fcb31a3cfc2b.yaml
releasenotes/notes/support-uplink_status_propagation-4d37452bcf03e0f8.yaml
+releasenotes/notes/task-40279-eb0d718ac1959c50.yaml
releasenotes/notes/unlock-volume-a6990fc3bf1f5f67.yaml
releasenotes/notes/unset-router-7b0cbd9518bb1de6.yaml
releasenotes/notes/unset-subnet-pool-333052dd85b95653.yaml
@@ -1041,6 +1069,7 @@ releasenotes/source/rocky.rst
releasenotes/source/stein.rst
releasenotes/source/train.rst
releasenotes/source/unreleased.rst
+releasenotes/source/ussuri.rst
releasenotes/source/_static/.placeholder
releasenotes/source/_templates/.placeholder
tools/fast8.sh \ No newline at end of file
diff --git a/python_openstackclient.egg-info/entry_points.txt b/python_openstackclient.egg-info/entry_points.txt
index 37e9c27..87e8d94 100644
--- a/python_openstackclient.egg-info/entry_points.txt
+++ b/python_openstackclient.egg-info/entry_points.txt
@@ -388,11 +388,13 @@ port_set = openstackclient.network.v2.port:SetPort
port_show = openstackclient.network.v2.port:ShowPort
port_unset = openstackclient.network.v2.port:UnsetPort
router_add_port = openstackclient.network.v2.router:AddPortToRouter
+router_add_route = openstackclient.network.v2.router:AddExtraRoutesToRouter
router_add_subnet = openstackclient.network.v2.router:AddSubnetToRouter
router_create = openstackclient.network.v2.router:CreateRouter
router_delete = openstackclient.network.v2.router:DeleteRouter
router_list = openstackclient.network.v2.router:ListRouter
router_remove_port = openstackclient.network.v2.router:RemovePortFromRouter
+router_remove_route = openstackclient.network.v2.router:RemoveExtraRoutesFromRouter
router_remove_subnet = openstackclient.network.v2.router:RemoveSubnetFromRouter
router_set = openstackclient.network.v2.router:SetRouter
router_show = openstackclient.network.v2.router:ShowRouter
@@ -554,6 +556,8 @@ consistency_group_snapshot_show = openstackclient.volume.v2.consistency_group_sn
volume_backup_create = openstackclient.volume.v2.volume_backup:CreateVolumeBackup
volume_backup_delete = openstackclient.volume.v2.volume_backup:DeleteVolumeBackup
volume_backup_list = openstackclient.volume.v2.volume_backup:ListVolumeBackup
+volume_backup_record_export = openstackclient.volume.v2.backup_record:ExportBackupRecord
+volume_backup_record_import = openstackclient.volume.v2.backup_record:ImportBackupRecord
volume_backup_restore = openstackclient.volume.v2.volume_backup:RestoreVolumeBackup
volume_backup_set = openstackclient.volume.v2.volume_backup:SetVolumeBackup
volume_backup_show = openstackclient.volume.v2.volume_backup:ShowVolumeBackup
diff --git a/python_openstackclient.egg-info/pbr.json b/python_openstackclient.egg-info/pbr.json
index 0de25cc..a09307c 100644
--- a/python_openstackclient.egg-info/pbr.json
+++ b/python_openstackclient.egg-info/pbr.json
@@ -1 +1 @@
-{"git_version": "c5719a12", "is_release": true} \ No newline at end of file
+{"git_version": "82ebddca", "is_release": true} \ No newline at end of file
diff --git a/python_openstackclient.egg-info/requires.txt b/python_openstackclient.egg-info/requires.txt
index 1121490..9a45d70 100644
--- a/python_openstackclient.egg-info/requires.txt
+++ b/python_openstackclient.egg-info/requires.txt
@@ -1,11 +1,11 @@
-pbr!=2.1.0,>=2.0.0
-six>=1.10.0
-Babel!=2.4.0,>=2.3.4
cliff!=2.9.0,>=2.8.0
-openstacksdk>=0.36.0
+openstacksdk>=0.48.0
osc-lib>=2.0.0
oslo.i18n>=3.15.3
oslo.utils>=3.33.0
+pbr!=2.1.0,>=2.0.0
+python-cinderclient>=3.3.0
python-keystoneclient>=3.22.0
python-novaclient>=15.1.0
-python-cinderclient>=3.3.0
+six>=1.10.0
+stevedore>=2.0.1
diff --git a/releasenotes/notes/add-description-field-in-port-forwarding-c536e077b243d517.yaml b/releasenotes/notes/add-description-field-in-port-forwarding-c536e077b243d517.yaml
new file mode 100644
index 0000000..6df5bb3
--- /dev/null
+++ b/releasenotes/notes/add-description-field-in-port-forwarding-c536e077b243d517.yaml
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ Add a new option `--description` to
+ ``floating ip port forwarding create`` and
+ ``floating ip port forwarding set`` commands.
diff --git a/releasenotes/notes/add-image-import-flag-899869dc5a92aea7.yaml b/releasenotes/notes/add-image-import-flag-899869dc5a92aea7.yaml
new file mode 100644
index 0000000..fbd29bc
--- /dev/null
+++ b/releasenotes/notes/add-image-import-flag-899869dc5a92aea7.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ Added ``--import`` flag to ``openstack image create`` to allow
+ the user to force use of the image import codepath.
diff --git a/releasenotes/notes/add_options_to_user_create_and_set-302401520f36d153.yaml b/releasenotes/notes/add_options_to_user_create_and_set-302401520f36d153.yaml
new file mode 100644
index 0000000..698a6f1
--- /dev/null
+++ b/releasenotes/notes/add_options_to_user_create_and_set-302401520f36d153.yaml
@@ -0,0 +1,19 @@
+---
+features:
+ - |
+ Added the below mentioned parameters to the user create and set commands.
+
+ * --ignore-lockout-failure-attempts
+ * --no-ignore-lockout-failure-attempts
+ * --ignore-password-expiry
+ * --no-ignore-password-expiry
+ * --ignore-change-password-upon-first-use
+ * --no-ignore-change-password-upon-first-use
+ * --enable-lock-password
+ * --disable-lock-password
+ * --enable-multi-factor-auth
+ * --disable-multi-factor-auth
+ * --multi-factor-auth-rule
+
+ This will now allow users to set user options via CLI.
+ <https://docs.openstack.org/keystone/latest/admin/resource-options.html#user-options>
diff --git a/releasenotes/notes/add_resource_option_immutable-efed6e1ebdc69591.yaml b/releasenotes/notes/add_resource_option_immutable-efed6e1ebdc69591.yaml
new file mode 100644
index 0000000..814823f
--- /dev/null
+++ b/releasenotes/notes/add_resource_option_immutable-efed6e1ebdc69591.yaml
@@ -0,0 +1,9 @@
+---
+features:
+ - |
+ Added the below mentioned parameters to the role, project and domain commands.
+
+ * --immutable
+ * --no-immutable
+
+ This will allow user to set "immutable" resource option. \ No newline at end of file
diff --git a/releasenotes/notes/bug-2005246-3fb70206bafc5444.yaml b/releasenotes/notes/bug-2005246-3fb70206bafc5444.yaml
new file mode 100644
index 0000000..4d7bdd5
--- /dev/null
+++ b/releasenotes/notes/bug-2005246-3fb70206bafc5444.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+ - |
+ [Story `2005246 <https://storyboard.openstack.org/#!/story/2005246>`_]
+ The `is_domain` property safely handles type checking.
diff --git a/releasenotes/notes/disallow-setting-default-on-internal-network-824fdea1a900891c.yaml b/releasenotes/notes/disallow-setting-default-on-internal-network-824fdea1a900891c.yaml
deleted file mode 100644
index baf4efe..0000000
--- a/releasenotes/notes/disallow-setting-default-on-internal-network-824fdea1a900891c.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
----
-fixes:
- - |
- For ``network create`` the
- `--default`` option should be only used for external networks.
- After this release, we enforce this scenario. If a users attempts
- to create an internal default network or update a network to be
- internal default, the command will be denied.
- [Bug `1745658 <https://bugs.launchpad.net/bugs/1745658>`_]
diff --git a/releasenotes/notes/entrypoint-3.8-0597d159889042f7.yaml b/releasenotes/notes/entrypoint-3.8-0597d159889042f7.yaml
new file mode 100644
index 0000000..cb25cff
--- /dev/null
+++ b/releasenotes/notes/entrypoint-3.8-0597d159889042f7.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+ - |
+ Fixes an issue with python 3.8 and entrypoint loading where the
+ new builtin importlib entrypoint support had a different
+ attribute api than expected.
diff --git a/releasenotes/notes/fix-story-2007890-0974f3e69f26801e.yaml b/releasenotes/notes/fix-story-2007890-0974f3e69f26801e.yaml
new file mode 100644
index 0000000..87d6f18
--- /dev/null
+++ b/releasenotes/notes/fix-story-2007890-0974f3e69f26801e.yaml
@@ -0,0 +1,7 @@
+---
+fixes:
+ - |
+ While uploading a signed image, a private key to sign that image must be
+ specified. The CLI client asks for the password of that private key. Due
+ to wrong encoding handling while using Python 3, the password is not
+ accepted, whether it is correct or not.
diff --git a/releasenotes/notes/force-flag-openstackclient-c172de2717e5cfac.yaml b/releasenotes/notes/force-flag-openstackclient-c172de2717e5cfac.yaml
new file mode 100644
index 0000000..e1980d1
--- /dev/null
+++ b/releasenotes/notes/force-flag-openstackclient-c172de2717e5cfac.yaml
@@ -0,0 +1,6 @@
+---
+features:
+ - Add ``--force`` options to the ``openstack quota set``
+ command. The compute service allows us to to force set a quota, setting a
+ quota value that is less than the amount of the resource currently
+ consumed. Expose this feature by way of a ``--force`` boolean parameter.
diff --git a/releasenotes/notes/rbac-add-address-scope-7f6409ab70d36306.yaml b/releasenotes/notes/rbac-add-address-scope-7f6409ab70d36306.yaml
new file mode 100644
index 0000000..22b3838
--- /dev/null
+++ b/releasenotes/notes/rbac-add-address-scope-7f6409ab70d36306.yaml
@@ -0,0 +1,4 @@
+features:
+ - |
+ Add ``address_scope`` as a valid ``--type`` value for the
+ ``network rbac create`` and ``network rbac list`` commands.
diff --git a/releasenotes/notes/rbac-add-subnetpool-f1fc0e728ff61654.yaml b/releasenotes/notes/rbac-add-subnetpool-f1fc0e728ff61654.yaml
new file mode 100644
index 0000000..5bb3b59
--- /dev/null
+++ b/releasenotes/notes/rbac-add-subnetpool-f1fc0e728ff61654.yaml
@@ -0,0 +1,4 @@
+features:
+ - |
+ Add ``subnetpool`` as a valid ``--type`` value for the
+ ``network rbac create`` and ``network rbac list`` commands. \ No newline at end of file
diff --git a/releasenotes/notes/router-extraroute-atomic-d6d406ffb15695f2.yaml b/releasenotes/notes/router-extraroute-atomic-d6d406ffb15695f2.yaml
new file mode 100644
index 0000000..33b5ba7
--- /dev/null
+++ b/releasenotes/notes/router-extraroute-atomic-d6d406ffb15695f2.yaml
@@ -0,0 +1,12 @@
+---
+features:
+ - |
+ Add new commands ``router add route`` and ``router remove route`` to
+ support new Neutron extension: ``extraroute-atomic`` (see `Neutron RFE
+ <https://bugs.launchpad.net/neutron/+bug/1826396>`_).
+deprecations:
+ - |
+ The use of ``router set --route`` to add extra routes next to already
+ existing extra routes is deprecated in favor of ``router add route
+ --route``, because ``router set --route`` if used from multiple clients
+ concurrently may lead to lost updates.
diff --git a/releasenotes/notes/stateful-security-group-a21fa8498e866b90.yaml b/releasenotes/notes/stateful-security-group-a21fa8498e866b90.yaml
new file mode 100644
index 0000000..9b70bce
--- /dev/null
+++ b/releasenotes/notes/stateful-security-group-a21fa8498e866b90.yaml
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ Add ``--stateful`` and ``--stateless`` option to the
+ ``security group create`` and ``security group set`` commands
+ to support stateful and stateless security groups.
diff --git a/releasenotes/notes/task-40279-eb0d718ac1959c50.yaml b/releasenotes/notes/task-40279-eb0d718ac1959c50.yaml
new file mode 100644
index 0000000..aedb3ea
--- /dev/null
+++ b/releasenotes/notes/task-40279-eb0d718ac1959c50.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+ - |
+ Makes ``volume backup record`` commands available in Volume API v3.
+ `Task 40279 <https://storyboard.openstack.org/#!/story/2007896>`__
diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py
index 4060f49..206c0ce 100644
--- a/releasenotes/source/conf.py
+++ b/releasenotes/source/conf.py
@@ -44,8 +44,9 @@ extensions = [
]
# openstackdocstheme options
-repository_name = 'openstack/python-openstackclient'
-use_storyboard = True
+openstackdocs_repo_name = 'openstack/python-openstackclient'
+openstackdocs_use_storyboard = True
+openstackdocs_auto_name = False
# Set aliases for extlinks
# * lpbug - generic Launchpad bug :lpbug:`123456`
@@ -118,7 +119,7 @@ exclude_patterns = []
# show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = 'native'
# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []
@@ -169,11 +170,6 @@ html_static_path = ['_static']
# directly to the root of the documentation.
# html_extra_path = []
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-# html_last_updated_fmt = '%b %d, %Y'
-html_last_updated_fmt = '%Y-%m-%d %H:%M'
-
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
# html_use_smartypants = True
diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst
index fed41f9..889eeb0 100644
--- a/releasenotes/source/index.rst
+++ b/releasenotes/source/index.rst
@@ -6,6 +6,7 @@ OpenStackClient Release Notes
:maxdepth: 1
unreleased
+ ussuri
train
stein
rocky
diff --git a/releasenotes/source/ussuri.rst b/releasenotes/source/ussuri.rst
new file mode 100644
index 0000000..e21e50e
--- /dev/null
+++ b/releasenotes/source/ussuri.rst
@@ -0,0 +1,6 @@
+===========================
+Ussuri Series Release Notes
+===========================
+
+.. release-notes::
+ :branch: stable/ussuri
diff --git a/requirements.txt b/requirements.txt
index b17b6a5..2b7976e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,12 +4,12 @@
pbr!=2.1.0,>=2.0.0 # Apache-2.0
six>=1.10.0 # MIT
-Babel!=2.4.0,>=2.3.4 # BSD
cliff!=2.9.0,>=2.8.0 # Apache-2.0
-openstacksdk>=0.36.0 # Apache-2.0
+openstacksdk>=0.48.0 # Apache-2.0
osc-lib>=2.0.0 # Apache-2.0
oslo.i18n>=3.15.3 # Apache-2.0
oslo.utils>=3.33.0 # Apache-2.0
python-keystoneclient>=3.22.0 # Apache-2.0
python-novaclient>=15.1.0 # Apache-2.0
python-cinderclient>=3.3.0 # Apache-2.0
+stevedore>=2.0.1 # Apache-2.0
diff --git a/setup.cfg b/setup.cfg
index 6c8ab65..fee1fb2 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -6,6 +6,7 @@ description-file =
author = OpenStack
author-email = openstack-discuss@lists.openstack.org
home-page = https://docs.openstack.org/python-openstackclient/latest/
+python-requires = >=3.6
classifier =
Environment :: OpenStack
Intended Audience :: Information Technology
@@ -16,6 +17,7 @@ classifier =
Programming Language :: Python :: 3
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
+ Programming Language :: Python :: 3.8
[files]
packages =
@@ -240,6 +242,15 @@ openstack.identity.v3 =
endpoint_group_set = openstackclient.identity.v3.endpoint_group:SetEndpointGroup
endpoint_group_show = openstackclient.identity.v3.endpoint_group:ShowEndpointGroup
+ federation_domain_list = openstackclient.identity.v3.unscoped_saml:ListAccessibleDomains
+ federation_project_list = openstackclient.identity.v3.unscoped_saml:ListAccessibleProjects
+
+ federation_protocol_create = openstackclient.identity.v3.federation_protocol:CreateProtocol
+ federation_protocol_delete = openstackclient.identity.v3.federation_protocol:DeleteProtocol
+ federation_protocol_list = openstackclient.identity.v3.federation_protocol:ListProtocols
+ federation_protocol_set = openstackclient.identity.v3.federation_protocol:SetProtocol
+ federation_protocol_show = openstackclient.identity.v3.federation_protocol:ShowProtocol
+
group_add_user = openstackclient.identity.v3.group:AddUserToGroup
group_contains_user = openstackclient.identity.v3.group:CheckUserInGroup
group_create = openstackclient.identity.v3.group:CreateGroup
@@ -283,15 +294,6 @@ openstack.identity.v3 =
project_set = openstackclient.identity.v3.project:SetProject
project_show = openstackclient.identity.v3.project:ShowProject
- federation_protocol_create = openstackclient.identity.v3.federation_protocol:CreateProtocol
- federation_protocol_delete = openstackclient.identity.v3.federation_protocol:DeleteProtocol
- federation_protocol_list = openstackclient.identity.v3.federation_protocol:ListProtocols
- federation_protocol_set = openstackclient.identity.v3.federation_protocol:SetProtocol
- federation_protocol_show = openstackclient.identity.v3.federation_protocol:ShowProtocol
-
- federation_domain_list = openstackclient.identity.v3.unscoped_saml:ListAccessibleDomains
- federation_project_list = openstackclient.identity.v3.unscoped_saml:ListAccessibleProjects
-
region_create = openstackclient.identity.v3.region:CreateRegion
region_delete = openstackclient.identity.v3.region:DeleteRegion
region_list = openstackclient.identity.v3.region:ListRegion
@@ -471,11 +473,13 @@ openstack.network.v2 =
port_unset = openstackclient.network.v2.port:UnsetPort
router_add_port = openstackclient.network.v2.router:AddPortToRouter
+ router_add_route = openstackclient.network.v2.router:AddExtraRoutesToRouter
router_add_subnet = openstackclient.network.v2.router:AddSubnetToRouter
router_create = openstackclient.network.v2.router:CreateRouter
router_delete = openstackclient.network.v2.router:DeleteRouter
router_list = openstackclient.network.v2.router:ListRouter
router_remove_port = openstackclient.network.v2.router:RemovePortFromRouter
+ router_remove_route = openstackclient.network.v2.router:RemoveExtraRoutesFromRouter
router_remove_subnet = openstackclient.network.v2.router:RemoveSubnetFromRouter
router_set = openstackclient.network.v2.router:SetRouter
router_show = openstackclient.network.v2.router:ShowRouter
@@ -668,6 +672,9 @@ openstack.volume.v3 =
volume_backup_set = openstackclient.volume.v2.volume_backup:SetVolumeBackup
volume_backup_show = openstackclient.volume.v2.volume_backup:ShowVolumeBackup
+ volume_backup_record_export = openstackclient.volume.v2.backup_record:ExportBackupRecord
+ volume_backup_record_import = openstackclient.volume.v2.backup_record:ImportBackupRecord
+
volume_host_set = openstackclient.volume.v2.volume_host:SetVolumeHost
volume_snapshot_create = openstackclient.volume.v2.volume_snapshot:CreateVolumeSnapshot
@@ -702,23 +709,6 @@ openstack.volume.v3 =
volume_transfer_request_list = openstackclient.volume.v2.volume_transfer_request:ListTransferRequest
volume_transfer_request_show = openstackclient.volume.v2.volume_transfer_request:ShowTransferRequest
-[upload_sphinx]
-upload-dir = doc/build/html
-
-[extract_messages]
-keywords = _ gettext ngettext l_ lazy_gettext
-mapping_file = babel.cfg
-output_file = openstackclient/locale/openstackclient.pot
-
-[update_catalog]
-domain = openstackclient
-output_dir = openstackclient/locale
-input_file = openstackclient/locale/openstackclient.pot
-
-[compile_catalog]
-directory = openstackclient/locale
-domain = openstackclient
-
[egg_info]
tag_build =
tag_date = 0
diff --git a/setup.py b/setup.py
index 566d844..cd35c3c 100644
--- a/setup.py
+++ b/setup.py
@@ -13,17 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
import setuptools
-# In python < 2.7.4, a lazy loading of package `pbr` will break
-# setuptools if some other modules registered functions in `atexit`.
-# solution from: http://bugs.python.org/issue15881#msg170215
-try:
- import multiprocessing # noqa
-except ImportError:
- pass
-
setuptools.setup(
setup_requires=['pbr>=2.0.0'],
pbr=True)
diff --git a/test-requirements.txt b/test-requirements.txt
index 55ae1ea..3dce687 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -5,15 +5,13 @@ hacking>=2.0.0 # Apache-2.0
coverage!=4.4,>=4.0 # Apache-2.0
fixtures>=3.0.0 # Apache-2.0/BSD
flake8-import-order>=0.13 # LGPLv3
-mock>=2.0.0 # BSD
oslotest>=3.2.0 # Apache-2.0
requests>=2.14.2 # Apache-2.0
requests-mock>=1.2.0 # Apache-2.0
-stevedore>=1.20.0 # Apache-2.0
-os-client-config>=1.28.0 # Apache-2.0
stestr>=1.0.0 # Apache-2.0
testtools>=2.2.0 # MIT
tempest>=17.1.0 # Apache-2.0
osprofiler>=1.4.0 # Apache-2.0
bandit!=1.6.0,>=1.1.0 # Apache-2.0
wrapt>=1.7.0 # BSD License
+ddt>=1.0.1 # MIT
diff --git a/tox.ini b/tox.ini
index 3b4b66a..3a2a307 100644
--- a/tox.ini
+++ b/tox.ini
@@ -64,7 +64,6 @@ commands =
python -m pip install -q -U -e "git+file://{toxinidir}/../cliff#egg=cliff"
python -m pip install -q -U -e "git+file://{toxinidir}/../keystoneauth#egg=keystoneauth"
python -m pip install -q -U -e "git+file://{toxinidir}/../osc-lib#egg=osc_lib"
- python -m pip install -q -U -e "git+file://{toxinidir}/../os-client-config#egg=os_client_config"
pythom -m pip install -q -e "git+file://{toxinidir}/../openstacksdk#egg=openstacksdk"
python -m pip freeze
stestr run {posargs}
@@ -83,7 +82,6 @@ commands =
python -m pip install -q -U -e "git+file://{toxinidir}/../cliff#egg=cliff"
python -m pip install -q -U -e "git+file://{toxinidir}/../keystoneauth#egg=keystoneauth"
python -m pip install -q -U -e "git+file://{toxinidir}/../osc-lib#egg=osc_lib"
- python -m pip install -q -U -e "git+file://{toxinidir}/../os-client-config#egg=os_client_config"
python -m pip install -q -U -e "git+file://{toxinidir}/../openstacksdk#egg=openstacksdk"
python -m pip freeze
stestr run {posargs}