summaryrefslogtreecommitdiff
diff options
authorJames Page <james.page@ubuntu.com>2025-02-27 12:47:04 +0000
committergit-ubuntu importer <ubuntu-devel-discuss@lists.ubuntu.com>2025-02-27 12:48:11 +0000
commitcadf285ef3bba5f6cb863c72568936e007bf556e (patch)
tree9cac5298d12ec2fc915fdd7a64a1c49ec1e7fb90
parentba57fd4e657ceaead84ad821e6ac4b05b785c4ca (diff)
Imported using git-ubuntu import.
Notes
Notes: * New upstream release for OpenStack Epoxy.
-rw-r--r--.zuul.yaml12
-rw-r--r--AUTHORS3
-rw-r--r--ChangeLog54
-rw-r--r--PKG-INFO298
-rw-r--r--debian/changelog6
-rw-r--r--openstackclient/common/limits.py2
-rw-r--r--openstackclient/common/quota.py9
-rw-r--r--openstackclient/compute/v2/server.py60
-rw-r--r--openstackclient/compute/v2/usage.py4
-rw-r--r--openstackclient/identity/common.py56
-rw-r--r--openstackclient/identity/v3/credential.py77
-rw-r--r--openstackclient/identity/v3/limit.py15
-rw-r--r--openstackclient/identity/v3/region.py45
-rw-r--r--openstackclient/identity/v3/registered_limit.py18
-rw-r--r--openstackclient/identity/v3/role.py404
-rw-r--r--openstackclient/identity/v3/role_assignment.py2
-rw-r--r--openstackclient/identity/v3/service_provider.py140
-rw-r--r--openstackclient/identity/v3/trust.py189
-rw-r--r--openstackclient/image/v2/image.py3
-rw-r--r--openstackclient/network/v2/network.py33
-rw-r--r--openstackclient/network/v2/network_flavor_profile.py18
-rw-r--r--openstackclient/network/v2/port.py111
-rw-r--r--openstackclient/network/v2/router.py3
-rw-r--r--openstackclient/tests/functional/compute/v2/test_server.py88
-rw-r--r--openstackclient/tests/functional/identity/v3/common.py2
-rw-r--r--openstackclient/tests/functional/identity/v3/test_application_credential.py3
-rw-r--r--openstackclient/tests/functional/identity/v3/test_role.py24
-rw-r--r--openstackclient/tests/functional/identity/v3/test_role_assignment.py8
-rw-r--r--openstackclient/tests/functional/identity/v3/test_service_provider.py6
-rw-r--r--openstackclient/tests/functional/network/v2/test_port.py108
-rw-r--r--openstackclient/tests/unit/compute/v2/fakes.py304
-rw-r--r--openstackclient/tests/unit/compute/v2/test_aggregate.py71
-rw-r--r--openstackclient/tests/unit/compute/v2/test_console.py10
-rw-r--r--openstackclient/tests/unit/compute/v2/test_hypervisor.py113
-rw-r--r--openstackclient/tests/unit/compute/v2/test_keypair.py126
-rw-r--r--openstackclient/tests/unit/compute/v2/test_server.py68
-rw-r--r--openstackclient/tests/unit/compute/v2/test_server_group.py204
-rw-r--r--openstackclient/tests/unit/compute/v2/test_server_volume.py17
-rw-r--r--openstackclient/tests/unit/compute/v2/test_service.py120
-rw-r--r--openstackclient/tests/unit/compute/v2/test_usage.py19
-rw-r--r--openstackclient/tests/unit/identity/v2_0/test_catalog.py9
-rw-r--r--openstackclient/tests/unit/identity/v2_0/test_role.py3
-rw-r--r--openstackclient/tests/unit/identity/v2_0/test_role_assignment.py3
-rw-r--r--openstackclient/tests/unit/identity/v2_0/test_token.py26
-rw-r--r--openstackclient/tests/unit/identity/v3/test_catalog.py7
-rw-r--r--openstackclient/tests/unit/identity/v3/test_credential.py145
-rw-r--r--openstackclient/tests/unit/identity/v3/test_project.py4
-rw-r--r--openstackclient/tests/unit/identity/v3/test_region.py170
-rw-r--r--openstackclient/tests/unit/identity/v3/test_role.py1282
-rw-r--r--openstackclient/tests/unit/identity/v3/test_role_assignment.py264
-rw-r--r--openstackclient/tests/unit/identity/v3/test_service_provider.py368
-rw-r--r--openstackclient/tests/unit/identity/v3/test_token.py25
-rw-r--r--openstackclient/tests/unit/identity/v3/test_trust.py292
-rw-r--r--openstackclient/tests/unit/image/v2/test_image.py6
-rw-r--r--openstackclient/tests/unit/network/v2/fakes.py3
-rw-r--r--openstackclient/tests/unit/network/v2/test_network.py25
-rw-r--r--openstackclient/tests/unit/network/v2/test_network_flavor_profile.py35
-rw-r--r--openstackclient/tests/unit/network/v2/test_port.py172
-rw-r--r--openstackclient/tests/unit/network/v2/test_router.py64
-rw-r--r--openstackclient/tests/unit/utils.py10
-rw-r--r--openstackclient/tests/unit/volume/v2/test_volume_backup.py44
-rw-r--r--openstackclient/tests/unit/volume/v3/test_volume_backup.py47
-rw-r--r--openstackclient/volume/v2/volume_backup.py13
-rw-r--r--openstackclient/volume/v3/volume_backup.py15
-rw-r--r--python_openstackclient.egg-info/PKG-INFO298
-rw-r--r--python_openstackclient.egg-info/SOURCES.txt11
-rw-r--r--python_openstackclient.egg-info/entry_points.txt1
-rw-r--r--python_openstackclient.egg-info/pbr.json2
-rw-r--r--python_openstackclient.egg-info/requires.txt6
-rw-r--r--releasenotes/notes/Add-trusted-vif-to-the-port-0a0c76d9da8f3da0.yaml7
-rw-r--r--releasenotes/notes/add-vlan_qinq-to-the-network-3556c094aeedc0de.yaml7
-rw-r--r--releasenotes/notes/fix-restore-resp-e664a643a723cd2e.yaml4
-rw-r--r--releasenotes/notes/fix-show-backup-by-name-0759c55396be77a3.yaml5
-rw-r--r--releasenotes/notes/migrate-credential-to-sdk-33a841847fe7d568.yaml10
-rw-r--r--releasenotes/notes/migrate-region-to-sdk-fbd27bceaa1db9dc.yaml10
-rw-r--r--releasenotes/notes/migrate-service-provider-to-sdk-74dc48b227f21a05.yaml10
-rw-r--r--releasenotes/notes/migrate-trust-to-sdk-9397c9cfddcb636a.yaml9
-rw-r--r--releasenotes/notes/port_uplink_status_propagation_updatable-d1e155c19247b666.yaml5
-rw-r--r--releasenotes/notes/server-create-no-security-group-option-627697bddae429b1.yaml7
-rw-r--r--releasenotes/notes/volume-backup-created-at-list-v3-47400b31be5143bc.yaml5
-rw-r--r--releasenotes/source/2023.1.rst2
-rw-r--r--test-requirements.txt2
82 files changed, 3688 insertions, 2598 deletions
diff --git a/.zuul.yaml b/.zuul.yaml
index ac4d63a..e688bd2 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -6,6 +6,11 @@
Run unit tests for OpenStackClient with master branch of important libs.
Takes advantage of the base tox job's install-siblings feature.
+ irrelevant-files: &common-irrelevant-files
+ - ^.*\.rst$
+ - ^doc/.*$
+ - ^releasenotes/.*$
+ - ^\.pre-commit-config\.yaml$
required-projects:
- openstack/cliff
- openstack/keystoneauth
@@ -81,13 +86,6 @@
# NOTE(amotoki): Some neutron features are enabled by devstack plugin
neutron: https://opendev.org/openstack/neutron
devstack_services:
- ceilometer-acentral: false
- ceilometer-acompute: false
- ceilometer-alarm-evaluator: false
- ceilometer-alarm-notifier: false
- ceilometer-anotification: false
- ceilometer-api: false
- ceilometer-collector: false
s-account: true
s-container: true
s-object: true
diff --git a/AUTHORS b/AUTHORS
index 86c2022..8280344 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -112,6 +112,7 @@ Dmitriy Rabotyagov <noonedeadpunk@ya.ru>
Dmitry Tantsur <dtantsur@protonmail.com>
Dolph Mathews <dolph.mathews@gmail.com>
Dongcan Ye <hellochosen@gmail.com>
+Doug Goldstein <cardoe@cardoe.com>
Doug Hellmann <doug.hellmann@dreamhost.com>
Doug Hellmann <doug@doughellmann.com>
Doug Wiegley <dwiegley@salesforce.com>
@@ -128,6 +129,7 @@ Fan Zhang <zh.f@outlook.com>
Fang Zhen <zhen.fang@easystack.cn>
Fei Long Wang <flwang@catalyst.net.nz>
Felix Yan <felixonmars@archlinux.org>
+Fernando Royo <froyo@redhat.com>
Flavio Percoco <flaper87@gmail.com>
Florent Flament <florent.flament-ext@cloudwatt.com>
Florian Streibelt <florian.streibelt@sap.com>
@@ -439,6 +441,7 @@ Yi Zhao <zhaoyi@cmss.chinamobile.com>
Yongli He <yongli.he@intel.com>
YoonSoo LIM <msdbtjd123@naver.com>
Yoonsoo Lim <msdbtjd123@naver.com>
+Yosef Salmalian <flaslnm@gmail.com>
Youngjun <yj.yoo@okestro.com>
YuehuiLei <leiyuehui@inspur.com>
Yunpeng Li <yunpeng.li@live.cn>
diff --git a/ChangeLog b/ChangeLog
index dcd921f..f183169 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,10 +1,64 @@
CHANGES
=======
+7.4.0
+-----
+
+* Fix credential creation
+
+7.3.1
+-----
+
+* [Neutron] Fix the "port show" command for trunk details
+* [Neutron] Support \`\`uplink-status-propagation-updatable\`\` extension
+* handle 'router create --flavor' option
+* [Neutron] "uplink-status-propagation" enabled by default
+
+7.3.0
+-----
+
+* Add "qinq-vlan" and "no-qinq-vlan" params to the "network create" cmd
+* Temporary ignore "is\_vlan\_qinq" column in the output
+* Identity: Deprecate \`--region None\` in limits/registered limits
+* Get "security\_groups" when port list
+* Show final image state after image create
+* Identity: Migrate 'role' commands to SDK
+* Add the trunk subports information to the port list command
+* Fix: Volume backup restore output
+* identity: Migrate 'trust' commands to SDK
+* tests: Stop setting attributes on class
+* Adopt sdk\_fakes for compute.test\_server\_volume
+* Adopt sdk\_fakes for compute.test\_server\_group
+* Adopt sdk\_fakes for compute.test\_hypervisor
+* Adopt sdk\_fakes for compute.test\_usage
+* Adopt sdk\_fakes for compute.test\_service
+* Adopt sdk\_fakes for compute.test\_keypair
+* Adopt sdk\_fakes for compute.test\_console
+* Adopt sdk\_fakes for compute.aggregate
+* identity: Migrate 'service provider' commands to SDK
+* quota: Catch correct exception type for Compute quotas
+* tests: Add functional test for adding, removing SGs
+* compute: Workaround bug #2089821
+* network: Make better use of argparse
+* compute: Add server create --no-security-group option
+* Remove ceilometer service overrides
+* identity: Migrate \`region\` commands to SDK
+* reno: Update master for unmaintained/2023.1
+* identity: Migrate 'credential' commands to SDK
+* Replace deprecated datetime.utcnow()
+* requirements: Remove unused test deps
+* Skip tips jobs on pre-commit config update
+* common: Use correct argument for volume limits
+* Add "trusted" attribute to the "port"
+* Fix ignored --user-domain in role assignment list
+* Show Created At column for volume backups in v3
+* remove project from network flavor profile
+
7.2.1
-----
* clientmanager: Check for 'block-storage' service type
+* Fix volume backup show by name
7.2.0
-----
diff --git a/PKG-INFO b/PKG-INFO
index 5b0b4cc..619eb75 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,152 +1,10 @@
-Metadata-Version: 1.2
+Metadata-Version: 2.1
Name: python-openstackclient
-Version: 7.2.1
+Version: 7.4.0
Summary: OpenStack Command-line Client
Home-page: https://docs.openstack.org/python-openstackclient/latest/
Author: OpenStack
Author-email: openstack-discuss@lists.openstack.org
-License: UNKNOWN
-Description: ========================
- Team and repository tags
- ========================
-
- .. image:: https://governance.openstack.org/tc/badges/python-openstackclient.svg
- :target: https://governance.openstack.org/tc/reference/tags/index.html
-
- .. Change things from this point on
-
- ===============
- OpenStackClient
- ===============
-
- .. image:: https://img.shields.io/pypi/v/python-openstackclient.svg
- :target: https://pypi.org/project/python-openstackclient/
- :alt: Latest Version
-
- OpenStackClient (aka OSC) is a command-line client for OpenStack that brings
- the command set for Compute, Identity, Image, Network, Object Store and Block
- Storage APIs together in a single shell with a uniform command structure.
-
- The primary goal is to provide a unified shell command structure and a common
- language to describe operations in OpenStack.
-
- * `PyPi`_ - package installation
- * `Online Documentation`_
- * `Launchpad project`_ - bugs and feature requests
- * `Blueprints`_ - feature specifications (historical only)
- * `Source`_
- * `Developer`_ - getting started as a developer
- * `Contributing`_ - contributing code
- * `Testing`_ - testing code
- * IRC: #openstack-sdks on OFTC (irc.oftc.net)
- * License: Apache 2.0
-
- .. _PyPi: https://pypi.org/project/python-openstackclient
- .. _Online Documentation: https://docs.openstack.org/python-openstackclient/latest/
- .. _Blueprints: https://blueprints.launchpad.net/python-openstackclient
- .. _`Launchpad project`: https://bugs.launchpad.net/python-openstackclient
- .. _Source: https://opendev.org/openstack/python-openstackclient
- .. _Developer: https://docs.openstack.org/project-team-guide/project-setup/python.html
- .. _Contributing: https://docs.openstack.org/infra/manual/developers.html
- .. _Testing: https://docs.openstack.org/python-openstackclient/latest/contributor/developing.html#testing
- .. _Release Notes: https://docs.openstack.org/releasenotes/python-openstackclient
-
- Getting Started
- ===============
-
- OpenStack Client can be installed from PyPI using pip::
-
- pip install python-openstackclient
-
- There are a few variants on getting help. A list of global options and supported
- commands is shown with ``--help``::
-
- openstack --help
-
- There is also a ``help`` command that can be used to get help text for a specific
- command::
-
- openstack help
- openstack help server create
-
- If you want to make changes to the OpenStackClient for testing and contribution,
- make any changes and then run::
-
- python setup.py develop
-
- or::
-
- pip install -e .
-
- Configuration
- =============
-
- The CLI is configured via environment variables and command-line
- options as listed in https://docs.openstack.org/python-openstackclient/latest/cli/authentication.html.
-
- Authentication using username/password is most commonly used:
-
- - For a local user, your configuration will look like the one below::
-
- export OS_AUTH_URL=<url-to-openstack-identity>
- export OS_IDENTITY_API_VERSION=3
- export OS_PROJECT_NAME=<project-name>
- export OS_PROJECT_DOMAIN_NAME=<project-domain-name>
- export OS_USERNAME=<username>
- export OS_USER_DOMAIN_NAME=<user-domain-name>
- export OS_PASSWORD=<password> # (optional)
-
- The corresponding command-line options look very similar::
-
- --os-auth-url <url>
- --os-identity-api-version 3
- --os-project-name <project-name>
- --os-project-domain-name <project-domain-name>
- --os-username <username>
- --os-user-domain-name <user-domain-name>
- [--os-password <password>]
-
- - For a federated user, your configuration will look the so::
-
- export OS_PROJECT_NAME=<project-name>
- export OS_PROJECT_DOMAIN_NAME=<project-domain-name>
- export OS_AUTH_URL=<url-to-openstack-identity>
- export OS_IDENTITY_API_VERSION=3
- export OS_AUTH_PLUGIN=openid
- export OS_AUTH_TYPE=v3oidcpassword
- export OS_USERNAME=<username-in-idp>
- export OS_PASSWORD=<password-in-idp>
- export OS_IDENTITY_PROVIDER=<the-desired-idp-in-keystone>
- export OS_CLIENT_ID=<the-client-id-configured-in-the-idp>
- export OS_CLIENT_SECRET=<the-client-secred-configured-in-the-idp>
- export OS_OPENID_SCOPE=<the-scopes-of-desired-attributes-to-claim-from-idp>
- export OS_PROTOCOL=<the-protocol-used-in-the-apache2-oidc-proxy>
- export OS_ACCESS_TOKEN_TYPE=<the-access-token-type-used-by-your-idp>
- export OS_DISCOVERY_ENDPOINT=<the-well-known-endpoint-of-the-idp>
-
- The corresponding command-line options look very similar::
-
- --os-project-name <project-name>
- --os-project-domain-name <project-domain-name>
- --os-auth-url <url-to-openstack-identity>
- --os-identity-api-version 3
- --os-auth-plugin openid
- --os-auth-type v3oidcpassword
- --os-username <username-in-idp>
- --os-password <password-in-idp>
- --os-identity-provider <the-desired-idp-in-keystone>
- --os-client-id <the-client-id-configured-in-the-idp>
- --os-client-secret <the-client-secred-configured-in-the-idp>
- --os-openid-scope <the-scopes-of-desired-attributes-to-claim-from-idp>
- --os-protocol <the-protocol-used-in-the-apache2-oidc-proxy>
- --os-access-token-type <the-access-token-type-used-by-your-idp>
- --os-discovery-endpoint <the-well-known-endpoint-of-the-idp>
-
- If a password is not provided above (in plaintext), you will be interactively
- prompted to provide one securely.
-
-
-Platform: UNKNOWN
Classifier: Environment :: OpenStack
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
@@ -159,3 +17,155 @@ Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.9
+License-File: LICENSE
+Requires-Dist: pbr!=2.1.0,>=2.0.0
+Requires-Dist: cryptography>=2.7
+Requires-Dist: cliff>=3.5.0
+Requires-Dist: iso8601>=0.1.11
+Requires-Dist: openstacksdk>=3.3.0
+Requires-Dist: osc-lib>=2.3.0
+Requires-Dist: oslo.i18n>=3.15.3
+Requires-Dist: python-keystoneclient>=3.22.0
+Requires-Dist: python-cinderclient>=3.3.0
+Requires-Dist: requests>=2.27.0
+Requires-Dist: stevedore>=2.0.1
+
+========================
+Team and repository tags
+========================
+
+.. image:: https://governance.openstack.org/tc/badges/python-openstackclient.svg
+ :target: https://governance.openstack.org/tc/reference/tags/index.html
+
+.. Change things from this point on
+
+===============
+OpenStackClient
+===============
+
+.. image:: https://img.shields.io/pypi/v/python-openstackclient.svg
+ :target: https://pypi.org/project/python-openstackclient/
+ :alt: Latest Version
+
+OpenStackClient (aka OSC) is a command-line client for OpenStack that brings
+the command set for Compute, Identity, Image, Network, Object Store and Block
+Storage APIs together in a single shell with a uniform command structure.
+
+The primary goal is to provide a unified shell command structure and a common
+language to describe operations in OpenStack.
+
+* `PyPi`_ - package installation
+* `Online Documentation`_
+* `Launchpad project`_ - bugs and feature requests
+* `Blueprints`_ - feature specifications (historical only)
+* `Source`_
+* `Developer`_ - getting started as a developer
+* `Contributing`_ - contributing code
+* `Testing`_ - testing code
+* IRC: #openstack-sdks on OFTC (irc.oftc.net)
+* License: Apache 2.0
+
+.. _PyPi: https://pypi.org/project/python-openstackclient
+.. _Online Documentation: https://docs.openstack.org/python-openstackclient/latest/
+.. _Blueprints: https://blueprints.launchpad.net/python-openstackclient
+.. _`Launchpad project`: https://bugs.launchpad.net/python-openstackclient
+.. _Source: https://opendev.org/openstack/python-openstackclient
+.. _Developer: https://docs.openstack.org/project-team-guide/project-setup/python.html
+.. _Contributing: https://docs.openstack.org/infra/manual/developers.html
+.. _Testing: https://docs.openstack.org/python-openstackclient/latest/contributor/developing.html#testing
+.. _Release Notes: https://docs.openstack.org/releasenotes/python-openstackclient
+
+Getting Started
+===============
+
+OpenStack Client can be installed from PyPI using pip::
+
+ pip install python-openstackclient
+
+There are a few variants on getting help. A list of global options and supported
+commands is shown with ``--help``::
+
+ openstack --help
+
+There is also a ``help`` command that can be used to get help text for a specific
+command::
+
+ openstack help
+ openstack help server create
+
+If you want to make changes to the OpenStackClient for testing and contribution,
+make any changes and then run::
+
+ python setup.py develop
+
+or::
+
+ pip install -e .
+
+Configuration
+=============
+
+The CLI is configured via environment variables and command-line
+options as listed in https://docs.openstack.org/python-openstackclient/latest/cli/authentication.html.
+
+Authentication using username/password is most commonly used:
+
+- For a local user, your configuration will look like the one below::
+
+ export OS_AUTH_URL=<url-to-openstack-identity>
+ export OS_IDENTITY_API_VERSION=3
+ export OS_PROJECT_NAME=<project-name>
+ export OS_PROJECT_DOMAIN_NAME=<project-domain-name>
+ export OS_USERNAME=<username>
+ export OS_USER_DOMAIN_NAME=<user-domain-name>
+ export OS_PASSWORD=<password> # (optional)
+
+ The corresponding command-line options look very similar::
+
+ --os-auth-url <url>
+ --os-identity-api-version 3
+ --os-project-name <project-name>
+ --os-project-domain-name <project-domain-name>
+ --os-username <username>
+ --os-user-domain-name <user-domain-name>
+ [--os-password <password>]
+
+- For a federated user, your configuration will look the so::
+
+ export OS_PROJECT_NAME=<project-name>
+ export OS_PROJECT_DOMAIN_NAME=<project-domain-name>
+ export OS_AUTH_URL=<url-to-openstack-identity>
+ export OS_IDENTITY_API_VERSION=3
+ export OS_AUTH_PLUGIN=openid
+ export OS_AUTH_TYPE=v3oidcpassword
+ export OS_USERNAME=<username-in-idp>
+ export OS_PASSWORD=<password-in-idp>
+ export OS_IDENTITY_PROVIDER=<the-desired-idp-in-keystone>
+ export OS_CLIENT_ID=<the-client-id-configured-in-the-idp>
+ export OS_CLIENT_SECRET=<the-client-secred-configured-in-the-idp>
+ export OS_OPENID_SCOPE=<the-scopes-of-desired-attributes-to-claim-from-idp>
+ export OS_PROTOCOL=<the-protocol-used-in-the-apache2-oidc-proxy>
+ export OS_ACCESS_TOKEN_TYPE=<the-access-token-type-used-by-your-idp>
+ export OS_DISCOVERY_ENDPOINT=<the-well-known-endpoint-of-the-idp>
+
+ The corresponding command-line options look very similar::
+
+ --os-project-name <project-name>
+ --os-project-domain-name <project-domain-name>
+ --os-auth-url <url-to-openstack-identity>
+ --os-identity-api-version 3
+ --os-auth-plugin openid
+ --os-auth-type v3oidcpassword
+ --os-username <username-in-idp>
+ --os-password <password-in-idp>
+ --os-identity-provider <the-desired-idp-in-keystone>
+ --os-client-id <the-client-id-configured-in-the-idp>
+ --os-client-secret <the-client-secred-configured-in-the-idp>
+ --os-openid-scope <the-scopes-of-desired-attributes-to-claim-from-idp>
+ --os-protocol <the-protocol-used-in-the-apache2-oidc-proxy>
+ --os-access-token-type <the-access-token-type-used-by-your-idp>
+ --os-discovery-endpoint <the-well-known-endpoint-of-the-idp>
+
+If a password is not provided above (in plaintext), you will be interactively
+prompted to provide one securely.
+
diff --git a/debian/changelog b/debian/changelog
index be14d11..471cf81 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+python-openstackclient (7.4.0-0ubuntu1) plucky; urgency=medium
+
+ * New upstream release for OpenStack Epoxy.
+
+ -- James Page <james.page@ubuntu.com> Thu, 27 Feb 2025 12:47:04 +0000
+
python-openstackclient (7.2.1-0ubuntu1) plucky; urgency=medium
* d/gbp.conf, .launchpad.yaml: Sync from cloud-archive-tools for
diff --git a/openstackclient/common/limits.py b/openstackclient/common/limits.py
index cb2f331..ac613fd 100644
--- a/openstackclient/common/limits.py
+++ b/openstackclient/common/limits.py
@@ -130,7 +130,7 @@ class ShowLimits(command.Lister):
if self.app.client_manager.is_volume_endpoint_enabled():
volume_client = self.app.client_manager.sdk_connection.volume
volume_limits = volume_client.get_limits(
- project_id=project_id,
+ project=project_id,
)
if parsed_args.is_absolute:
diff --git a/openstackclient/common/quota.py b/openstackclient/common/quota.py
index 4356cae..638d2e1 100644
--- a/openstackclient/common/quota.py
+++ b/openstackclient/common/quota.py
@@ -249,9 +249,14 @@ class ListQuota(command.Lister):
for project_id in project_ids:
try:
project_data = compute_client.get_quota_set(project_id)
+ # NOTE(stephenfin): Unfortunately, Nova raises a HTTP 400 (Bad
+ # Request) if the project ID is invalid, even though the project
+ # ID is actually the resource's identifier which would normally
+ # lead us to expect a HTTP 404 (Not Found).
except (
- sdk_exceptions.NotFoundException,
+ sdk_exceptions.BadRequestException,
sdk_exceptions.ForbiddenException,
+ sdk_exceptions.NotFoundException,
) as exc:
# Project not found, move on to next one
LOG.warning(f"Project {project_id} not found: {exc}")
@@ -312,8 +317,8 @@ class ListQuota(command.Lister):
try:
project_data = volume_client.get_quota_set(project_id)
except (
- sdk_exceptions.NotFoundException,
sdk_exceptions.ForbiddenException,
+ sdk_exceptions.NotFoundException,
) as exc:
# Project not found, move on to next one
LOG.warning(f"Project {project_id} not found: {exc}")
diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index f7b860d..dcadca1 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -714,7 +714,8 @@ class AddServerSecurityGroup(command.Command):
for security_group in security_groups:
try:
compute_client.add_security_group_to_server(
- server, security_group
+ server,
+ {'name': security_group},
)
except sdk_exceptions.HttpException as e:
errors += 1
@@ -1356,14 +1357,26 @@ class CreateServer(command.ShowOne):
'This option requires cloud support.'
),
)
- parser.add_argument(
+ secgroups = parser.add_mutually_exclusive_group()
+ secgroups.add_argument(
+ '--no-security-group',
+ dest='security_groups',
+ action='store_const',
+ const=[],
+ help=_(
+ 'Do not associate a security group with ports attached to '
+ 'this server. This does not affect the security groups '
+ 'associated with pre-existing ports.'
+ ),
+ )
+ secgroups.add_argument(
'--security-group',
metavar='<security-group>',
action='append',
- default=[],
dest='security_groups',
help=_(
- 'Security group to assign to this server (name or ID) '
+ 'Security group to associate with ports attached to this '
+ 'server (name or ID) '
'(repeat option to set multiple groups)'
),
)
@@ -1980,22 +1993,24 @@ class CreateServer(command.ShowOne):
networks = 'auto'
# Check security group(s) exist and convert ID to name
- security_groups = []
- if self.app.client_manager.is_network_endpoint_enabled():
- network_client = self.app.client_manager.network
- for security_group in parsed_args.security_groups:
- sg = network_client.find_security_group(
- security_group, ignore_missing=False
- )
- # Use security group ID to avoid multiple security group have
- # same name in neutron networking backend
- security_groups.append({'name': sg.id})
- else: # nova-network
- for security_group in parsed_args.security_groups:
- sg = compute_v2.find_security_group(
- compute_client, security_group
- )
- security_groups.append({'name': sg['name']})
+ security_groups = None
+ if parsed_args.security_groups is not None:
+ security_groups = []
+ if self.app.client_manager.is_network_endpoint_enabled():
+ network_client = self.app.client_manager.network
+ for security_group in parsed_args.security_groups:
+ sg = network_client.find_security_group(
+ security_group, ignore_missing=False
+ )
+ # Use security group ID to avoid multiple security group
+ # have same name in neutron networking backend
+ security_groups.append({'name': sg.id})
+ else: # nova-network
+ for security_group in parsed_args.security_groups:
+ sg = compute_v2.find_security_group(
+ compute_client, security_group
+ )
+ security_groups.append({'name': sg['name']})
hints = {}
for key, values in parsed_args.hints.items():
@@ -2058,7 +2073,7 @@ class CreateServer(command.ShowOne):
if files:
kwargs['personality'] = files
- if security_groups:
+ if security_groups is not None:
kwargs['security_groups'] = security_groups
if block_device_mapping_v2:
@@ -4083,7 +4098,8 @@ class RemoveServerSecurityGroup(command.Command):
for security_group in security_groups:
try:
compute_client.remove_security_group_from_server(
- server, security_group
+ server,
+ {'name': security_group},
)
except sdk_exceptions.HttpException as e:
errors += 1
diff --git a/openstackclient/compute/v2/usage.py b/openstackclient/compute/v2/usage.py
index 27f9335..5d91358 100644
--- a/openstackclient/compute/v2/usage.py
+++ b/openstackclient/compute/v2/usage.py
@@ -153,7 +153,7 @@ class ListUsage(command.Lister):
)
date_cli_format = "%Y-%m-%d"
- now = datetime.datetime.utcnow()
+ now = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
if parsed_args.start:
start = datetime.datetime.strptime(
@@ -238,7 +238,7 @@ class ShowUsage(command.ShowOne):
identity_client = self.app.client_manager.identity
compute_client = self.app.client_manager.sdk_connection.compute
date_cli_format = "%Y-%m-%d"
- now = datetime.datetime.utcnow()
+ now = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
if parsed_args.start:
start = datetime.datetime.strptime(
diff --git a/openstackclient/identity/common.py b/openstackclient/identity/common.py
index b8a5b88..9f4402f 100644
--- a/openstackclient/identity/common.py
+++ b/openstackclient/identity/common.py
@@ -184,13 +184,6 @@ def _get_token_resource(client, resource, parsed_name, parsed_domain=None):
return parsed_name
-def _get_domain_id_if_requested(identity_client, domain_name_or_id):
- if not domain_name_or_id:
- return None
- domain = find_domain(identity_client, domain_name_or_id)
- return domain.id
-
-
def find_domain(identity_client, name_or_id):
return _find_identity_resource(
identity_client.domains, name_or_id, domains.Domain
@@ -198,48 +191,43 @@ def find_domain(identity_client, name_or_id):
def find_group(identity_client, name_or_id, domain_name_or_id=None):
- domain_id = _get_domain_id_if_requested(identity_client, domain_name_or_id)
- if not domain_id:
+ if domain_name_or_id is None:
return _find_identity_resource(
identity_client.groups, name_or_id, groups.Group
)
- else:
- domain_id = find_domain(identity_client, domain_id).id
- return _find_identity_resource(
- identity_client.groups,
- name_or_id,
- groups.Group,
- domain_id=domain_id,
- )
+
+ domain_id = find_domain(identity_client, domain_name_or_id).id
+ return _find_identity_resource(
+ identity_client.groups,
+ name_or_id,
+ groups.Group,
+ domain_id=domain_id,
+ )
def find_project(identity_client, name_or_id, domain_name_or_id=None):
- domain_id = _get_domain_id_if_requested(identity_client, domain_name_or_id)
- if not domain_id:
+ if domain_name_or_id is None:
return _find_identity_resource(
identity_client.projects, name_or_id, projects.Project
)
- else:
- domain_id = find_domain(identity_client, domain_id).id
- return _find_identity_resource(
- identity_client.projects,
- name_or_id,
- projects.Project,
- domain_id=domain_id,
- )
+ domain_id = find_domain(identity_client, domain_name_or_id).id
+ return _find_identity_resource(
+ identity_client.projects,
+ name_or_id,
+ projects.Project,
+ domain_id=domain_id,
+ )
def find_user(identity_client, name_or_id, domain_name_or_id=None):
- domain_id = _get_domain_id_if_requested(identity_client, domain_name_or_id)
- if not domain_id:
+ if domain_name_or_id is None:
return _find_identity_resource(
identity_client.users, name_or_id, users.User
)
- else:
- domain_id = find_domain(identity_client, domain_id).id
- return _find_identity_resource(
- identity_client.users, name_or_id, users.User, domain_id=domain_id
- )
+ domain_id = find_domain(identity_client, domain_name_or_id).id
+ return _find_identity_resource(
+ identity_client.users, name_or_id, users.User, domain_id=domain_id
+ )
def _find_identity_resource(
diff --git a/openstackclient/identity/v3/credential.py b/openstackclient/identity/v3/credential.py
index 1b0d525..33297e9 100644
--- a/openstackclient/identity/v3/credential.py
+++ b/openstackclient/identity/v3/credential.py
@@ -28,6 +28,23 @@ from openstackclient.identity import common
LOG = logging.getLogger(__name__)
+def _format_credential(credential):
+ columns = (
+ 'blob',
+ 'id',
+ 'project_id',
+ 'type',
+ 'user_id',
+ )
+ return (
+ columns,
+ utils.get_item_properties(
+ credential,
+ columns,
+ ),
+ )
+
+
class CreateCredential(command.ShowOne):
_description = _("Create new credential")
@@ -60,25 +77,24 @@ class CreateCredential(command.ShowOne):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
- user_id = utils.find_resource(
- identity_client.users, parsed_args.user
+ identity_client = self.app.client_manager.sdk_connection.identity
+ user_id = identity_client.find_user(
+ parsed_args.user, ignore_missing=False
).id
if parsed_args.project:
- project = utils.find_resource(
- identity_client.projects, parsed_args.project
+ project = identity_client.find_project(
+ parsed_args.project, ignore_missing=False
).id
else:
project = None
- credential = identity_client.credentials.create(
- user=user_id,
+ credential = identity_client.create_credential(
+ user_id=user_id,
type=parsed_args.type,
blob=parsed_args.data,
- project=project,
+ project_id=project,
)
- credential._info.pop('links')
- return zip(*sorted(credential._info.items()))
+ return _format_credential(credential)
class DeleteCredential(command.Command):
@@ -95,11 +111,11 @@ class DeleteCredential(command.Command):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
+ identity_client = self.app.client_manager.sdk_connection.identity
result = 0
for i in parsed_args.credential:
try:
- identity_client.credentials.delete(i)
+ identity_client.delete_credential(i)
except Exception as e:
result += 1
LOG.error(
@@ -137,14 +153,17 @@ class ListCredential(command.Lister):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
+ identity_client = self.app.client_manager.sdk_connection.identity
kwargs = {}
if parsed_args.user:
- user_id = common.find_user(
- identity_client,
- parsed_args.user,
- parsed_args.user_domain,
+ domain_id = None
+ if parsed_args.user_domain:
+ domain_id = identity_client.find_domain(
+ parsed_args.user_domain, ignore_missing=False
+ )
+ user_id = identity_client.find_user(
+ parsed_args.user, domain_id=domain_id, ignore_missing=False
).id
kwargs["user_id"] = user_id
@@ -153,7 +172,8 @@ class ListCredential(command.Lister):
columns = ('ID', 'Type', 'User ID', 'Blob', 'Project ID')
column_headers = ('ID', 'Type', 'User ID', 'Data', 'Project ID')
- data = self.app.client_manager.identity.credentials.list(**kwargs)
+ data = identity_client.credentials(**kwargs)
+
return (
column_headers,
(
@@ -206,20 +226,20 @@ class SetCredential(command.Command):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
+ identity_client = self.app.client_manager.sdk_connection.identity
- user_id = utils.find_resource(
- identity_client.users, parsed_args.user
+ user_id = identity_client.find_user(
+ parsed_args.user, ignore_missing=False
).id
if parsed_args.project:
- project = utils.find_resource(
- identity_client.projects, parsed_args.project
+ project = identity_client.find_project(
+ parsed_args.project, ignore_missing=False
).id
else:
project = None
- identity_client.credentials.update(
+ identity_client.update_credential(
parsed_args.credential,
user=user_id,
type=parsed_args.type,
@@ -241,10 +261,7 @@ class ShowCredential(command.ShowOne):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
- credential = utils.find_resource(
- identity_client.credentials, parsed_args.credential
- )
+ identity_client = self.app.client_manager.sdk_connection.identity
+ credential = identity_client.get_credential(parsed_args.credential)
- credential._info.pop('links')
- return zip(*sorted(credential._info.items()))
+ return _format_credential(credential)
diff --git a/openstackclient/identity/v3/limit.py b/openstackclient/identity/v3/limit.py
index 59cc139..44a3f63 100644
--- a/openstackclient/identity/v3/limit.py
+++ b/openstackclient/identity/v3/limit.py
@@ -90,6 +90,13 @@ class CreateLimit(command.ShowOne):
region = common_utils.get_resource(
identity_client.regions, parsed_args.region
)
+ else:
+ self.log.warning(
+ _(
+ "Passing 'None' to indicate no region is deprecated. "
+ "Instead, don't pass --region."
+ )
+ )
limit = identity_client.limits.create(
project,
@@ -158,6 +165,14 @@ class ListLimit(command.Lister):
region = common_utils.get_resource(
identity_client.regions, parsed_args.region
)
+ else:
+ self.log.warning(
+ _(
+ "Passing 'None' to indicate no region is deprecated. "
+ "Instead, don't pass --region."
+ )
+ )
+
project = None
if parsed_args.project:
project = utils.find_resource(
diff --git a/openstackclient/identity/v3/region.py b/openstackclient/identity/v3/region.py
index ba8c02c..faa2bc4 100644
--- a/openstackclient/identity/v3/region.py
+++ b/openstackclient/identity/v3/region.py
@@ -25,6 +25,15 @@ from openstackclient.i18n import _
LOG = logging.getLogger(__name__)
+def _format_region(region):
+ columns = ('id', 'description', 'parent_region_id')
+ column_headers = ('region', 'description', 'parent_region')
+ return (
+ column_headers,
+ utils.get_item_properties(region, columns),
+ )
+
+
class CreateRegion(command.ShowOne):
_description = _("Create new region")
@@ -50,18 +59,15 @@ class CreateRegion(command.ShowOne):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
+ identity_client = self.app.client_manager.sdk_connection.identity
- region = identity_client.regions.create(
+ region = identity_client.create_region(
id=parsed_args.region,
- parent_region=parsed_args.parent_region,
+ parent_region_id=parsed_args.parent_region,
description=parsed_args.description,
)
- region._info['region'] = region._info.pop('id')
- region._info['parent_region'] = region._info.pop('parent_region_id')
- region._info.pop('links', None)
- return zip(*sorted(region._info.items()))
+ return _format_region(region)
class DeleteRegion(command.Command):
@@ -78,11 +84,11 @@ class DeleteRegion(command.Command):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
+ identity_client = self.app.client_manager.sdk_connection.identity
result = 0
for i in parsed_args.region:
try:
- identity_client.regions.delete(i)
+ identity_client.delete_region(i)
except Exception as e:
result += 1
LOG.error(
@@ -115,7 +121,7 @@ class ListRegion(command.Lister):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
+ identity_client = self.app.client_manager.sdk_connection.identity
kwargs = {}
if parsed_args.parent_region:
@@ -124,7 +130,7 @@ class ListRegion(command.Lister):
columns_headers = ('Region', 'Parent Region', 'Description')
columns = ('ID', 'Parent Region Id', 'Description')
- data = identity_client.regions.list(**kwargs)
+ data = identity_client.regions(**kwargs)
return (
columns_headers,
(
@@ -161,15 +167,15 @@ class SetRegion(command.Command):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
+ identity_client = self.app.client_manager.sdk_connection.identity
kwargs = {}
if parsed_args.description:
kwargs['description'] = parsed_args.description
if parsed_args.parent_region:
- kwargs['parent_region'] = parsed_args.parent_region
+ kwargs['parent_region_id'] = parsed_args.parent_region
- identity_client.regions.update(parsed_args.region, **kwargs)
+ identity_client.update_region(parsed_args.region, **kwargs)
class ShowRegion(command.ShowOne):
@@ -185,13 +191,8 @@ class ShowRegion(command.ShowOne):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
+ identity_client = self.app.client_manager.sdk_connection.identity
- region = utils.find_resource(
- identity_client.regions, parsed_args.region
- )
+ region = identity_client.get_region(parsed_args.region)
- region._info['region'] = region._info.pop('id')
- region._info['parent_region'] = region._info.pop('parent_region_id')
- region._info.pop('links', None)
- return zip(*sorted(region._info.items()))
+ return _format_region(region)
diff --git a/openstackclient/identity/v3/registered_limit.py b/openstackclient/identity/v3/registered_limit.py
index f71ef1f..336151d 100644
--- a/openstackclient/identity/v3/registered_limit.py
+++ b/openstackclient/identity/v3/registered_limit.py
@@ -81,6 +81,13 @@ class CreateRegisteredLimit(command.ShowOne):
region = common_utils.get_resource(
identity_client.regions, parsed_args.region
)
+ else:
+ self.log.warning(
+ _(
+ "Passing 'None' to indicate no region is deprecated. "
+ "Instead, don't pass --region."
+ )
+ )
registered_limit = identity_client.registered_limits.create(
service,
@@ -182,6 +189,13 @@ class ListRegisteredLimit(command.Lister):
region = common_utils.get_resource(
identity_client.regions, parsed_args.region
)
+ else:
+ self.log.warning(
+ _(
+ "Passing 'None' to indicate no region is deprecated. "
+ "Instead, don't pass --region."
+ )
+ )
registered_limits = identity_client.registered_limits.list(
service=service,
@@ -280,6 +294,10 @@ class SetRegisteredLimit(command.ShowOne):
region = common_utils.get_resource(
identity_client.regions, parsed_args.region
)
+ else:
+ self.log.warning(
+ _("Passing 'None' to indicate no region is deprecated.")
+ )
registered_limit = identity_client.registered_limits.update(
parsed_args.registered_limit_id,
diff --git a/openstackclient/identity/v3/role.py b/openstackclient/identity/v3/role.py
index c43f389..a7fb664 100644
--- a/openstackclient/identity/v3/role.py
+++ b/openstackclient/identity/v3/role.py
@@ -17,7 +17,7 @@
import logging
-from keystoneauth1 import exceptions as ks_exc
+from openstack import exceptions as sdk_exc
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
@@ -29,6 +29,25 @@ from openstackclient.identity import common
LOG = logging.getLogger(__name__)
+def _format_role(role):
+ columns = (
+ "id",
+ "name",
+ "domain_id",
+ "description",
+ )
+ column_headers = (
+ "id",
+ "name",
+ "domain_id",
+ "description",
+ )
+ return (
+ column_headers,
+ utils.get_item_properties(role, columns),
+ )
+
+
def _add_identity_and_resource_options_to_parser(parser):
system_or_domain_or_project = parser.add_mutually_exclusive_group()
system_or_domain_or_project.add_argument(
@@ -63,32 +82,79 @@ def _add_identity_and_resource_options_to_parser(parser):
common.add_inherited_option_to_parser(parser)
+def _find_sdk_id(
+ find_command, name_or_id, validate_actor_existence=True, **kwargs
+):
+ try:
+ resource = find_command(
+ name_or_id=name_or_id, ignore_missing=False, **kwargs
+ )
+
+ # Mimic the behavior of
+ # openstackclient.identity.common._find_identity_resource()
+ # and ignore if we don't have permission to find a resource.
+ except sdk_exc.ForbiddenException:
+ return name_or_id
+ except sdk_exc.ResourceNotFound as exc:
+ if not validate_actor_existence:
+ return name_or_id
+ raise exceptions.CommandError from exc
+ return resource.id
+
+
def _process_identity_and_resource_options(
- parsed_args, identity_client_manager, validate_actor_existence=True
+ parsed_args, identity_client, validate_actor_existence=True
):
def _find_user():
- try:
- return common.find_user(
- identity_client_manager,
- parsed_args.user,
- parsed_args.user_domain,
- ).id
- except exceptions.CommandError:
- if not validate_actor_existence:
- return parsed_args.user
- raise
+ domain_id = (
+ _find_sdk_id(
+ identity_client.find_domain,
+ name_or_id=parsed_args.user_domain,
+ validate_actor_existence=validate_actor_existence,
+ )
+ if parsed_args.user_domain
+ else None
+ )
+ return _find_sdk_id(
+ identity_client.find_user,
+ name_or_id=parsed_args.user,
+ validate_actor_existence=validate_actor_existence,
+ domain_id=domain_id,
+ )
def _find_group():
- try:
- return common.find_group(
- identity_client_manager,
- parsed_args.group,
- parsed_args.group_domain,
- ).id
- except exceptions.CommandError:
- if not validate_actor_existence:
- return parsed_args.group
- raise
+ domain_id = (
+ _find_sdk_id(
+ identity_client.find_domain,
+ name_or_id=parsed_args.group_domain,
+ validate_actor_existence=validate_actor_existence,
+ )
+ if parsed_args.group_domain
+ else None
+ )
+ return _find_sdk_id(
+ identity_client.find_group,
+ name_or_id=parsed_args.group,
+ validate_actor_existence=validate_actor_existence,
+ domain_id=domain_id,
+ )
+
+ def _find_project():
+ domain_id = (
+ _find_sdk_id(
+ identity_client.find_domain,
+ name_or_id=parsed_args.project_domain,
+ validate_actor_existence=validate_actor_existence,
+ )
+ if parsed_args.project_domain
+ else None
+ )
+ return _find_sdk_id(
+ identity_client.find_project,
+ name_or_id=parsed_args.project,
+ validate_actor_existence=validate_actor_existence,
+ domain_id=domain_id,
+ )
kwargs = {}
if parsed_args.user and parsed_args.system:
@@ -96,34 +162,35 @@ def _process_identity_and_resource_options(
kwargs['system'] = parsed_args.system
elif parsed_args.user and parsed_args.domain:
kwargs['user'] = _find_user()
- kwargs['domain'] = common.find_domain(
- identity_client_manager,
- parsed_args.domain,
- ).id
+ kwargs['domain'] = _find_sdk_id(
+ identity_client.find_domain,
+ name_or_id=parsed_args.domain,
+ validate_actor_existence=validate_actor_existence,
+ )
elif parsed_args.user and parsed_args.project:
kwargs['user'] = _find_user()
- kwargs['project'] = common.find_project(
- identity_client_manager,
- parsed_args.project,
- parsed_args.project_domain,
- ).id
+ kwargs['project'] = _find_project()
elif parsed_args.group and parsed_args.system:
kwargs['group'] = _find_group()
kwargs['system'] = parsed_args.system
elif parsed_args.group and parsed_args.domain:
kwargs['group'] = _find_group()
- kwargs['domain'] = common.find_domain(
- identity_client_manager,
- parsed_args.domain,
- ).id
+ kwargs['domain'] = _find_sdk_id(
+ identity_client.find_domain,
+ name_or_id=parsed_args.domain,
+ validate_actor_existence=validate_actor_existence,
+ )
elif parsed_args.group and parsed_args.project:
kwargs['group'] = _find_group()
- kwargs['project'] = common.find_project(
- identity_client_manager,
- parsed_args.project,
- parsed_args.project_domain,
- ).id
- kwargs['os_inherit_extension_inherited'] = parsed_args.inherited
+ kwargs['project'] = _find_project()
+ else:
+ msg = _(
+ "Role not added, incorrect set of arguments "
+ "provided. See openstack --help for more details"
+ )
+ raise exceptions.CommandError(msg)
+
+ kwargs['inherited'] = parsed_args.inherited
return kwargs
@@ -145,7 +212,7 @@ class AddRole(command.Command):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
+ identity_client = self.app.client_manager.sdk_connection.identity
if (
not parsed_args.user
@@ -161,18 +228,71 @@ class AddRole(command.Command):
domain_id = None
if parsed_args.role_domain:
- domain_id = common.find_domain(
- identity_client, parsed_args.role_domain
- ).id
- role = utils.find_resource(
- identity_client.roles, parsed_args.role, domain_id=domain_id
+ domain_id = _find_sdk_id(
+ identity_client.find_domain, name_or_id=parsed_args.role_domain
+ )
+ role = _find_sdk_id(
+ identity_client.find_role,
+ name_or_id=parsed_args.role,
+ domain_id=domain_id,
)
- kwargs = _process_identity_and_resource_options(
- parsed_args, self.app.client_manager.identity
+ add_kwargs = _process_identity_and_resource_options(
+ parsed_args, identity_client
)
- identity_client.roles.grant(role.id, **kwargs)
+ if add_kwargs.get("domain"):
+ if add_kwargs.get("user"):
+ identity_client.assign_domain_role_to_user(
+ domain=add_kwargs["domain"],
+ user=add_kwargs["user"],
+ role=role,
+ inherited=add_kwargs["inherited"],
+ )
+ if add_kwargs.get("group"):
+ identity_client.assign_domain_role_to_group(
+ domain=add_kwargs["domain"],
+ group=add_kwargs["group"],
+ role=role,
+ inherited=add_kwargs["inherited"],
+ )
+ elif add_kwargs.get("project"):
+ if add_kwargs.get("user"):
+ identity_client.assign_project_role_to_user(
+ project=add_kwargs["project"],
+ user=add_kwargs["user"],
+ role=role,
+ inherited=add_kwargs["inherited"],
+ )
+ if add_kwargs.get("group"):
+ identity_client.assign_project_role_to_group(
+ project=add_kwargs["project"],
+ group=add_kwargs["group"],
+ role=role,
+ inherited=add_kwargs["inherited"],
+ )
+ elif add_kwargs.get("system"):
+ if add_kwargs["inherited"]:
+ LOG.warning(
+ _(
+ "'--inherited' was given, which is not supported "
+ "when adding a system role. This will be an error "
+ "in a future release."
+ )
+ )
+ # TODO(0weng): This should be an error in a future release
+ if add_kwargs.get("user"):
+ identity_client.assign_system_role_to_user(
+ system=add_kwargs["system"],
+ user=add_kwargs["user"],
+ role=role,
+ )
+ if add_kwargs.get("group"):
+ identity_client.assign_system_role_to_group(
+ system=add_kwargs["system"],
+ group=add_kwargs["group"],
+ role=role,
+ )
class CreateRole(command.ShowOne):
@@ -204,37 +324,35 @@ class CreateRole(command.ShowOne):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
+ identity_client = self.app.client_manager.sdk_connection.identity
- domain_id = None
+ create_kwargs = {}
if parsed_args.domain:
- domain_id = common.find_domain(
- identity_client, parsed_args.domain
- ).id
+ create_kwargs['domain_id'] = _find_sdk_id(
+ identity_client.find_domain, name_or_id=parsed_args.domain
+ )
- options = common.get_immutable_options(parsed_args)
+ if parsed_args.name:
+ create_kwargs['name'] = parsed_args.name
+ if parsed_args.description:
+ create_kwargs['description'] = parsed_args.description
+ create_kwargs['options'] = common.get_immutable_options(parsed_args)
try:
- role = identity_client.roles.create(
- name=parsed_args.name,
- domain=domain_id,
- description=parsed_args.description,
- options=options,
- )
+ role = identity_client.create_role(**create_kwargs)
- except ks_exc.Conflict:
+ except sdk_exc.ConflictException:
if parsed_args.or_show:
- role = utils.find_resource(
- identity_client.roles,
- parsed_args.name,
- domain_id=domain_id,
+ role = identity_client.find_role(
+ name_or_id=parsed_args.name,
+ domain_id=parsed_args.domain,
+ ignore_missing=False,
)
LOG.info(_('Returning existing role %s'), role.name)
else:
raise
- role._info.pop('links')
- return zip(*sorted(role._info.items()))
+ return _format_role(role)
class DeleteRole(command.Command):
@@ -245,7 +363,7 @@ class DeleteRole(command.Command):
parser.add_argument(
'roles',
metavar='<role>',
- nargs="+",
+ nargs='+',
help=_('Role(s) to delete (name or ID)'),
)
parser.add_argument(
@@ -256,20 +374,22 @@ class DeleteRole(command.Command):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
+ identity_client = self.app.client_manager.sdk_connection.identity
domain_id = None
if parsed_args.domain:
- domain_id = common.find_domain(
- identity_client, parsed_args.domain
- ).id
+ domain_id = _find_sdk_id(
+ identity_client.find_domain, parsed_args.domain
+ )
errors = 0
for role in parsed_args.roles:
try:
- role_obj = utils.find_resource(
- identity_client.roles, role, domain_id=domain_id
+ role_id = _find_sdk_id(
+ identity_client.find_role,
+ name_or_id=role,
+ domain_id=domain_id,
)
- identity_client.roles.delete(role_obj.id)
+ identity_client.delete_role(role=role_id, ignore_missing=False)
except Exception as e:
errors += 1
LOG.error(
@@ -302,20 +422,17 @@ class ListRole(command.Lister):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
+ identity_client = self.app.client_manager.sdk_connection.identity
if parsed_args.domain:
- domain = common.find_domain(
- identity_client,
- parsed_args.domain,
+ domain = identity_client.find_domain(
+ name_or_id=parsed_args.domain,
)
columns = ('ID', 'Name', 'Domain')
- data = identity_client.roles.list(domain_id=domain.id)
- for role in data:
- role.domain = domain.name
+ data = identity_client.roles(domain_id=domain.id)
else:
columns = ('ID', 'Name')
- data = identity_client.roles.list()
+ data = identity_client.roles()
return (
columns,
@@ -323,7 +440,7 @@ class ListRole(command.Lister):
utils.get_item_properties(
s,
columns,
- formatters={},
+ formatters={'Domain': lambda _: domain.name},
)
for s in data
),
@@ -348,8 +465,7 @@ class RemoveRole(command.Command):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
-
+ identity_client = self.app.client_manager.sdk_connection.identity
if (
not parsed_args.user
and not parsed_args.domain
@@ -364,19 +480,65 @@ class RemoveRole(command.Command):
domain_id = None
if parsed_args.role_domain:
- domain_id = common.find_domain(
- identity_client, parsed_args.role_domain
- ).id
- role = utils.find_resource(
- identity_client.roles, parsed_args.role, domain_id=domain_id
+ domain_id = _find_sdk_id(
+ identity_client.find_domain,
+ name_or_id=parsed_args.role_domain,
+ )
+ role = _find_sdk_id(
+ identity_client.find_role,
+ name_or_id=parsed_args.role,
+ domain_id=domain_id,
)
- kwargs = _process_identity_and_resource_options(
+ remove_kwargs = _process_identity_and_resource_options(
parsed_args,
- self.app.client_manager.identity,
+ identity_client,
validate_actor_existence=False,
)
- identity_client.roles.revoke(role.id, **kwargs)
+
+ if remove_kwargs.get("domain"):
+ if remove_kwargs.get("user"):
+ identity_client.unassign_domain_role_from_user(
+ domain=remove_kwargs["domain"],
+ user=remove_kwargs["user"],
+ role=role,
+ inherited=remove_kwargs["inherited"],
+ )
+ if remove_kwargs.get("group"):
+ identity_client.unassign_domain_role_from_group(
+ domain=remove_kwargs["domain"],
+ group=remove_kwargs["group"],
+ role=role,
+ inherited=remove_kwargs["inherited"],
+ )
+ elif remove_kwargs.get("project"):
+ if remove_kwargs.get("user"):
+ identity_client.unassign_project_role_from_user(
+ project=remove_kwargs["project"],
+ user=remove_kwargs["user"],
+ role=role,
+ inherited=remove_kwargs["inherited"],
+ )
+ if remove_kwargs.get("group"):
+ identity_client.unassign_project_role_from_group(
+ project=remove_kwargs["project"],
+ group=remove_kwargs["group"],
+ role=role,
+ inherited=remove_kwargs["inherited"],
+ )
+ elif remove_kwargs.get("system"):
+ if remove_kwargs.get("user"):
+ identity_client.unassign_system_role_from_user(
+ system=remove_kwargs["system"],
+ user=remove_kwargs["user"],
+ role=role,
+ )
+ if remove_kwargs.get("group"):
+ identity_client.unassign_system_role_from_group(
+ system=remove_kwargs["system"],
+ group=remove_kwargs["group"],
+ role=role,
+ )
class SetRole(command.Command):
@@ -408,25 +570,31 @@ class SetRole(command.Command):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
+ identity_client = self.app.client_manager.sdk_connection.identity
+
+ update_kwargs = {}
+ if parsed_args.description:
+ update_kwargs["description"] = parsed_args.description
+ if parsed_args.name:
+ update_kwargs["name"] = parsed_args.name
domain_id = None
if parsed_args.domain:
- domain_id = common.find_domain(
- identity_client, parsed_args.domain
- ).id
+ domain_id = _find_sdk_id(
+ identity_client.find_domain,
+ name_or_id=parsed_args.domain,
+ )
+ update_kwargs["domain_id"] = domain_id
- options = common.get_immutable_options(parsed_args)
- role = utils.find_resource(
- identity_client.roles, parsed_args.role, domain_id=domain_id
+ update_kwargs["options"] = common.get_immutable_options(parsed_args)
+ role = _find_sdk_id(
+ identity_client.find_role,
+ name_or_id=parsed_args.role,
+ domain_id=domain_id,
)
+ update_kwargs["role"] = role
- identity_client.roles.update(
- role.id,
- name=parsed_args.name,
- description=parsed_args.description,
- options=options,
- )
+ identity_client.update_role(**update_kwargs)
class ShowRole(command.ShowOne):
@@ -447,17 +615,19 @@ class ShowRole(command.ShowOne):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
+ identity_client = self.app.client_manager.sdk_connection.identity
domain_id = None
if parsed_args.domain:
- domain_id = common.find_domain(
- identity_client, parsed_args.domain
- ).id
+ domain_id = _find_sdk_id(
+ identity_client.find_domain,
+ name_or_id=parsed_args.domain,
+ )
- role = utils.find_resource(
- identity_client.roles, parsed_args.role, domain_id=domain_id
+ role = identity_client.find_role(
+ name_or_id=parsed_args.role,
+ domain_id=domain_id,
+ ignore_missing=False,
)
- role._info.pop('links')
- return zip(*sorted(role._info.items()))
+ return _format_role(role)
diff --git a/openstackclient/identity/v3/role_assignment.py b/openstackclient/identity/v3/role_assignment.py
index 7d4dfcd..12e1527 100644
--- a/openstackclient/identity/v3/role_assignment.py
+++ b/openstackclient/identity/v3/role_assignment.py
@@ -148,7 +148,7 @@ class ListRoleAssignment(command.Lister):
user_domain_id = None
if parsed_args.user_domain:
- project_domain_id = _find_sdk_id(
+ user_domain_id = _find_sdk_id(
identity_client.find_domain,
name_or_id=parsed_args.user_domain,
)
diff --git a/openstackclient/identity/v3/service_provider.py b/openstackclient/identity/v3/service_provider.py
index 79869ee..1a7b02f 100644
--- a/openstackclient/identity/v3/service_provider.py
+++ b/openstackclient/identity/v3/service_provider.py
@@ -25,6 +25,29 @@ from openstackclient.i18n import _
LOG = logging.getLogger(__name__)
+def _format_service_provider(sp):
+ column_headers = (
+ 'id',
+ 'enabled',
+ 'description',
+ 'auth_url',
+ 'sp_url',
+ 'relay_state_prefix',
+ )
+ columns = (
+ 'id',
+ 'is_enabled',
+ 'description',
+ 'auth_url',
+ 'sp_url',
+ 'relay_state_prefix',
+ )
+ return (
+ column_headers,
+ utils.get_item_properties(sp, columns),
+ )
+
+
class CreateServiceProvider(command.ShowOne):
_description = _("Create new service provider")
@@ -62,14 +85,14 @@ class CreateServiceProvider(command.ShowOne):
enable_service_provider = parser.add_mutually_exclusive_group()
enable_service_provider.add_argument(
'--enable',
- dest='enabled',
+ dest='is_enabled',
action='store_true',
default=True,
help=_('Enable the service provider (default)'),
)
enable_service_provider.add_argument(
'--disable',
- dest='enabled',
+ dest='is_enabled',
action='store_false',
help=_('Disable the service provider'),
)
@@ -77,17 +100,27 @@ class CreateServiceProvider(command.ShowOne):
return parser
def take_action(self, parsed_args):
- service_client = self.app.client_manager.identity
- sp = service_client.federation.service_providers.create(
- id=parsed_args.service_provider_id,
- auth_url=parsed_args.auth_url,
- description=parsed_args.description,
- enabled=parsed_args.enabled,
- sp_url=parsed_args.service_provider_url,
- )
+ service_client = self.app.client_manager.sdk_connection.identity
+
+ kwargs = {}
+
+ kwargs = {'id': parsed_args.service_provider_id}
+
+ if parsed_args.is_enabled is not None:
+ kwargs['is_enabled'] = parsed_args.is_enabled
- sp._info.pop('links', None)
- return zip(*sorted(sp._info.items()))
+ if parsed_args.description:
+ kwargs['description'] = parsed_args.description
+
+ if parsed_args.auth_url:
+ kwargs['auth_url'] = parsed_args.auth_url
+
+ if parsed_args.service_provider_url:
+ kwargs['sp_url'] = parsed_args.service_provider_url
+
+ sp = service_client.create_service_provider(**kwargs)
+
+ return _format_service_provider(sp)
class DeleteServiceProvider(command.Command):
@@ -104,11 +137,11 @@ class DeleteServiceProvider(command.Command):
return parser
def take_action(self, parsed_args):
- service_client = self.app.client_manager.identity
+ service_client = self.app.client_manager.sdk_connection.identity
result = 0
for i in parsed_args.service_provider:
try:
- service_client.federation.service_providers.delete(i)
+ service_client.delete_service_provider(i)
except Exception as e:
result += 1
LOG.error(
@@ -132,24 +165,32 @@ class ListServiceProvider(command.Lister):
_description = _("List service providers")
def take_action(self, parsed_args):
- service_client = self.app.client_manager.identity
- data = service_client.federation.service_providers.list()
-
- column_headers = ('ID', 'Enabled', 'Description', 'Auth URL')
+ service_client = self.app.client_manager.sdk_connection.identity
+ data = service_client.service_providers()
+
+ column_headers = (
+ 'ID',
+ 'Enabled',
+ 'Description',
+ 'Auth URL',
+ 'Service Provider URL',
+ 'Relay State Prefix',
+ )
+ columns = (
+ 'id',
+ 'is_enabled',
+ 'description',
+ 'auth_url',
+ 'sp_url',
+ 'relay_state_prefix',
+ )
return (
column_headers,
- (
- utils.get_item_properties(
- s,
- column_headers,
- formatters={},
- )
- for s in data
- ),
+ (utils.get_item_properties(s, columns) for s in data),
)
-class SetServiceProvider(command.Command):
+class SetServiceProvider(command.ShowOne):
_description = _("Set service provider properties")
def get_parser(self, prog_name):
@@ -181,33 +222,44 @@ class SetServiceProvider(command.Command):
enable_service_provider = parser.add_mutually_exclusive_group()
enable_service_provider.add_argument(
'--enable',
+ dest='is_enabled',
action='store_true',
+ default=None,
help=_('Enable the service provider'),
)
enable_service_provider.add_argument(
'--disable',
- action='store_true',
+ dest='is_enabled',
+ action='store_false',
+ default=None,
help=_('Disable the service provider'),
)
return parser
def take_action(self, parsed_args):
- federation_client = self.app.client_manager.identity.federation
+ service_client = self.app.client_manager.sdk_connection.identity
- enabled = None
- if parsed_args.enable is True:
- enabled = True
- elif parsed_args.disable is True:
- enabled = False
+ kwargs = {}
- federation_client.service_providers.update(
+ if parsed_args.is_enabled is not None:
+ kwargs['is_enabled'] = parsed_args.is_enabled
+
+ if parsed_args.description:
+ kwargs['description'] = parsed_args.description
+
+ if parsed_args.auth_url:
+ kwargs['auth_url'] = parsed_args.auth_url
+
+ if parsed_args.service_provider_url:
+ kwargs['sp_url'] = parsed_args.service_provider_url
+
+ service_provider = service_client.update_service_provider(
parsed_args.service_provider,
- enabled=enabled,
- description=parsed_args.description,
- auth_url=parsed_args.auth_url,
- sp_url=parsed_args.service_provider_url,
+ **kwargs,
)
+ return _format_service_provider(service_provider)
+
class ShowServiceProvider(command.ShowOne):
_description = _("Display service provider details")
@@ -222,12 +274,10 @@ class ShowServiceProvider(command.ShowOne):
return parser
def take_action(self, parsed_args):
- service_client = self.app.client_manager.identity
- service_provider = utils.find_resource(
- service_client.federation.service_providers,
+ service_client = self.app.client_manager.sdk_connection.identity
+ service_provider = service_client.find_service_provider(
parsed_args.service_provider,
- id=parsed_args.service_provider,
+ ignore_missing=False,
)
- service_provider._info.pop('links', None)
- return zip(*sorted(service_provider._info.items()))
+ return _format_service_provider(service_provider)
diff --git a/openstackclient/identity/v3/trust.py b/openstackclient/identity/v3/trust.py
index 33fee4a..447a57f 100644
--- a/openstackclient/identity/v3/trust.py
+++ b/openstackclient/identity/v3/trust.py
@@ -14,9 +14,10 @@
"""Identity v3 Trust action implementations"""
import datetime
+import itertools
import logging
-from keystoneclient import exceptions as identity_exc
+from openstack import exceptions as sdk_exceptions
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
@@ -28,6 +29,25 @@ from openstackclient.identity import common
LOG = logging.getLogger(__name__)
+def _format_trust(trust):
+ columns = (
+ 'expires_at',
+ 'id',
+ 'is_impersonation',
+ 'project_id',
+ 'redelegated_trust_id',
+ 'redelegation_count',
+ 'remaining_uses',
+ 'roles',
+ 'trustee_user_id',
+ 'trustor_user_id',
+ )
+ return (
+ columns,
+ utils.get_item_properties(trust, columns),
+ )
+
+
class CreateTrust(command.ShowOne):
_description = _("Create new trust")
@@ -52,6 +72,7 @@ class CreateTrust(command.ShowOne):
parser.add_argument(
'--role',
metavar='<role>',
+ dest='roles',
action='append',
default=[],
help=_(
@@ -62,7 +83,7 @@ class CreateTrust(command.ShowOne):
)
parser.add_argument(
'--impersonate',
- dest='impersonate',
+ dest='is_impersonation',
action='store_true',
default=False,
help=_(
@@ -92,58 +113,60 @@ class CreateTrust(command.ShowOne):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
+ identity_client = self.app.client_manager.sdk_connection.identity
+
+ kwargs = {}
# NOTE(stevemar): Find the two users, project and roles that
# are necessary for making a trust usable, the API dictates that
# trustee, project and role are optional, but that makes the trust
# pointless, and trusts are immutable, so let's enforce it at the
# client level.
- trustor_id = common.find_user(
- identity_client, parsed_args.trustor, parsed_args.trustor_domain
- ).id
- trustee_id = common.find_user(
- identity_client, parsed_args.trustee, parsed_args.trustee_domain
- ).id
- project_id = common.find_project(
- identity_client, parsed_args.project, parsed_args.project_domain
- ).id
+ try:
+ trustor_id = identity_client.find_user(
+ parsed_args.trustor, parsed_args.trustor_domain
+ ).id
+ kwargs['trustor_id'] = trustor_id
+ except sdk_exceptions.ForbiddenException:
+ kwargs['trustor_id'] = parsed_args.trustor
+
+ try:
+ trustee_id = identity_client.find_user(
+ parsed_args.trustee, parsed_args.trustee_domain
+ ).id
+ kwargs['trustee_id'] = trustee_id
+ except sdk_exceptions.ForbiddenException:
+ kwargs['trustee_id'] = parsed_args.trustee
+
+ try:
+ project_id = identity_client.find_project(
+ parsed_args.project, parsed_args.project_domain
+ ).id
+ kwargs['project_id'] = project_id
+ except sdk_exceptions.ForbiddenException:
+ kwargs['project_id'] = parsed_args.project
role_ids = []
- for role in parsed_args.role:
+ for role in parsed_args.roles:
try:
- role_id = utils.find_resource(
- identity_client.roles,
- role,
- ).id
- except identity_exc.Forbidden:
+ role_id = identity_client.find_role(role).id
+ except sdk_exceptions.ForbiddenException:
role_id = role
role_ids.append(role_id)
+ kwargs['roles'] = role_ids
- expires_at = None
if parsed_args.expiration:
expires_at = datetime.datetime.strptime(
parsed_args.expiration, '%Y-%m-%dT%H:%M:%S'
)
+ kwargs['expires_at'] = expires_at
- trust = identity_client.trusts.create(
- trustee_id,
- trustor_id,
- impersonation=parsed_args.impersonate,
- project=project_id,
- role_ids=role_ids,
- expires_at=expires_at,
- )
-
- trust._info.pop('roles_links', None)
- trust._info.pop('links', None)
+ if parsed_args.is_impersonation:
+ kwargs['is_impersonation'] = parsed_args.is_impersonation
- # Format roles into something sensible
- roles = trust._info.pop('roles')
- msg = ' '.join(r['name'] for r in roles)
- trust._info['roles'] = msg
+ trust = identity_client.create_trust(**kwargs)
- return zip(*sorted(trust._info.items()))
+ return _format_trust(trust)
class DeleteTrust(command.Command):
@@ -160,13 +183,15 @@ class DeleteTrust(command.Command):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
+ identity_client = self.app.client_manager.sdk_connection.identity
errors = 0
for trust in parsed_args.trust:
try:
- trust_obj = utils.find_resource(identity_client.trusts, trust)
- identity_client.trusts.delete(trust_obj.id)
+ trust_obj = identity_client.find_trust(
+ trust, ignore_missing=False
+ )
+ identity_client.delete_trust(trust_obj.id)
except Exception as e:
errors += 1
LOG.error(
@@ -220,7 +245,7 @@ class ListTrust(command.Lister):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
+ identity_client = self.app.client_manager.sdk_connection.identity
auth_ref = self.app.client_manager.auth_ref
if parsed_args.authuser and any(
@@ -243,38 +268,50 @@ class ListTrust(command.Lister):
raise exceptions.CommandError(msg)
if parsed_args.authuser:
- if auth_ref:
- user = common.find_user(identity_client, auth_ref.user_id)
- # We need two calls here as we want trusts with
- # either the trustor or the trustee set to current user
- # using a single call would give us trusts with both
- # trustee and trustor set to current user
- data1 = identity_client.trusts.list(trustor_user=user)
- data2 = identity_client.trusts.list(trustee_user=user)
- data = set(data1 + data2)
+ # We need two calls here as we want trusts with
+ # either the trustor or the trustee set to current user
+ # using a single call would give us trusts with both
+ # trustee and trustor set to current user
+ data = list(
+ {
+ x.id: x
+ for x in itertools.chain(
+ identity_client.trusts(
+ trustor_user_id=auth_ref.user_id
+ ),
+ identity_client.trusts(
+ trustee_user_id=auth_ref.user_id
+ ),
+ )
+ }.values()
+ )
else:
trustor = None
if parsed_args.trustor:
- trustor = common.find_user(
- identity_client,
- parsed_args.trustor,
- parsed_args.trustor_domain,
- )
+ try:
+ trustor_id = identity_client.find_user(
+ parsed_args.trustor, parsed_args.trustor_domain
+ ).id
+ trustor = trustor_id
+ except sdk_exceptions.ForbiddenException:
+ trustor = parsed_args.trustor
trustee = None
if parsed_args.trustee:
- trustee = common.find_user(
- identity_client,
- parsed_args.trustor,
- parsed_args.trustor_domain,
- )
-
- data = self.app.client_manager.identity.trusts.list(
- trustor_user=trustor,
- trustee_user=trustee,
+ try:
+ trustee_id = identity_client.find_user(
+ parsed_args.trustee, parsed_args.trustee_domain
+ ).id
+ trustee = trustee_id
+ except sdk_exceptions.ForbiddenException:
+ trustee = parsed_args.trustee
+
+ data = identity_client.trusts(
+ trustor_user_id=trustor,
+ trustee_user_id=trustee,
)
- columns = (
+ column_headers = (
'ID',
'Expires At',
'Impersonation',
@@ -282,9 +319,17 @@ class ListTrust(command.Lister):
'Trustee User ID',
'Trustor User ID',
)
+ columns = (
+ 'id',
+ 'expires_at',
+ 'is_impersonation',
+ 'project_id',
+ 'trustee_user_id',
+ 'trustor_user_id',
+ )
return (
- columns,
+ column_headers,
(
utils.get_item_properties(
s,
@@ -309,15 +354,9 @@ class ShowTrust(command.ShowOne):
return parser
def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
- trust = utils.find_resource(identity_client.trusts, parsed_args.trust)
-
- trust._info.pop('roles_links', None)
- trust._info.pop('links', None)
-
- # Format roles into something sensible
- roles = trust._info.pop('roles')
- msg = ' '.join(r['name'] for r in roles)
- trust._info['roles'] = msg
+ identity_client = self.app.client_manager.sdk_connection.identity
+ trust = identity_client.find_trust(
+ parsed_args.trust, ignore_missing=False
+ )
- return zip(*sorted(trust._info.items()))
+ return _format_trust(trust)
diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py
index 094c507..fe237e4 100644
--- a/openstackclient/image/v2/image.py
+++ b/openstackclient/image/v2/image.py
@@ -576,6 +576,9 @@ class CreateImage(command.ShowOne):
if parsed_args.filename:
fp.close()
+ # NOTE(pas-ha): create_image returns the image object as it was created
+ # before the data was uploaded, need a refresh to show the final state
+ image = image_client.get_image(image)
return _format_image(image)
def _take_action_volume(self, parsed_args):
diff --git a/openstackclient/network/v2/network.py b/openstackclient/network/v2/network.py
index de1910e..7636de0 100644
--- a/openstackclient/network/v2/network.py
+++ b/openstackclient/network/v2/network.py
@@ -14,6 +14,7 @@
from cliff import columns as cliff_columns
from osc_lib.cli import format_columns
+from osc_lib import exceptions
from osc_lib import utils
from osc_lib.utils import tags as _tag
@@ -349,6 +350,25 @@ class CreateNetwork(
),
)
+ vlan_qinq_grp = parser.add_mutually_exclusive_group()
+ vlan_qinq_grp.add_argument(
+ '--qinq-vlan',
+ action='store_true',
+ help=self.enhance_help_neutron(
+ _("Enable VLAN QinQ (S-Tag ethtype 0x8a88) " "for the network")
+ ),
+ )
+ vlan_qinq_grp.add_argument(
+ '--no-qinq-vlan',
+ action='store_true',
+ help=self.enhance_help_neutron(
+ _(
+ "Disable VLAN QinQ (S-Tag ethtype 0x8a88) "
+ "for the network"
+ )
+ ),
+ )
+
_add_additional_network_options(parser)
_tag.add_tag_option_to_parser_for_create(
parser, _('network'), enhance_help=self.enhance_help_neutron
@@ -372,6 +392,19 @@ class CreateNetwork(
attrs['vlan_transparent'] = True
if parsed_args.no_transparent_vlan:
attrs['vlan_transparent'] = False
+
+ if parsed_args.qinq_vlan:
+ attrs['vlan_qinq'] = True
+ if parsed_args.no_qinq_vlan:
+ attrs['vlan_qinq'] = False
+
+ if attrs.get('vlan_transparent') and attrs.get('vlan_qinq'):
+ msg = _(
+ "--transparent-vlan and --qinq-vlan can not be both enabled "
+ "for the network."
+ )
+ raise exceptions.CommandError(msg)
+
attrs.update(
self._parse_extra_properties(parsed_args.extra_properties)
)
diff --git a/openstackclient/network/v2/network_flavor_profile.py b/openstackclient/network/v2/network_flavor_profile.py
index 1fb5a80..d9a4b5d 100644
--- a/openstackclient/network/v2/network_flavor_profile.py
+++ b/openstackclient/network/v2/network_flavor_profile.py
@@ -18,7 +18,6 @@ from osc_lib import exceptions
from osc_lib import utils
from openstackclient.i18n import _
-from openstackclient.identity import common as identity_common
from openstackclient.network import common
LOG = logging.getLogger(__name__)
@@ -29,7 +28,7 @@ def _get_columns(item):
'is_enabled': 'enabled',
}
- hidden_columns = ['location', 'name', 'tenant_id']
+ hidden_columns = ['location', 'name', 'tenant_id', 'project_id']
return utils.get_osc_show_columns_for_sdk_resource(
item, column_map, hidden_columns
)
@@ -47,14 +46,6 @@ def _get_attrs(client_manager, parsed_args):
attrs['enabled'] = True
if parsed_args.disable:
attrs['enabled'] = False
- if 'project' in parsed_args and parsed_args.project is not None:
- identity_client = client_manager.identity
- project_id = identity_common.find_project(
- identity_client,
- parsed_args.project,
- parsed_args.project_domain,
- ).id
- attrs['project_id'] = project_id
return attrs
@@ -69,12 +60,6 @@ class CreateNetworkFlavorProfile(
def get_parser(self, prog_name):
parser = super().get_parser(prog_name)
parser.add_argument(
- '--project',
- metavar="<project>",
- help=_("Owner's project (name or ID)"),
- )
- identity_common.add_project_domain_option_to_parser(parser)
- parser.add_argument(
'--description',
metavar="<description>",
help=_("Description for the flavor profile"),
@@ -212,7 +197,6 @@ class SetNetworkFlavorProfile(common.NeutronCommandWithExtraArgs):
metavar="<flavor-profile>",
help=_("Flavor profile to update (ID only)"),
)
- identity_common.add_project_domain_option_to_parser(parser)
parser.add_argument(
'--description',
metavar="<description>",
diff --git a/openstackclient/network/v2/port.py b/openstackclient/network/v2/port.py
index c45b34a..3579194 100644
--- a/openstackclient/network/v2/port.py
+++ b/openstackclient/network/v2/port.py
@@ -38,6 +38,20 @@ class AdminStateColumn(cliff_columns.FormattableColumn):
return 'UP' if self._value else 'DOWN'
+class SubPortColumn(format_columns.ListDictColumn):
+ def _retrieve_subports(self):
+ if isinstance(self._value, dict):
+ self._value = self._value['sub_ports']
+
+ def human_readable(self):
+ self._retrieve_subports()
+ return super().human_readable()
+
+ def machine_readable(self):
+ self._retrieve_subports()
+ return super().machine_readable()
+
+
_formatters = {
'admin_state_up': AdminStateColumn,
'is_admin_state_up': AdminStateColumn,
@@ -52,6 +66,8 @@ _formatters = {
'security_group_ids': format_columns.ListColumn,
'tags': format_columns.ListColumn,
}
+_list_formatters = copy.deepcopy(_formatters)
+_list_formatters.update({'trunk_details': SubPortColumn})
def _get_columns(item):
@@ -93,6 +109,7 @@ def _get_columns(item):
'status': 'status',
'tags': 'tags',
'trunk_details': 'trunk_details',
+ 'trusted': 'trusted',
'updated_at': 'updated_at',
}
return (
@@ -222,6 +239,10 @@ def _get_attrs(client_manager, parsed_args):
and parsed_args.hardware_offload_type
):
attrs['hardware_offload_type'] = parsed_args.hardware_offload_type
+ if parsed_args.not_trusted:
+ attrs['trusted'] = False
+ if parsed_args.trusted:
+ attrs['trusted'] = True
return attrs
@@ -388,6 +409,25 @@ def _add_updatable_args(parser, create=False):
'(repeat option to set multiple hints)'
),
)
+ port_trusted = parser.add_mutually_exclusive_group()
+ port_trusted.add_argument(
+ '--trusted',
+ action='store_true',
+ help=_(
+ "Set port to be trusted. This will be populated into the "
+ "'binding:profile' dictionary and passed to the services "
+ "which expect it in this dictionary (for example, Nova)"
+ ),
+ )
+ port_trusted.add_argument(
+ '--not-trusted',
+ action='store_true',
+ help=_(
+ "Set port to be not trusted. This will be populated into the "
+ "'binding:profile' dictionary and passed to the services "
+ "which expect it in this dictionary (for example, Nova)"
+ ),
+ )
# TODO(abhiraut): Use the SDK resource mapped attribute names once the
@@ -498,12 +538,12 @@ class CreatePort(command.ShowOne, common.NeutronCommandWithExtraArgs):
uplink_status_group.add_argument(
'--enable-uplink-status-propagation',
action='store_true',
- help=_("Enable uplink status propagate"),
+ help=_("Enable uplink status propagation (default)"),
)
uplink_status_group.add_argument(
'--disable-uplink-status-propagation',
action='store_true',
- help=_("Disable uplink status propagate (default)"),
+ help=_("Disable uplink status propagation"),
)
parser.add_argument(
'--project',
@@ -534,7 +574,7 @@ class CreatePort(command.ShowOne, common.NeutronCommandWithExtraArgs):
'--security-group',
metavar='<security-group>',
action='append',
- dest='security_group',
+ dest='security_groups',
help=_(
"Security group to associate with this port (name or ID) "
"(repeat option to set multiple security groups)"
@@ -542,8 +582,9 @@ class CreatePort(command.ShowOne, common.NeutronCommandWithExtraArgs):
)
secgroups.add_argument(
'--no-security-group',
- dest='no_security_group',
- action='store_true',
+ action='store_const',
+ const=[],
+ dest='security_groups',
help=_("Associate no security groups with this port"),
)
parser.add_argument(
@@ -609,13 +650,11 @@ class CreatePort(command.ShowOne, common.NeutronCommandWithExtraArgs):
elif parsed_args.no_fixed_ip:
attrs['fixed_ips'] = []
- if parsed_args.security_group:
+ if parsed_args.security_groups is not None:
attrs['security_group_ids'] = [
client.find_security_group(sg, ignore_missing=False).id
- for sg in parsed_args.security_group
+ for sg in parsed_args.security_groups
]
- elif parsed_args.no_security_group:
- attrs['security_group_ids'] = []
if parsed_args.allowed_address_pairs:
attrs['allowed_address_pairs'] = _convert_address_pairs(
@@ -828,25 +867,30 @@ class ListPort(command.Lister):
network_client = self.app.client_manager.network
identity_client = self.app.client_manager.identity
- columns = (
+ columns = [
'id',
'name',
'mac_address',
'fixed_ips',
'status',
- )
- column_headers = (
+ ]
+ column_headers = [
'ID',
'Name',
'MAC Address',
'Fixed IP Addresses',
'Status',
- )
+ ]
filters = {}
if parsed_args.long:
- columns += ('security_group_ids', 'device_owner', 'tags')
- column_headers += ('Security Groups', 'Device Owner', 'Tags')
+ columns.extend(
+ ['security_groups', 'device_owner', 'tags', 'trunk_details']
+ )
+ column_headers.extend(
+ ['Security Groups', 'Device Owner', 'Tags', 'Trunk subports']
+ )
+
if parsed_args.device_owner is not None:
filters['device_owner'] = parsed_args.device_owner
if parsed_args.device_id is not None:
@@ -894,6 +938,12 @@ class ListPort(command.Lister):
data = network_client.ports(fields=columns, **filters)
+ if parsed_args.long:
+ columns = [
+ 'security_group_ids' if item == 'security_groups' else item
+ for item in columns
+ ]
+
headers, attrs = utils.calculate_header_and_attrs(
column_headers, columns, parsed_args
)
@@ -903,7 +953,7 @@ class ListPort(command.Lister):
utils.get_item_properties(
s,
attrs,
- formatters=_formatters,
+ formatters=_list_formatters,
)
for s in data
),
@@ -982,7 +1032,7 @@ class SetPort(common.NeutronCommandWithExtraArgs):
'--security-group',
metavar='<security-group>',
action='append',
- dest='security_group',
+ dest='security_groups',
help=_(
"Security group to associate with this port (name or ID) "
"(repeat option to set multiple security groups)"
@@ -1053,6 +1103,18 @@ class SetPort(common.NeutronCommandWithExtraArgs):
"(requires data plane status extension)"
),
)
+ uplink_status_group = parser.add_mutually_exclusive_group()
+ uplink_status_group.add_argument(
+ '--enable-uplink-status-propagation',
+ action='store_true',
+ help=_('Enable uplink status propagation'),
+ )
+ uplink_status_group.add_argument(
+ '--disable-uplink-status-propagation',
+ action='store_true',
+ help=_('Disable uplink status propagation'),
+ )
+
_tag.add_tag_option_to_parser_for_set(parser, _('port'))
return parser
@@ -1083,7 +1145,7 @@ class SetPort(common.NeutronCommandWithExtraArgs):
if parsed_args.no_security_group:
attrs['security_group_ids'] = []
- if parsed_args.security_group:
+ if parsed_args.security_groups:
if 'security_group_ids' not in attrs:
# NOTE(dtroyer): Get existing security groups, iterate the
# list to force a new list object to be
@@ -1094,7 +1156,7 @@ class SetPort(common.NeutronCommandWithExtraArgs):
]
attrs['security_group_ids'].extend(
client.find_security_group(sg, ignore_missing=False).id
- for sg in parsed_args.security_group
+ for sg in parsed_args.security_groups
)
if parsed_args.no_allowed_address_pair:
@@ -1137,6 +1199,11 @@ class SetPort(common.NeutronCommandWithExtraArgs):
raise exceptions.CommandError(msg)
attrs['hints'] = expanded_hints
+ if parsed_args.not_trusted:
+ attrs['trusted'] = False
+ if parsed_args.trusted:
+ attrs['trusted'] = True
+
attrs.update(
self._parse_extra_properties(parsed_args.extra_properties)
)
@@ -1202,7 +1269,7 @@ class UnsetPort(common.NeutronUnsetCommandWithExtraArgs):
'--security-group',
metavar='<security-group>',
action='append',
- dest='security_group_ids',
+ dest='security_groups',
help=_(
"Security group which should be removed this port (name "
"or ID) (repeat option to unset multiple security groups)"
@@ -1287,9 +1354,9 @@ class UnsetPort(common.NeutronUnsetCommandWithExtraArgs):
msg = _("Port does not contain binding-profile %s") % key
raise exceptions.CommandError(msg)
attrs['binding:profile'] = tmp_binding_profile
- if parsed_args.security_group_ids:
+ if parsed_args.security_groups:
try:
- for sg in parsed_args.security_group_ids:
+ for sg in parsed_args.security_groups:
sg_id = client.find_security_group(
sg, ignore_missing=False
).id
diff --git a/openstackclient/network/v2/router.py b/openstackclient/network/v2/router.py
index 5193abc..0deae36 100644
--- a/openstackclient/network/v2/router.py
+++ b/openstackclient/network/v2/router.py
@@ -237,6 +237,9 @@ def _get_attrs(client_manager, parsed_args):
if 'flavor_id' in parsed_args and parsed_args.flavor_id is not None:
flavor = n_client.find_flavor(parsed_args.flavor_id)
attrs['flavor_id'] = flavor.id
+ elif 'flavor' in parsed_args and parsed_args.flavor is not None:
+ flavor = n_client.find_flavor(parsed_args.flavor, ignore_missing=False)
+ attrs['flavor_id'] = flavor.id
for attr in ('enable_default_route_bfd', 'enable_default_route_ecmp'):
value = getattr(parsed_args, attr, None)
diff --git a/openstackclient/tests/functional/compute/v2/test_server.py b/openstackclient/tests/functional/compute/v2/test_server.py
index 19531da..47b6d7c 100644
--- a/openstackclient/tests/functional/compute/v2/test_server.py
+++ b/openstackclient/tests/functional/compute/v2/test_server.py
@@ -1295,7 +1295,7 @@ class ServerTests(common.ComputeTestCase):
)
if ip_address in cmd_output['addresses']['private']:
# Hang out for a bit and try again
- print('retrying add port check')
+ print('retrying remove port check')
wait_time += 10
time.sleep(10)
else:
@@ -1367,6 +1367,92 @@ class ServerTests(common.ComputeTestCase):
addresses = cmd_output['addresses']['private']
self.assertIn(ip_address, addresses)
+ def test_server_add_remove_security_group(self):
+ name = uuid.uuid4().hex
+ cmd_output = self.openstack(
+ 'server create '
+ + '--network private '
+ + '--flavor '
+ + self.flavor_name
+ + ' '
+ + '--image '
+ + self.image_name
+ + ' '
+ + '--wait '
+ + name,
+ parse_output=True,
+ )
+
+ self.assertIsNotNone(cmd_output['id'])
+ self.assertEqual(name, cmd_output['name'])
+ self.addCleanup(self.openstack, 'server delete --wait ' + name)
+
+ # create security group
+ security_group_name = uuid.uuid4().hex
+
+ cmd_output = self.openstack(
+ 'security group list',
+ parse_output=True,
+ )
+ self.assertNotIn(security_group_name, cmd_output)
+
+ cmd_output = self.openstack(
+ 'security group create ' + security_group_name,
+ parse_output=True,
+ )
+ self.assertIsNotNone(cmd_output['id'])
+ self.addCleanup(
+ self.openstack, 'security group delete ' + security_group_name
+ )
+
+ # add security group to server, assert the name of the security group
+ # appears
+ self.openstack(
+ 'server add security group ' + name + ' ' + security_group_name
+ )
+
+ wait_time = 0
+ while wait_time < 60:
+ cmd_output = self.openstack(
+ 'server show ' + name,
+ parse_output=True,
+ )
+ if security_group_name not in [
+ x['name'] for x in cmd_output['security_groups']
+ ]:
+ # Hang out for a bit and try again
+ print('retrying add security group check')
+ wait_time += 10
+ time.sleep(10)
+ else:
+ break
+ security_groups = [x['name'] for x in cmd_output['security_groups']]
+ self.assertIn(security_group_name, security_groups)
+
+ # remove security group, assert the name of the security group doesn't
+ # appear
+ self.openstack(
+ 'server remove security group ' + name + ' ' + security_group_name
+ )
+
+ wait_time = 0
+ while wait_time < 60:
+ cmd_output = self.openstack(
+ 'server show ' + name,
+ parse_output=True,
+ )
+ if security_group_name not in [
+ x['name'] for x in cmd_output['security_groups']
+ ]:
+ # Hang out for a bit and try again
+ print('retrying remove security group check')
+ wait_time += 10
+ time.sleep(10)
+ else:
+ break
+ security_groups = [x['name'] for x in cmd_output['security_groups']]
+ self.assertNotIn(security_group_name, security_groups)
+
def test_server_add_remove_volume(self):
volume_wait_for = volume_common.BaseVolumeTests.wait_for_status
diff --git a/openstackclient/tests/functional/identity/v3/common.py b/openstackclient/tests/functional/identity/v3/common.py
index e44f291..ecabfd2 100644
--- a/openstackclient/tests/functional/identity/v3/common.py
+++ b/openstackclient/tests/functional/identity/v3/common.py
@@ -49,7 +49,7 @@ class IdentityTests(base.TestCase):
]
ROLE_FIELDS = ['id', 'name', 'domain_id', 'description']
SERVICE_FIELDS = ['id', 'enabled', 'name', 'type', 'description']
- REGION_FIELDS = ['description', 'enabled', 'parent_region', 'region']
+ REGION_FIELDS = ['description', 'parent_region', 'region']
ENDPOINT_FIELDS = [
'id',
'region',
diff --git a/openstackclient/tests/functional/identity/v3/test_application_credential.py b/openstackclient/tests/functional/identity/v3/test_application_credential.py
index 4412592..39c735b 100644
--- a/openstackclient/tests/functional/identity/v3/test_application_credential.py
+++ b/openstackclient/tests/functional/identity/v3/test_application_credential.py
@@ -107,7 +107,8 @@ class ApplicationCredentialTests(common.IdentityTests):
secret = data_utils.rand_name('secret')
description = data_utils.rand_name('description')
tomorrow = (
- datetime.datetime.utcnow() + datetime.timedelta(days=1)
+ datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
+ + datetime.timedelta(days=1)
).strftime('%Y-%m-%dT%H:%M:%S%z')
role1, role2 = self._create_role_assignments()
raw_output = self.openstack(
diff --git a/openstackclient/tests/functional/identity/v3/test_role.py b/openstackclient/tests/functional/identity/v3/test_role.py
index 16ddc23..f4c6832 100644
--- a/openstackclient/tests/functional/identity/v3/test_role.py
+++ b/openstackclient/tests/functional/identity/v3/test_role.py
@@ -93,6 +93,30 @@ class RoleTests(common.IdentityTests):
)
self.assertEqual(0, len(raw_output))
+ def test_role_add_inherited(self):
+ role_name = self._create_dummy_role()
+ username = self._create_dummy_user()
+ raw_output = self.openstack(
+ 'role add '
+ f'--project {self.project_name} '
+ f'--project-domain {self.domain_name} '
+ f'--user {username} '
+ f'--user-domain {self.domain_name} '
+ '--inherited '
+ f'{role_name}'
+ )
+ self.addCleanup(
+ self.openstack,
+ 'role remove '
+ f'--project {self.project_name} '
+ f'--project-domain {self.domain_name} '
+ f'--user {username} '
+ f'--user-domain {self.domain_name} '
+ '--inherited '
+ f'{role_name}',
+ )
+ self.assertEqual(0, len(raw_output))
+
def test_role_remove(self):
role_name = self._create_dummy_role()
username = self._create_dummy_user()
diff --git a/openstackclient/tests/functional/identity/v3/test_role_assignment.py b/openstackclient/tests/functional/identity/v3/test_role_assignment.py
index 941563c..6c53bc2 100644
--- a/openstackclient/tests/functional/identity/v3/test_role_assignment.py
+++ b/openstackclient/tests/functional/identity/v3/test_role_assignment.py
@@ -151,6 +151,14 @@ class RoleAssignmentTests(common.IdentityTests):
'--inherited '
f'{role_name}'
)
+ self.addCleanup(
+ self.openstack,
+ 'role remove '
+ f'--project {self.project_name} '
+ f'--user {username} '
+ '--inherited '
+ f'{role_name}',
+ )
self.assertEqual(0, len(raw_output))
raw_output = self.openstack('role assignment list --inherited')
diff --git a/openstackclient/tests/functional/identity/v3/test_service_provider.py b/openstackclient/tests/functional/identity/v3/test_service_provider.py
index 793223b..2f941d5 100644
--- a/openstackclient/tests/functional/identity/v3/test_service_provider.py
+++ b/openstackclient/tests/functional/identity/v3/test_service_provider.py
@@ -60,9 +60,5 @@ class ServiceProviderTests(common.IdentityTests):
'description': new_description,
}
)
- self.assertEqual(0, len(raw_output))
- raw_output = self.openstack(
- f'service provider show {service_provider}'
- )
updated_value = self.parse_show_as_object(raw_output)
- self.assertIn(new_description, updated_value['description'])
+ self.assertEqual(new_description, updated_value.get('description'))
diff --git a/openstackclient/tests/functional/network/v2/test_port.py b/openstackclient/tests/functional/network/v2/test_port.py
index 24fbe0e..4530395 100644
--- a/openstackclient/tests/functional/network/v2/test_port.py
+++ b/openstackclient/tests/functional/network/v2/test_port.py
@@ -81,10 +81,20 @@ class PortTests(common.NetworkTagTests):
self.addCleanup(self.openstack, f'port delete {id1}')
self.assertEqual(self.NAME, json_output.get('name'))
+ # sg for port2
+ sg_name1 = uuid.uuid4().hex
json_output = self.openstack(
- f'port create --network {self.NETWORK_NAME} {self.NAME}x',
+ f'security group create {sg_name1}',
parse_output=True,
)
+ sg_id1 = json_output.get('id')
+ self.addCleanup(self.openstack, f'security group delete {sg_id1}')
+ json_output = self.openstack(
+ f'port create --network {self.NETWORK_NAME} '
+ f'--security-group {sg_name1} {self.NAME}x',
+ parse_output=True,
+ )
+
id2 = json_output.get('id')
self.assertIsNotNone(id2)
mac2 = json_output.get('mac_address')
@@ -113,6 +123,12 @@ class PortTests(common.NetworkTagTests):
id_list = [item.get('ID') for item in json_output]
self.assertIn(id1, id_list)
self.assertIn(id2, id_list)
+ item_sg_map = {
+ item.get('ID'): item.get('Security Groups') for item in json_output
+ }
+ self.assertIn(id1, item_sg_map.keys())
+ self.assertIn(id2, item_sg_map.keys())
+ self.assertIn([sg_id1], item_sg_map.values())
# Test list --mac-address
json_output = self.openstack(
@@ -127,6 +143,17 @@ class PortTests(common.NetworkTagTests):
self.assertNotIn(mac1, item_map.values())
self.assertIn(mac2, item_map.values())
+ # Test list --security-group
+ json_output = self.openstack(
+ f'port list --security-group {sg_id1}',
+ parse_output=True,
+ )
+ item_map = {
+ item.get('ID'): item.get('Security Groups') for item in json_output
+ }
+ self.assertNotIn(id1, item_map.keys())
+ self.assertIn(id2, item_map.keys())
+
# Test list with unknown fields
json_output = self.openstack(
'port list -c ID -c Name -c device_id',
@@ -262,3 +289,82 @@ class PortTests(common.NetworkTagTests):
f'{self.base_command} create --network {self.NETWORK_NAME} {args} {name}',
parse_output=True,
)
+
+ def _trunk_creation(self):
+ pport = uuid.uuid4().hex
+ sport1 = uuid.uuid4().hex
+ sport2 = uuid.uuid4().hex
+ trunk = uuid.uuid4().hex
+ json_output = self.openstack(
+ 'port create ' f'--network {self.NETWORK_NAME} {pport}',
+ parse_output=True,
+ )
+ pport_id = json_output.get('id')
+ json_output = self.openstack(
+ 'port create ' f'--network {self.NETWORK_NAME} {sport1}',
+ parse_output=True,
+ )
+ sport1_id = json_output.get('id')
+ json_output = self.openstack(
+ 'port create ' f'--network {self.NETWORK_NAME} {sport2}',
+ parse_output=True,
+ )
+ sport2_id = json_output.get('id')
+
+ self.openstack(
+ f'network trunk create --parent-port {pport} {trunk}',
+ )
+ self.openstack(
+ f'network trunk set --subport port={sport1},'
+ f'segmentation-type=vlan,segmentation-id=100 {trunk}',
+ )
+ self.openstack(
+ f'network trunk set --subport port={sport2},'
+ f'segmentation-type=vlan,segmentation-id=101 {trunk}',
+ )
+
+ # NOTE(ralonsoh): keep this order to first delete the trunk and then
+ # the ports.
+ self.addCleanup(self.openstack, f'port delete {pport_id}')
+ self.addCleanup(self.openstack, f'port delete {sport1_id}')
+ self.addCleanup(self.openstack, f'port delete {sport2_id}')
+ self.addCleanup(self.openstack, f'network trunk delete {trunk}')
+
+ return pport_id, sport1_id, sport2_id
+
+ def check_subports(self, subports, pport_id, sport1_id, sport2_id):
+ self.assertEqual(2, len(subports))
+ for subport in subports:
+ if subport['port_id'] == sport1_id:
+ self.assertEqual(100, subport['segmentation_id'])
+ elif subport['port_id'] == sport2_id:
+ self.assertEqual(101, subport['segmentation_id'])
+ else:
+ self.fail(
+ f'Port {pport_id} does not have subport '
+ f'{subport["port_id"]}'
+ )
+ self.assertEqual('vlan', subport['segmentation_type'])
+
+ def test_port_list_with_trunk(self):
+ pport_id, sport1_id, sport2_id = self._trunk_creation()
+
+ # List all ports with "--long" flag to retrieve the trunk details
+ json_output = self.openstack(
+ 'port list --long',
+ parse_output=True,
+ )
+ port = next(port for port in json_output if port['ID'] == pport_id)
+ subports = port['Trunk subports']
+ self.check_subports(subports, pport_id, sport1_id, sport2_id)
+
+ def test_port_show_with_trunk(self):
+ pport_id, sport1_id, sport2_id = self._trunk_creation()
+
+ # List all ports with "--long" flag to retrieve the trunk details
+ port = self.openstack(
+ f'port show {pport_id}',
+ parse_output=True,
+ )
+ subports = port['trunk_details']['sub_ports']
+ self.check_subports(subports, pport_id, sport1_id, sport2_id)
diff --git a/openstackclient/tests/unit/compute/v2/fakes.py b/openstackclient/tests/unit/compute/v2/fakes.py
index d021c5d..62758c8 100644
--- a/openstackclient/tests/unit/compute/v2/fakes.py
+++ b/openstackclient/tests/unit/compute/v2/fakes.py
@@ -21,21 +21,15 @@ import uuid
from keystoneauth1 import discover
from openstack.compute.v2 import _proxy
-from openstack.compute.v2 import aggregate as _aggregate
from openstack.compute.v2 import availability_zone as _availability_zone
from openstack.compute.v2 import extension as _extension
from openstack.compute.v2 import flavor as _flavor
-from openstack.compute.v2 import hypervisor as _hypervisor
-from openstack.compute.v2 import keypair as _keypair
from openstack.compute.v2 import limits as _limits
from openstack.compute.v2 import migration as _migration
from openstack.compute.v2 import server as _server
from openstack.compute.v2 import server_action as _server_action
-from openstack.compute.v2 import server_group as _server_group
from openstack.compute.v2 import server_interface as _server_interface
from openstack.compute.v2 import server_migration as _server_migration
-from openstack.compute.v2 import service as _service
-from openstack.compute.v2 import usage as _usage
from openstack.compute.v2 import volume_attachment as _volume_attachment
from openstackclient.tests.unit import fakes
@@ -142,63 +136,6 @@ class TestComputev2(
): ...
-def create_one_aggregate(attrs=None):
- """Create a fake aggregate.
-
- :param dict attrs: A dictionary with all attributes
- :return: A fake openstack.compute.v2.aggregate.Aggregate object
- """
- attrs = attrs or {}
-
- # Set default attribute
- aggregate_info = {
- "name": "aggregate-name-" + uuid.uuid4().hex,
- "availability_zone": "ag_zone",
- "hosts": [],
- "id": "aggregate-id-" + uuid.uuid4().hex,
- "metadata": {
- "availability_zone": "ag_zone",
- "key1": "value1",
- },
- }
-
- # Overwrite default attributes.
- aggregate_info.update(attrs)
-
- aggregate = _aggregate.Aggregate(**aggregate_info)
- return aggregate
-
-
-def create_aggregates(attrs=None, count=2):
- """Create multiple fake aggregates.
-
- :param dict attrs: A dictionary with all attributes
- :param int count: The number of aggregates to fake
- :return: A list of fake openstack.compute.v2.aggregate.Aggregate objects
- """
- aggregates = []
- for i in range(0, count):
- aggregates.append(create_one_aggregate(attrs))
-
- return aggregates
-
-
-def get_aggregates(aggregates=None, count=2):
- """Get an iterable MagicMock object with a list of faked aggregates.
-
- If aggregates list is provided, then initialize the Mock object
- with the list. Otherwise create one.
-
- :return: A list of fake openstack.compute.v2.aggregate.Aggregate objects
- :param int count: The number of aggregates to fake
- :return: An iterable Mock object with side_effect set to a list of faked
- aggregates
- """
- if aggregates is None:
- aggregates = create_aggregates(count)
- return mock.Mock(side_effect=aggregates)
-
-
def create_one_agent(attrs=None):
"""Create a fake agent.
@@ -544,51 +481,6 @@ def create_one_server_action(attrs=None):
return server_action
-def create_one_service(attrs=None):
- """Create a fake service.
-
- :param dict attrs: A dictionary with all attributes
- :return: A fake openstack.compute.v2.service.Service object
- """
- attrs = attrs or {}
-
- # Set default attributes.
- service_info = {
- 'id': 'id-' + uuid.uuid4().hex,
- 'host': 'host-' + uuid.uuid4().hex,
- 'binary': 'binary-' + uuid.uuid4().hex,
- 'status': 'enabled',
- 'availability_zone': 'zone-' + uuid.uuid4().hex,
- 'state': 'state-' + uuid.uuid4().hex,
- 'updated_at': 'time-' + uuid.uuid4().hex,
- 'disabled_reason': 'earthquake',
- # Introduced in API microversion 2.11
- 'is_forced_down': False,
- }
-
- # Overwrite default attributes.
- service_info.update(attrs)
-
- return _service.Service(**service_info)
-
-
-def create_services(attrs=None, count=2):
- """Create multiple fake services.
-
- :param dict attrs:
- A dictionary with all attributes
- :param int count:
- The number of services to fake
- :return:
- A list of FakeResource objects faking the services
- """
- services = []
- for i in range(0, count):
- services.append(create_one_service(attrs))
-
- return services
-
-
def create_one_flavor(attrs=None):
"""Create a fake flavor.
@@ -678,61 +570,6 @@ def create_one_flavor_access(attrs=None):
return flavor_access
-def create_one_keypair(attrs=None):
- """Create a fake keypair
-
- :param dict attrs: A dictionary with all attributes
- :return: A fake openstack.compute.v2.keypair.Keypair object
- """
- attrs = attrs or {}
-
- # Set default attributes.
- keypair_info = {
- 'name': 'keypair-name-' + uuid.uuid4().hex,
- 'type': 'ssh',
- 'fingerprint': 'dummy',
- 'public_key': 'dummy',
- 'user_id': 'user',
- }
-
- # Overwrite default attributes.
- keypair_info.update(attrs)
-
- return _keypair.Keypair(**keypair_info)
-
-
-def create_keypairs(attrs=None, count=2):
- """Create multiple fake keypairs.
-
- :param dict attrs: A dictionary with all attributes
- :param int count: The number of keypairs to fake
- :return: A list of fake openstack.compute.v2.keypair.Keypair objects
- """
-
- keypairs = []
- for i in range(0, count):
- keypairs.append(create_one_keypair(attrs))
-
- return keypairs
-
-
-def get_keypairs(keypairs=None, count=2):
- """Get an iterable MagicMock object with a list of faked keypairs.
-
- If keypairs list is provided, then initialize the Mock object with the
- list. Otherwise create one.
-
- :param list keypairs: A list of fake openstack.compute.v2.keypair.Keypair
- objects
- :param int count: The number of keypairs to fake
- :return: An iterable Mock object with side_effect set to a list of faked
- keypairs
- """
- if keypairs is None:
- keypairs = create_keypairs(count)
- return mock.Mock(side_effect=keypairs)
-
-
def create_one_availability_zone(attrs=None):
"""Create a fake AZ.
@@ -970,62 +807,6 @@ def get_networks(networks=None, count=2):
return mock.Mock(side_effect=networks)
-def create_one_usage(attrs=None):
- """Create a fake usage.
-
- :param dict attrs:
- A dictionary with all attributes
- :return:
- A FakeResource object, with tenant_id and other attributes
- """
- if attrs is None:
- attrs = {}
-
- # Set default attributes.
- usage_info = {
- 'project_id': 'usage-tenant-id-' + uuid.uuid4().hex,
- 'total_memory_mb_usage': 512.0,
- 'total_vcpus_usage': 1.0,
- 'total_local_gb_usage': 1.0,
- 'server_usages': [
- {
- 'ended_at': None,
- 'flavor': 'usage-flavor-' + uuid.uuid4().hex,
- 'hours': 1.0,
- 'local_gb': 1,
- 'memory_mb': 512,
- 'name': 'usage-name-' + uuid.uuid4().hex,
- 'instance_id': uuid.uuid4().hex,
- 'state': 'active',
- 'uptime': 3600,
- 'vcpus': 1,
- }
- ],
- }
-
- # Overwrite default attributes.
- usage_info.update(attrs)
-
- return _usage.Usage(**usage_info)
-
-
-def create_usages(attrs=None, count=2):
- """Create multiple fake services.
-
- :param dict attrs:
- A dictionary with all attributes
- :param int count:
- The number of services to fake
- :return:
- A list of FakeResource objects faking the services
- """
- usages = []
- for i in range(0, count):
- usages.append(create_one_usage(attrs))
-
- return usages
-
-
def create_limits(attrs=None):
"""Create a fake limits object."""
attrs = attrs or {}
@@ -1237,91 +1018,6 @@ def create_volume_attachments(attrs=None, count=2):
return volume_attachments
-def create_one_hypervisor(attrs=None):
- """Create a fake hypervisor.
-
- :param dict attrs: A dictionary with all attributes
- :return: A fake openstack.compute.v2.hypervisor.Hypervisor object
- """
- attrs = attrs or {}
-
- # Set default attributes.
- hypervisor_info = {
- 'id': 'hypervisor-id-' + uuid.uuid4().hex,
- 'hypervisor_hostname': 'hypervisor-hostname-' + uuid.uuid4().hex,
- 'status': 'enabled',
- 'host_ip': '192.168.0.10',
- 'cpu_info': {
- 'aaa': 'aaa',
- },
- 'free_disk_gb': 50,
- 'hypervisor_version': 2004001,
- 'disk_available_least': 50,
- 'local_gb': 50,
- 'free_ram_mb': 1024,
- 'service': {
- 'host': 'aaa',
- 'disabled_reason': None,
- 'id': 1,
- },
- 'vcpus_used': 0,
- 'hypervisor_type': 'QEMU',
- 'local_gb_used': 0,
- 'vcpus': 4,
- 'memory_mb_used': 512,
- 'memory_mb': 1024,
- 'current_workload': 0,
- 'state': 'up',
- 'running_vms': 0,
- }
-
- # Overwrite default attributes.
- hypervisor_info.update(attrs)
-
- hypervisor = _hypervisor.Hypervisor(**hypervisor_info, loaded=True)
- return hypervisor
-
-
-def create_hypervisors(attrs=None, count=2):
- """Create multiple fake hypervisors.
-
- :param dict attrs: A dictionary with all attributes
- :param int count: The number of hypervisors to fake
- :return: A list of fake openstack.compute.v2.hypervisor.Hypervisor objects
- """
- hypervisors = []
- for i in range(0, count):
- hypervisors.append(create_one_hypervisor(attrs))
-
- return hypervisors
-
-
-def create_one_server_group(attrs=None):
- """Create a fake server group
-
- :param dict attrs: A dictionary with all attributes
- :return: A fake openstack.compute.v2.server_group.ServerGroup object
- """
- if attrs is None:
- attrs = {}
-
- # Set default attributes.
- server_group_info = {
- 'id': 'server-group-id-' + uuid.uuid4().hex,
- 'member_ids': '',
- 'metadata': {},
- 'name': 'server-group-name-' + uuid.uuid4().hex,
- 'project_id': 'server-group-project-id-' + uuid.uuid4().hex,
- 'user_id': 'server-group-user-id-' + uuid.uuid4().hex,
- }
-
- # Overwrite default attributes.
- server_group_info.update(attrs)
-
- server_group = _server_group.ServerGroup(**server_group_info)
- return server_group
-
-
def create_one_server_interface(attrs=None):
"""Create a fake SDK ServerInterface.
diff --git a/openstackclient/tests/unit/compute/v2/test_aggregate.py b/openstackclient/tests/unit/compute/v2/test_aggregate.py
index 933344e..f905d67 100644
--- a/openstackclient/tests/unit/compute/v2/test_aggregate.py
+++ b/openstackclient/tests/unit/compute/v2/test_aggregate.py
@@ -16,7 +16,9 @@
from unittest import mock
from unittest.mock import call
+from openstack.compute.v2 import aggregate as _aggregate
from openstack import exceptions as sdk_exceptions
+from openstack.test import fakes as sdk_fakes
from osc_lib.cli import format_columns
from osc_lib import exceptions
@@ -26,8 +28,6 @@ from openstackclient.tests.unit.image.v2 import fakes as image_fakes
class TestAggregate(compute_fakes.TestComputev2):
- fake_ag = compute_fakes.create_one_aggregate()
-
columns = (
'availability_zone',
'created_at',
@@ -41,18 +41,25 @@ class TestAggregate(compute_fakes.TestComputev2):
'uuid',
)
- data = (
- fake_ag.availability_zone,
- fake_ag.created_at,
- fake_ag.deleted_at,
- format_columns.ListColumn(fake_ag.hosts),
- fake_ag.id,
- fake_ag.is_deleted,
- fake_ag.name,
- format_columns.DictColumn(fake_ag.metadata),
- fake_ag.updated_at,
- fake_ag.uuid,
- )
+ def setUp(self):
+ super().setUp()
+
+ self.fake_ag = sdk_fakes.generate_fake_resource(
+ _aggregate.Aggregate,
+ metadata={'availability_zone': 'ag_zone', 'key1': 'value1'},
+ )
+ self.data = (
+ self.fake_ag.availability_zone,
+ self.fake_ag.created_at,
+ self.fake_ag.deleted_at,
+ format_columns.ListColumn(self.fake_ag.hosts),
+ self.fake_ag.id,
+ self.fake_ag.is_deleted,
+ self.fake_ag.name,
+ format_columns.DictColumn(self.fake_ag.metadata),
+ self.fake_ag.updated_at,
+ self.fake_ag.uuid,
+ )
class TestAggregateAddHost(TestAggregate):
@@ -155,13 +162,15 @@ class TestAggregateCreate(TestAggregate):
class TestAggregateDelete(TestAggregate):
- fake_ags = compute_fakes.create_aggregates(count=2)
-
def setUp(self):
super().setUp()
- self.compute_sdk_client.find_aggregate = compute_fakes.get_aggregates(
- self.fake_ags
+ self.fake_ags = list(
+ sdk_fakes.generate_fake_resources(_aggregate.Aggregate, 2)
+ )
+
+ self.compute_sdk_client.find_aggregate = mock.Mock(
+ side_effect=[self.fake_ags[0], self.fake_ags[1]]
)
self.cmd = aggregate.DeleteAggregate(self.app, None)
@@ -526,25 +535,25 @@ class TestAggregateShow(TestAggregate):
'uuid',
)
- data = (
- TestAggregate.fake_ag.availability_zone,
- TestAggregate.fake_ag.created_at,
- TestAggregate.fake_ag.deleted_at,
- format_columns.ListColumn(TestAggregate.fake_ag.hosts),
- TestAggregate.fake_ag.id,
- TestAggregate.fake_ag.is_deleted,
- TestAggregate.fake_ag.name,
- format_columns.DictColumn(TestAggregate.fake_ag.metadata),
- TestAggregate.fake_ag.updated_at,
- TestAggregate.fake_ag.uuid,
- )
-
def setUp(self):
super().setUp()
self.compute_sdk_client.find_aggregate.return_value = self.fake_ag
self.cmd = aggregate.ShowAggregate(self.app, None)
+ self.data = (
+ self.fake_ag.availability_zone,
+ self.fake_ag.created_at,
+ self.fake_ag.deleted_at,
+ format_columns.ListColumn(self.fake_ag.hosts),
+ self.fake_ag.id,
+ self.fake_ag.is_deleted,
+ self.fake_ag.name,
+ format_columns.DictColumn(self.fake_ag.metadata),
+ self.fake_ag.updated_at,
+ self.fake_ag.uuid,
+ )
+
def test_aggregate_show(self):
arglist = [
'ag1',
diff --git a/openstackclient/tests/unit/compute/v2/test_console.py b/openstackclient/tests/unit/compute/v2/test_console.py
index a179db5..d4c6940 100644
--- a/openstackclient/tests/unit/compute/v2/test_console.py
+++ b/openstackclient/tests/unit/compute/v2/test_console.py
@@ -15,6 +15,9 @@
from unittest import mock
+from openstack.compute.v2 import server as _server
+from openstack.test import fakes as sdk_fakes
+
from openstackclient.compute.v2 import console
from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
from openstackclient.tests.unit import utils
@@ -24,7 +27,7 @@ class TestConsoleLog(compute_fakes.TestComputev2):
def setUp(self):
super().setUp()
- self._server = compute_fakes.create_one_sdk_server()
+ self._server = sdk_fakes.generate_fake_resource(_server.Server)
self.compute_sdk_client.find_server.return_value = self._server
self.cmd = console.ShowConsoleLog(self.app, None)
@@ -76,11 +79,12 @@ class TestConsoleLog(compute_fakes.TestComputev2):
class TestConsoleUrlShow(compute_fakes.TestComputev2):
- _server = compute_fakes.create_one_sdk_server()
-
def setUp(self):
super().setUp()
+
+ self._server = sdk_fakes.generate_fake_resource(_server.Server)
self.compute_sdk_client.find_server.return_value = self._server
+
fake_console_data = {
'url': 'http://localhost',
'protocol': 'fake_protocol',
diff --git a/openstackclient/tests/unit/compute/v2/test_hypervisor.py b/openstackclient/tests/unit/compute/v2/test_hypervisor.py
index 2c83fe4..da6e7e5 100644
--- a/openstackclient/tests/unit/compute/v2/test_hypervisor.py
+++ b/openstackclient/tests/unit/compute/v2/test_hypervisor.py
@@ -14,7 +14,9 @@
import json
+from openstack.compute.v2 import hypervisor as _hypervisor
from openstack import exceptions as sdk_exceptions
+from openstack.test import fakes as sdk_fakes
from osc_lib.cli import format_columns
from osc_lib import exceptions
@@ -27,8 +29,12 @@ class TestHypervisorList(compute_fakes.TestComputev2):
super().setUp()
# Fake hypervisors to be listed up
- self.hypervisors = compute_fakes.create_hypervisors()
- self.compute_sdk_client.hypervisors.return_value = self.hypervisors
+ self.hypervisors = list(
+ sdk_fakes.generate_fake_resources(_hypervisor.Hypervisor, count=2)
+ )
+ self.compute_sdk_client.hypervisors.return_value = iter(
+ self.hypervisors
+ )
self.columns = (
"ID",
@@ -125,9 +131,9 @@ class TestHypervisorList(compute_fakes.TestComputev2):
(
self.hypervisors[0].id,
self.hypervisors[0].name,
- self.hypervisors[1].hypervisor_type,
- self.hypervisors[1].host_ip,
- self.hypervisors[1].state,
+ self.hypervisors[0].hypervisor_type,
+ self.hypervisors[0].host_ip,
+ self.hypervisors[0].state,
),
)
@@ -290,10 +296,11 @@ class TestHypervisorShow(compute_fakes.TestComputev2):
)
# Fake hypervisors to be listed up
- self.hypervisor = compute_fakes.create_one_hypervisor(
- attrs={
- 'uptime': uptime_string,
- }
+ self.hypervisor = sdk_fakes.generate_fake_resource(
+ _hypervisor.Hypervisor,
+ uptime=uptime_string,
+ service={"id": 1, "host": "aaa"},
+ cpu_info={"aaa": "aaa"},
)
self.compute_sdk_client.find_hypervisor.return_value = self.hypervisor
@@ -332,18 +339,18 @@ class TestHypervisorShow(compute_fakes.TestComputev2):
self.data_v288 = (
[],
- format_columns.DictColumn({'aaa': 'aaa'}),
- '192.168.0.10',
+ format_columns.DictColumn(self.hypervisor.cpu_info),
+ self.hypervisor.host_ip,
'01:28:24',
self.hypervisor.name,
- 'QEMU',
- 2004001,
+ self.hypervisor.hypervisor_type,
+ self.hypervisor.hypervisor_version,
self.hypervisor.id,
'0.94, 0.62, 0.50',
- 'aaa',
- 1,
- 'up',
- 'enabled',
+ self.hypervisor.service_details["host"],
+ self.hypervisor.service_details["id"],
+ self.hypervisor.state,
+ self.hypervisor.status,
'3 days, 11:15',
'1',
)
@@ -378,31 +385,31 @@ class TestHypervisorShow(compute_fakes.TestComputev2):
)
self.data = (
[],
- format_columns.DictColumn({'aaa': 'aaa'}),
- 0,
- 50,
- 50,
- 1024,
- '192.168.0.10',
+ format_columns.DictColumn(self.hypervisor.cpu_info),
+ self.hypervisor.current_workload,
+ self.hypervisor.disk_available,
+ self.hypervisor.local_disk_free,
+ self.hypervisor.memory_free,
+ self.hypervisor.host_ip,
'01:28:24',
self.hypervisor.name,
- 'QEMU',
- 2004001,
+ self.hypervisor.hypervisor_type,
+ self.hypervisor.hypervisor_version,
self.hypervisor.id,
'0.94, 0.62, 0.50',
- 50,
- 0,
- 1024,
- 512,
- 0,
- 'aaa',
+ self.hypervisor.local_disk_size,
+ self.hypervisor.local_disk_used,
+ self.hypervisor.memory_size,
+ self.hypervisor.memory_used,
+ self.hypervisor.running_vms,
+ self.hypervisor.service_details["host"],
1,
- 'up',
- 'enabled',
+ self.hypervisor.state,
+ self.hypervisor.status,
'3 days, 11:15',
'1',
- 4,
- 0,
+ self.hypervisor.vcpus,
+ self.hypervisor.vcpus_used,
)
# Get the command object to test
@@ -537,27 +544,27 @@ class TestHypervisorShow(compute_fakes.TestComputev2):
)
expected_data = (
[],
- format_columns.DictColumn({'aaa': 'aaa'}),
- 0,
- 50,
- 50,
- 1024,
- '192.168.0.10',
+ format_columns.DictColumn(self.hypervisor.cpu_info),
+ self.hypervisor.current_workload,
+ self.hypervisor.disk_available,
+ self.hypervisor.local_disk_free,
+ self.hypervisor.memory_free,
+ self.hypervisor.host_ip,
self.hypervisor.name,
- 'QEMU',
- 2004001,
+ self.hypervisor.hypervisor_type,
+ self.hypervisor.hypervisor_version,
self.hypervisor.id,
- 50,
- 0,
- 1024,
- 512,
- 0,
- 'aaa',
+ self.hypervisor.local_disk_size,
+ self.hypervisor.local_disk_used,
+ self.hypervisor.memory_size,
+ self.hypervisor.memory_used,
+ self.hypervisor.running_vms,
+ self.hypervisor.service_details["host"],
1,
- 'up',
- 'enabled',
- 4,
- 0,
+ self.hypervisor.state,
+ self.hypervisor.status,
+ self.hypervisor.vcpus,
+ self.hypervisor.vcpus_used,
)
self.assertEqual(expected_columns, columns)
diff --git a/openstackclient/tests/unit/compute/v2/test_keypair.py b/openstackclient/tests/unit/compute/v2/test_keypair.py
index d6be7d0..0ce08b4 100644
--- a/openstackclient/tests/unit/compute/v2/test_keypair.py
+++ b/openstackclient/tests/unit/compute/v2/test_keypair.py
@@ -12,17 +12,18 @@
# License for the specific language governing permissions and limitations
# under the License.
-import copy
from unittest import mock
from unittest.mock import call
import uuid
+from openstack.compute.v2 import keypair as _keypair
+from openstack.identity.v3 import project as _project
+from openstack.identity.v3 import user as _user
+from openstack.test import fakes as sdk_fakes
from osc_lib import exceptions
from openstackclient.compute.v2 import keypair
from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
-from openstackclient.tests.unit import fakes
-from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes
from openstackclient.tests.unit import utils as tests_utils
@@ -31,20 +32,17 @@ class TestKeypair(compute_fakes.TestComputev2):
super().setUp()
# Initialize the user mock
+ self._user = sdk_fakes.generate_fake_resource(_user.User)
self.users_mock = self.identity_client.users
self.users_mock.reset_mock()
- self.users_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
+ self.users_mock.get.return_value = self._user
class TestKeypairCreate(TestKeypair):
def setUp(self):
super().setUp()
- self.keypair = compute_fakes.create_one_keypair()
+ self.keypair = sdk_fakes.generate_fake_resource(_keypair.Keypair)
self.columns = (
'created_at',
@@ -122,7 +120,7 @@ class TestKeypairCreate(TestKeypair):
) as mock_open:
mock_open.return_value = mock.MagicMock()
m_file = mock_open.return_value.__enter__.return_value
- m_file.read.return_value = 'dummy'
+ m_file.read.return_value = self.keypair.public_key
columns, data = self.cmd.take_action(parsed_args)
@@ -208,7 +206,7 @@ class TestKeypairCreate(TestKeypair):
) as mock_open:
mock_open.return_value = mock.MagicMock()
m_file = mock_open.return_value.__enter__.return_value
- m_file.read.return_value = 'dummy'
+ m_file.read.return_value = self.keypair.public_key
columns, data = self.cmd.take_action(parsed_args)
self.compute_sdk_client.create_keypair.assert_called_with(
@@ -263,11 +261,11 @@ class TestKeypairCreate(TestKeypair):
arglist = [
'--user',
- identity_fakes.user_name,
+ self._user.name,
self.keypair.name,
]
verifylist = [
- ('user', identity_fakes.user_name),
+ ('user', self._user.name),
('name', self.keypair.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -276,7 +274,7 @@ class TestKeypairCreate(TestKeypair):
self.compute_sdk_client.create_keypair.assert_called_with(
name=self.keypair.name,
- user_id=identity_fakes.user_id,
+ user_id=self._user.id,
public_key=mock_generate.return_value.public_key,
)
@@ -288,11 +286,11 @@ class TestKeypairCreate(TestKeypair):
arglist = [
'--user',
- identity_fakes.user_name,
+ self._user.name,
self.keypair.name,
]
verifylist = [
- ('user', identity_fakes.user_name),
+ ('user', self._user.name),
('name', self.keypair.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -306,11 +304,13 @@ class TestKeypairCreate(TestKeypair):
class TestKeypairDelete(TestKeypair):
- keypairs = compute_fakes.create_keypairs(count=2)
-
def setUp(self):
super().setUp()
+ self.keypairs = list(
+ sdk_fakes.generate_fake_resources(_keypair.Keypair, count=2)
+ )
+
self.cmd = keypair.DeleteKeypair(self.app, None)
def test_keypair_delete(self):
@@ -374,9 +374,9 @@ class TestKeypairDelete(TestKeypair):
def test_keypair_delete_with_user(self):
self.set_compute_api_version('2.10')
- arglist = ['--user', identity_fakes.user_name, self.keypairs[0].name]
+ arglist = ['--user', self._user.name, self.keypairs[0].name]
verifylist = [
- ('user', identity_fakes.user_name),
+ ('user', self._user.name),
('name', [self.keypairs[0].name]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -386,16 +386,16 @@ class TestKeypairDelete(TestKeypair):
self.assertIsNone(ret)
self.compute_sdk_client.delete_keypair.assert_called_with(
self.keypairs[0].name,
- user_id=identity_fakes.user_id,
+ user_id=self._user.id,
ignore_missing=False,
)
def test_keypair_delete_with_user_pre_v210(self):
self.set_compute_api_version('2.9')
- arglist = ['--user', identity_fakes.user_name, self.keypairs[0].name]
+ arglist = ['--user', self._user.name, self.keypairs[0].name]
verifylist = [
- ('user', identity_fakes.user_name),
+ ('user', self._user.name),
('name', [self.keypairs[0].name]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -409,17 +409,19 @@ class TestKeypairDelete(TestKeypair):
class TestKeypairList(TestKeypair):
- # Return value of self.compute_sdk_client.keypairs().
- keypairs = compute_fakes.create_keypairs(count=1)
-
def setUp(self):
super().setUp()
- self.compute_sdk_client.keypairs.return_value = self.keypairs
+ self.keypairs = list(
+ sdk_fakes.generate_fake_resources(_keypair.Keypair, count=1)
+ )
+ self.compute_sdk_client.keypairs.return_value = iter(self.keypairs)
# Get the command object to test
self.cmd = keypair.ListKeypair(self.app, None)
+ self._project = sdk_fakes.generate_fake_resource(_project.Project)
+
def test_keypair_list_no_options(self):
arglist = []
verifylist = []
@@ -475,26 +477,22 @@ class TestKeypairList(TestKeypair):
users_mock = self.identity_client.users
users_mock.reset_mock()
- users_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
+ users_mock.get.return_value = self._user
arglist = [
'--user',
- identity_fakes.user_name,
+ self._user.name,
]
verifylist = [
- ('user', identity_fakes.user_name),
+ ('user', self._user.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- users_mock.get.assert_called_with(identity_fakes.user_name)
+ users_mock.get.assert_called_with(self._user.name)
self.compute_sdk_client.keypairs.assert_called_with(
- user_id=identity_fakes.user_id,
+ user_id=self._user.id,
)
self.assertEqual(('Name', 'Fingerprint', 'Type'), columns)
@@ -514,10 +512,10 @@ class TestKeypairList(TestKeypair):
arglist = [
'--user',
- identity_fakes.user_name,
+ self._user.name,
]
verifylist = [
- ('user', identity_fakes.user_name),
+ ('user', self._user.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -533,32 +531,22 @@ class TestKeypairList(TestKeypair):
projects_mock = self.identity_client.tenants
projects_mock.reset_mock()
- projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
+ projects_mock.get.return_value = self._project
users_mock = self.identity_client.users
users_mock.reset_mock()
- users_mock.list.return_value = [
- fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- ),
- ]
+ users_mock.list.return_value = [self._user]
- arglist = ['--project', identity_fakes.project_name]
- verifylist = [('project', identity_fakes.project_name)]
+ arglist = ['--project', self._project.name]
+ verifylist = [('project', self._project.name)]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- projects_mock.get.assert_called_with(identity_fakes.project_name)
- users_mock.list.assert_called_with(tenant_id=identity_fakes.project_id)
+ projects_mock.get.assert_called_with(self._project.name)
+ users_mock.list.assert_called_with(tenant_id=self._project.id)
self.compute_sdk_client.keypairs.assert_called_with(
- user_id=identity_fakes.user_id,
+ user_id=self._user.id,
)
self.assertEqual(('Name', 'Fingerprint', 'Type'), columns)
@@ -576,8 +564,8 @@ class TestKeypairList(TestKeypair):
def test_keypair_list_with_project_pre_v210(self):
self.set_compute_api_version('2.9')
- arglist = ['--project', identity_fakes.project_name]
- verifylist = [('project', identity_fakes.project_name)]
+ arglist = ['--project', self._project.name]
+ verifylist = [('project', self._project.name)]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
ex = self.assertRaises(
@@ -590,9 +578,9 @@ class TestKeypairList(TestKeypair):
def test_keypair_list_conflicting_user_options(self):
arglist = [
'--user',
- identity_fakes.user_name,
+ self._user.name,
'--project',
- identity_fakes.project_name,
+ self._project.name,
]
self.assertRaises(
@@ -707,7 +695,7 @@ class TestKeypairShow(TestKeypair):
)
def test_keypair_show(self):
- self.keypair = compute_fakes.create_one_keypair()
+ self.keypair = sdk_fakes.generate_fake_resource(_keypair.Keypair)
self.compute_sdk_client.find_keypair.return_value = self.keypair
self.data = (
@@ -735,7 +723,7 @@ class TestKeypairShow(TestKeypair):
self.assertEqual(self.data, data)
def test_keypair_show_public(self):
- self.keypair = compute_fakes.create_one_keypair()
+ self.keypair = sdk_fakes.generate_fake_resource(_keypair.Keypair)
self.compute_sdk_client.find_keypair.return_value = self.keypair
arglist = ['--public-key', self.keypair.name]
@@ -751,7 +739,7 @@ class TestKeypairShow(TestKeypair):
def test_keypair_show_with_user(self):
self.set_compute_api_version('2.10')
- self.keypair = compute_fakes.create_one_keypair()
+ self.keypair = sdk_fakes.generate_fake_resource(_keypair.Keypair)
self.compute_sdk_client.find_keypair.return_value = self.keypair
self.data = (
@@ -767,22 +755,22 @@ class TestKeypairShow(TestKeypair):
arglist = [
'--user',
- identity_fakes.user_name,
+ self._user.name,
self.keypair.name,
]
verifylist = [
- ('user', identity_fakes.user_name),
+ ('user', self._user.name),
('name', self.keypair.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- self.users_mock.get.assert_called_with(identity_fakes.user_name)
+ self.users_mock.get.assert_called_with(self._user.name)
self.compute_sdk_client.find_keypair.assert_called_with(
self.keypair.name,
ignore_missing=False,
- user_id=identity_fakes.user_id,
+ user_id=self._user.id,
)
self.assertEqual(self.columns, columns)
@@ -791,14 +779,14 @@ class TestKeypairShow(TestKeypair):
def test_keypair_show_with_user_pre_v210(self):
self.set_compute_api_version('2.9')
- self.keypair = compute_fakes.create_one_keypair()
+ self.keypair = sdk_fakes.generate_fake_resource(_keypair.Keypair)
arglist = [
'--user',
- identity_fakes.user_name,
+ self._user.name,
self.keypair.name,
]
verifylist = [
- ('user', identity_fakes.user_name),
+ ('user', self._user.name),
('name', self.keypair.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/unit/compute/v2/test_server.py b/openstackclient/tests/unit/compute/v2/test_server.py
index a07e333..789daad 100644
--- a/openstackclient/tests/unit/compute/v2/test_server.py
+++ b/openstackclient/tests/unit/compute/v2/test_server.py
@@ -21,7 +21,9 @@ from unittest import mock
import uuid
import iso8601
+from openstack.compute.v2 import server_group as _server_group
from openstack import exceptions as sdk_exceptions
+from openstack.test import fakes as sdk_fakes
from osc_lib.cli import format_columns
from osc_lib import exceptions
from osc_lib import utils as common_utils
@@ -1165,7 +1167,7 @@ class TestServerAddSecurityGroup(compute_fakes.TestComputev2):
self.server.id, ignore_missing=False
)
self.compute_sdk_client.add_security_group_to_server.assert_called_once_with(
- self.server, 'fake_sg'
+ self.server, {'name': 'fake_sg'}
)
mock_find_nova_net_sg.assert_called_once_with(
self.compute_sdk_client, 'fake_sg'
@@ -1186,7 +1188,7 @@ class TestServerAddSecurityGroup(compute_fakes.TestComputev2):
self.server.id, ignore_missing=False
)
self.compute_sdk_client.add_security_group_to_server.assert_called_once_with(
- self.server, 'fake_sg'
+ self.server, {'name': 'fake_sg'}
)
self.assertIsNone(result)
@@ -1375,7 +1377,9 @@ class TestServerCreate(TestServer):
self.assertEqual(self.datalist(), data)
def test_server_create_with_options(self):
- server_group = compute_fakes.create_one_server_group()
+ server_group = sdk_fakes.generate_fake_resource(
+ _server_group.ServerGroup
+ )
self.compute_sdk_client.find_server_group.return_value = server_group
security_group = network_fakes.create_one_security_group()
@@ -1544,6 +1548,60 @@ class TestServerCreate(TestServer):
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist(), data)
+ def test_server_create_with_no_security_group(self):
+ arglist = [
+ '--image',
+ self.image.id,
+ '--flavor',
+ self.flavor.id,
+ '--no-security-group',
+ self.server.name,
+ ]
+ verifylist = [
+ ('image', self.image.id),
+ ('flavor', self.flavor.id),
+ ('key_name', None),
+ ('properties', None),
+ ('security_groups', []),
+ ('hints', {}),
+ ('server_group', None),
+ ('config_drive', False),
+ ('password', None),
+ ('server_name', self.server.name),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.compute_sdk_client.find_flavor.assert_has_calls(
+ [mock.call(self.flavor.id, ignore_missing=False)] * 2
+ )
+ self.network_client.find_security_group.assert_not_called()
+ self.image_client.find_image.assert_called_once_with(
+ self.image.id, ignore_missing=False
+ )
+ self.compute_sdk_client.create_server.assert_called_once_with(
+ name=self.server.name,
+ image_id=self.image.id,
+ flavor_id=self.flavor.id,
+ min_count=1,
+ max_count=1,
+ security_groups=[],
+ networks=[],
+ block_device_mapping=[
+ {
+ 'uuid': self.image.id,
+ 'boot_index': 0,
+ 'source_type': 'image',
+ 'destination_type': 'local',
+ 'delete_on_termination': True,
+ },
+ ],
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist(), data)
+
def test_server_create_with_network(self):
network_net1 = network_fakes.create_one_network()
network_net2 = network_fakes.create_one_network()
@@ -7400,7 +7458,7 @@ class TestServerRemoveSecurityGroup(TestServer):
self.server.id, ignore_missing=False
)
self.compute_sdk_client.remove_security_group_from_server.assert_called_once_with(
- self.server, 'fake_sg'
+ self.server, {'name': 'fake_sg'}
)
mock_find_nova_net_sg.assert_called_once_with(
self.compute_sdk_client, 'fake_sg'
@@ -7421,7 +7479,7 @@ class TestServerRemoveSecurityGroup(TestServer):
self.server.id, ignore_missing=False
)
self.compute_sdk_client.remove_security_group_from_server.assert_called_once_with(
- self.server, 'fake_sg'
+ self.server, {'name': 'fake_sg'}
)
self.assertIsNone(result)
diff --git a/openstackclient/tests/unit/compute/v2/test_server_group.py b/openstackclient/tests/unit/compute/v2/test_server_group.py
index 2bef027..2e34493 100644
--- a/openstackclient/tests/unit/compute/v2/test_server_group.py
+++ b/openstackclient/tests/unit/compute/v2/test_server_group.py
@@ -13,6 +13,8 @@
# under the License.
#
+from openstack.compute.v2 import server_group as _server_group
+from openstack.test import fakes as sdk_fakes
from osc_lib.cli import format_columns
from osc_lib import exceptions
@@ -22,27 +24,31 @@ from openstackclient.tests.unit import utils as tests_utils
class TestServerGroup(compute_fakes.TestComputev2):
- fake_server_group = compute_fakes.create_one_server_group()
-
- columns = (
- 'id',
- 'members',
- 'name',
- 'policy',
- 'project_id',
- 'rules',
- 'user_id',
- )
-
- data = (
- fake_server_group.id,
- format_columns.ListColumn(fake_server_group.member_ids),
- fake_server_group.name,
- fake_server_group.policy,
- fake_server_group.project_id,
- format_columns.DictColumn(fake_server_group.rules),
- fake_server_group.user_id,
- )
+ def setUp(self):
+ super().setUp()
+
+ self.fake_server_group = sdk_fakes.generate_fake_resource(
+ _server_group.ServerGroup
+ )
+
+ self.columns = (
+ 'id',
+ 'members',
+ 'name',
+ 'policy',
+ 'project_id',
+ 'rules',
+ 'user_id',
+ )
+ self.data = (
+ self.fake_server_group.id,
+ format_columns.ListColumn(self.fake_server_group.member_ids),
+ self.fake_server_group.name,
+ self.fake_server_group.policy,
+ self.fake_server_group.project_id,
+ format_columns.DictColumn(self.fake_server_group.rules),
+ self.fake_server_group.user_id,
+ )
class TestServerGroupCreate(TestServerGroup):
@@ -262,82 +268,6 @@ class TestServerGroupDelete(TestServerGroup):
class TestServerGroupList(TestServerGroup):
- list_columns = (
- 'ID',
- 'Name',
- 'Policies',
- )
-
- list_columns_long = (
- 'ID',
- 'Name',
- 'Policies',
- 'Members',
- 'Project Id',
- 'User Id',
- )
-
- list_columns_v264 = (
- 'ID',
- 'Name',
- 'Policy',
- )
-
- list_columns_v264_long = (
- 'ID',
- 'Name',
- 'Policy',
- 'Members',
- 'Project Id',
- 'User Id',
- )
-
- list_data = (
- (
- TestServerGroup.fake_server_group.id,
- TestServerGroup.fake_server_group.name,
- format_columns.ListColumn(
- TestServerGroup.fake_server_group.policies
- ),
- ),
- )
-
- list_data_long = (
- (
- TestServerGroup.fake_server_group.id,
- TestServerGroup.fake_server_group.name,
- format_columns.ListColumn(
- TestServerGroup.fake_server_group.policies
- ),
- format_columns.ListColumn(
- TestServerGroup.fake_server_group.member_ids
- ),
- TestServerGroup.fake_server_group.project_id,
- TestServerGroup.fake_server_group.user_id,
- ),
- )
-
- list_data_v264 = (
- (
- TestServerGroup.fake_server_group.id,
- TestServerGroup.fake_server_group.name,
- TestServerGroup.fake_server_group.policy,
- ),
- )
-
- list_data_v264_long = (
- (
- TestServerGroup.fake_server_group.id,
- TestServerGroup.fake_server_group.name,
- TestServerGroup.fake_server_group.policy,
- format_columns.ListColumn(
- TestServerGroup.fake_server_group.member_ids
- ),
- TestServerGroup.fake_server_group.project_id,
- TestServerGroup.fake_server_group.user_id,
- ),
- )
-
def setUp(self):
super().setUp()
@@ -359,8 +289,21 @@ class TestServerGroupList(TestServerGroup):
self.compute_sdk_client.server_groups.assert_called_once_with()
- self.assertCountEqual(self.list_columns, columns)
- self.assertCountEqual(self.list_data, tuple(data))
+ expected_columns = (
+ 'ID',
+ 'Name',
+ 'Policies',
+ )
+ expected_data = (
+ (
+ self.fake_server_group.id,
+ self.fake_server_group.name,
+ format_columns.ListColumn(self.fake_server_group.policies),
+ ),
+ )
+
+ self.assertCountEqual(expected_columns, columns)
+ self.assertCountEqual(expected_data, tuple(data))
def test_server_group_list_with_all_projects_and_long(self):
arglist = [
@@ -379,8 +322,27 @@ class TestServerGroupList(TestServerGroup):
all_projects=True
)
- self.assertCountEqual(self.list_columns_long, columns)
- self.assertCountEqual(self.list_data_long, tuple(data))
+ expected_columns = (
+ 'ID',
+ 'Name',
+ 'Policies',
+ 'Members',
+ 'Project Id',
+ 'User Id',
+ )
+ expected_data = (
+ (
+ self.fake_server_group.id,
+ self.fake_server_group.name,
+ format_columns.ListColumn(self.fake_server_group.policies),
+ format_columns.ListColumn(self.fake_server_group.member_ids),
+ self.fake_server_group.project_id,
+ self.fake_server_group.user_id,
+ ),
+ )
+
+ self.assertCountEqual(expected_columns, columns)
+ self.assertCountEqual(expected_data, tuple(data))
def test_server_group_list_with_limit(self):
arglist = [
@@ -428,8 +390,21 @@ class TestServerGroupList(TestServerGroup):
columns, data = self.cmd.take_action(parsed_args)
self.compute_sdk_client.server_groups.assert_called_once_with()
- self.assertCountEqual(self.list_columns_v264, columns)
- self.assertCountEqual(self.list_data_v264, tuple(data))
+ expected_columns = (
+ 'ID',
+ 'Name',
+ 'Policy',
+ )
+ expected_data = (
+ (
+ self.fake_server_group.id,
+ self.fake_server_group.name,
+ self.fake_server_group.policy,
+ ),
+ )
+
+ self.assertCountEqual(expected_columns, columns)
+ self.assertCountEqual(expected_data, tuple(data))
def test_server_group_list_with_all_projects_and_long_v264(self):
self.set_compute_api_version('2.64')
@@ -448,8 +423,27 @@ class TestServerGroupList(TestServerGroup):
all_projects=True
)
- self.assertCountEqual(self.list_columns_v264_long, columns)
- self.assertCountEqual(self.list_data_v264_long, tuple(data))
+ expected_columns = (
+ 'ID',
+ 'Name',
+ 'Policy',
+ 'Members',
+ 'Project Id',
+ 'User Id',
+ )
+ expected_data = (
+ (
+ self.fake_server_group.id,
+ self.fake_server_group.name,
+ self.fake_server_group.policy,
+ format_columns.ListColumn(self.fake_server_group.member_ids),
+ self.fake_server_group.project_id,
+ self.fake_server_group.user_id,
+ ),
+ )
+
+ self.assertCountEqual(expected_columns, columns)
+ self.assertCountEqual(expected_data, tuple(data))
class TestServerGroupShow(TestServerGroup):
diff --git a/openstackclient/tests/unit/compute/v2/test_server_volume.py b/openstackclient/tests/unit/compute/v2/test_server_volume.py
index e598532..d42da95 100644
--- a/openstackclient/tests/unit/compute/v2/test_server_volume.py
+++ b/openstackclient/tests/unit/compute/v2/test_server_volume.py
@@ -10,19 +10,26 @@
# License for the specific language governing permissions and limitations
# under the License.
+from openstack.block_storage.v3 import volume as _volume
+from openstack.compute.v2 import server as _server
+from openstack.compute.v2 import volume_attachment as _volume_attachment
+from openstack.test import fakes as sdk_fakes
from osc_lib import exceptions
from openstackclient.compute.v2 import server_volume
from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
-from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
class TestServerVolumeList(compute_fakes.TestComputev2):
def setUp(self):
super().setUp()
- self.server = compute_fakes.create_one_sdk_server()
- self.volume_attachments = compute_fakes.create_volume_attachments()
+ self.server = sdk_fakes.generate_fake_resource(_server.Server)
+ self.volume_attachments = list(
+ sdk_fakes.generate_fake_resources(
+ _volume_attachment.VolumeAttachment, count=2
+ )
+ )
self.compute_sdk_client.find_server.return_value = self.server
self.compute_sdk_client.volume_attachments.return_value = (
@@ -217,10 +224,10 @@ class TestServerVolumeUpdate(compute_fakes.TestComputev2):
def setUp(self):
super().setUp()
- self.server = compute_fakes.create_one_sdk_server()
+ self.server = sdk_fakes.generate_fake_resource(_server.Server)
self.compute_sdk_client.find_server.return_value = self.server
- self.volume = volume_fakes.create_one_sdk_volume()
+ self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
self.volume_sdk_client.find_volume.return_value = self.volume
# Get the command object to test
diff --git a/openstackclient/tests/unit/compute/v2/test_service.py b/openstackclient/tests/unit/compute/v2/test_service.py
index 2997fec..ce7791d 100644
--- a/openstackclient/tests/unit/compute/v2/test_service.py
+++ b/openstackclient/tests/unit/compute/v2/test_service.py
@@ -14,6 +14,8 @@
from unittest import mock
+from openstack.compute.v2 import service as _service
+from openstack.test import fakes as sdk_fakes
from osc_lib import exceptions
from openstackclient.compute.v2 import service
@@ -21,11 +23,13 @@ from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
class TestServiceDelete(compute_fakes.TestComputev2):
- services = compute_fakes.create_services(count=2)
-
def setUp(self):
super().setUp()
+ self.services = list(
+ sdk_fakes.generate_fake_resources(_service.Service, count=2)
+ )
+
self.compute_sdk_client.delete_service.return_value = None
# Get the command object to test
@@ -94,35 +98,11 @@ class TestServiceDelete(compute_fakes.TestComputev2):
class TestServiceList(compute_fakes.TestComputev2):
- service = compute_fakes.create_one_service()
-
- columns = (
- 'ID',
- 'Binary',
- 'Host',
- 'Zone',
- 'Status',
- 'State',
- 'Updated At',
- )
- columns_long = columns + ('Disabled Reason',)
-
- data = [
- (
- service.id,
- service.binary,
- service.host,
- service.availability_zone,
- service.status,
- service.state,
- service.updated_at,
- )
- ]
- data_long = [data[0] + (service.disabled_reason,)]
-
def setUp(self):
super().setUp()
+ self.service = sdk_fakes.generate_fake_resource(_service.Service)
+
self.compute_sdk_client.services.return_value = [self.service]
# Get the command object to test
@@ -151,8 +131,29 @@ class TestServiceList(compute_fakes.TestComputev2):
binary=self.service.binary,
)
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, list(data))
+ expected_columns = (
+ 'ID',
+ 'Binary',
+ 'Host',
+ 'Zone',
+ 'Status',
+ 'State',
+ 'Updated At',
+ )
+ expected_data = [
+ (
+ self.service.id,
+ self.service.binary,
+ self.service.host,
+ self.service.availability_zone,
+ self.service.status,
+ self.service.state,
+ self.service.updated_at,
+ )
+ ]
+
+ self.assertEqual(expected_columns, columns)
+ self.assertEqual(expected_data, list(data))
def test_service_list_with_long_option(self):
arglist = [
@@ -179,8 +180,31 @@ class TestServiceList(compute_fakes.TestComputev2):
binary=self.service.binary,
)
- self.assertEqual(self.columns_long, columns)
- self.assertEqual(self.data_long, list(data))
+ expected_columns = (
+ 'ID',
+ 'Binary',
+ 'Host',
+ 'Zone',
+ 'Status',
+ 'State',
+ 'Updated At',
+ 'Disabled Reason',
+ )
+ expected_data = [
+ (
+ self.service.id,
+ self.service.binary,
+ self.service.host,
+ self.service.availability_zone,
+ self.service.status,
+ self.service.state,
+ self.service.updated_at,
+ self.service.disabled_reason,
+ )
+ ]
+
+ self.assertEqual(expected_columns, columns)
+ self.assertEqual(expected_data, list(data))
def test_service_list_with_long_option_2_11(self):
self.set_compute_api_version('2.11')
@@ -210,18 +234,40 @@ class TestServiceList(compute_fakes.TestComputev2):
)
# In 2.11 there is also a forced_down column.
- columns_long = self.columns_long + ('Forced Down',)
- data_long = [self.data_long[0] + (self.service.is_forced_down,)]
+ expected_columns = (
+ 'ID',
+ 'Binary',
+ 'Host',
+ 'Zone',
+ 'Status',
+ 'State',
+ 'Updated At',
+ 'Disabled Reason',
+ 'Forced Down',
+ )
+ expected_data = [
+ (
+ self.service.id,
+ self.service.binary,
+ self.service.host,
+ self.service.availability_zone,
+ self.service.status,
+ self.service.state,
+ self.service.updated_at,
+ self.service.disabled_reason,
+ self.service.is_forced_down,
+ )
+ ]
- self.assertEqual(columns_long, columns)
- self.assertEqual(data_long, list(data))
+ self.assertEqual(expected_columns, columns)
+ self.assertEqual(expected_data, list(data))
class TestServiceSet(compute_fakes.TestComputev2):
def setUp(self):
super().setUp()
- self.service = compute_fakes.create_one_service()
+ self.service = sdk_fakes.generate_fake_resource(_service.Service)
self.compute_sdk_client.enable_service.return_value = self.service
self.compute_sdk_client.disable_service.return_value = self.service
diff --git a/openstackclient/tests/unit/compute/v2/test_usage.py b/openstackclient/tests/unit/compute/v2/test_usage.py
index 2efd25b..346e2fb 100644
--- a/openstackclient/tests/unit/compute/v2/test_usage.py
+++ b/openstackclient/tests/unit/compute/v2/test_usage.py
@@ -14,9 +14,12 @@
import datetime
from unittest import mock
+from openstack.compute.v2 import usage as _usage
+from openstack.identity.v3 import project as _project
+from openstack.test import fakes as sdk_fakes
+
from openstackclient.compute.v2 import usage as usage_cmds
from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
-from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
class TestUsage(compute_fakes.TestComputev2):
@@ -28,11 +31,11 @@ class TestUsage(compute_fakes.TestComputev2):
class TestUsageList(TestUsage):
- project = identity_fakes.FakeProject.create_one_project()
+ project = sdk_fakes.generate_fake_resource(_project.Project)
# Return value of self.usage_mock.list().
- usages = compute_fakes.create_usages(
- attrs={'project_id': project.name}, count=1
- )
+ usages = [
+ sdk_fakes.generate_fake_resource(_usage.Usage, project_id=project.name)
+ ]
columns = (
"Project",
@@ -123,9 +126,11 @@ class TestUsageList(TestUsage):
class TestUsageShow(TestUsage):
- project = identity_fakes.FakeProject.create_one_project()
+ project = sdk_fakes.generate_fake_resource(_project.Project)
# Return value of self.usage_mock.list().
- usage = compute_fakes.create_one_usage(attrs={'project_id': project.name})
+ usage = sdk_fakes.generate_fake_resource(
+ _usage.Usage, project_id=project.name
+ )
columns = (
'Project',
diff --git a/openstackclient/tests/unit/identity/v2_0/test_catalog.py b/openstackclient/tests/unit/identity/v2_0/test_catalog.py
index 63b3d47..ef8b1cf 100644
--- a/openstackclient/tests/unit/identity/v2_0/test_catalog.py
+++ b/openstackclient/tests/unit/identity/v2_0/test_catalog.py
@@ -53,8 +53,7 @@ class TestCatalogList(TestCatalog):
identity_fakes.TOKEN,
fake_service=self.service_catalog,
)
- self.ar_mock = mock.PropertyMock(return_value=auth_ref)
- type(self.app.client_manager).auth_ref = self.ar_mock
+ self.app.client_manager.auth_ref = auth_ref
arglist = []
verifylist = []
@@ -99,8 +98,7 @@ class TestCatalogList(TestCatalog):
identity_fakes.TOKEN,
fake_service=service_catalog,
)
- self.ar_mock = mock.PropertyMock(return_value=auth_ref)
- type(self.app.client_manager).auth_ref = self.ar_mock
+ self.app.client_manager.auth_ref = auth_ref
arglist = []
verifylist = []
@@ -136,8 +134,7 @@ class TestCatalogShow(TestCatalog):
identity_fakes.UNSCOPED_TOKEN,
fake_service=self.service_catalog,
)
- self.ar_mock = mock.PropertyMock(return_value=auth_ref)
- type(self.app.client_manager).auth_ref = self.ar_mock
+ self.app.client_manager.auth_ref = auth_ref
arglist = [
'compute',
diff --git a/openstackclient/tests/unit/identity/v2_0/test_role.py b/openstackclient/tests/unit/identity/v2_0/test_role.py
index 830653b..117d2f0 100644
--- a/openstackclient/tests/unit/identity/v2_0/test_role.py
+++ b/openstackclient/tests/unit/identity/v2_0/test_role.py
@@ -58,8 +58,7 @@ class TestRole(identity_fakes.TestIdentityv2):
identity_fakes.TOKEN,
fake_service=self.fake_service,
)
- self.ar_mock = mock.PropertyMock(return_value=auth_ref)
- type(self.app.client_manager).auth_ref = self.ar_mock
+ self.app.client_manager.auth_ref = auth_ref
class TestRoleAdd(TestRole):
diff --git a/openstackclient/tests/unit/identity/v2_0/test_role_assignment.py b/openstackclient/tests/unit/identity/v2_0/test_role_assignment.py
index a06c270..741b3ee 100644
--- a/openstackclient/tests/unit/identity/v2_0/test_role_assignment.py
+++ b/openstackclient/tests/unit/identity/v2_0/test_role_assignment.py
@@ -169,7 +169,8 @@ class TestRoleAssignmentList(TestRoleAssignment):
self.assertEqual(datalist, tuple(data))
def test_role_assignment_list_def_creds(self):
- auth_ref = self.app.client_manager.auth_ref = mock.Mock()
+ self.app.client_manager.auth_ref = mock.Mock()
+ auth_ref = self.app.client_manager.auth_ref
auth_ref.project_id.return_value = identity_fakes.project_id
auth_ref.user_id.return_value = identity_fakes.user_id
diff --git a/openstackclient/tests/unit/identity/v2_0/test_token.py b/openstackclient/tests/unit/identity/v2_0/test_token.py
index 1e90104..56a5a2c 100644
--- a/openstackclient/tests/unit/identity/v2_0/test_token.py
+++ b/openstackclient/tests/unit/identity/v2_0/test_token.py
@@ -11,29 +11,17 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
-#
-
-from unittest import mock
from openstackclient.identity.v2_0 import token
from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes
-class TestToken(identity_fakes.TestIdentityv2):
- fake_user = identity_fakes.FakeUser.create_one_user()
- fake_project = identity_fakes.FakeProject.create_one_project()
-
+class TestTokenIssue(identity_fakes.TestIdentityv2):
def setUp(self):
super().setUp()
- # Get a shortcut to the Auth Ref Mock
- self.ar_mock = mock.PropertyMock()
- type(self.app.client_manager).auth_ref = self.ar_mock
-
-
-class TestTokenIssue(TestToken):
- def setUp(self):
- super().setUp()
+ self.fake_user = identity_fakes.FakeUser.create_one_user()
+ self.fake_project = identity_fakes.FakeProject.create_one_project()
self.cmd = token.IssueToken(self.app, None)
@@ -41,8 +29,7 @@ class TestTokenIssue(TestToken):
auth_ref = identity_fakes.fake_auth_ref(
identity_fakes.TOKEN,
)
- self.ar_mock = mock.PropertyMock(return_value=auth_ref)
- type(self.app.client_manager).auth_ref = self.ar_mock
+ self.app.client_manager.auth_ref = auth_ref
arglist = []
verifylist = []
@@ -67,8 +54,7 @@ class TestTokenIssue(TestToken):
auth_ref = identity_fakes.fake_auth_ref(
identity_fakes.UNSCOPED_TOKEN,
)
- self.ar_mock = mock.PropertyMock(return_value=auth_ref)
- type(self.app.client_manager).auth_ref = self.ar_mock
+ self.app.client_manager.auth_ref = auth_ref
arglist = []
verifylist = []
@@ -91,7 +77,7 @@ class TestTokenIssue(TestToken):
self.assertEqual(datalist, data)
-class TestTokenRevoke(TestToken):
+class TestTokenRevoke(identity_fakes.TestIdentityv2):
TOKEN = 'fob'
def setUp(self):
diff --git a/openstackclient/tests/unit/identity/v3/test_catalog.py b/openstackclient/tests/unit/identity/v3/test_catalog.py
index ed2db3b..df292b1 100644
--- a/openstackclient/tests/unit/identity/v3/test_catalog.py
+++ b/openstackclient/tests/unit/identity/v3/test_catalog.py
@@ -9,7 +9,6 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
-#
from unittest import mock
@@ -72,8 +71,7 @@ class TestCatalogList(TestCatalog):
identity_fakes.TOKEN_WITH_PROJECT_ID,
fake_service=self.fake_service,
)
- self.ar_mock = mock.PropertyMock(return_value=auth_ref)
- type(self.app.client_manager).auth_ref = self.ar_mock
+ self.app.client_manager.auth_ref = auth_ref
arglist = []
verifylist = []
@@ -110,8 +108,7 @@ class TestCatalogShow(TestCatalog):
identity_fakes.TOKEN_WITH_PROJECT_ID,
fake_service=self.fake_service,
)
- self.ar_mock = mock.PropertyMock(return_value=auth_ref)
- type(self.app.client_manager).auth_ref = self.ar_mock
+ self.app.client_manager.auth_ref = auth_ref
arglist = [
'compute',
diff --git a/openstackclient/tests/unit/identity/v3/test_credential.py b/openstackclient/tests/unit/identity/v3/test_credential.py
index 794f40b..f21fd71 100644
--- a/openstackclient/tests/unit/identity/v3/test_credential.py
+++ b/openstackclient/tests/unit/identity/v3/test_credential.py
@@ -10,9 +10,13 @@
# License for the specific language governing permissions and limitations
# under the License.
-from unittest import mock
from unittest.mock import call
+from openstack import exceptions as sdk_exceptions
+from openstack.identity.v3 import credential as _credential
+from openstack.identity.v3 import project as _project
+from openstack.identity.v3 import user as _user
+from openstack.test import fakes as sdk_fakes
from osc_lib import exceptions
from openstackclient.identity.v3 import credential
@@ -20,26 +24,9 @@ from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
from openstackclient.tests.unit import utils
-class TestCredential(identity_fakes.TestIdentityv3):
- def setUp(self):
- super().setUp()
-
- # Get a shortcut to the CredentialManager Mock
- self.credentials_mock = self.identity_client.credentials
- self.credentials_mock.reset_mock()
-
- # Get a shortcut to the UserManager Mock
- self.users_mock = self.identity_client.users
- self.users_mock.reset_mock()
-
- # Get a shortcut to the ProjectManager Mock
- self.projects_mock = self.identity_client.projects
- self.projects_mock.reset_mock()
-
-
-class TestCredentialCreate(TestCredential):
- user = identity_fakes.FakeUser.create_one_user()
- project = identity_fakes.FakeProject.create_one_project()
+class TestCredentialCreate(identity_fakes.TestIdentityv3):
+ user = sdk_fakes.generate_fake_resource(_user.User)
+ project = sdk_fakes.generate_fake_resource(_project.Project)
columns = (
'blob',
'id',
@@ -51,12 +38,17 @@ class TestCredentialCreate(TestCredential):
def setUp(self):
super().setUp()
- self.credential = identity_fakes.FakeCredential.create_one_credential(
- attrs={'user_id': self.user.id, 'project_id': self.project.id}
+ self.credential = sdk_fakes.generate_fake_resource(
+ resource_type=_credential.Credential,
+ user_id=self.user.id,
+ project_id=self.project.id,
+ type='cert',
)
- self.credentials_mock.create.return_value = self.credential
- self.users_mock.get.return_value = self.user
- self.projects_mock.get.return_value = self.project
+ self.identity_sdk_client.create_credential.return_value = (
+ self.credential
+ )
+ self.identity_sdk_client.find_user.return_value = self.user
+ self.identity_sdk_client.find_project.return_value = self.project
self.data = (
self.credential.blob,
self.credential.id,
@@ -81,12 +73,14 @@ class TestCredentialCreate(TestCredential):
columns, data = self.cmd.take_action(parsed_args)
kwargs = {
- 'user': self.credential.user_id,
+ 'user_id': self.credential.user_id,
'type': self.credential.type,
'blob': self.credential.blob,
- 'project': None,
+ 'project_id': None,
}
- self.credentials_mock.create.assert_called_once_with(**kwargs)
+ self.identity_sdk_client.create_credential.assert_called_once_with(
+ **kwargs
+ )
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
@@ -111,47 +105,53 @@ class TestCredentialCreate(TestCredential):
columns, data = self.cmd.take_action(parsed_args)
kwargs = {
- 'user': self.credential.user_id,
+ 'user_id': self.credential.user_id,
'type': self.credential.type,
'blob': self.credential.blob,
- 'project': self.credential.project_id,
+ 'project_id': self.credential.project_id,
}
- self.credentials_mock.create.assert_called_once_with(**kwargs)
+ self.identity_sdk_client.create_credential.assert_called_once_with(
+ **kwargs
+ )
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
-class TestCredentialDelete(TestCredential):
- credentials = identity_fakes.FakeCredential.create_credentials(count=2)
-
+class TestCredentialDelete(identity_fakes.TestIdentityv3):
def setUp(self):
super().setUp()
- self.credentials_mock.delete.return_value = None
+ self.identity_sdk_client.delete_credential.return_value = None
# Get the command object to test
self.cmd = credential.DeleteCredential(self.app, None)
def test_credential_delete(self):
+ credential = sdk_fakes.generate_fake_resource(
+ _credential.Credential,
+ )
arglist = [
- self.credentials[0].id,
+ credential.id,
]
verifylist = [
- ('credential', [self.credentials[0].id]),
+ ('credential', [credential.id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
- self.credentials_mock.delete.assert_called_with(
- self.credentials[0].id,
+ self.identity_sdk_client.delete_credential.assert_called_with(
+ credential.id,
)
self.assertIsNone(result)
def test_credential_multi_delete(self):
+ credentials = sdk_fakes.generate_fake_resources(
+ _credential.Credential, count=2
+ )
arglist = []
- for c in self.credentials:
+ for c in credentials:
arglist.append(c.id)
verifylist = [
('credential', arglist),
@@ -161,25 +161,26 @@ class TestCredentialDelete(TestCredential):
result = self.cmd.take_action(parsed_args)
calls = []
- for c in self.credentials:
+ for c in credentials:
calls.append(call(c.id))
- self.credentials_mock.delete.assert_has_calls(calls)
+ self.identity_sdk_client.delete_credential.assert_has_calls(calls)
self.assertIsNone(result)
def test_credential_multi_delete_with_exception(self):
+ credential = sdk_fakes.generate_fake_resource(
+ _credential.Credential,
+ )
arglist = [
- self.credentials[0].id,
+ credential.id,
'unexist_credential',
]
- verifylist = [
- ('credential', [self.credentials[0].id, 'unexist_credential'])
- ]
+ verifylist = [('credential', [credential.id, 'unexist_credential'])]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- delete_mock_result = [None, exceptions.CommandError]
- self.credentials_mock.delete = mock.Mock(
- side_effect=delete_mock_result
- )
+ self.identity_sdk_client.delete_credential.side_effect = [
+ None,
+ sdk_exceptions.NotFoundException,
+ ]
try:
self.cmd.take_action(parsed_args)
@@ -187,12 +188,16 @@ class TestCredentialDelete(TestCredential):
except exceptions.CommandError as e:
self.assertEqual('1 of 2 credential failed to delete.', str(e))
- self.credentials_mock.delete.assert_any_call(self.credentials[0].id)
- self.credentials_mock.delete.assert_any_call('unexist_credential')
+ self.identity_sdk_client.delete_credential.assert_any_call(
+ credential.id
+ )
+ self.identity_sdk_client.delete_credential.assert_any_call(
+ 'unexist_credential'
+ )
-class TestCredentialList(TestCredential):
- credential = identity_fakes.FakeCredential.create_one_credential()
+class TestCredentialList(identity_fakes.TestIdentityv3):
+ credential = sdk_fakes.generate_fake_resource(_credential.Credential)
columns = ('ID', 'Type', 'User ID', 'Data', 'Project ID')
data = (
@@ -208,10 +213,10 @@ class TestCredentialList(TestCredential):
def setUp(self):
super().setUp()
- self.user = identity_fakes.FakeUser.create_one_user()
- self.users_mock.get.return_value = self.user
+ self.user = sdk_fakes.generate_fake_resource(_user.User)
+ self.identity_sdk_client.find_user.return_value = self.user
- self.credentials_mock.list.return_value = [self.credential]
+ self.identity_sdk_client.credentials.return_value = [self.credential]
# Get the command object to test
self.cmd = credential.ListCredential(self.app, None)
@@ -223,7 +228,7 @@ class TestCredentialList(TestCredential):
columns, data = self.cmd.take_action(parsed_args)
- self.credentials_mock.list.assert_called_with()
+ self.identity_sdk_client.credentials.assert_called_with()
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, tuple(data))
@@ -246,15 +251,17 @@ class TestCredentialList(TestCredential):
'user_id': self.user.id,
'type': self.credential.type,
}
- self.users_mock.get.assert_called_with(self.credential.user_id)
- self.credentials_mock.list.assert_called_with(**kwargs)
+ self.identity_sdk_client.find_user.assert_called_with(
+ self.credential.user_id, domain_id=None, ignore_missing=False
+ )
+ self.identity_sdk_client.credentials.assert_called_with(**kwargs)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, tuple(data))
-class TestCredentialSet(TestCredential):
- credential = identity_fakes.FakeCredential.create_one_credential()
+class TestCredentialSet(identity_fakes.TestIdentityv3):
+ credential = sdk_fakes.generate_fake_resource(_credential.Credential)
def setUp(self):
super().setUp()
@@ -343,7 +350,7 @@ class TestCredentialSet(TestCredential):
self.assertIsNone(result)
-class TestCredentialShow(TestCredential):
+class TestCredentialShow(identity_fakes.TestIdentityv3):
columns = (
'blob',
'id',
@@ -355,8 +362,10 @@ class TestCredentialShow(TestCredential):
def setUp(self):
super().setUp()
- self.credential = identity_fakes.FakeCredential.create_one_credential()
- self.credentials_mock.get.return_value = self.credential
+ self.credential = sdk_fakes.generate_fake_resource(
+ _credential.Credential
+ )
+ self.identity_sdk_client.get_credential.return_value = self.credential
self.data = (
self.credential.blob,
self.credential.id,
@@ -378,6 +387,8 @@ class TestCredentialShow(TestCredential):
columns, data = self.cmd.take_action(parsed_args)
- self.credentials_mock.get.assert_called_once_with(self.credential.id)
+ self.identity_sdk_client.get_credential.assert_called_once_with(
+ self.credential.id
+ )
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
diff --git a/openstackclient/tests/unit/identity/v3/test_project.py b/openstackclient/tests/unit/identity/v3/test_project.py
index 9b7fc8c..9085498 100644
--- a/openstackclient/tests/unit/identity/v3/test_project.py
+++ b/openstackclient/tests/unit/identity/v3/test_project.py
@@ -11,7 +11,6 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
-#
from unittest import mock
from unittest.mock import call
@@ -914,8 +913,7 @@ class TestProjectList(TestProject):
auth_ref = identity_fakes.fake_auth_ref(
identity_fakes.TOKEN_WITH_PROJECT_ID,
)
- ar_mock = mock.PropertyMock(return_value=auth_ref)
- type(self.app.client_manager).auth_ref = ar_mock
+ self.app.client_manager.auth_ref = auth_ref
arglist = [
'--my-projects',
diff --git a/openstackclient/tests/unit/identity/v3/test_region.py b/openstackclient/tests/unit/identity/v3/test_region.py
index 9b66c3c..eecb079 100644
--- a/openstackclient/tests/unit/identity/v3/test_region.py
+++ b/openstackclient/tests/unit/identity/v3/test_region.py
@@ -11,55 +11,44 @@
# under the License.
#
-import copy
+
+from openstack.identity.v3 import region as _region
+from openstack.test import fakes as sdk_fakes
from openstackclient.identity.v3 import region
-from openstackclient.tests.unit import fakes
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
-class TestRegion(identity_fakes.TestIdentityv3):
- def setUp(self):
- super().setUp()
-
- # Get a shortcut to the RegionManager Mock
- self.regions_mock = self.identity_client.regions
- self.regions_mock.reset_mock()
-
-
-class TestRegionCreate(TestRegion):
+class TestRegionCreate(identity_fakes.TestIdentityv3):
+ region = sdk_fakes.generate_fake_resource(_region.Region)
columns = (
+ 'region',
'description',
'parent_region',
- 'region',
)
datalist = (
- identity_fakes.region_description,
- identity_fakes.region_parent_region_id,
- identity_fakes.region_id,
+ region.id,
+ region.description,
+ region.parent_region_id,
)
def setUp(self):
super().setUp()
- self.regions_mock.create.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.REGION),
- loaded=True,
- )
+ self.identity_sdk_client.create_region.return_value = self.region
# Get the command object to test
self.cmd = region.CreateRegion(self.app, None)
def test_region_create_description(self):
arglist = [
- identity_fakes.region_id,
+ self.region.id,
'--description',
- identity_fakes.region_description,
+ self.region.description,
]
verifylist = [
- ('region', identity_fakes.region_id),
- ('description', identity_fakes.region_description),
+ ('region', self.region.id),
+ ('description', self.region.description),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -70,21 +59,21 @@ class TestRegionCreate(TestRegion):
# Set expected values
kwargs = {
- 'description': identity_fakes.region_description,
- 'id': identity_fakes.region_id,
- 'parent_region': None,
+ 'description': self.region.description,
+ 'id': self.region.id,
+ 'parent_region_id': None,
}
- self.regions_mock.create.assert_called_with(**kwargs)
+ self.identity_sdk_client.create_region.assert_called_with(**kwargs)
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, data)
def test_region_create_no_options(self):
arglist = [
- identity_fakes.region_id,
+ self.region.id,
]
verifylist = [
- ('region', identity_fakes.region_id),
+ ('region', self.region.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -96,23 +85,23 @@ class TestRegionCreate(TestRegion):
# Set expected values
kwargs = {
'description': None,
- 'id': identity_fakes.region_id,
- 'parent_region': None,
+ 'id': self.region.id,
+ 'parent_region_id': None,
}
- self.regions_mock.create.assert_called_with(**kwargs)
+ self.identity_sdk_client.create_region.assert_called_with(**kwargs)
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, data)
def test_region_create_parent_region_id(self):
arglist = [
- identity_fakes.region_id,
+ self.region.id,
'--parent-region',
- identity_fakes.region_parent_region_id,
+ self.region.parent_region_id,
]
verifylist = [
- ('region', identity_fakes.region_id),
- ('parent_region', identity_fakes.region_parent_region_id),
+ ('region', self.region.id),
+ ('parent_region', self.region.parent_region_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -124,41 +113,43 @@ class TestRegionCreate(TestRegion):
# Set expected values
kwargs = {
'description': None,
- 'id': identity_fakes.region_id,
- 'parent_region': identity_fakes.region_parent_region_id,
+ 'id': self.region.id,
+ 'parent_region_id': self.region.parent_region_id,
}
- self.regions_mock.create.assert_called_with(**kwargs)
+ self.identity_sdk_client.create_region.assert_called_with(**kwargs)
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, data)
-class TestRegionDelete(TestRegion):
+class TestRegionDelete(identity_fakes.TestIdentityv3):
def setUp(self):
super().setUp()
- self.regions_mock.delete.return_value = None
+ self.region = sdk_fakes.generate_fake_resource(_region.Region)
+ self.identity_sdk_client.delete_region.return_value = None
# Get the command object to test
self.cmd = region.DeleteRegion(self.app, None)
def test_region_delete_no_options(self):
arglist = [
- identity_fakes.region_id,
+ self.region.id,
]
verifylist = [
- ('region', [identity_fakes.region_id]),
+ ('region', [self.region.id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
- self.regions_mock.delete.assert_called_with(
- identity_fakes.region_id,
+ self.identity_sdk_client.delete_region.assert_called_with(
+ self.region.id,
)
self.assertIsNone(result)
-class TestRegionList(TestRegion):
+class TestRegionList(identity_fakes.TestIdentityv3):
+ region = sdk_fakes.generate_fake_resource(_region.Region)
columns = (
'Region',
'Parent Region',
@@ -166,22 +157,16 @@ class TestRegionList(TestRegion):
)
datalist = (
(
- identity_fakes.region_id,
- identity_fakes.region_parent_region_id,
- identity_fakes.region_description,
+ region.id,
+ region.parent_region_id,
+ region.description,
),
)
def setUp(self):
super().setUp()
- self.regions_mock.list.return_value = [
- fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.REGION),
- loaded=True,
- ),
- ]
+ self.identity_sdk_client.regions.return_value = [self.region]
# Get the command object to test
self.cmd = region.ListRegion(self.app, None)
@@ -195,7 +180,7 @@ class TestRegionList(TestRegion):
# returns a tuple containing the column names and an iterable
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
- self.regions_mock.list.assert_called_with()
+ self.identity_sdk_client.regions.assert_called_with()
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, tuple(data))
@@ -203,10 +188,10 @@ class TestRegionList(TestRegion):
def test_region_list_parent_region_id(self):
arglist = [
'--parent-region',
- identity_fakes.region_parent_region_id,
+ self.region.parent_region_id,
]
verifylist = [
- ('parent_region', identity_fakes.region_parent_region_id),
+ ('parent_region', self.region.parent_region_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -214,41 +199,37 @@ class TestRegionList(TestRegion):
# returns a tuple containing the column names and an iterable
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
- self.regions_mock.list.assert_called_with(
- parent_region_id=identity_fakes.region_parent_region_id
+ self.identity_sdk_client.regions.assert_called_with(
+ parent_region_id=self.region.parent_region_id
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, tuple(data))
-class TestRegionSet(TestRegion):
+class TestRegionSet(identity_fakes.TestIdentityv3):
def setUp(self):
super().setUp()
- self.regions_mock.update.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.REGION),
- loaded=True,
- )
+ self.region = sdk_fakes.generate_fake_resource(_region.Region)
# Get the command object to test
self.cmd = region.SetRegion(self.app, None)
def test_region_set_no_options(self):
arglist = [
- identity_fakes.region_id,
+ self.region.id,
]
verifylist = [
- ('region', identity_fakes.region_id),
+ ('region', self.region.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
kwargs = {}
- self.regions_mock.update.assert_called_with(
- identity_fakes.region_id, **kwargs
+ self.identity_sdk_client.update_region.assert_called_with(
+ self.region.id, **kwargs
)
self.assertIsNone(result)
@@ -256,11 +237,11 @@ class TestRegionSet(TestRegion):
arglist = [
'--description',
'qwerty',
- identity_fakes.region_id,
+ self.region.id,
]
verifylist = [
('description', 'qwerty'),
- ('region', identity_fakes.region_id),
+ ('region', self.region.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -270,8 +251,8 @@ class TestRegionSet(TestRegion):
kwargs = {
'description': 'qwerty',
}
- self.regions_mock.update.assert_called_with(
- identity_fakes.region_id, **kwargs
+ self.identity_sdk_client.update_region.assert_called_with(
+ self.region.id, **kwargs
)
self.assertIsNone(result)
@@ -279,11 +260,11 @@ class TestRegionSet(TestRegion):
arglist = [
'--parent-region',
'new_parent',
- identity_fakes.region_id,
+ self.region.id,
]
verifylist = [
('parent_region', 'new_parent'),
- ('region', identity_fakes.region_id),
+ ('region', self.region.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -291,33 +272,30 @@ class TestRegionSet(TestRegion):
# Set expected values
kwargs = {
- 'parent_region': 'new_parent',
+ 'parent_region_id': 'new_parent',
}
- self.regions_mock.update.assert_called_with(
- identity_fakes.region_id, **kwargs
+ self.identity_sdk_client.update_region.assert_called_with(
+ self.region.id, **kwargs
)
self.assertIsNone(result)
-class TestRegionShow(TestRegion):
+class TestRegionShow(identity_fakes.TestIdentityv3):
def setUp(self):
super().setUp()
- self.regions_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.REGION),
- loaded=True,
- )
+ self.region = sdk_fakes.generate_fake_resource(_region.Region)
+ self.identity_sdk_client.get_region.return_value = self.region
# Get the command object to test
self.cmd = region.ShowRegion(self.app, None)
def test_region_show(self):
arglist = [
- identity_fakes.region_id,
+ self.region.id,
]
verifylist = [
- ('region', identity_fakes.region_id),
+ ('region', self.region.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -325,15 +303,15 @@ class TestRegionShow(TestRegion):
# 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)
- self.regions_mock.get.assert_called_with(
- identity_fakes.region_id,
+ self.identity_sdk_client.get_region.assert_called_with(
+ self.region.id,
)
- collist = ('description', 'parent_region', 'region')
+ collist = ('region', 'description', 'parent_region')
self.assertEqual(collist, columns)
datalist = (
- identity_fakes.region_description,
- identity_fakes.region_parent_region_id,
- identity_fakes.region_id,
+ self.region.id,
+ self.region.description,
+ self.region.parent_region_id,
)
self.assertEqual(datalist, data)
diff --git a/openstackclient/tests/unit/identity/v3/test_role.py b/openstackclient/tests/unit/identity/v3/test_role.py
index 09b7536..e4a27ed 100644
--- a/openstackclient/tests/unit/identity/v3/test_role.py
+++ b/openstackclient/tests/unit/identity/v3/test_role.py
@@ -13,110 +13,177 @@
# under the License.
#
-import copy
from unittest import mock
from osc_lib import exceptions
-from osc_lib import utils
-from openstackclient.identity import common
+from openstack import exceptions as sdk_exc
+from openstack.identity.v3 import domain as _domain
+from openstack.identity.v3 import group as _group
+from openstack.identity.v3 import project as _project
+from openstack.identity.v3 import role as _role
+from openstack.identity.v3 import system as _system
+from openstack.identity.v3 import user as _user
+from openstack.test import fakes as sdk_fakes
+
from openstackclient.identity.v3 import role
-from openstackclient.tests.unit import fakes
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
+from openstackclient.tests.unit import utils as test_utils
+
+
+class TestRoleInherited(identity_fakes.TestIdentityv3):
+ def _is_inheritance_testcase(self):
+ return True
-class TestRole(identity_fakes.TestIdentityv3):
+class TestFindSDKId(test_utils.TestCase):
def setUp(self):
super().setUp()
+ self.user = sdk_fakes.generate_fake_resource(_user.User)
+ self.identity_sdk_client = mock.Mock()
+ self.identity_sdk_client.find_user = mock.Mock()
- # Get a shortcut to the UserManager Mock
- self.users_mock = self.identity_client.users
- self.users_mock.reset_mock()
+ def test_find_sdk_id_validate(self):
+ self.identity_sdk_client.find_user.side_effect = [self.user]
- # Get a shortcut to the UserManager Mock
- self.groups_mock = self.identity_client.groups
- self.groups_mock.reset_mock()
+ result = role._find_sdk_id(
+ self.identity_sdk_client.find_user,
+ name_or_id=self.user.id,
+ validate_actor_existence=True,
+ )
+ self.assertEqual(self.user.id, result)
- # Get a shortcut to the DomainManager Mock
- self.domains_mock = self.identity_client.domains
- self.domains_mock.reset_mock()
+ def test_find_sdk_id_no_validate(self):
+ self.identity_sdk_client.find_user.side_effect = [self.user]
- # Get a shortcut to the ProjectManager Mock
- self.projects_mock = self.identity_client.projects
- self.projects_mock.reset_mock()
+ result = role._find_sdk_id(
+ self.identity_sdk_client.find_user,
+ name_or_id=self.user.id,
+ validate_actor_existence=False,
+ )
+ self.assertEqual(self.user.id, result)
- # Get a shortcut to the RoleManager Mock
- self.roles_mock = self.identity_client.roles
- self.roles_mock.reset_mock()
+ def test_find_sdk_id_not_found_validate(self):
+ self.identity_sdk_client.find_user.side_effect = [
+ sdk_exc.ResourceNotFound,
+ ]
- def _is_inheritance_testcase(self):
- return False
+ self.assertRaises(
+ exceptions.CommandError,
+ role._find_sdk_id,
+ self.identity_sdk_client.find_user,
+ name_or_id=self.user.id,
+ validate_actor_existence=True,
+ )
+
+ def test_find_sdk_id_not_found_no_validate(self):
+ self.identity_sdk_client.find_user.side_effect = [
+ sdk_exc.ResourceNotFound,
+ ]
+
+ result = role._find_sdk_id(
+ self.identity_sdk_client.find_user,
+ name_or_id=self.user.id,
+ validate_actor_existence=False,
+ )
+ self.assertEqual(self.user.id, result)
+
+ def test_find_sdk_id_forbidden_validate(self):
+ self.identity_sdk_client.find_user.side_effect = [
+ sdk_exc.ForbiddenException,
+ ]
+
+ result = role._find_sdk_id(
+ self.identity_sdk_client.find_user,
+ name_or_id=self.user.id,
+ validate_actor_existence=True,
+ )
+
+ self.assertEqual(self.user.id, result)
+
+ def test_find_sdk_id_forbidden_no_validate(self):
+ self.identity_sdk_client.find_user.side_effect = [
+ sdk_exc.ForbiddenException,
+ ]
+
+ result = role._find_sdk_id(
+ self.identity_sdk_client.find_user,
+ name_or_id=self.user.id,
+ validate_actor_existence=False,
+ )
+
+ self.assertEqual(self.user.id, result)
-class TestRoleInherited(TestRole):
+class TestRoleAdd(identity_fakes.TestIdentityv3):
def _is_inheritance_testcase(self):
- return True
+ return False
+ user = sdk_fakes.generate_fake_resource(_user.User)
+ group = sdk_fakes.generate_fake_resource(_group.Group)
+ domain = sdk_fakes.generate_fake_resource(_domain.Domain)
+ project = sdk_fakes.generate_fake_resource(_project.Project)
-class TestRoleAdd(TestRole):
def setUp(self):
super().setUp()
- self.users_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
+ self.identity_sdk_client.find_user.return_value = self.user
+ self.identity_sdk_client.find_group.return_value = self.group
+ self.identity_sdk_client.find_domain.return_value = self.domain
+ self.identity_sdk_client.find_project.return_value = self.project
- self.groups_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.GROUP),
- loaded=True,
+ self.role = sdk_fakes.generate_fake_resource(
+ resource_type=_role.Role,
+ domain_id=None,
+ description=None,
)
-
- self.domains_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.DOMAIN),
- loaded=True,
+ self.identity_sdk_client.find_role.return_value = self.role
+ self.role_with_domain = sdk_fakes.generate_fake_resource(
+ resource_type=_role.Role,
+ domain_id=self.domain.id,
+ description=None,
)
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
+ self.identity_sdk_client.assign_domain_role_to_user.return_value = (
+ self.role
)
-
- self.roles_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE),
- loaded=True,
+ self.identity_sdk_client.assign_domain_role_to_group.return_value = (
+ self.role
)
- self.roles_mock.grant.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE),
- loaded=True,
+ self.identity_sdk_client.assign_project_role_to_user.return_value = (
+ self.role
+ )
+ self.identity_sdk_client.assign_project_role_to_group.return_value = (
+ self.role
+ )
+ self.identity_sdk_client.assign_system_role_to_user.return_value = (
+ self.role
+ )
+ self.identity_sdk_client.assign_system_role_to_group.return_value = (
+ self.role
)
# Get the command object to test
self.cmd = role.AddRole(self.app, None)
- def test_role_add_user_system(self):
+ @mock.patch.object(role.LOG, 'warning')
+ def test_role_add_user_system(self, mock_warning):
arglist = [
'--user',
- identity_fakes.user_name,
+ self.user.name,
'--system',
'all',
- identity_fakes.role_name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
- ('user', identity_fakes.user_name),
+ ('user', self.user.name),
('group', None),
('system', 'all'),
('domain', None),
('project', None),
- ('role', identity_fakes.role_name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -125,32 +192,36 @@ class TestRoleAdd(TestRole):
# Set expected values
kwargs = {
- 'user': identity_fakes.user_id,
'system': 'all',
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'user': self.user.id,
+ 'role': self.role.id,
}
- # RoleManager.grant(role, user=, group=, domain=, project=)
- self.roles_mock.grant.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.assign_system_role_to_user.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
+ if self._is_inheritance_testcase():
+ mock_warning.assert_called_with(
+ "'--inherited' was given, which is not supported when adding a system role; this will be an error in a future release"
+ )
+
def test_role_add_user_domain(self):
arglist = [
'--user',
- identity_fakes.user_name,
+ self.user.name,
'--domain',
- identity_fakes.domain_name,
- identity_fakes.role_name,
+ self.domain.name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
- ('user', identity_fakes.user_name),
+ ('user', self.user.name),
('group', None),
- ('domain', identity_fakes.domain_name),
+ ('domain', self.domain.name),
('project', None),
- ('role', identity_fakes.role_name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -159,32 +230,32 @@ class TestRoleAdd(TestRole):
# Set expected values
kwargs = {
- 'user': identity_fakes.user_id,
- 'domain': identity_fakes.domain_id,
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'domain': self.domain.id,
+ 'user': self.user.id,
+ 'role': self.role.id,
+ 'inherited': self._is_inheritance_testcase(),
}
- # RoleManager.grant(role, user=, group=, domain=, project=)
- self.roles_mock.grant.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.assign_domain_role_to_user.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
def test_role_add_user_project(self):
arglist = [
'--user',
- identity_fakes.user_name,
+ self.user.name,
'--project',
- identity_fakes.project_name,
- identity_fakes.role_name,
+ self.project.name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
- ('user', identity_fakes.user_name),
+ ('user', self.user.name),
('group', None),
('domain', None),
- ('project', identity_fakes.project_name),
- ('role', identity_fakes.role_name),
+ ('project', self.project.name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -193,33 +264,34 @@ class TestRoleAdd(TestRole):
# Set expected values
kwargs = {
- 'user': identity_fakes.user_id,
- 'project': identity_fakes.project_id,
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'project': self.project.id,
+ 'user': self.user.id,
+ 'role': self.role.id,
+ 'inherited': self._is_inheritance_testcase(),
}
- # RoleManager.grant(role, user=, group=, domain=, project=)
- self.roles_mock.grant.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.assign_project_role_to_user.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
- def test_role_add_group_system(self):
+ @mock.patch.object(role.LOG, 'warning')
+ def test_role_add_group_system(self, mock_warning):
arglist = [
'--group',
- identity_fakes.group_name,
+ self.group.name,
'--system',
'all',
- identity_fakes.role_name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
('user', None),
- ('group', identity_fakes.group_name),
+ ('group', self.group.name),
('system', 'all'),
('domain', None),
('project', None),
- ('role', identity_fakes.role_name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -228,32 +300,36 @@ class TestRoleAdd(TestRole):
# Set expected values
kwargs = {
- 'group': identity_fakes.group_id,
'system': 'all',
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'group': self.group.id,
+ 'role': self.role.id,
}
- # RoleManager.grant(role, user=, group=, domain=, project=)
- self.roles_mock.grant.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.assign_system_role_to_group.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
+ if self._is_inheritance_testcase():
+ mock_warning.assert_called_with(
+ "'--inherited' was given, which is not supported when adding a system role; this will be an error in a future release"
+ )
+
def test_role_add_group_domain(self):
arglist = [
'--group',
- identity_fakes.group_name,
+ self.group.name,
'--domain',
- identity_fakes.domain_name,
- identity_fakes.role_name,
+ self.domain.name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
('user', None),
- ('group', identity_fakes.group_name),
- ('domain', identity_fakes.domain_name),
+ ('group', self.group.name),
+ ('domain', self.domain.name),
('project', None),
- ('role', identity_fakes.role_name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -262,32 +338,32 @@ class TestRoleAdd(TestRole):
# Set expected values
kwargs = {
- 'group': identity_fakes.group_id,
- 'domain': identity_fakes.domain_id,
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'domain': self.domain.id,
+ 'group': self.group.id,
+ 'role': self.role.id,
+ 'inherited': self._is_inheritance_testcase(),
}
- # RoleManager.grant(role, user=, group=, domain=, project=)
- self.roles_mock.grant.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.assign_domain_role_to_group.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
def test_role_add_group_project(self):
arglist = [
'--group',
- identity_fakes.group_name,
+ self.group.name,
'--project',
- identity_fakes.project_name,
- identity_fakes.role_name,
+ self.project.name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
('user', None),
- ('group', identity_fakes.group_name),
+ ('group', self.group.name),
('domain', None),
- ('project', identity_fakes.project_name),
- ('role', identity_fakes.role_name),
+ ('project', self.project.name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -296,39 +372,36 @@ class TestRoleAdd(TestRole):
# Set expected values
kwargs = {
- 'group': identity_fakes.group_id,
- 'project': identity_fakes.project_id,
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'project': self.project.id,
+ 'group': self.group.id,
+ 'role': self.role.id,
+ 'inherited': self._is_inheritance_testcase(),
}
- # RoleManager.grant(role, user=, group=, domain=, project=)
- self.roles_mock.grant.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.assign_project_role_to_group.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
def test_role_add_domain_role_on_user_project(self):
- self.roles_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE_2),
- loaded=True,
- )
+ self.identity_sdk_client.find_role.return_value = self.role_with_domain
+
arglist = [
'--user',
- identity_fakes.user_name,
+ self.user.name,
'--project',
- identity_fakes.project_name,
+ self.project.name,
'--role-domain',
- identity_fakes.domain_name,
- identity_fakes.ROLE_2['name'],
+ self.domain.name,
+ self.role_with_domain.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
- ('user', identity_fakes.user_name),
+ ('user', self.user.name),
('group', None),
('domain', None),
- ('project', identity_fakes.project_name),
- ('role', identity_fakes.ROLE_2['name']),
+ ('project', self.project.name),
+ ('role', self.role_with_domain.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -337,26 +410,26 @@ class TestRoleAdd(TestRole):
# Set expected values
kwargs = {
- 'user': identity_fakes.user_id,
- 'project': identity_fakes.project_id,
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'project': self.project.id,
+ 'user': self.user.id,
+ 'role': self.role_with_domain.id,
+ 'inherited': self._is_inheritance_testcase(),
}
- # RoleManager.grant(role, user=, group=, domain=, project=)
- self.roles_mock.grant.assert_called_with(
- identity_fakes.ROLE_2['id'], **kwargs
+ self.identity_sdk_client.assign_project_role_to_user.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
def test_role_add_with_error(self):
arglist = [
- identity_fakes.role_name,
+ self.role.name,
]
verifylist = [
('user', None),
('group', None),
('domain', None),
('project', None),
- ('role', identity_fakes.role_name),
+ ('role', self.role.name),
('inherited', False),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -369,31 +442,47 @@ class TestRoleAddInherited(TestRoleAdd, TestRoleInherited):
pass
-class TestRoleCreate(TestRole):
+class TestRoleCreate(identity_fakes.TestIdentityv3):
+ collist = ('id', 'name', 'domain_id', 'description')
+ domain = sdk_fakes.generate_fake_resource(_domain.Domain)
+
def setUp(self):
super().setUp()
- self.domains_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.DOMAIN),
- loaded=True,
+ self.role = sdk_fakes.generate_fake_resource(
+ resource_type=_role.Role,
+ domain_id=None,
+ description=None,
)
-
- self.roles_mock.create.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE),
- loaded=True,
+ self.role_with_domain = sdk_fakes.generate_fake_resource(
+ resource_type=_role.Role,
+ domain_id=self.domain.id,
+ description=None,
+ )
+ self.role_with_description = sdk_fakes.generate_fake_resource(
+ resource_type=_role.Role,
+ domain_id=None,
+ description='role description',
)
+ self.role_with_immutable_option = sdk_fakes.generate_fake_resource(
+ resource_type=_role.Role,
+ domain_id=None,
+ description=None,
+ options={'immutable': True},
+ )
+ self.identity_sdk_client.find_domain.return_value = self.domain
# Get the command object to test
self.cmd = role.CreateRole(self.app, None)
def test_role_create_no_options(self):
+ self.identity_sdk_client.create_role.return_value = self.role
+
arglist = [
- identity_fakes.role_name,
+ self.role.name,
]
verifylist = [
- ('name', identity_fakes.role_name),
+ ('name', self.role.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -404,39 +493,34 @@ class TestRoleCreate(TestRole):
# Set expected values
kwargs = {
- 'domain': None,
- 'name': identity_fakes.role_name,
- 'description': None,
+ 'name': self.role.name,
'options': {},
}
- # RoleManager.create(name=, domain=)
- self.roles_mock.create.assert_called_with(**kwargs)
+ self.identity_sdk_client.create_role.assert_called_with(**kwargs)
- collist = ('domain', 'id', 'name')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.collist, columns)
datalist = (
+ self.role.id,
+ self.role.name,
+ None,
None,
- identity_fakes.role_id,
- identity_fakes.role_name,
)
self.assertEqual(datalist, data)
def test_role_create_with_domain(self):
- self.roles_mock.create.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE_2),
- loaded=True,
+ self.identity_sdk_client.create_role.return_value = (
+ self.role_with_domain
)
arglist = [
'--domain',
- identity_fakes.domain_name,
- identity_fakes.ROLE_2['name'],
+ self.domain.name,
+ self.role_with_domain.name,
]
verifylist = [
- ('domain', identity_fakes.domain_name),
- ('name', identity_fakes.ROLE_2['name']),
+ ('domain', self.domain.name),
+ ('name', self.role_with_domain.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -447,38 +531,35 @@ class TestRoleCreate(TestRole):
# Set expected values
kwargs = {
- 'domain': identity_fakes.domain_id,
- 'name': identity_fakes.ROLE_2['name'],
- 'description': None,
+ 'domain_id': self.domain.id,
+ 'name': self.role_with_domain.name,
'options': {},
}
- # RoleManager.create(name=, domain=)
- self.roles_mock.create.assert_called_with(**kwargs)
+ self.identity_sdk_client.create_role.assert_called_with(**kwargs)
- collist = ('domain', 'id', 'name')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.collist, columns)
datalist = (
- identity_fakes.domain_id,
- identity_fakes.ROLE_2['id'],
- identity_fakes.ROLE_2['name'],
+ self.role_with_domain.id,
+ self.role_with_domain.name,
+ self.domain.id,
+ None,
)
self.assertEqual(datalist, data)
def test_role_create_with_description(self):
- self.roles_mock.create.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE_2),
- loaded=True,
+ self.identity_sdk_client.create_role.return_value = (
+ self.role_with_description
)
+
arglist = [
'--description',
- identity_fakes.role_description,
- identity_fakes.ROLE_2['name'],
+ self.role_with_description.description,
+ self.role_with_description.name,
]
verifylist = [
- ('description', identity_fakes.role_description),
- ('name', identity_fakes.ROLE_2['name']),
+ ('description', self.role_with_description.description),
+ ('name', self.role_with_description.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -489,37 +570,32 @@ class TestRoleCreate(TestRole):
# Set expected values
kwargs = {
- 'description': identity_fakes.role_description,
- 'name': identity_fakes.ROLE_2['name'],
- 'domain': None,
+ 'name': self.role_with_description.name,
+ 'description': self.role_with_description.description,
'options': {},
}
- # RoleManager.create(name=, domain=)
- self.roles_mock.create.assert_called_with(**kwargs)
+ self.identity_sdk_client.create_role.assert_called_with(**kwargs)
- collist = ('domain', 'id', 'name')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.collist, columns)
datalist = (
- 'd1',
- identity_fakes.ROLE_2['id'],
- identity_fakes.ROLE_2['name'],
+ self.role_with_description.id,
+ self.role_with_description.name,
+ None,
+ self.role_with_description.description,
)
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,
- )
+ self.identity_sdk_client.create_role.return_value = self.role
+
arglist = [
'--immutable',
- identity_fakes.ROLE_2['name'],
+ self.role.name,
]
verifylist = [
('immutable', True),
- ('name', identity_fakes.ROLE_2['name']),
+ ('name', self.role.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -531,36 +607,30 @@ class TestRoleCreate(TestRole):
# Set expected values
kwargs = {
'options': {'immutable': True},
- 'description': None,
- 'name': identity_fakes.ROLE_2['name'],
- 'domain': None,
+ 'name': self.role.name,
}
- # RoleManager.create(name=, domain=)
- self.roles_mock.create.assert_called_with(**kwargs)
+ self.identity_sdk_client.create_role.assert_called_with(**kwargs)
- collist = ('domain', 'id', 'name')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.collist, columns)
datalist = (
- 'd1',
- identity_fakes.ROLE_2['id'],
- identity_fakes.ROLE_2['name'],
+ self.role.id,
+ self.role.name,
+ None,
+ None,
)
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,
- )
+ self.identity_sdk_client.create_role.return_value = self.role
+
arglist = [
'--no-immutable',
- identity_fakes.ROLE_2['name'],
+ self.role.name,
]
verifylist = [
('no_immutable', True),
- ('name', identity_fakes.ROLE_2['name']),
+ ('name', self.role.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -572,88 +642,94 @@ class TestRoleCreate(TestRole):
# Set expected values
kwargs = {
'options': {'immutable': False},
- 'description': None,
- 'name': identity_fakes.ROLE_2['name'],
- 'domain': None,
+ 'name': self.role.name,
}
- # RoleManager.create(name=, domain=)
- self.roles_mock.create.assert_called_with(**kwargs)
+ self.identity_sdk_client.create_role.assert_called_with(**kwargs)
- collist = ('domain', 'id', 'name')
- self.assertEqual(collist, columns)
+ self.assertEqual(self.collist, columns)
datalist = (
- 'd1',
- identity_fakes.ROLE_2['id'],
- identity_fakes.ROLE_2['name'],
+ self.role.id,
+ self.role.name,
+ None,
+ None,
)
self.assertEqual(datalist, data)
-class TestRoleDelete(TestRole):
+class TestRoleDelete(identity_fakes.TestIdentityv3):
def setUp(self):
super().setUp()
- self.roles_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE),
- loaded=True,
- )
- self.roles_mock.delete.return_value = None
-
# Get the command object to test
self.cmd = role.DeleteRole(self.app, None)
def test_role_delete_no_options(self):
+ self.role = sdk_fakes.generate_fake_resource(
+ resource_type=_role.Role,
+ domain_id=None,
+ description=None,
+ )
+ self.identity_sdk_client.find_role.return_value = self.role
+ self.identity_sdk_client.delete_role.return_value = None
+
arglist = [
- identity_fakes.role_name,
+ self.role.name,
]
verifylist = [
- ('roles', [identity_fakes.role_name]),
+ ('roles', [self.role.name]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
- self.roles_mock.delete.assert_called_with(
- identity_fakes.role_id,
+ self.identity_sdk_client.delete_role.assert_called_with(
+ role=self.role.id,
+ ignore_missing=False,
)
self.assertIsNone(result)
def test_role_delete_with_domain(self):
- self.roles_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE_2),
- loaded=True,
+ self.domain = sdk_fakes.generate_fake_resource(_domain.Domain)
+ self.role_with_domain = sdk_fakes.generate_fake_resource(
+ resource_type=_role.Role,
+ domain_id=self.domain.id,
+ description=None,
)
- self.roles_mock.delete.return_value = None
+ self.identity_sdk_client.find_role.return_value = self.role_with_domain
+ self.identity_sdk_client.delete_role.return_value = None
arglist = [
'--domain',
- identity_fakes.domain_name,
- identity_fakes.ROLE_2['name'],
+ self.domain.name,
+ self.role_with_domain.name,
]
verifylist = [
- ('roles', [identity_fakes.ROLE_2['name']]),
- ('domain', identity_fakes.domain_name),
+ ('roles', [self.role_with_domain.name]),
+ ('domain', self.domain.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
- self.roles_mock.delete.assert_called_with(
- identity_fakes.ROLE_2['id'],
+ self.identity_sdk_client.delete_role.assert_called_with(
+ role=self.role_with_domain.id,
+ ignore_missing=False,
)
self.assertIsNone(result)
- @mock.patch.object(utils, 'find_resource')
- def test_delete_multi_roles_with_exception(self, find_mock):
- find_mock.side_effect = [
- self.roles_mock.get.return_value,
- exceptions.CommandError,
+ def test_delete_multi_roles_with_exception(self):
+ self.role = sdk_fakes.generate_fake_resource(
+ resource_type=_role.Role,
+ domain_id=None,
+ description=None,
+ )
+ self.identity_sdk_client.find_role.side_effect = [
+ self.role,
+ sdk_exc.ResourceNotFound,
]
arglist = [
- identity_fakes.role_name,
+ self.role.id,
'unexist_role',
]
verifylist = [
@@ -667,44 +743,62 @@ class TestRoleDelete(TestRole):
except exceptions.CommandError as e:
self.assertEqual('1 of 2 roles failed to delete.', str(e))
- find_mock.assert_any_call(
- self.roles_mock, identity_fakes.role_name, domain_id=None
- )
- find_mock.assert_any_call(
- self.roles_mock, 'unexist_role', domain_id=None
+ self.identity_sdk_client.find_role.assert_has_calls(
+ [
+ mock.call(
+ name_or_id=self.role.id,
+ ignore_missing=False,
+ domain_id=None,
+ ),
+ mock.call(
+ name_or_id='unexist_role',
+ ignore_missing=False,
+ domain_id=None,
+ ),
+ ]
)
- self.assertEqual(2, find_mock.call_count)
- self.roles_mock.delete.assert_called_once_with(identity_fakes.role_id)
+ self.assertEqual(2, self.identity_sdk_client.find_role.call_count)
+ self.identity_sdk_client.delete_role.assert_called_once_with(
+ role=self.role.id, ignore_missing=False
+ )
-class TestRoleList(TestRole):
+class TestRoleList(identity_fakes.TestIdentityv3):
columns = (
'ID',
'Name',
)
- datalist = (
- (
- identity_fakes.role_id,
- identity_fakes.role_name,
- ),
- )
+ domain = sdk_fakes.generate_fake_resource(_domain.Domain)
def setUp(self):
super().setUp()
- self.roles_mock.list.return_value = [
- fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE),
- loaded=True,
- ),
+ self.role = sdk_fakes.generate_fake_resource(
+ resource_type=_role.Role,
+ domain_id=None,
+ description=None,
+ )
+ self.role_with_domain = sdk_fakes.generate_fake_resource(
+ resource_type=_role.Role,
+ domain_id=self.domain.id,
+ description=None,
+ )
+ self.identity_sdk_client.roles.return_value = [
+ self.role,
+ self.role_with_domain,
]
+ self.identity_sdk_client.find_domain.return_value = self.domain
- self.domains_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.DOMAIN),
- loaded=True,
+ self.datalist = (
+ (
+ self.role.id,
+ self.role.name,
+ ),
+ (
+ self.role_with_domain.id,
+ self.role_with_domain.name,
+ ),
)
# Get the command object to test
@@ -720,25 +814,19 @@ class TestRoleList(TestRole):
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
- self.roles_mock.list.assert_called_with()
+ self.identity_sdk_client.roles.assert_called_with()
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, tuple(data))
def test_role_list_domain_role(self):
- self.roles_mock.list.return_value = [
- fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE_2),
- loaded=True,
- ),
- ]
+ self.identity_sdk_client.roles.return_value = [self.role_with_domain]
arglist = [
'--domain',
- identity_fakes.domain_name,
+ self.domain.name,
]
verifylist = [
- ('domain', identity_fakes.domain_name),
+ ('domain', self.domain.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -748,56 +836,51 @@ class TestRoleList(TestRole):
columns, data = self.cmd.take_action(parsed_args)
# Set expected values
- kwargs = {'domain_id': identity_fakes.domain_id}
- # RoleManager.list(user=, group=, domain=, project=, **kwargs)
- self.roles_mock.list.assert_called_with(**kwargs)
+ kwargs = {'domain_id': self.domain.id}
+ self.identity_sdk_client.roles.assert_called_with(**kwargs)
collist = ('ID', 'Name', 'Domain')
self.assertEqual(collist, columns)
datalist = (
(
- identity_fakes.ROLE_2['id'],
- identity_fakes.ROLE_2['name'],
- identity_fakes.domain_name,
+ self.role_with_domain.id,
+ self.role_with_domain.name,
+ self.domain.name,
),
)
self.assertEqual(datalist, tuple(data))
-class TestRoleRemove(TestRole):
- def setUp(self):
- super().setUp()
+class TestRoleRemove(identity_fakes.TestIdentityv3):
+ def _is_inheritance_testcase(self):
+ return False
- self.users_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
+ user = sdk_fakes.generate_fake_resource(_user.User)
+ group = sdk_fakes.generate_fake_resource(_group.Group)
+ domain = sdk_fakes.generate_fake_resource(_domain.Domain)
+ project = sdk_fakes.generate_fake_resource(_project.Project)
+ system = sdk_fakes.generate_fake_resource(_system.System)
- self.groups_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.GROUP),
- loaded=True,
- )
+ def setUp(self):
+ super().setUp()
- self.domains_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.DOMAIN),
- loaded=True,
+ self.role = sdk_fakes.generate_fake_resource(
+ resource_type=_role.Role,
+ domain_id=None,
+ description=None,
)
+ self.identity_sdk_client.find_role.return_value = self.role
+ self.identity_sdk_client.find_user.return_value = self.user
+ self.identity_sdk_client.find_group.return_value = self.group
+ self.identity_sdk_client.find_domain.return_value = self.domain
+ self.identity_sdk_client.find_project.return_value = self.project
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
-
- self.roles_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE),
- loaded=True,
- )
- self.roles_mock.revoke.return_value = None
+ self.identity_sdk_client.unassign_domain_role_from_user.return_value = None
+ self.identity_sdk_client.unassign_domain_role_from_group.return_value = None
+ self.identity_sdk_client.unassign_project_role_from_user.return_value = None
+ self.identity_sdk_client.unassign_project_role_from_group.return_value = None
+ self.identity_sdk_client.unassign_system_role_from_user.return_value = None
+ self.identity_sdk_client.unassign_system_role_from_group.return_value = None
# Get the command object to test
self.cmd = role.RemoveRole(self.app, None)
@@ -805,20 +888,20 @@ class TestRoleRemove(TestRole):
def test_role_remove_user_system(self):
arglist = [
'--user',
- identity_fakes.user_name,
+ self.user.name,
'--system',
'all',
- identity_fakes.role_name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
- ('user', identity_fakes.user_name),
+ ('user', self.user.name),
('group', None),
('system', 'all'),
('domain', None),
('project', None),
- ('role', identity_fakes.role_name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -827,40 +910,39 @@ class TestRoleRemove(TestRole):
# Set expected values
kwargs = {
- 'user': identity_fakes.user_id,
+ 'user': self.user.id,
'system': 'all',
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'role': self.role.id,
}
- # RoleManager.revoke(role, user=, group=, domain=, project=)
- self.roles_mock.revoke.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.unassign_system_role_from_user.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
- @mock.patch.object(common, 'find_user')
- def test_role_remove_non_existent_user_system(self, find_mock):
- # Simulate the user not being in keystone, the client should gracefully
+ def test_role_remove_non_existent_user_system(self):
+ # Simulate the user not being in keystone; the client should gracefully
# handle this exception and send the request to remove the role since
# keystone supports removing role assignments with non-existent actors
# (e.g., users or groups).
- find_mock.side_effect = exceptions.CommandError
-
+ self.identity_sdk_client.find_user.side_effect = [
+ sdk_exc.ResourceNotFound,
+ ]
arglist = [
'--user',
- identity_fakes.user_id,
+ self.user.id,
'--system',
'all',
- identity_fakes.role_name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
- ('user', identity_fakes.user_id),
+ ('user', self.user.id),
('group', None),
('system', 'all'),
('domain', None),
('project', None),
- ('role', identity_fakes.role_name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -869,32 +951,31 @@ class TestRoleRemove(TestRole):
# Set expected values
kwargs = {
- 'user': identity_fakes.user_id,
+ 'user': self.user.id,
'system': 'all',
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'role': self.role.id,
}
- # RoleManager.revoke(role, user=, group=, domain=, project=)
- self.roles_mock.revoke.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.unassign_system_role_from_user.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
def test_role_remove_user_domain(self):
arglist = [
'--user',
- identity_fakes.user_name,
+ self.user.name,
'--domain',
- identity_fakes.domain_name,
- identity_fakes.role_name,
+ self.domain.name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
- ('user', identity_fakes.user_name),
+ ('user', self.user.name),
('group', None),
- ('domain', identity_fakes.domain_name),
+ ('domain', self.domain.name),
('project', None),
- ('role', identity_fakes.role_name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -903,39 +984,39 @@ class TestRoleRemove(TestRole):
# Set expected values
kwargs = {
- 'user': identity_fakes.user_id,
- 'domain': identity_fakes.domain_id,
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'user': self.user.id,
+ 'domain': self.domain.id,
+ 'role': self.role.id,
+ 'inherited': self._is_inheritance_testcase(),
}
- # RoleManager.revoke(role, user=, group=, domain=, project=)
- self.roles_mock.revoke.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.unassign_domain_role_from_user.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
- @mock.patch.object(common, 'find_user')
- def test_role_remove_non_existent_user_domain(self, find_mock):
+ def test_role_remove_non_existent_user_domain(self):
# Simulate the user not being in keystone, the client the gracefully
# handle this exception and send the request to remove the role since
# keystone will validate.
- find_mock.side_effect = exceptions.CommandError
-
+ self.identity_sdk_client.find_user.side_effect = [
+ sdk_exc.ResourceNotFound,
+ ]
arglist = [
'--user',
- identity_fakes.user_id,
+ self.user.id,
'--domain',
- identity_fakes.domain_name,
- identity_fakes.role_name,
+ self.domain.name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
- ('user', identity_fakes.user_id),
+ ('user', self.user.id),
('group', None),
('system', None),
- ('domain', identity_fakes.domain_name),
+ ('domain', self.domain.name),
('project', None),
- ('role', identity_fakes.role_name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -944,32 +1025,32 @@ class TestRoleRemove(TestRole):
# Set expected values
kwargs = {
- 'user': identity_fakes.user_id,
- 'domain': identity_fakes.domain_id,
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'user': self.user.id,
+ 'domain': self.domain.id,
+ 'role': self.role.id,
+ 'inherited': self._is_inheritance_testcase(),
}
- # RoleManager.revoke(role, user=, group=, domain=, project=)
- self.roles_mock.revoke.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.unassign_domain_role_from_user.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
def test_role_remove_user_project(self):
arglist = [
'--user',
- identity_fakes.user_name,
+ self.user.name,
'--project',
- identity_fakes.project_name,
- identity_fakes.role_name,
+ self.project.name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
- ('user', identity_fakes.user_name),
+ ('user', self.user.name),
('group', None),
('domain', None),
- ('project', identity_fakes.project_name),
- ('role', identity_fakes.role_name),
+ ('project', self.project.name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -978,39 +1059,40 @@ class TestRoleRemove(TestRole):
# Set expected values
kwargs = {
- 'user': identity_fakes.user_id,
- 'project': identity_fakes.project_id,
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'user': self.user.id,
+ 'project': self.project.id,
+ 'role': self.role.id,
+ 'inherited': self._is_inheritance_testcase(),
}
- # RoleManager.revoke(role, user=, group=, domain=, project=)
- self.roles_mock.revoke.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.unassign_project_role_from_user.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
- @mock.patch.object(common, 'find_user')
- def test_role_remove_non_existent_user_project(self, find_mock):
+ def test_role_remove_non_existent_user_project(self):
# Simulate the user not being in keystone, the client the gracefully
# handle this exception and send the request to remove the role since
# keystone will validate.
- find_mock.side_effect = exceptions.CommandError
+ self.identity_sdk_client.find_user.side_effect = [
+ sdk_exc.ResourceNotFound,
+ ]
arglist = [
'--user',
- identity_fakes.user_id,
+ self.user.id,
'--project',
- identity_fakes.project_name,
- identity_fakes.role_name,
+ self.project.name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
- ('user', identity_fakes.user_id),
+ ('user', self.user.id),
('group', None),
('system', None),
('domain', None),
- ('project', identity_fakes.project_name),
- ('role', identity_fakes.role_name),
+ ('project', self.project.name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1019,34 +1101,34 @@ class TestRoleRemove(TestRole):
# Set expected values
kwargs = {
- 'user': identity_fakes.user_id,
- 'project': identity_fakes.project_id,
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'user': self.user.id,
+ 'project': self.project.id,
+ 'role': self.role.id,
+ 'inherited': self._is_inheritance_testcase(),
}
- # RoleManager.revoke(role, user=, group=, domain=, project=)
- self.roles_mock.revoke.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.unassign_project_role_from_user.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
def test_role_remove_group_system(self):
arglist = [
'--group',
- identity_fakes.group_name,
+ self.group.name,
'--system',
'all',
- identity_fakes.role_name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
('user', None),
- ('group', identity_fakes.group_name),
+ ('group', self.group.name),
('system', 'all'),
('domain', None),
('project', None),
- ('role', identity_fakes.role_name),
- ('role', identity_fakes.role_name),
+ ('role', self.role.name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1055,39 +1137,39 @@ class TestRoleRemove(TestRole):
# Set expected values
kwargs = {
- 'group': identity_fakes.group_id,
+ 'group': self.group.id,
'system': 'all',
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'role': self.role.id,
}
- # RoleManager.revoke(role, user=, group=, domain=, project=)
- self.roles_mock.revoke.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.unassign_system_role_from_group.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
- @mock.patch.object(common, 'find_group')
- def test_role_remove_non_existent_group_system(self, find_mock):
+ def test_role_remove_non_existent_group_system(self):
# Simulate the user not being in keystone, the client the gracefully
# handle this exception and send the request to remove the role since
# keystone will validate.
- find_mock.side_effect = exceptions.CommandError
+ self.identity_sdk_client.find_group.side_effect = [
+ sdk_exc.ResourceNotFound,
+ ]
arglist = [
'--group',
- identity_fakes.group_id,
+ self.group.id,
'--system',
'all',
- identity_fakes.role_name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
('user', None),
- ('group', identity_fakes.group_id),
+ ('group', self.group.id),
('system', 'all'),
('domain', None),
('project', None),
- ('role', identity_fakes.role_name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1096,33 +1178,32 @@ class TestRoleRemove(TestRole):
# Set expected values
kwargs = {
- 'group': identity_fakes.group_id,
+ 'group': self.group.id,
'system': 'all',
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'role': self.role.id,
}
- # RoleManager.revoke(role, user=, group=, domain=, project=)
- self.roles_mock.revoke.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.unassign_system_role_from_group.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
def test_role_remove_group_domain(self):
arglist = [
'--group',
- identity_fakes.group_name,
+ self.group.name,
'--domain',
- identity_fakes.domain_name,
- identity_fakes.role_name,
+ self.domain.name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
('user', None),
- ('group', identity_fakes.group_name),
- ('domain', identity_fakes.domain_name),
+ ('group', self.group.name),
+ ('domain', self.domain.name),
('project', None),
- ('role', identity_fakes.role_name),
- ('role', identity_fakes.role_name),
+ ('role', self.role.name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1131,39 +1212,40 @@ class TestRoleRemove(TestRole):
# Set expected values
kwargs = {
- 'group': identity_fakes.group_id,
- 'domain': identity_fakes.domain_id,
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'group': self.group.id,
+ 'domain': self.domain.id,
+ 'role': self.role.id,
+ 'inherited': self._is_inheritance_testcase(),
}
- # RoleManager.revoke(role, user=, group=, domain=, project=)
- self.roles_mock.revoke.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.unassign_domain_role_from_group.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
- @mock.patch.object(common, 'find_group')
- def test_role_remove_non_existent_group_domain(self, find_mock):
+ def test_role_remove_non_existent_group_domain(self):
# Simulate the user not being in keystone, the client the gracefully
# handle this exception and send the request to remove the role since
# keystone will validate.
- find_mock.side_effect = exceptions.CommandError
+ self.identity_sdk_client.find_group.side_effect = [
+ sdk_exc.ResourceNotFound,
+ ]
arglist = [
'--group',
- identity_fakes.group_id,
+ self.group.id,
'--domain',
- identity_fakes.domain_name,
- identity_fakes.role_name,
+ self.domain.name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
('user', None),
- ('group', identity_fakes.group_id),
+ ('group', self.group.id),
('system', None),
- ('domain', identity_fakes.domain_name),
+ ('domain', self.domain.name),
('project', None),
- ('role', identity_fakes.role_name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1172,32 +1254,32 @@ class TestRoleRemove(TestRole):
# Set expected values
kwargs = {
- 'group': identity_fakes.group_id,
- 'domain': identity_fakes.domain_id,
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'group': self.group.id,
+ 'domain': self.domain.id,
+ 'role': self.role.id,
+ 'inherited': self._is_inheritance_testcase(),
}
- # RoleManager.revoke(role, user=, group=, domain=, project=)
- self.roles_mock.revoke.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.unassign_domain_role_from_group.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
def test_role_remove_group_project(self):
arglist = [
'--group',
- identity_fakes.group_name,
+ self.group.name,
'--project',
- identity_fakes.project_name,
- identity_fakes.role_name,
+ self.project.name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
('user', None),
- ('group', identity_fakes.group_name),
+ ('group', self.group.name),
('domain', None),
- ('project', identity_fakes.project_name),
- ('role', identity_fakes.role_name),
+ ('project', self.project.name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1206,39 +1288,39 @@ class TestRoleRemove(TestRole):
# Set expected values
kwargs = {
- 'group': identity_fakes.group_id,
- 'project': identity_fakes.project_id,
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'group': self.group.id,
+ 'project': self.project.id,
+ 'role': self.role.id,
+ 'inherited': self._is_inheritance_testcase(),
}
- # RoleManager.revoke(role, user=, group=, domain=, project=)
- self.roles_mock.revoke.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.unassign_project_role_from_group.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
- @mock.patch.object(common, 'find_group')
- def test_role_remove_non_existent_group_project(self, find_mock):
+ def test_role_remove_non_existent_group_project(self):
# Simulate the user not being in keystone, the client the gracefully
# handle this exception and send the request to remove the role since
# keystone will validate.
- find_mock.side_effect = exceptions.CommandError
-
+ self.identity_sdk_client.find_group.side_effect = [
+ sdk_exc.ResourceNotFound,
+ ]
arglist = [
'--group',
- identity_fakes.group_id,
+ self.group.id,
'--project',
- identity_fakes.project_name,
- identity_fakes.role_name,
+ self.project.name,
+ self.role.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
('user', None),
- ('group', identity_fakes.group_id),
+ ('group', self.group.id),
('system', None),
('domain', None),
- ('project', identity_fakes.project_name),
- ('role', identity_fakes.role_name),
+ ('project', self.project.name),
+ ('role', self.role.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1247,37 +1329,38 @@ class TestRoleRemove(TestRole):
# Set expected values
kwargs = {
- 'group': identity_fakes.group_id,
- 'project': identity_fakes.project_id,
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'group': self.group.id,
+ 'project': self.project.id,
+ 'role': self.role.id,
+ 'inherited': self._is_inheritance_testcase(),
}
- # RoleManager.revoke(role, user=, group=, domain=, project=)
- self.roles_mock.revoke.assert_called_with(
- identity_fakes.role_id, **kwargs
+ self.identity_sdk_client.unassign_project_role_from_group.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
def test_role_remove_domain_role_on_group_domain(self):
- self.roles_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE_2),
- loaded=True,
+ self.role_with_domain = sdk_fakes.generate_fake_resource(
+ resource_type=_role.Role,
+ domain_id=self.domain.id,
+ description=None,
)
+ self.identity_sdk_client.find_role.return_value = self.role_with_domain
arglist = [
'--group',
- identity_fakes.group_name,
+ self.group.name,
'--domain',
- identity_fakes.domain_name,
- identity_fakes.ROLE_2['name'],
+ self.domain.name,
+ self.role_with_domain.name,
]
if self._is_inheritance_testcase():
arglist.append('--inherited')
verifylist = [
('user', None),
- ('group', identity_fakes.group_name),
- ('domain', identity_fakes.domain_name),
+ ('group', self.group.name),
+ ('domain', self.domain.name),
('project', None),
- ('role', identity_fakes.ROLE_2['name']),
+ ('role', self.role_with_domain.name),
('inherited', self._is_inheritance_testcase()),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1286,26 +1369,26 @@ class TestRoleRemove(TestRole):
# Set expected values
kwargs = {
- 'group': identity_fakes.group_id,
- 'domain': identity_fakes.domain_id,
- 'os_inherit_extension_inherited': self._is_inheritance_testcase(),
+ 'group': self.group.id,
+ 'domain': self.domain.id,
+ 'role': self.role_with_domain.id,
+ 'inherited': self._is_inheritance_testcase(),
}
- # RoleManager.revoke(role, user=, group=, domain=, project=)
- self.roles_mock.revoke.assert_called_with(
- identity_fakes.ROLE_2['id'], **kwargs
+ self.identity_sdk_client.unassign_domain_role_from_group.assert_called_with(
+ **kwargs
)
self.assertIsNone(result)
def test_role_remove_with_error(self):
arglist = [
- identity_fakes.role_name,
+ self.role.name,
]
verifylist = [
('user', None),
('group', None),
('domain', None),
('project', None),
- ('role', identity_fakes.role_name),
+ ('role', self.role.name),
('inherited', False),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1314,29 +1397,37 @@ class TestRoleRemove(TestRole):
)
-class TestRoleSet(TestRole):
+class TestRoleSet(identity_fakes.TestIdentityv3):
def setUp(self):
super().setUp()
- self.roles_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE),
- loaded=True,
+ self.domain = sdk_fakes.generate_fake_resource(_domain.Domain)
+ self.role_with_domain = sdk_fakes.generate_fake_resource(
+ resource_type=_role.Role,
+ domain_id=self.domain.id,
+ description=None,
)
- self.roles_mock.update.return_value = None
# Get the command object to test
self.cmd = role.SetRole(self.app, None)
def test_role_set_no_options(self):
+ self.role = sdk_fakes.generate_fake_resource(
+ resource_type=_role.Role,
+ domain_id=None,
+ description=None,
+ )
+ self.identity_sdk_client.find_role.return_value = self.role
+ self.identity_sdk_client.update_role.return_value = self.role
+
arglist = [
'--name',
'over',
- identity_fakes.role_name,
+ self.role.name,
]
verifylist = [
('name', 'over'),
- ('role', identity_fakes.role_name),
+ ('role', self.role.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1345,32 +1436,32 @@ class TestRoleSet(TestRole):
# Set expected values
kwargs = {
'name': 'over',
- 'description': None,
+ 'role': self.role.id,
'options': {},
}
- # RoleManager.update(role, name=)
- self.roles_mock.update.assert_called_with(
- identity_fakes.role_id, **kwargs
- )
+ self.identity_sdk_client.update_role.assert_called_with(**kwargs)
self.assertIsNone(result)
def test_role_set_domain_role(self):
- self.roles_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE_2),
- loaded=True,
+ self.domain2 = sdk_fakes.generate_fake_resource(_domain.Domain)
+ self.identity_sdk_client.find_domain.return_value = self.domain2
+
+ self.identity_sdk_client.find_role.return_value = self.role_with_domain
+ self.identity_sdk_client.update_role.return_value = (
+ self.role_with_domain
)
+
arglist = [
'--name',
'over',
'--domain',
- identity_fakes.domain_name,
- identity_fakes.ROLE_2['name'],
+ self.domain2.name,
+ self.role_with_domain.name,
]
verifylist = [
('name', 'over'),
- ('domain', identity_fakes.domain_name),
- ('role', identity_fakes.ROLE_2['name']),
+ ('domain', self.domain2.name),
+ ('role', self.role_with_domain.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1379,32 +1470,27 @@ class TestRoleSet(TestRole):
# Set expected values
kwargs = {
'name': 'over',
- 'description': None,
+ 'role': self.role_with_domain.id,
+ 'domain_id': self.domain2.id,
'options': {},
}
- # RoleManager.update(role, name=)
- self.roles_mock.update.assert_called_with(
- identity_fakes.ROLE_2['id'], **kwargs
- )
+ self.identity_sdk_client.update_role.assert_called_with(**kwargs)
self.assertIsNone(result)
def test_role_set_description(self):
- self.roles_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE_2),
- loaded=True,
- )
+ self.identity_sdk_client.find_role.return_value = self.role_with_domain
+
arglist = [
'--name',
'over',
'--description',
- identity_fakes.role_description,
- identity_fakes.ROLE_2['name'],
+ 'role description',
+ self.role_with_domain.name,
]
verifylist = [
('name', 'over'),
- ('description', identity_fakes.role_description),
- ('role', identity_fakes.ROLE_2['name']),
+ ('description', 'role description'),
+ ('role', self.role_with_domain.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1413,31 +1499,26 @@ class TestRoleSet(TestRole):
# Set expected values
kwargs = {
'name': 'over',
- 'description': identity_fakes.role_description,
+ 'description': 'role description',
+ 'role': self.role_with_domain.id,
'options': {},
}
- # RoleManager.update(role, name=)
- self.roles_mock.update.assert_called_with(
- identity_fakes.ROLE_2['id'], **kwargs
- )
+ self.identity_sdk_client.update_role.assert_called_with(**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,
- )
+ self.identity_sdk_client.find_role.return_value = self.role_with_domain
+
arglist = [
'--name',
'over',
'--immutable',
- identity_fakes.ROLE_2['name'],
+ self.role_with_domain.name,
]
verifylist = [
('name', 'over'),
('immutable', True),
- ('role', identity_fakes.ROLE_2['name']),
+ ('role', self.role_with_domain.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1446,31 +1527,25 @@ class TestRoleSet(TestRole):
# Set expected values
kwargs = {
'name': 'over',
- 'description': None,
+ 'role': self.role_with_domain.id,
'options': {'immutable': True},
}
- # RoleManager.update(role, name=)
- self.roles_mock.update.assert_called_with(
- identity_fakes.ROLE_2['id'], **kwargs
- )
+ self.identity_sdk_client.update_role.assert_called_with(**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,
- )
+ self.identity_sdk_client.find_role.return_value = self.role_with_domain
+
arglist = [
'--name',
'over',
'--no-immutable',
- identity_fakes.ROLE_2['name'],
+ self.role_with_domain.name,
]
verifylist = [
('name', 'over'),
('no_immutable', True),
- ('role', identity_fakes.ROLE_2['name']),
+ ('role', self.role_with_domain.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1479,35 +1554,37 @@ class TestRoleSet(TestRole):
# Set expected values
kwargs = {
'name': 'over',
- 'description': None,
+ 'role': self.role_with_domain.id,
'options': {'immutable': False},
}
- # RoleManager.update(role, name=)
- self.roles_mock.update.assert_called_with(
- identity_fakes.ROLE_2['id'], **kwargs
- )
+ self.identity_sdk_client.update_role.assert_called_with(**kwargs)
self.assertIsNone(result)
-class TestRoleShow(TestRole):
+class TestRoleShow(identity_fakes.TestIdentityv3):
+ domain = sdk_fakes.generate_fake_resource(_domain.Domain)
+
def setUp(self):
super().setUp()
- self.roles_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE),
- loaded=True,
- )
+ self.identity_sdk_client.find_domain.return_value = self.domain
# Get the command object to test
self.cmd = role.ShowRole(self.app, None)
def test_role_show(self):
+ self.role = sdk_fakes.generate_fake_resource(
+ resource_type=_role.Role,
+ domain_id=None,
+ description=None,
+ )
+ self.identity_sdk_client.find_role.return_value = self.role
+
arglist = [
- identity_fakes.role_name,
+ self.role.name,
]
verifylist = [
- ('role', identity_fakes.role_name),
+ ('role', self.role.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1516,34 +1593,38 @@ class TestRoleShow(TestRole):
# data to be shown.
columns, data = self.cmd.take_action(parsed_args)
- # RoleManager.get(role)
- self.roles_mock.get.assert_called_with(
- identity_fakes.role_name,
+ self.identity_sdk_client.find_role.assert_called_with(
+ name_or_id=self.role.name,
+ domain_id=None,
+ ignore_missing=False,
)
- collist = ('domain', 'id', 'name')
+ collist = ('id', 'name', 'domain_id', 'description')
self.assertEqual(collist, columns)
datalist = (
+ self.role.id,
+ self.role.name,
+ None,
None,
- identity_fakes.role_id,
- identity_fakes.role_name,
)
self.assertEqual(datalist, data)
def test_role_show_domain_role(self):
- self.roles_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE_2),
- loaded=True,
+ self.role_with_domain = sdk_fakes.generate_fake_resource(
+ resource_type=_role.Role,
+ domain_id=self.domain.id,
+ description=None,
)
+ self.identity_sdk_client.find_role.return_value = self.role_with_domain
+
arglist = [
'--domain',
- identity_fakes.domain_name,
- identity_fakes.ROLE_2['name'],
+ self.domain.name,
+ self.role_with_domain.id,
]
verifylist = [
- ('domain', identity_fakes.domain_name),
- ('role', identity_fakes.ROLE_2['name']),
+ ('domain', self.domain.name),
+ ('role', self.role_with_domain.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1552,23 +1633,18 @@ class TestRoleShow(TestRole):
# data to be shown.
columns, data = self.cmd.take_action(parsed_args)
- # RoleManager.get(role). This is called from utils.find_resource().
- # In fact, the current implementation calls the get(role) first with
- # just the name, then with the name+domain_id. So technically we should
- # mock this out with a call list, with the first call returning None
- # and the second returning the object. However, if we did that we are
- # then just testing the current sequencing within the utils method, and
- # would become brittle to changes within that method. Hence we just
- # check for the first call which is always lookup by name.
- self.roles_mock.get.assert_called_with(
- identity_fakes.ROLE_2['name'],
+ self.identity_sdk_client.find_role.assert_called_with(
+ name_or_id=self.role_with_domain.id,
+ domain_id=self.domain.id,
+ ignore_missing=False,
)
- collist = ('domain', 'id', 'name')
+ collist = ('id', 'name', 'domain_id', 'description')
self.assertEqual(collist, columns)
datalist = (
- identity_fakes.domain_id,
- identity_fakes.ROLE_2['id'],
- identity_fakes.ROLE_2['name'],
+ self.role_with_domain.id,
+ self.role_with_domain.name,
+ self.domain.id,
+ None,
)
self.assertEqual(datalist, data)
diff --git a/openstackclient/tests/unit/identity/v3/test_role_assignment.py b/openstackclient/tests/unit/identity/v3/test_role_assignment.py
index ec7c7da..6fc6646 100644
--- a/openstackclient/tests/unit/identity/v3/test_role_assignment.py
+++ b/openstackclient/tests/unit/identity/v3/test_role_assignment.py
@@ -165,10 +165,13 @@ class TestRoleAssignmentList(identity_fakes.TestIdentityv3):
arglist = ['--user', self.user.name]
verifylist = [
('user', self.user.name),
+ ('user_domain', None),
('group', None),
+ ('group_domain', None),
('system', None),
('domain', None),
('project', None),
+ ('project_domain', None),
('role', None),
('effective', None),
('inherited', False),
@@ -181,6 +184,79 @@ class TestRoleAssignmentList(identity_fakes.TestIdentityv3):
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
+ self.identity_sdk_client.find_user.assert_called_with(
+ name_or_id=self.user.name, ignore_missing=False, domain_id=None
+ )
+ self.identity_sdk_client.role_assignments.assert_called_with(
+ role_id=None,
+ user_id=self.user.id,
+ group_id=None,
+ scope_project_id=None,
+ scope_domain_id=None,
+ scope_system=None,
+ effective=None,
+ include_names=None,
+ inherited_to=None,
+ )
+
+ self.assertEqual(self.columns, columns)
+ datalist = (
+ (
+ self.role.id,
+ self.user.id,
+ '',
+ '',
+ self.domain.id,
+ '',
+ False,
+ ),
+ (
+ self.role.id,
+ self.user.id,
+ '',
+ self.project.id,
+ '',
+ '',
+ False,
+ ),
+ )
+ self.assertEqual(datalist, tuple(data))
+
+ def test_role_assignment_list_user_with_domain(self):
+ self.identity_sdk_client.role_assignments.return_value = [
+ self.assignment_with_domain_id_and_user_id,
+ self.assignment_with_project_id_and_user_id,
+ ]
+
+ arglist = ['--user', self.user.name, '--user-domain', self.domain.name]
+ verifylist = [
+ ('user', self.user.name),
+ ('user_domain', self.domain.name),
+ ('group', None),
+ ('group_domain', None),
+ ('system', None),
+ ('domain', None),
+ ('project', None),
+ ('role', None),
+ ('effective', None),
+ ('inherited', False),
+ ('names', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class Lister in cliff, abstract method take_action()
+ # returns a tuple containing the column names and an iterable
+ # containing the data to be listed.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.identity_sdk_client.find_domain.assert_called_with(
+ name_or_id=self.domain.name, ignore_missing=False
+ )
+ self.identity_sdk_client.find_user.assert_called_with(
+ name_or_id=self.user.name,
+ ignore_missing=False,
+ domain_id=self.domain.id,
+ )
self.identity_sdk_client.role_assignments.assert_called_with(
role_id=None,
user_id=self.user.id,
@@ -230,10 +306,13 @@ class TestRoleAssignmentList(identity_fakes.TestIdentityv3):
arglist = ['--user', self.user.id]
verifylist = [
('user', self.user.id),
+ ('user_domain', None),
('group', None),
+ ('group_domain', None),
('system', None),
('domain', None),
('project', None),
+ ('project_domain', None),
('role', None),
('effective', None),
('inherited', False),
@@ -290,10 +369,13 @@ class TestRoleAssignmentList(identity_fakes.TestIdentityv3):
arglist = ['--group', self.group.name]
verifylist = [
('user', None),
+ ('user_domain', None),
('group', self.group.name),
+ ('group_domain', None),
('system', None),
('domain', None),
('project', None),
+ ('project_domain', None),
('role', None),
('effective', None),
('inherited', False),
@@ -306,6 +388,85 @@ class TestRoleAssignmentList(identity_fakes.TestIdentityv3):
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
+ self.identity_sdk_client.find_group.assert_called_with(
+ name_or_id=self.group.name, ignore_missing=False, domain_id=None
+ )
+ self.identity_sdk_client.role_assignments.assert_called_with(
+ role_id=None,
+ user_id=None,
+ group_id=self.group.id,
+ scope_project_id=None,
+ scope_domain_id=None,
+ scope_system=None,
+ effective=None,
+ include_names=None,
+ inherited_to=None,
+ )
+
+ self.assertEqual(self.columns, columns)
+ datalist = (
+ (
+ self.role.id,
+ '',
+ self.group.id,
+ '',
+ self.domain.id,
+ '',
+ False,
+ ),
+ (
+ self.role.id,
+ '',
+ self.group.id,
+ self.project.id,
+ '',
+ '',
+ False,
+ ),
+ )
+ self.assertEqual(datalist, tuple(data))
+
+ def test_role_assignment_list_group_with_domain(self):
+ self.identity_sdk_client.role_assignments.return_value = [
+ self.assignment_with_domain_id_and_group_id,
+ self.assignment_with_project_id_and_group_id,
+ ]
+
+ arglist = [
+ '--group',
+ self.group.name,
+ '--group-domain',
+ self.domain.name,
+ ]
+ verifylist = [
+ ('user', None),
+ ('user_domain', None),
+ ('group', self.group.name),
+ ('group_domain', self.domain.name),
+ ('system', None),
+ ('domain', None),
+ ('project', None),
+ ('project_domain', None),
+ ('role', None),
+ ('effective', None),
+ ('inherited', False),
+ ('names', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class Lister in cliff, abstract method take_action()
+ # returns a tuple containing the column names and an iterable
+ # containing the data to be listed.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.identity_sdk_client.find_domain.assert_called_with(
+ name_or_id=self.domain.name, ignore_missing=False
+ )
+ self.identity_sdk_client.find_group.assert_called_with(
+ name_or_id=self.group.name,
+ ignore_missing=False,
+ domain_id=self.domain.id,
+ )
self.identity_sdk_client.role_assignments.assert_called_with(
role_id=None,
user_id=None,
@@ -350,10 +511,13 @@ class TestRoleAssignmentList(identity_fakes.TestIdentityv3):
arglist = ['--domain', self.domain.name]
verifylist = [
('user', None),
+ ('user_domain', None),
('group', None),
+ ('group_domain', None),
('system', None),
('domain', self.domain.name),
('project', None),
+ ('project_domain', None),
('role', None),
('effective', None),
('inherited', False),
@@ -410,10 +574,13 @@ class TestRoleAssignmentList(identity_fakes.TestIdentityv3):
arglist = ['--project', self.project.name]
verifylist = [
('user', None),
+ ('user_domain', None),
('group', None),
+ ('group_domain', None),
('system', None),
('domain', None),
('project', self.project.name),
+ ('project_domain', None),
('role', None),
('effective', None),
('inherited', False),
@@ -426,6 +593,85 @@ class TestRoleAssignmentList(identity_fakes.TestIdentityv3):
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
+ self.identity_sdk_client.find_project.assert_called_with(
+ name_or_id=self.project.name, ignore_missing=False, domain_id=None
+ )
+ self.identity_sdk_client.role_assignments.assert_called_with(
+ role_id=None,
+ user_id=None,
+ group_id=None,
+ scope_project_id=self.project.id,
+ scope_domain_id=None,
+ scope_system=None,
+ effective=None,
+ include_names=None,
+ inherited_to=None,
+ )
+
+ self.assertEqual(self.columns, columns)
+ datalist = (
+ (
+ self.role.id,
+ self.user.id,
+ '',
+ self.project.id,
+ '',
+ '',
+ False,
+ ),
+ (
+ self.role.id,
+ '',
+ self.group.id,
+ self.project.id,
+ '',
+ '',
+ False,
+ ),
+ )
+ self.assertEqual(datalist, tuple(data))
+
+ def test_role_assignment_list_project_with_domain(self):
+ self.identity_sdk_client.role_assignments.return_value = [
+ self.assignment_with_project_id_and_user_id,
+ self.assignment_with_project_id_and_group_id,
+ ]
+
+ arglist = [
+ '--project',
+ self.project.name,
+ '--project-domain',
+ self.domain.name,
+ ]
+ verifylist = [
+ ('user', None),
+ ('user_domain', None),
+ ('group', None),
+ ('group_domain', None),
+ ('system', None),
+ ('domain', None),
+ ('project', self.project.name),
+ ('project_domain', self.domain.name),
+ ('role', None),
+ ('effective', None),
+ ('inherited', False),
+ ('names', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class Lister in cliff, abstract method take_action()
+ # returns a tuple containing the column names and an iterable
+ # containing the data to be listed.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.identity_sdk_client.find_domain.assert_called_with(
+ name_or_id=self.domain.name, ignore_missing=False
+ )
+ self.identity_sdk_client.find_project.assert_called_with(
+ name_or_id=self.project.name,
+ ignore_missing=False,
+ domain_id=self.domain.id,
+ )
self.identity_sdk_client.role_assignments.assert_called_with(
role_id=None,
user_id=None,
@@ -462,7 +708,8 @@ class TestRoleAssignmentList(identity_fakes.TestIdentityv3):
self.assertEqual(datalist, tuple(data))
def test_role_assignment_list_def_creds(self):
- auth_ref = self.app.client_manager.auth_ref = mock.Mock()
+ self.app.client_manager.auth_ref = mock.Mock()
+ auth_ref = self.app.client_manager.auth_ref
auth_ref.project_id.return_value = self.project.id
auth_ref.user_id.return_value = self.user.id
@@ -476,10 +723,13 @@ class TestRoleAssignmentList(identity_fakes.TestIdentityv3):
]
verifylist = [
('user', None),
+ ('user_domain', None),
('group', None),
+ ('group_domain', None),
('system', None),
('domain', None),
('project', None),
+ ('project_domain', None),
('role', None),
('effective', None),
('inherited', False),
@@ -529,10 +779,13 @@ class TestRoleAssignmentList(identity_fakes.TestIdentityv3):
arglist = ['--effective']
verifylist = [
('user', None),
+ ('user_domain', None),
('group', None),
+ ('group_domain', None),
('system', None),
('domain', None),
('project', None),
+ ('project_domain', None),
('role', None),
('effective', True),
('inherited', False),
@@ -611,10 +864,13 @@ class TestRoleAssignmentList(identity_fakes.TestIdentityv3):
arglist = ['--inherited']
verifylist = [
('user', None),
+ ('user_domain', None),
('group', None),
+ ('group_domain', None),
('system', None),
('domain', None),
('project', None),
+ ('project_domain', None),
('role', None),
('effective', None),
('inherited', True),
@@ -707,10 +963,13 @@ class TestRoleAssignmentList(identity_fakes.TestIdentityv3):
arglist = ['--names']
verifylist = [
('user', None),
+ ('user_domain', None),
('group', None),
+ ('group_domain', None),
('system', None),
('domain', None),
('project', None),
+ ('project_domain', None),
('role', None),
('effective', None),
('inherited', False),
@@ -799,10 +1058,13 @@ class TestRoleAssignmentList(identity_fakes.TestIdentityv3):
]
verifylist = [
('user', None),
+ ('user_domain', None),
('group', None),
+ ('group_domain', None),
('system', None),
('domain', None),
('project', None),
+ ('project_domain', None),
('role', role_2.name),
('effective', None),
('inherited', False),
diff --git a/openstackclient/tests/unit/identity/v3/test_service_provider.py b/openstackclient/tests/unit/identity/v3/test_service_provider.py
index 23402d9..185cdc6 100644
--- a/openstackclient/tests/unit/identity/v3/test_service_provider.py
+++ b/openstackclient/tests/unit/identity/v3/test_service_provider.py
@@ -12,92 +12,88 @@
# License for the specific language governing permissions and limitations
# under the License.
-import copy
+
+from openstack.identity.v3 import service_provider as _service_provider
+from openstack.test import fakes as sdk_fakes
from openstackclient.identity.v3 import service_provider
-from openstackclient.tests.unit import fakes
from openstackclient.tests.unit.identity.v3 import fakes as service_fakes
-class TestServiceProvider(service_fakes.TestFederatedIdentity):
- def setUp(self):
- super().setUp()
-
- federation_lib = self.identity_client.federation
- self.service_providers_mock = federation_lib.service_providers
- self.service_providers_mock.reset_mock()
-
-
-class TestServiceProviderCreate(TestServiceProvider):
+class TestServiceProviderCreate(service_fakes.TestFederatedIdentity):
columns = (
- 'auth_url',
- 'description',
- 'enabled',
'id',
+ 'enabled',
+ 'description',
+ 'auth_url',
'sp_url',
- )
- datalist = (
- service_fakes.sp_auth_url,
- service_fakes.sp_description,
- True,
- service_fakes.sp_id,
- service_fakes.service_provider_url,
+ 'relay_state_prefix',
)
def setUp(self):
super().setUp()
- copied_sp = copy.deepcopy(service_fakes.SERVICE_PROVIDER)
- resource = fakes.FakeResource(None, copied_sp, loaded=True)
- self.service_providers_mock.create.return_value = resource
+ self.service_provider = sdk_fakes.generate_fake_resource(
+ _service_provider.ServiceProvider
+ )
+ self.identity_sdk_client.create_service_provider.return_value = (
+ self.service_provider
+ )
+ self.data = (
+ self.service_provider.id,
+ self.service_provider.is_enabled,
+ self.service_provider.description,
+ self.service_provider.auth_url,
+ self.service_provider.sp_url,
+ self.service_provider.relay_state_prefix,
+ )
self.cmd = service_provider.CreateServiceProvider(self.app, None)
def test_create_service_provider_required_options_only(self):
arglist = [
'--auth-url',
- service_fakes.sp_auth_url,
+ self.service_provider.auth_url,
'--service-provider-url',
- service_fakes.service_provider_url,
- service_fakes.sp_id,
+ self.service_provider.sp_url,
+ self.service_provider.id,
]
verifylist = [
- ('auth_url', service_fakes.sp_auth_url),
- ('service_provider_url', service_fakes.service_provider_url),
- ('service_provider_id', service_fakes.sp_id),
+ ('auth_url', self.service_provider.auth_url),
+ ('service_provider_url', self.service_provider.sp_url),
+ ('service_provider_id', self.service_provider.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
# Set expected values
kwargs = {
- 'enabled': True,
- 'description': None,
- 'auth_url': service_fakes.sp_auth_url,
- 'sp_url': service_fakes.service_provider_url,
+ 'is_enabled': True,
+ 'auth_url': self.service_provider.auth_url,
+ 'sp_url': self.service_provider.sp_url,
}
- self.service_providers_mock.create.assert_called_with(
- id=service_fakes.sp_id, **kwargs
+ self.identity_sdk_client.create_service_provider.assert_called_with(
+ id=self.service_provider.id, **kwargs
)
self.assertEqual(self.columns, columns)
- self.assertEqual(self.datalist, data)
+ self.assertEqual(self.data, data)
def test_create_service_provider_description(self):
arglist = [
'--description',
- service_fakes.sp_description,
+ self.service_provider.description,
'--auth-url',
- service_fakes.sp_auth_url,
+ self.service_provider.auth_url,
'--service-provider-url',
- service_fakes.service_provider_url,
- service_fakes.sp_id,
+ self.service_provider.sp_url,
+ self.service_provider.id,
]
verifylist = [
- ('description', service_fakes.sp_description),
- ('auth_url', service_fakes.sp_auth_url),
- ('service_provider_url', service_fakes.service_provider_url),
- ('service_provider_id', service_fakes.sp_id),
+ ('description', self.service_provider.description),
+ ('auth_url', self.service_provider.auth_url),
+ ('service_provider_url', self.service_provider.sp_url),
+ ('service_provider_id', self.service_provider.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -105,111 +101,85 @@ class TestServiceProviderCreate(TestServiceProvider):
# Set expected values
kwargs = {
- 'description': service_fakes.sp_description,
- 'auth_url': service_fakes.sp_auth_url,
- 'sp_url': service_fakes.service_provider_url,
- 'enabled': True,
+ 'description': self.service_provider.description,
+ 'auth_url': self.service_provider.auth_url,
+ 'sp_url': self.service_provider.sp_url,
+ 'is_enabled': self.service_provider.is_enabled,
}
- self.service_providers_mock.create.assert_called_with(
- id=service_fakes.sp_id, **kwargs
+ self.identity_sdk_client.create_service_provider.assert_called_with(
+ id=self.service_provider.id, **kwargs
)
self.assertEqual(self.columns, columns)
- self.assertEqual(self.datalist, data)
+ self.assertEqual(self.data, data)
def test_create_service_provider_disabled(self):
- # Prepare FakeResource object
- service_provider = copy.deepcopy(service_fakes.SERVICE_PROVIDER)
- service_provider['enabled'] = False
- service_provider['description'] = None
-
- resource = fakes.FakeResource(None, service_provider, loaded=True)
- self.service_providers_mock.create.return_value = resource
-
arglist = [
'--auth-url',
- service_fakes.sp_auth_url,
+ self.service_provider.auth_url,
'--service-provider-url',
- service_fakes.service_provider_url,
+ self.service_provider.sp_url,
'--disable',
- service_fakes.sp_id,
+ self.service_provider.id,
]
verifylist = [
- ('auth_url', service_fakes.sp_auth_url),
- ('service_provider_url', service_fakes.service_provider_url),
- ('service_provider_id', service_fakes.sp_id),
+ ('auth_url', self.service_provider.auth_url),
+ ('service_provider_url', self.service_provider.sp_url),
+ ('service_provider_id', self.service_provider.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
# Set expected values
kwargs = {
- 'auth_url': service_fakes.sp_auth_url,
- 'sp_url': service_fakes.service_provider_url,
- 'enabled': False,
- 'description': None,
+ 'auth_url': self.service_provider.auth_url,
+ 'sp_url': self.service_provider.sp_url,
+ 'is_enabled': False,
}
- self.service_providers_mock.create.assert_called_with(
- id=service_fakes.sp_id, **kwargs
+ self.identity_sdk_client.create_service_provider.assert_called_with(
+ id=self.service_provider.id, **kwargs
)
self.assertEqual(self.columns, columns)
- datalist = (
- service_fakes.sp_auth_url,
- None,
- False,
- service_fakes.sp_id,
- service_fakes.service_provider_url,
- )
- self.assertEqual(datalist, data)
+ self.assertEqual(self.data, data)
-class TestServiceProviderDelete(TestServiceProvider):
+class TestServiceProviderDelete(service_fakes.TestFederatedIdentity):
def setUp(self):
super().setUp()
- # This is the return value for utils.find_resource()
- self.service_providers_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(service_fakes.SERVICE_PROVIDER),
- loaded=True,
+ self.service_provider = sdk_fakes.generate_fake_resource(
+ _service_provider.ServiceProvider
)
-
- self.service_providers_mock.delete.return_value = None
+ self.identity_sdk_client.delete_service_provider.return_value = None
self.cmd = service_provider.DeleteServiceProvider(self.app, None)
def test_delete_service_provider(self):
arglist = [
- service_fakes.sp_id,
+ self.service_provider.id,
]
verifylist = [
- ('service_provider', [service_fakes.sp_id]),
+ ('service_provider', [self.service_provider.id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
- self.service_providers_mock.delete.assert_called_with(
- service_fakes.sp_id,
+ self.identity_sdk_client.delete_service_provider.assert_called_with(
+ self.service_provider.id,
)
self.assertIsNone(result)
-class TestServiceProviderList(TestServiceProvider):
+class TestServiceProviderList(service_fakes.TestFederatedIdentity):
def setUp(self):
super().setUp()
- self.service_providers_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(service_fakes.SERVICE_PROVIDER),
- loaded=True,
+ self.service_provider = sdk_fakes.generate_fake_resource(
+ _service_provider.ServiceProvider
)
- self.service_providers_mock.list.return_value = [
- fakes.FakeResource(
- None,
- copy.deepcopy(service_fakes.SERVICE_PROVIDER),
- loaded=True,
- ),
+ self.identity_sdk_client.service_providers.return_value = [
+ self.service_provider
]
# Get the command object to test
@@ -225,39 +195,56 @@ class TestServiceProviderList(TestServiceProvider):
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
- self.service_providers_mock.list.assert_called_with()
+ self.identity_sdk_client.service_providers.assert_called_with()
- collist = ('ID', 'Enabled', 'Description', 'Auth URL')
+ collist = (
+ 'ID',
+ 'Enabled',
+ 'Description',
+ 'Auth URL',
+ 'Service Provider URL',
+ 'Relay State Prefix',
+ )
self.assertEqual(collist, columns)
datalist = (
(
- service_fakes.sp_id,
+ self.service_provider.id,
True,
- service_fakes.sp_description,
- service_fakes.sp_auth_url,
+ self.service_provider.description,
+ self.service_provider.auth_url,
+ self.service_provider.sp_url,
+ self.service_provider.relay_state_prefix,
),
)
self.assertEqual(tuple(data), datalist)
-class TestServiceProviderSet(TestServiceProvider):
+class TestServiceProviderSet(service_fakes.TestFederatedIdentity):
columns = (
- 'auth_url',
- 'description',
- 'enabled',
'id',
+ 'enabled',
+ 'description',
+ 'auth_url',
'sp_url',
- )
- datalist = (
- service_fakes.sp_auth_url,
- service_fakes.sp_description,
- False,
- service_fakes.sp_id,
- service_fakes.service_provider_url,
+ 'relay_state_prefix',
)
def setUp(self):
super().setUp()
+ self.service_provider = sdk_fakes.generate_fake_resource(
+ _service_provider.ServiceProvider
+ )
+ self.identity_sdk_client.update_service_provider.return_value = (
+ self.service_provider
+ )
+ self.data = (
+ self.service_provider.id,
+ self.service_provider.is_enabled,
+ self.service_provider.description,
+ self.service_provider.auth_url,
+ self.service_provider.sp_url,
+ self.service_provider.relay_state_prefix,
+ )
self.cmd = service_provider.SetServiceProvider(self.app, None)
def test_service_provider_disable(self):
@@ -265,144 +252,107 @@ class TestServiceProviderSet(TestServiceProvider):
Set Service Provider's ``enabled`` attribute to False.
"""
-
- def prepare(self):
- """Prepare fake return objects before the test is executed"""
- updated_sp = copy.deepcopy(service_fakes.SERVICE_PROVIDER)
- updated_sp['enabled'] = False
- resources = fakes.FakeResource(None, updated_sp, loaded=True)
- self.service_providers_mock.update.return_value = resources
-
- prepare(self)
arglist = [
'--disable',
- service_fakes.sp_id,
+ self.service_provider.id,
]
verifylist = [
- ('service_provider', service_fakes.sp_id),
- ('enable', False),
- ('disable', True),
+ ('service_provider', self.service_provider.id),
+ ('is_enabled', False),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- self.cmd.take_action(parsed_args)
- self.service_providers_mock.update.assert_called_with(
- service_fakes.sp_id,
- enabled=False,
- description=None,
- auth_url=None,
- sp_url=None,
+ columns, data = self.cmd.take_action(parsed_args)
+ self.identity_sdk_client.update_service_provider.assert_called_with(
+ self.service_provider.id,
+ is_enabled=False,
)
+ self.assertEqual(columns, self.columns)
+ self.assertEqual(data, self.data)
def test_service_provider_enable(self):
"""Enable Service Provider.
Set Service Provider's ``enabled`` attribute to True.
"""
-
- def prepare(self):
- """Prepare fake return objects before the test is executed"""
- resources = fakes.FakeResource(
- None,
- copy.deepcopy(service_fakes.SERVICE_PROVIDER),
- loaded=True,
- )
- self.service_providers_mock.update.return_value = resources
-
- prepare(self)
arglist = [
'--enable',
- service_fakes.sp_id,
+ self.service_provider.id,
]
verifylist = [
- ('service_provider', service_fakes.sp_id),
- ('enable', True),
- ('disable', False),
+ ('service_provider', self.service_provider.id),
+ ('is_enabled', True),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- self.cmd.take_action(parsed_args)
- self.service_providers_mock.update.assert_called_with(
- service_fakes.sp_id,
- enabled=True,
- description=None,
- auth_url=None,
- sp_url=None,
+ columns, data = self.cmd.take_action(parsed_args)
+ self.identity_sdk_client.update_service_provider.assert_called_with(
+ self.service_provider.id,
+ is_enabled=True,
)
+ self.assertEqual(columns, self.columns)
+ self.assertEqual(data, self.data)
def test_service_provider_no_options(self):
- def prepare(self):
- """Prepare fake return objects before the test is executed"""
- resources = fakes.FakeResource(
- None,
- copy.deepcopy(service_fakes.SERVICE_PROVIDER),
- loaded=True,
- )
- self.service_providers_mock.get.return_value = resources
-
- resources = fakes.FakeResource(
- None,
- copy.deepcopy(service_fakes.SERVICE_PROVIDER),
- loaded=True,
- )
- self.service_providers_mock.update.return_value = resources
-
- prepare(self)
arglist = [
- service_fakes.sp_id,
+ self.service_provider.id,
]
verifylist = [
- ('service_provider', service_fakes.sp_id),
+ ('service_provider', self.service_provider.id),
('description', None),
- ('enable', False),
- ('disable', False),
+ ('is_enabled', None),
('auth_url', None),
('service_provider_url', None),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- self.cmd.take_action(parsed_args)
+ columns, data = self.cmd.take_action(parsed_args)
+ self.assertEqual(columns, self.columns)
+ self.assertEqual(data, self.data)
-class TestServiceProviderShow(TestServiceProvider):
+class TestServiceProviderShow(service_fakes.TestFederatedIdentity):
def setUp(self):
super().setUp()
- ret = fakes.FakeResource(
- None,
- copy.deepcopy(service_fakes.SERVICE_PROVIDER),
- loaded=True,
+ self.service_provider = sdk_fakes.generate_fake_resource(
+ _service_provider.ServiceProvider
+ )
+ self.identity_sdk_client.find_service_provider.return_value = (
+ self.service_provider
+ )
+ self.data = (
+ self.service_provider.id,
+ self.service_provider.is_enabled,
+ self.service_provider.description,
+ self.service_provider.auth_url,
+ self.service_provider.sp_url,
+ self.service_provider.relay_state_prefix,
)
- self.service_providers_mock.get.side_effect = [
- Exception("Not found"),
- ret,
- ]
- self.service_providers_mock.get.return_value = ret
# Get the command object to test
self.cmd = service_provider.ShowServiceProvider(self.app, None)
def test_service_provider_show(self):
arglist = [
- service_fakes.sp_id,
+ self.service_provider.id,
]
verifylist = [
- ('service_provider', service_fakes.sp_id),
+ ('service_provider', self.service_provider.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- self.service_providers_mock.get.assert_called_with(
- service_fakes.sp_id, id='BETA'
+ self.identity_sdk_client.find_service_provider.assert_called_with(
+ self.service_provider.id,
+ ignore_missing=False,
)
- collist = ('auth_url', 'description', 'enabled', 'id', 'sp_url')
- self.assertEqual(collist, columns)
- datalist = (
- service_fakes.sp_auth_url,
- service_fakes.sp_description,
- True,
- service_fakes.sp_id,
- service_fakes.service_provider_url,
+ collist = (
+ 'id',
+ 'enabled',
+ 'description',
+ 'auth_url',
+ 'sp_url',
+ 'relay_state_prefix',
)
- self.assertEqual(data, datalist)
+ self.assertEqual(collist, columns)
+ self.assertEqual(data, self.data)
diff --git a/openstackclient/tests/unit/identity/v3/test_token.py b/openstackclient/tests/unit/identity/v3/test_token.py
index 96375ea..f8d09b7 100644
--- a/openstackclient/tests/unit/identity/v3/test_token.py
+++ b/openstackclient/tests/unit/identity/v3/test_token.py
@@ -11,24 +11,12 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
-#
-
-from unittest import mock
from openstackclient.identity.v3 import token
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
-class TestToken(identity_fakes.TestIdentityv3):
- def setUp(self):
- super().setUp()
-
- # Get a shortcut to the Auth Ref Mock
- self.ar_mock = mock.PropertyMock()
- type(self.app.client_manager).auth_ref = self.ar_mock
-
-
-class TestTokenIssue(TestToken):
+class TestTokenIssue(identity_fakes.TestIdentityv3):
def setUp(self):
super().setUp()
@@ -38,8 +26,7 @@ class TestTokenIssue(TestToken):
auth_ref = identity_fakes.fake_auth_ref(
identity_fakes.TOKEN_WITH_PROJECT_ID,
)
- self.ar_mock = mock.PropertyMock(return_value=auth_ref)
- type(self.app.client_manager).auth_ref = self.ar_mock
+ self.app.client_manager.auth_ref = auth_ref
arglist = []
verifylist = []
@@ -64,8 +51,7 @@ class TestTokenIssue(TestToken):
auth_ref = identity_fakes.fake_auth_ref(
identity_fakes.TOKEN_WITH_DOMAIN_ID,
)
- self.ar_mock = mock.PropertyMock(return_value=auth_ref)
- type(self.app.client_manager).auth_ref = self.ar_mock
+ self.app.client_manager.auth_ref = auth_ref
arglist = []
verifylist = []
@@ -90,8 +76,7 @@ class TestTokenIssue(TestToken):
auth_ref = identity_fakes.fake_auth_ref(
identity_fakes.UNSCOPED_TOKEN,
)
- self.ar_mock = mock.PropertyMock(return_value=auth_ref)
- type(self.app.client_manager).auth_ref = self.ar_mock
+ self.app.client_manager.auth_ref = auth_ref
arglist = []
verifylist = []
@@ -114,7 +99,7 @@ class TestTokenIssue(TestToken):
self.assertEqual(datalist, data)
-class TestTokenRevoke(TestToken):
+class TestTokenRevoke(identity_fakes.TestIdentityv3):
TOKEN = 'fob'
def setUp(self):
diff --git a/openstackclient/tests/unit/identity/v3/test_trust.py b/openstackclient/tests/unit/identity/v3/test_trust.py
index fb7ac9b..07776fa 100644
--- a/openstackclient/tests/unit/identity/v3/test_trust.py
+++ b/openstackclient/tests/unit/identity/v3/test_trust.py
@@ -11,58 +11,36 @@
# under the License.
#
-import copy
from unittest import mock
from osc_lib import exceptions
-from osc_lib import utils
+
+from openstack import exceptions as sdk_exceptions
+from openstack.identity.v3 import project as _project
+from openstack.identity.v3 import role as _role
+from openstack.identity.v3 import trust as _trust
+from openstack.identity.v3 import user as _user
+from openstack.test import fakes as sdk_fakes
from openstackclient.identity.v3 import trust
-from openstackclient.tests.unit import fakes
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
-class TestTrust(identity_fakes.TestIdentityv3):
+class TestTrustCreate(identity_fakes.TestIdentityv3):
def setUp(self):
super().setUp()
- self.trusts_mock = self.identity_client.trusts
- self.trusts_mock.reset_mock()
- self.projects_mock = self.identity_client.projects
- self.projects_mock.reset_mock()
- self.users_mock = self.identity_client.users
- self.users_mock.reset_mock()
- self.roles_mock = self.identity_client.roles
- self.roles_mock.reset_mock()
-
+ self.trust = sdk_fakes.generate_fake_resource(_trust.Trust)
+ self.identity_sdk_client.create_trust.return_value = self.trust
-class TestTrustCreate(TestTrust):
- def setUp(self):
- super().setUp()
+ self.project = sdk_fakes.generate_fake_resource(_project.Project)
+ self.identity_sdk_client.find_project.return_value = self.project
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
+ self.user = sdk_fakes.generate_fake_resource(_user.User)
+ self.identity_sdk_client.find_user.return_value = self.user
- self.users_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
-
- self.roles_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE),
- loaded=True,
- )
-
- self.trusts_mock.create.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.TRUST),
- loaded=True,
- )
+ self.role = sdk_fakes.generate_fake_resource(_role.Role)
+ self.identity_sdk_client.find_role.return_value = self.role
# Get the command object to test
self.cmd = trust.CreateTrust(self.app, None)
@@ -70,18 +48,17 @@ class TestTrustCreate(TestTrust):
def test_trust_create_basic(self):
arglist = [
'--project',
- identity_fakes.project_id,
+ self.project.id,
'--role',
- identity_fakes.role_id,
- identity_fakes.user_id,
- identity_fakes.user_id,
+ self.role.id,
+ self.user.id,
+ self.user.id,
]
verifylist = [
- ('project', identity_fakes.project_id),
- ('impersonate', False),
- ('role', [identity_fakes.role_id]),
- ('trustor', identity_fakes.user_id),
- ('trustee', identity_fakes.user_id),
+ ('project', self.project.id),
+ ('roles', [self.role.id]),
+ ('trustor', self.user.id),
+ ('trustee', self.user.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -92,76 +69,71 @@ class TestTrustCreate(TestTrust):
# Set expected values
kwargs = {
- 'impersonation': False,
- 'project': identity_fakes.project_id,
- 'role_ids': [identity_fakes.role_id],
- 'expires_at': None,
+ 'project_id': self.project.id,
+ 'roles': [self.role.id],
}
# TrustManager.create(trustee_id, trustor_id, impersonation=,
# project=, role_names=, expires_at=)
- self.trusts_mock.create.assert_called_with(
- identity_fakes.user_id, identity_fakes.user_id, **kwargs
+ self.identity_sdk_client.create_trust.assert_called_with(
+ trustor_id=self.user.id, trustee_id=self.user.id, **kwargs
)
collist = (
'expires_at',
'id',
- 'impersonation',
+ 'is_impersonation',
'project_id',
+ 'redelegated_trust_id',
+ 'redelegation_count',
+ 'remaining_uses',
'roles',
'trustee_user_id',
'trustor_user_id',
)
self.assertEqual(collist, columns)
datalist = (
- identity_fakes.trust_expires,
- identity_fakes.trust_id,
- identity_fakes.trust_impersonation,
- identity_fakes.project_id,
- identity_fakes.role_name,
- identity_fakes.user_id,
- identity_fakes.user_id,
+ self.trust.expires_at,
+ self.trust.id,
+ self.trust.is_impersonation,
+ self.trust.project_id,
+ self.trust.redelegated_trust_id,
+ self.trust.redelegation_count,
+ self.trust.remaining_uses,
+ self.trust.roles,
+ self.trust.trustee_user_id,
+ self.trust.trustor_user_id,
)
self.assertEqual(datalist, data)
-class TestTrustDelete(TestTrust):
+class TestTrustDelete(identity_fakes.TestIdentityv3):
def setUp(self):
super().setUp()
- # This is the return value for utils.find_resource()
- self.trusts_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.TRUST),
- loaded=True,
- )
- self.trusts_mock.delete.return_value = None
+ self.trust = sdk_fakes.generate_fake_resource(_trust.Trust)
+ self.identity_sdk_client.delete_trust.return_value = None
+ self.identity_sdk_client.find_trust.return_value = self.trust
# Get the command object to test
self.cmd = trust.DeleteTrust(self.app, None)
def test_trust_delete(self):
arglist = [
- identity_fakes.trust_id,
+ self.trust.id,
]
- verifylist = [('trust', [identity_fakes.trust_id])]
+ verifylist = [('trust', [self.trust.id])]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
- self.trusts_mock.delete.assert_called_with(
- identity_fakes.trust_id,
+ self.identity_sdk_client.delete_trust.assert_called_with(
+ self.trust.id,
)
self.assertIsNone(result)
- @mock.patch.object(utils, 'find_resource')
- def test_delete_multi_trusts_with_exception(self, find_mock):
- find_mock.side_effect = [
- self.trusts_mock.get.return_value,
- exceptions.CommandError,
- ]
+ def test_delete_multi_trusts_with_exception(self):
arglist = [
- identity_fakes.trust_id,
+ self.trust.id,
'unexist_trust',
]
verifylist = [
@@ -169,32 +141,37 @@ class TestTrustDelete(TestTrust):
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ self.identity_sdk_client.find_trust.side_effect = [
+ self.trust,
+ sdk_exceptions.ResourceNotFound,
+ ]
+
try:
self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.')
except exceptions.CommandError as e:
self.assertEqual('1 of 2 trusts failed to delete.', str(e))
- find_mock.assert_any_call(self.trusts_mock, identity_fakes.trust_id)
- find_mock.assert_any_call(self.trusts_mock, 'unexist_trust')
-
- self.assertEqual(2, find_mock.call_count)
- self.trusts_mock.delete.assert_called_once_with(
- identity_fakes.trust_id
+ self.identity_sdk_client.find_trust.assert_has_calls(
+ [
+ mock.call(self.trust.id, ignore_missing=False),
+ mock.call('unexist_trust', ignore_missing=False),
+ ]
+ )
+ self.identity_sdk_client.delete_trust.assert_called_once_with(
+ self.trust.id
)
-class TestTrustList(TestTrust):
+class TestTrustList(identity_fakes.TestIdentityv3):
def setUp(self):
super().setUp()
- self.trusts_mock.list.return_value = [
- fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.TRUST),
- loaded=True,
- ),
- ]
+ self.trust = sdk_fakes.generate_fake_resource(_trust.Trust)
+ self.identity_sdk_client.trusts.return_value = [self.trust]
+
+ self.user = sdk_fakes.generate_fake_resource(_user.User)
+ self.identity_sdk_client.find_user.return_value = self.user
# Get the command object to test
self.cmd = trust.ListTrust(self.app, None)
@@ -209,9 +186,9 @@ class TestTrustList(TestTrust):
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
- self.trusts_mock.list.assert_called_with(
- trustor_user=None,
- trustee_user=None,
+ self.identity_sdk_client.trusts.assert_called_with(
+ trustor_user_id=None,
+ trustee_user_id=None,
)
collist = (
@@ -225,19 +202,19 @@ class TestTrustList(TestTrust):
self.assertEqual(collist, columns)
datalist = (
(
- identity_fakes.trust_id,
- identity_fakes.trust_expires,
- identity_fakes.trust_impersonation,
- identity_fakes.project_id,
- identity_fakes.user_id,
- identity_fakes.user_id,
+ self.trust.id,
+ self.trust.expires_at,
+ self.trust.is_impersonation,
+ self.trust.project_id,
+ self.trust.trustee_user_id,
+ self.trust.trustor_user_id,
),
)
self.assertEqual(datalist, tuple(data))
def test_trust_list_auth_user(self):
- auth_ref = self.app.client_manager.auth_ref = mock.Mock()
- auth_ref.user_id.return_value = identity_fakes.user_id
+ self.app.client_manager.auth_ref = mock.Mock()
+ auth_ref = self.app.client_manager.auth_ref
arglist = ['--auth-user']
verifylist = [
@@ -252,11 +229,11 @@ class TestTrustList(TestTrust):
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
- self.trusts_mock.list.assert_any_call(
- trustor_user=self.users_mock.get()
- )
- self.trusts_mock.list.assert_any_call(
- trustee_user=self.users_mock.get()
+ self.identity_sdk_client.trusts.assert_has_calls(
+ [
+ mock.call(trustor_user_id=auth_ref.user_id),
+ mock.call(trustee_user_id=auth_ref.user_id),
+ ]
)
collist = (
@@ -270,21 +247,21 @@ class TestTrustList(TestTrust):
self.assertEqual(collist, columns)
datalist = (
(
- identity_fakes.trust_id,
- identity_fakes.trust_expires,
- identity_fakes.trust_impersonation,
- identity_fakes.project_id,
- identity_fakes.user_id,
- identity_fakes.user_id,
+ self.trust.id,
+ self.trust.expires_at,
+ self.trust.is_impersonation,
+ self.trust.project_id,
+ self.trust.trustee_user_id,
+ self.trust.trustor_user_id,
),
)
self.assertEqual(datalist, tuple(data))
def test_trust_list_trustee(self):
- arglist = ['--trustee', identity_fakes.user_name]
+ arglist = ['--trustee', self.user.name]
verifylist = [
('trustor', None),
- ('trustee', identity_fakes.user_name),
+ ('trustee', self.user.name),
('authuser', False),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -294,9 +271,9 @@ class TestTrustList(TestTrust):
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
- self.trusts_mock.list.assert_any_call(
- trustee_user=self.users_mock.get(),
- trustor_user=None,
+ self.identity_sdk_client.trusts.assert_called_with(
+ trustee_user_id=self.user.id,
+ trustor_user_id=None,
)
collist = (
@@ -310,21 +287,21 @@ class TestTrustList(TestTrust):
self.assertEqual(collist, columns)
datalist = (
(
- identity_fakes.trust_id,
- identity_fakes.trust_expires,
- identity_fakes.trust_impersonation,
- identity_fakes.project_id,
- identity_fakes.user_id,
- identity_fakes.user_id,
+ self.trust.id,
+ self.trust.expires_at,
+ self.trust.is_impersonation,
+ self.trust.project_id,
+ self.trust.trustee_user_id,
+ self.trust.trustor_user_id,
),
)
self.assertEqual(datalist, tuple(data))
def test_trust_list_trustor(self):
- arglist = ['--trustor', identity_fakes.user_name]
+ arglist = ['--trustor', self.user.name]
verifylist = [
('trustee', None),
- ('trustor', identity_fakes.user_name),
+ ('trustor', self.user.name),
('authuser', False),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -334,9 +311,9 @@ class TestTrustList(TestTrust):
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
- self.trusts_mock.list.assert_any_call(
- trustor_user=self.users_mock.get(),
- trustee_user=None,
+ self.identity_sdk_client.trusts.assert_called_once_with(
+ trustor_user_id=self.user.id,
+ trustee_user_id=None,
)
collist = (
@@ -350,36 +327,33 @@ class TestTrustList(TestTrust):
self.assertEqual(collist, columns)
datalist = (
(
- identity_fakes.trust_id,
- identity_fakes.trust_expires,
- identity_fakes.trust_impersonation,
- identity_fakes.project_id,
- identity_fakes.user_id,
- identity_fakes.user_id,
+ self.trust.id,
+ self.trust.expires_at,
+ self.trust.is_impersonation,
+ self.trust.project_id,
+ self.trust.trustee_user_id,
+ self.trust.trustor_user_id,
),
)
self.assertEqual(datalist, tuple(data))
-class TestTrustShow(TestTrust):
+class TestTrustShow(identity_fakes.TestIdentityv3):
def setUp(self):
super().setUp()
- self.trusts_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.TRUST),
- loaded=True,
- )
+ self.trust = sdk_fakes.generate_fake_resource(_trust.Trust)
+ self.identity_sdk_client.find_trust.return_value = self.trust
# Get the command object to test
self.cmd = trust.ShowTrust(self.app, None)
def test_trust_show(self):
arglist = [
- identity_fakes.trust_id,
+ self.trust.id,
]
verifylist = [
- ('trust', identity_fakes.trust_id),
+ ('trust', self.trust.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -388,25 +362,33 @@ class TestTrustShow(TestTrust):
# data to be shown.
columns, data = self.cmd.take_action(parsed_args)
- self.trusts_mock.get.assert_called_with(identity_fakes.trust_id)
+ self.identity_sdk_client.find_trust.assert_called_with(
+ self.trust.id, ignore_missing=False
+ )
collist = (
'expires_at',
'id',
- 'impersonation',
+ 'is_impersonation',
'project_id',
+ 'redelegated_trust_id',
+ 'redelegation_count',
+ 'remaining_uses',
'roles',
'trustee_user_id',
'trustor_user_id',
)
self.assertEqual(collist, columns)
datalist = (
- identity_fakes.trust_expires,
- identity_fakes.trust_id,
- identity_fakes.trust_impersonation,
- identity_fakes.project_id,
- identity_fakes.role_name,
- identity_fakes.user_id,
- identity_fakes.user_id,
+ self.trust.expires_at,
+ self.trust.id,
+ self.trust.is_impersonation,
+ self.trust.project_id,
+ self.trust.redelegated_trust_id,
+ self.trust.redelegation_count,
+ self.trust.remaining_uses,
+ self.trust.roles,
+ self.trust.trustee_user_id,
+ self.trust.trustor_user_id,
)
self.assertEqual(datalist, data)
diff --git a/openstackclient/tests/unit/image/v2/test_image.py b/openstackclient/tests/unit/image/v2/test_image.py
index e8aafa8..69a65a5 100644
--- a/openstackclient/tests/unit/image/v2/test_image.py
+++ b/openstackclient/tests/unit/image/v2/test_image.py
@@ -55,6 +55,7 @@ class TestImageCreate(TestImage):
self.new_image = image_fakes.create_one_image()
self.image_client.create_image.return_value = self.new_image
self.image_client.update_image.return_value = self.new_image
+ self.image_client.get_image.return_value = self.new_image
self.project_mock.get.return_value = self.project
@@ -89,6 +90,7 @@ class TestImageCreate(TestImage):
container_format=_image.DEFAULT_CONTAINER_FORMAT,
disk_format=_image.DEFAULT_DISK_FORMAT,
)
+ self.image_client.get_image.assert_called_once_with(self.new_image)
self.assertEqual(self.expected_columns, columns)
self.assertCountEqual(self.expected_data, data)
@@ -146,6 +148,7 @@ class TestImageCreate(TestImage):
is_protected=self.new_image.is_protected,
visibility=self.new_image.visibility,
)
+ self.image_client.get_image.assert_called_once_with(self.new_image)
self.assertEqual(self.expected_columns, columns)
self.assertCountEqual(self.expected_data, data)
@@ -243,6 +246,7 @@ class TestImageCreate(TestImage):
tags=self.new_image.tags,
filename=imagefile.name,
)
+ self.image_client.get_image.assert_called_once_with(self.new_image)
self.assertEqual(self.expected_columns, columns)
self.assertCountEqual(self.expected_data, data)
@@ -275,6 +279,7 @@ class TestImageCreate(TestImage):
data=fake_stdin,
validate_checksum=False,
)
+ self.image_client.get_image.assert_called_once_with(self.new_image)
self.assertEqual(self.expected_columns, columns)
self.assertCountEqual(self.expected_data, data)
@@ -315,6 +320,7 @@ class TestImageCreate(TestImage):
disk_format=_image.DEFAULT_DISK_FORMAT,
use_import=True,
)
+ self.image_client.get_image.assert_called_once_with(self.new_image)
@mock.patch('osc_lib.utils.find_resource')
@mock.patch('openstackclient.image.v2.image.get_data_from_stdin')
diff --git a/openstackclient/tests/unit/network/v2/fakes.py b/openstackclient/tests/unit/network/v2/fakes.py
index 999e102..d0b1c1e 100644
--- a/openstackclient/tests/unit/network/v2/fakes.py
+++ b/openstackclient/tests/unit/network/v2/fakes.py
@@ -1419,6 +1419,7 @@ def create_one_network(attrs=None):
'availability_zone_hints': [],
'is_default': False,
'is_vlan_transparent': True,
+ 'is_vlan_qinq': False,
'port_security_enabled': True,
'qos_policy_id': 'qos-policy-id-' + uuid.uuid4().hex,
'ipv4_address_scope': 'ipv4' + uuid.uuid4().hex,
@@ -1676,8 +1677,10 @@ def create_one_port(attrs=None):
'qos_network_policy_id': 'qos-policy-id-' + uuid.uuid4().hex,
'qos_policy_id': 'qos-policy-id-' + uuid.uuid4().hex,
'tags': [],
+ 'trusted': None,
'propagate_uplink_status': False,
'location': 'MUNCHMUNCHMUNCH',
+ 'trunk_details': {},
}
# Overwrite default attributes.
diff --git a/openstackclient/tests/unit/network/v2/test_network.py b/openstackclient/tests/unit/network/v2/test_network.py
index 33fe5be..0222be6 100644
--- a/openstackclient/tests/unit/network/v2/test_network.py
+++ b/openstackclient/tests/unit/network/v2/test_network.py
@@ -63,6 +63,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
'ipv6_address_scope',
'is_default',
'is_vlan_transparent',
+ 'is_vlan_qinq',
'mtu',
'name',
'port_security_enabled',
@@ -103,6 +104,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
network.RouterExternalColumn(_network.is_router_external),
_network.is_shared,
_network.is_vlan_transparent,
+ _network.is_vlan_qinq,
_network.status,
_network.segments,
format_columns.ListColumn(_network.subnet_ids),
@@ -190,6 +192,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
"--qos-policy",
self.qos_policy.id,
"--transparent-vlan",
+ "--no-qinq-vlan",
"--enable-port-security",
"--dns-domain",
"example.org.",
@@ -210,6 +213,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
('segmentation_id', '400'),
('qos_policy', self.qos_policy.id),
('transparent_vlan', True),
+ ('qinq_vlan', False),
('enable_port_security', True),
('name', self._network.name),
('dns_domain', 'example.org.'),
@@ -234,6 +238,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
'provider:segmentation_id': '400',
'qos_policy_id': self.qos_policy.id,
'vlan_transparent': True,
+ 'vlan_qinq': False,
'port_security_enabled': True,
'dns_domain': 'example.org.',
}
@@ -246,6 +251,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
"--enable",
"--no-share",
"--disable-port-security",
+ "--qinq-vlan",
self._network.name,
]
verifylist = [
@@ -253,6 +259,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
('no_share', True),
('name', self._network.name),
('external', False),
+ ('qinq_vlan', True),
('disable_port_security', True),
]
@@ -264,6 +271,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
'admin_state_up': True,
'name': self._network.name,
'shared': False,
+ 'vlan_qinq': True,
'port_security_enabled': False,
}
)
@@ -309,6 +317,19 @@ class TestCreateNetworkIdentityV3(TestNetwork):
def test_create_with_no_tag(self):
self._test_create_with_tag(add_tags=False)
+ def test_create_with_vlan_qinq_and_transparency_enabled(self):
+ arglist = [
+ "--transparent-vlan",
+ "--qinq-vlan",
+ self._network.name,
+ ]
+ verifylist = []
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ self.assertRaises(
+ exceptions.CommandError, self.cmd.take_action, parsed_args
+ )
+
class TestCreateNetworkIdentityV2(
identity_fakes_v2.FakeClientMixin,
@@ -332,6 +353,7 @@ class TestCreateNetworkIdentityV2(
'ipv6_address_scope',
'is_default',
'is_vlan_transparent',
+ 'is_vlan_qinq',
'mtu',
'name',
'port_security_enabled',
@@ -372,6 +394,7 @@ class TestCreateNetworkIdentityV2(
network.RouterExternalColumn(_network.is_router_external),
_network.is_shared,
_network.is_vlan_transparent,
+ _network.is_vlan_qinq,
_network.status,
_network.segments,
format_columns.ListColumn(_network.subnet_ids),
@@ -1149,6 +1172,7 @@ class TestShowNetwork(TestNetwork):
'ipv6_address_scope',
'is_default',
'is_vlan_transparent',
+ 'is_vlan_qinq',
'mtu',
'name',
'port_security_enabled',
@@ -1189,6 +1213,7 @@ class TestShowNetwork(TestNetwork):
network.RouterExternalColumn(_network.is_router_external),
_network.is_shared,
_network.is_vlan_transparent,
+ _network.is_vlan_qinq,
_network.status,
_network.segments,
format_columns.ListColumn(_network.subnet_ids),
diff --git a/openstackclient/tests/unit/network/v2/test_network_flavor_profile.py b/openstackclient/tests/unit/network/v2/test_network_flavor_profile.py
index 44cc4f4..d94926c 100644
--- a/openstackclient/tests/unit/network/v2/test_network_flavor_profile.py
+++ b/openstackclient/tests/unit/network/v2/test_network_flavor_profile.py
@@ -23,14 +23,11 @@ class TestFlavorProfile(network_fakes.TestNetworkV2):
def setUp(self):
super().setUp()
- # Get the ProjectManager Mock
- self.projects_mock = self.identity_client.projects
# Get the DomainManager Mock
self.domains_mock = self.identity_client.domains
class TestCreateFlavorProfile(TestFlavorProfile):
- project = identity_fakes_v3.FakeProject.create_one_project()
domain = identity_fakes_v3.FakeDomain.create_one_domain()
new_flavor_profile = network_fakes.create_one_service_profile()
@@ -40,7 +37,6 @@ class TestCreateFlavorProfile(TestFlavorProfile):
'enabled',
'id',
'meta_info',
- 'project_id',
)
data = (
@@ -49,7 +45,6 @@ class TestCreateFlavorProfile(TestFlavorProfile):
new_flavor_profile.is_enabled,
new_flavor_profile.id,
new_flavor_profile.meta_info,
- new_flavor_profile.project_id,
)
def setUp(self):
@@ -57,7 +52,6 @@ class TestCreateFlavorProfile(TestFlavorProfile):
self.network_client.create_service_profile = mock.Mock(
return_value=self.new_flavor_profile
)
- self.projects_mock.get.return_value = self.project
# Get the command object to test
self.cmd = network_flavor_profile.CreateNetworkFlavorProfile(
self.app, None
@@ -67,10 +61,6 @@ class TestCreateFlavorProfile(TestFlavorProfile):
arglist = [
"--description",
self.new_flavor_profile.description,
- "--project",
- self.new_flavor_profile.project_id,
- '--project-domain',
- self.domain.name,
"--enable",
"--driver",
self.new_flavor_profile.driver,
@@ -80,8 +70,6 @@ class TestCreateFlavorProfile(TestFlavorProfile):
verifylist = [
('description', self.new_flavor_profile.description),
- ('project', self.new_flavor_profile.project_id),
- ('project_domain', self.domain.name),
('enable', True),
('driver', self.new_flavor_profile.driver),
('metainfo', self.new_flavor_profile.meta_info),
@@ -93,7 +81,6 @@ class TestCreateFlavorProfile(TestFlavorProfile):
self.network_client.create_service_profile.assert_called_once_with(
**{
'description': self.new_flavor_profile.description,
- 'project_id': self.project.id,
'enabled': self.new_flavor_profile.is_enabled,
'driver': self.new_flavor_profile.driver,
'metainfo': self.new_flavor_profile.meta_info,
@@ -106,10 +93,6 @@ class TestCreateFlavorProfile(TestFlavorProfile):
arglist = [
"--description",
self.new_flavor_profile.description,
- "--project",
- self.new_flavor_profile.project_id,
- '--project-domain',
- self.domain.name,
"--enable",
"--metainfo",
self.new_flavor_profile.meta_info,
@@ -117,8 +100,6 @@ class TestCreateFlavorProfile(TestFlavorProfile):
verifylist = [
('description', self.new_flavor_profile.description),
- ('project', self.new_flavor_profile.project_id),
- ('project_domain', self.domain.name),
('enable', True),
('metainfo', self.new_flavor_profile.meta_info),
]
@@ -129,7 +110,6 @@ class TestCreateFlavorProfile(TestFlavorProfile):
self.network_client.create_service_profile.assert_called_once_with(
**{
'description': self.new_flavor_profile.description,
- 'project_id': self.project.id,
'enabled': self.new_flavor_profile.is_enabled,
'metainfo': self.new_flavor_profile.meta_info,
}
@@ -141,10 +121,6 @@ class TestCreateFlavorProfile(TestFlavorProfile):
arglist = [
"--description",
self.new_flavor_profile.description,
- "--project",
- self.new_flavor_profile.project_id,
- '--project-domain',
- self.domain.name,
"--enable",
"--driver",
self.new_flavor_profile.driver,
@@ -152,8 +128,6 @@ class TestCreateFlavorProfile(TestFlavorProfile):
verifylist = [
('description', self.new_flavor_profile.description),
- ('project', self.new_flavor_profile.project_id),
- ('project_domain', self.domain.name),
('enable', True),
('driver', self.new_flavor_profile.driver),
]
@@ -164,7 +138,6 @@ class TestCreateFlavorProfile(TestFlavorProfile):
self.network_client.create_service_profile.assert_called_once_with(
**{
'description': self.new_flavor_profile.description,
- 'project_id': self.project.id,
'enabled': self.new_flavor_profile.is_enabled,
'driver': self.new_flavor_profile.driver,
}
@@ -176,17 +149,11 @@ class TestCreateFlavorProfile(TestFlavorProfile):
arglist = [
"--description",
self.new_flavor_profile.description,
- "--project",
- self.new_flavor_profile.project_id,
- '--project-domain',
- self.domain.name,
"--enable",
]
verifylist = [
('description', self.new_flavor_profile.description),
- ('project', self.new_flavor_profile.project_id),
- ('project_domain', self.domain.name),
('enable', True),
]
@@ -377,7 +344,6 @@ class TestShowFlavorProfile(TestFlavorProfile):
'enabled',
'id',
'meta_info',
- 'project_id',
)
data = (
network_flavor_profile.description,
@@ -385,7 +351,6 @@ class TestShowFlavorProfile(TestFlavorProfile):
network_flavor_profile.is_enabled,
network_flavor_profile.id,
network_flavor_profile.meta_info,
- network_flavor_profile.project_id,
)
def setUp(self):
diff --git a/openstackclient/tests/unit/network/v2/test_port.py b/openstackclient/tests/unit/network/v2/test_port.py
index 81f3cd7..3f521a4 100644
--- a/openstackclient/tests/unit/network/v2/test_port.py
+++ b/openstackclient/tests/unit/network/v2/test_port.py
@@ -12,6 +12,7 @@
from unittest import mock
from unittest.mock import call
+import uuid
from osc_lib.cli import format_columns
from osc_lib import exceptions
@@ -23,8 +24,13 @@ from openstackclient.tests.unit.network.v2 import fakes as network_fakes
from openstackclient.tests.unit import utils as test_utils
-LIST_FIELDS_TO_RETRIEVE = ('id', 'name', 'mac_address', 'fixed_ips', 'status')
-LIST_FIELDS_TO_RETRIEVE_LONG = ('security_group_ids', 'device_owner', 'tags')
+LIST_FIELDS_TO_RETRIEVE = ['id', 'name', 'mac_address', 'fixed_ips', 'status']
+LIST_FIELDS_TO_RETRIEVE_LONG = [
+ 'security_groups',
+ 'device_owner',
+ 'tags',
+ 'trunk_details',
+]
class TestPort(network_fakes.TestNetworkV2):
@@ -73,6 +79,7 @@ class TestPort(network_fakes.TestNetworkV2):
'security_group_ids',
'status',
'tags',
+ 'trusted',
'trunk_details',
'updated_at',
)
@@ -114,6 +121,7 @@ class TestPort(network_fakes.TestNetworkV2):
format_columns.ListColumn(fake_port.security_group_ids),
fake_port.status,
format_columns.ListColumn(fake_port.tags),
+ fake_port.trusted,
fake_port.trunk_details,
fake_port.updated_at,
)
@@ -330,7 +338,7 @@ class TestCreatePort(TestPort):
self._port.network_id,
),
('enable', True),
- ('security_group', [secgroup.id]),
+ ('security_groups', [secgroup.id]),
('name', 'test-port'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -403,7 +411,7 @@ class TestCreatePort(TestPort):
self._port.network_id,
),
('enable', True),
- ('security_group', [sg_1.id, sg_2.id]),
+ ('security_groups', [sg_1.id, sg_2.id]),
('name', 'test-port'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -432,7 +440,7 @@ class TestCreatePort(TestPort):
verifylist = [
('network', self._port.network_id),
('enable', True),
- ('no_security_group', True),
+ ('security_groups', []),
('name', 'test-port'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1111,6 +1119,50 @@ class TestCreatePort(TestPort):
def test_create_with_hardware_offload_type_null(self):
self._test_create_with_hardware_offload_type()
+ def _test_create_with_trusted_field(self, trusted):
+ arglist = [
+ '--network',
+ self._port.network_id,
+ 'test-port',
+ ]
+ if trusted:
+ arglist += ['--trusted']
+ else:
+ arglist += ['--not-trusted']
+
+ verifylist = [
+ (
+ 'network',
+ self._port.network_id,
+ ),
+ ('name', 'test-port'),
+ ]
+ if trusted:
+ verifylist.append(('trusted', True))
+ else:
+ verifylist.append(('trusted', False))
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ create_args = {
+ 'admin_state_up': True,
+ 'network_id': self._port.network_id,
+ 'name': 'test-port',
+ }
+ create_args['trusted'] = trusted
+ self.network_client.create_port.assert_called_once_with(**create_args)
+
+ self.assertEqual(set(self.columns), set(columns))
+ self.assertCountEqual(self.data, data)
+
+ def test_create_with_trusted_true(self):
+ self._test_create_with_trusted_field(True)
+
+ def test_create_with_trusted_false(self):
+ self._test_create_with_trusted_field(False)
+
class TestDeletePort(TestPort):
# Ports to delete.
@@ -1190,17 +1242,47 @@ class TestDeletePort(TestPort):
class TestListPort(compute_fakes.FakeClientMixin, TestPort):
- _ports = network_fakes.create_ports(count=3)
+ _project = identity_fakes.FakeProject.create_one_project()
+ _networks = network_fakes.create_networks(count=3)
+ _sport1 = network_fakes.create_one_port(
+ attrs={'project_id': _project.id, 'network_id': _networks[1]['id']}
+ )
+ _sport2 = network_fakes.create_one_port(
+ attrs={'project_id': _project.id, 'network_id': _networks[2]['id']}
+ )
+ _trunk_details = {
+ 'trunk_id': str(uuid.uuid4()),
+ 'sub_ports': [
+ {
+ 'segmentation_id': 100,
+ 'segmentation_type': 'vlan',
+ 'port_id': _sport1.id,
+ },
+ {
+ 'segmentation_id': 102,
+ 'segmentation_type': 'vlan',
+ 'port_id': _sport2.id,
+ },
+ ],
+ }
+ _pport = network_fakes.create_one_port(
+ attrs={
+ 'project_id': _project.id,
+ 'network_id': _networks[0]['id'],
+ 'trunk_details': _trunk_details,
+ }
+ )
+ _ports = (_pport, _sport1, _sport2)
- columns = (
+ columns = [
'ID',
'Name',
'MAC Address',
'Fixed IP Addresses',
'Status',
- )
+ ]
- columns_long = (
+ columns_long = [
'ID',
'Name',
'MAC Address',
@@ -1209,7 +1291,8 @@ class TestListPort(compute_fakes.FakeClientMixin, TestPort):
'Security Groups',
'Device Owner',
'Tags',
- )
+ 'Trunk subports',
+ ]
data = []
for prt in _ports:
@@ -1235,6 +1318,7 @@ class TestListPort(compute_fakes.FakeClientMixin, TestPort):
format_columns.ListColumn(prt.security_group_ids),
prt.device_owner,
format_columns.ListColumn(prt.tags),
+ port.SubPortColumn(prt.trunk_details),
)
)
@@ -2021,7 +2105,7 @@ class TestSetPort(TestPort):
self._port.name,
]
verifylist = [
- ('security_group', [sg.id]),
+ ('security_groups', [sg.id]),
('port', self._port.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -2054,7 +2138,7 @@ class TestSetPort(TestPort):
_testport.name,
]
verifylist = [
- ('security_group', [sg_2.id, sg_3.id]),
+ ('security_groups', [sg_2.id, sg_3.id]),
('port', _testport.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -2103,7 +2187,7 @@ class TestSetPort(TestPort):
_testport.name,
]
verifylist = [
- ('security_group', [sg2.id]),
+ ('security_groups', [sg2.id]),
('no_security_group', True),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -2520,6 +2604,64 @@ class TestSetPort(TestPort):
)
self.assertIsNone(result)
+ def _test_set_trusted_field(self, trusted):
+ arglist = [self._port.id]
+ if trusted:
+ arglist += ['--trusted']
+ else:
+ arglist += ['--not-trusted']
+
+ verifylist = [
+ ('port', self._port.id),
+ ]
+ if trusted:
+ verifylist.append(('trusted', True))
+ else:
+ verifylist.append(('trusted', False))
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.network_client.update_port.assert_called_once_with(
+ self._port, **{'trusted': trusted}
+ )
+ self.assertIsNone(result)
+
+ def test_set_trusted_true(self):
+ self._test_set_trusted_field(True)
+
+ def test_set_trusted_false(self):
+ self._test_set_trusted_field(False)
+
+ def _test_set_uplink_status_propagation(self, uspropagation):
+ arglist = [self._port.id]
+ if uspropagation:
+ arglist += ['--enable-uplink-status-propagation']
+ else:
+ arglist += ['--disable-uplink-status-propagation']
+
+ verifylist = [
+ ('port', self._port.id),
+ ]
+ if uspropagation:
+ verifylist.append(('enable_uplink_status_propagation', True))
+ else:
+ verifylist.append(('enable_uplink_status_propagation', False))
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.network_client.update_port.assert_called_once_with(
+ self._port, **{'propagate_uplink_status': uspropagation}
+ )
+ self.assertIsNone(result)
+
+ def test_set_uplink_status_propagation_true(self):
+ self._test_set_uplink_status_propagation(True)
+
+ def test_set_uplink_status_propagation_false(self):
+ self._test_set_uplink_status_propagation(False)
+
class TestShowPort(TestPort):
# The port to show.
@@ -2695,7 +2837,7 @@ class TestUnsetPort(TestPort):
_fake_port.name,
]
verifylist = [
- ('security_group_ids', [_fake_sg2.id]),
+ ('security_groups', [_fake_sg2.id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -2722,7 +2864,7 @@ class TestUnsetPort(TestPort):
_fake_port.name,
]
verifylist = [
- ('security_group_ids', [_fake_sg2.id]),
+ ('security_groups', [_fake_sg2.id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/unit/network/v2/test_router.py b/openstackclient/tests/unit/network/v2/test_router.py
index e420f80..aa6de7d 100644
--- a/openstackclient/tests/unit/network/v2/test_router.py
+++ b/openstackclient/tests/unit/network/v2/test_router.py
@@ -384,7 +384,7 @@ class TestCreateRouter(TestRouter):
def test_create_with_no_tag(self):
self._test_create_with_tag(add_tags=False)
- def test_create_with_flavor_id_or_name(self):
+ def test_create_with_flavor_id_id(self):
_flavor = network_fakes.create_one_network_flavor()
self.network_client.find_flavor = mock.Mock(return_value=_flavor)
arglist = [
@@ -392,7 +392,6 @@ class TestCreateRouter(TestRouter):
'--flavor-id',
_flavor.id,
]
- arglist_with_name = [self.new_router.name, '--flavor-id', _flavor.name]
verifylist = [
('name', self.new_router.name),
('enable', True),
@@ -412,18 +411,69 @@ class TestCreateRouter(TestRouter):
self.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, data)
- self.network_client.create_router.reset_mock()
- verifylist_w_name = [
+ def test_create_with_flavor_id_name(self):
+ _flavor = network_fakes.create_one_network_flavor()
+ self.network_client.find_flavor = mock.Mock(return_value=_flavor)
+ arglist = [self.new_router.name, '--flavor-id', _flavor.name]
+ verifylist = [
('name', self.new_router.name),
('enable', True),
('distributed', False),
('ha', False),
('flavor_id', _flavor.name),
]
- parsed_args_w_name = self.check_parser(
- self.cmd, arglist_with_name, verifylist_w_name
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+ self.network_client.create_router.assert_called_once_with(
+ **{
+ 'admin_state_up': True,
+ 'name': self.new_router.name,
+ 'flavor_id': _flavor.id,
+ }
+ )
+ self.assertEqual(self.columns, columns)
+ self.assertCountEqual(self.data, data)
+
+ def test_create_with_flavor_id(self):
+ _flavor = network_fakes.create_one_network_flavor()
+ self.network_client.find_flavor = mock.Mock(return_value=_flavor)
+ arglist = [
+ self.new_router.name,
+ '--flavor',
+ _flavor.id,
+ ]
+ verifylist = [
+ ('name', self.new_router.name),
+ ('enable', True),
+ ('distributed', False),
+ ('ha', False),
+ ('flavor', _flavor.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+ self.network_client.create_router.assert_called_once_with(
+ **{
+ 'admin_state_up': True,
+ 'name': self.new_router.name,
+ 'flavor_id': _flavor.id,
+ }
)
- columns, data = self.cmd.take_action(parsed_args_w_name)
+ self.assertEqual(self.columns, columns)
+ self.assertCountEqual(self.data, data)
+
+ def test_create_with_flavor_name(self):
+ _flavor = network_fakes.create_one_network_flavor()
+ self.network_client.find_flavor = mock.Mock(return_value=_flavor)
+ arglist = [self.new_router.name, '--flavor', _flavor.name]
+ verifylist = [
+ ('name', self.new_router.name),
+ ('enable', True),
+ ('distributed', False),
+ ('ha', False),
+ ('flavor', _flavor.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
self.network_client.create_router.assert_called_once_with(
**{
'admin_state_up': True,
diff --git a/openstackclient/tests/unit/utils.py b/openstackclient/tests/unit/utils.py
index 2a39ca4..607047f 100644
--- a/openstackclient/tests/unit/utils.py
+++ b/openstackclient/tests/unit/utils.py
@@ -93,8 +93,14 @@ class TestCommand(TestCase):
f"Argument parse failed: {stderr.getvalue()}"
)
for av in verify_args:
- attr, value = av
+ attr, expected_value = av
if attr:
+ actual_value = getattr(parsed_args, attr)
self.assertIn(attr, parsed_args)
- self.assertEqual(value, getattr(parsed_args, attr))
+ self.assertEqual(
+ expected_value,
+ actual_value,
+ f'args.{attr}: expected: {expected_value}, got: '
+ f'{actual_value}',
+ )
return parsed_args
diff --git a/openstackclient/tests/unit/volume/v2/test_volume_backup.py b/openstackclient/tests/unit/volume/v2/test_volume_backup.py
index 483ca24..faf2489 100644
--- a/openstackclient/tests/unit/volume/v2/test_volume_backup.py
+++ b/openstackclient/tests/unit/volume/v2/test_volume_backup.py
@@ -364,16 +364,28 @@ class TestBackupRestore(volume_fakes.TestVolume):
attrs={'volume_id': volume.id},
)
+ columns = (
+ "id",
+ "volume_id",
+ "volume_name",
+ )
+
+ data = (
+ backup.id,
+ volume.id,
+ volume.name,
+ )
+
def setUp(self):
super().setUp()
self.volume_sdk_client.find_backup.return_value = self.backup
self.volume_sdk_client.find_volume.return_value = self.volume
- self.volume_sdk_client.restore_backup.return_value = (
- volume_fakes.create_one_volume(
- {'id': self.volume['id']},
- )
- )
+ self.volume_sdk_client.restore_backup.return_value = {
+ 'id': self.backup['id'],
+ 'volume_id': self.volume['id'],
+ 'volume_name': self.volume['name'],
+ }
# Get the command object to mock
self.cmd = volume_backup.RestoreVolumeBackup(self.app, None)
@@ -389,13 +401,15 @@ class TestBackupRestore(volume_fakes.TestVolume):
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- result = self.cmd.take_action(parsed_args)
+ columns, data = self.cmd.take_action(parsed_args)
self.volume_sdk_client.restore_backup.assert_called_with(
self.backup.id,
volume_id=None,
name=None,
)
- self.assertIsNotNone(result)
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
def test_backup_restore_with_volume(self):
self.volume_sdk_client.find_volume.side_effect = (
@@ -411,13 +425,15 @@ class TestBackupRestore(volume_fakes.TestVolume):
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- result = self.cmd.take_action(parsed_args)
+ columns, data = self.cmd.take_action(parsed_args)
self.volume_sdk_client.restore_backup.assert_called_with(
self.backup.id,
volume_id=None,
name=self.backup.volume_id,
)
- self.assertIsNotNone(result)
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
def test_backup_restore_with_volume_force(self):
arglist = [
@@ -432,13 +448,15 @@ class TestBackupRestore(volume_fakes.TestVolume):
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- result = self.cmd.take_action(parsed_args)
+ columns, data = self.cmd.take_action(parsed_args)
self.volume_sdk_client.restore_backup.assert_called_with(
self.backup.id,
volume_id=self.volume.id,
name=None,
)
- self.assertIsNotNone(result)
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
def test_backup_restore_with_volume_existing(self):
arglist = [
@@ -544,7 +562,7 @@ class TestBackupShow(volume_fakes.TestVolume):
def setUp(self):
super().setUp()
- self.volume_sdk_client.get_backup.return_value = self.backup
+ self.volume_sdk_client.find_backup.return_value = self.backup
# Get the command object to test
self.cmd = volume_backup.ShowVolumeBackup(self.app, None)
@@ -554,7 +572,7 @@ class TestBackupShow(volume_fakes.TestVolume):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- self.volume_sdk_client.get_backup.assert_called_with(self.backup.id)
+ self.volume_sdk_client.find_backup.assert_called_with(self.backup.id)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
diff --git a/openstackclient/tests/unit/volume/v3/test_volume_backup.py b/openstackclient/tests/unit/volume/v3/test_volume_backup.py
index d4e7e79..fb0a465 100644
--- a/openstackclient/tests/unit/volume/v3/test_volume_backup.py
+++ b/openstackclient/tests/unit/volume/v3/test_volume_backup.py
@@ -333,6 +333,7 @@ class TestBackupList(volume_fakes.TestVolume):
'Status',
'Size',
'Incremental',
+ 'Created At',
)
columns_long = columns + (
'Availability Zone',
@@ -350,6 +351,7 @@ class TestBackupList(volume_fakes.TestVolume):
b.status,
b.size,
b.is_incremental,
+ b.created_at,
)
)
data_long = []
@@ -362,6 +364,7 @@ class TestBackupList(volume_fakes.TestVolume):
b.status,
b.size,
b.is_incremental,
+ b.created_at,
b.availability_zone,
volume_backup.VolumeIdColumn(b.volume_id),
b.container,
@@ -459,16 +462,28 @@ class TestBackupRestore(volume_fakes.TestVolume):
attrs={'volume_id': volume.id},
)
+ columns = (
+ "id",
+ "volume_id",
+ "volume_name",
+ )
+
+ data = (
+ backup.id,
+ volume.id,
+ volume.name,
+ )
+
def setUp(self):
super().setUp()
self.volume_sdk_client.find_backup.return_value = self.backup
self.volume_sdk_client.find_volume.return_value = self.volume
- self.volume_sdk_client.restore_backup.return_value = (
- volume_fakes.create_one_volume(
- {'id': self.volume['id']},
- )
- )
+ self.volume_sdk_client.restore_backup.return_value = {
+ 'id': self.backup['id'],
+ 'volume_id': self.volume['id'],
+ 'volume_name': self.volume['name'],
+ }
# Get the command object to mock
self.cmd = volume_backup.RestoreVolumeBackup(self.app, None)
@@ -484,13 +499,15 @@ class TestBackupRestore(volume_fakes.TestVolume):
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- result = self.cmd.take_action(parsed_args)
+ columns, data = self.cmd.take_action(parsed_args)
self.volume_sdk_client.restore_backup.assert_called_with(
self.backup.id,
volume_id=None,
name=None,
)
- self.assertIsNotNone(result)
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
def test_backup_restore_with_volume(self):
self.volume_sdk_client.find_volume.side_effect = (
@@ -506,13 +523,15 @@ class TestBackupRestore(volume_fakes.TestVolume):
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- result = self.cmd.take_action(parsed_args)
+ columns, data = self.cmd.take_action(parsed_args)
self.volume_sdk_client.restore_backup.assert_called_with(
self.backup.id,
volume_id=None,
name=self.backup.volume_id,
)
- self.assertIsNotNone(result)
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
def test_backup_restore_with_volume_force(self):
arglist = [
@@ -527,13 +546,15 @@ class TestBackupRestore(volume_fakes.TestVolume):
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- result = self.cmd.take_action(parsed_args)
+ columns, data = self.cmd.take_action(parsed_args)
self.volume_sdk_client.restore_backup.assert_called_with(
self.backup.id,
volume_id=self.volume.id,
name=None,
)
- self.assertIsNotNone(result)
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
def test_backup_restore_with_volume_existing(self):
arglist = [
@@ -876,7 +897,7 @@ class TestBackupShow(volume_fakes.TestVolume):
def setUp(self):
super().setUp()
- self.volume_sdk_client.get_backup.return_value = self.backup
+ self.volume_sdk_client.find_backup.return_value = self.backup
# Get the command object to test
self.cmd = volume_backup.ShowVolumeBackup(self.app, None)
@@ -886,7 +907,7 @@ class TestBackupShow(volume_fakes.TestVolume):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- self.volume_sdk_client.get_backup.assert_called_with(self.backup.id)
+ self.volume_sdk_client.find_backup.assert_called_with(self.backup.id)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
diff --git a/openstackclient/volume/v2/volume_backup.py b/openstackclient/volume/v2/volume_backup.py
index fd59c0c..3c7b42e 100644
--- a/openstackclient/volume/v2/volume_backup.py
+++ b/openstackclient/volume/v2/volume_backup.py
@@ -359,6 +359,12 @@ class RestoreVolumeBackup(command.ShowOne):
ignore_missing=False,
)
+ columns = (
+ 'id',
+ 'volume_id',
+ 'volume_name',
+ )
+
volume_name = None
volume_id = None
try:
@@ -378,12 +384,15 @@ class RestoreVolumeBackup(command.ShowOne):
)
raise exceptions.CommandError(msg % parsed_args.volume)
- return volume_client.restore_backup(
+ restore = volume_client.restore_backup(
backup.id,
volume_id=volume_id,
name=volume_name,
)
+ data = utils.get_dict_properties(restore, columns)
+ return (columns, data)
+
class SetVolumeBackup(command.Command):
_description = _("Set volume backup properties")
@@ -439,7 +448,7 @@ class ShowVolumeBackup(command.ShowOne):
def take_action(self, parsed_args):
volume_client = self.app.client_manager.sdk_connection.volume
- backup = volume_client.get_backup(parsed_args.backup)
+ backup = volume_client.find_backup(parsed_args.backup)
columns = (
"availability_zone",
"container",
diff --git a/openstackclient/volume/v3/volume_backup.py b/openstackclient/volume/v3/volume_backup.py
index 471b4ce..dce5646 100644
--- a/openstackclient/volume/v3/volume_backup.py
+++ b/openstackclient/volume/v3/volume_backup.py
@@ -305,6 +305,7 @@ class ListVolumeBackup(command.Lister):
'status',
'size',
'is_incremental',
+ 'created_at',
)
column_headers = (
'ID',
@@ -313,6 +314,7 @@ class ListVolumeBackup(command.Lister):
'Status',
'Size',
'Incremental',
+ 'Created At',
)
if parsed_args.long:
columns += ('availability_zone', 'volume_id', 'container')
@@ -410,6 +412,12 @@ class RestoreVolumeBackup(command.ShowOne):
def take_action(self, parsed_args):
volume_client = self.app.client_manager.sdk_connection.volume
+ columns = (
+ 'id',
+ 'volume_id',
+ 'volume_name',
+ )
+
backup = volume_client.find_backup(
parsed_args.backup,
ignore_missing=False,
@@ -434,12 +442,15 @@ class RestoreVolumeBackup(command.ShowOne):
)
raise exceptions.CommandError(msg % parsed_args.volume)
- return volume_client.restore_backup(
+ restore = volume_client.restore_backup(
backup.id,
volume_id=volume_id,
name=volume_name,
)
+ data = utils.get_dict_properties(restore, columns)
+ return (columns, data)
+
class SetVolumeBackup(command.Command):
_description = _("Set volume backup properties")
@@ -643,7 +654,7 @@ class ShowVolumeBackup(command.ShowOne):
def take_action(self, parsed_args):
volume_client = self.app.client_manager.sdk_connection.volume
- backup = volume_client.get_backup(parsed_args.backup)
+ backup = volume_client.find_backup(parsed_args.backup)
columns = (
"availability_zone",
"container",
diff --git a/python_openstackclient.egg-info/PKG-INFO b/python_openstackclient.egg-info/PKG-INFO
index 5b0b4cc..619eb75 100644
--- a/python_openstackclient.egg-info/PKG-INFO
+++ b/python_openstackclient.egg-info/PKG-INFO
@@ -1,152 +1,10 @@
-Metadata-Version: 1.2
+Metadata-Version: 2.1
Name: python-openstackclient
-Version: 7.2.1
+Version: 7.4.0
Summary: OpenStack Command-line Client
Home-page: https://docs.openstack.org/python-openstackclient/latest/
Author: OpenStack
Author-email: openstack-discuss@lists.openstack.org
-License: UNKNOWN
-Description: ========================
- Team and repository tags
- ========================
-
- .. image:: https://governance.openstack.org/tc/badges/python-openstackclient.svg
- :target: https://governance.openstack.org/tc/reference/tags/index.html
-
- .. Change things from this point on
-
- ===============
- OpenStackClient
- ===============
-
- .. image:: https://img.shields.io/pypi/v/python-openstackclient.svg
- :target: https://pypi.org/project/python-openstackclient/
- :alt: Latest Version
-
- OpenStackClient (aka OSC) is a command-line client for OpenStack that brings
- the command set for Compute, Identity, Image, Network, Object Store and Block
- Storage APIs together in a single shell with a uniform command structure.
-
- The primary goal is to provide a unified shell command structure and a common
- language to describe operations in OpenStack.
-
- * `PyPi`_ - package installation
- * `Online Documentation`_
- * `Launchpad project`_ - bugs and feature requests
- * `Blueprints`_ - feature specifications (historical only)
- * `Source`_
- * `Developer`_ - getting started as a developer
- * `Contributing`_ - contributing code
- * `Testing`_ - testing code
- * IRC: #openstack-sdks on OFTC (irc.oftc.net)
- * License: Apache 2.0
-
- .. _PyPi: https://pypi.org/project/python-openstackclient
- .. _Online Documentation: https://docs.openstack.org/python-openstackclient/latest/
- .. _Blueprints: https://blueprints.launchpad.net/python-openstackclient
- .. _`Launchpad project`: https://bugs.launchpad.net/python-openstackclient
- .. _Source: https://opendev.org/openstack/python-openstackclient
- .. _Developer: https://docs.openstack.org/project-team-guide/project-setup/python.html
- .. _Contributing: https://docs.openstack.org/infra/manual/developers.html
- .. _Testing: https://docs.openstack.org/python-openstackclient/latest/contributor/developing.html#testing
- .. _Release Notes: https://docs.openstack.org/releasenotes/python-openstackclient
-
- Getting Started
- ===============
-
- OpenStack Client can be installed from PyPI using pip::
-
- pip install python-openstackclient
-
- There are a few variants on getting help. A list of global options and supported
- commands is shown with ``--help``::
-
- openstack --help
-
- There is also a ``help`` command that can be used to get help text for a specific
- command::
-
- openstack help
- openstack help server create
-
- If you want to make changes to the OpenStackClient for testing and contribution,
- make any changes and then run::
-
- python setup.py develop
-
- or::
-
- pip install -e .
-
- Configuration
- =============
-
- The CLI is configured via environment variables and command-line
- options as listed in https://docs.openstack.org/python-openstackclient/latest/cli/authentication.html.
-
- Authentication using username/password is most commonly used:
-
- - For a local user, your configuration will look like the one below::
-
- export OS_AUTH_URL=<url-to-openstack-identity>
- export OS_IDENTITY_API_VERSION=3
- export OS_PROJECT_NAME=<project-name>
- export OS_PROJECT_DOMAIN_NAME=<project-domain-name>
- export OS_USERNAME=<username>
- export OS_USER_DOMAIN_NAME=<user-domain-name>
- export OS_PASSWORD=<password> # (optional)
-
- The corresponding command-line options look very similar::
-
- --os-auth-url <url>
- --os-identity-api-version 3
- --os-project-name <project-name>
- --os-project-domain-name <project-domain-name>
- --os-username <username>
- --os-user-domain-name <user-domain-name>
- [--os-password <password>]
-
- - For a federated user, your configuration will look the so::
-
- export OS_PROJECT_NAME=<project-name>
- export OS_PROJECT_DOMAIN_NAME=<project-domain-name>
- export OS_AUTH_URL=<url-to-openstack-identity>
- export OS_IDENTITY_API_VERSION=3
- export OS_AUTH_PLUGIN=openid
- export OS_AUTH_TYPE=v3oidcpassword
- export OS_USERNAME=<username-in-idp>
- export OS_PASSWORD=<password-in-idp>
- export OS_IDENTITY_PROVIDER=<the-desired-idp-in-keystone>
- export OS_CLIENT_ID=<the-client-id-configured-in-the-idp>
- export OS_CLIENT_SECRET=<the-client-secred-configured-in-the-idp>
- export OS_OPENID_SCOPE=<the-scopes-of-desired-attributes-to-claim-from-idp>
- export OS_PROTOCOL=<the-protocol-used-in-the-apache2-oidc-proxy>
- export OS_ACCESS_TOKEN_TYPE=<the-access-token-type-used-by-your-idp>
- export OS_DISCOVERY_ENDPOINT=<the-well-known-endpoint-of-the-idp>
-
- The corresponding command-line options look very similar::
-
- --os-project-name <project-name>
- --os-project-domain-name <project-domain-name>
- --os-auth-url <url-to-openstack-identity>
- --os-identity-api-version 3
- --os-auth-plugin openid
- --os-auth-type v3oidcpassword
- --os-username <username-in-idp>
- --os-password <password-in-idp>
- --os-identity-provider <the-desired-idp-in-keystone>
- --os-client-id <the-client-id-configured-in-the-idp>
- --os-client-secret <the-client-secred-configured-in-the-idp>
- --os-openid-scope <the-scopes-of-desired-attributes-to-claim-from-idp>
- --os-protocol <the-protocol-used-in-the-apache2-oidc-proxy>
- --os-access-token-type <the-access-token-type-used-by-your-idp>
- --os-discovery-endpoint <the-well-known-endpoint-of-the-idp>
-
- If a password is not provided above (in plaintext), you will be interactively
- prompted to provide one securely.
-
-
-Platform: UNKNOWN
Classifier: Environment :: OpenStack
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
@@ -159,3 +17,155 @@ Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.9
+License-File: LICENSE
+Requires-Dist: pbr!=2.1.0,>=2.0.0
+Requires-Dist: cryptography>=2.7
+Requires-Dist: cliff>=3.5.0
+Requires-Dist: iso8601>=0.1.11
+Requires-Dist: openstacksdk>=3.3.0
+Requires-Dist: osc-lib>=2.3.0
+Requires-Dist: oslo.i18n>=3.15.3
+Requires-Dist: python-keystoneclient>=3.22.0
+Requires-Dist: python-cinderclient>=3.3.0
+Requires-Dist: requests>=2.27.0
+Requires-Dist: stevedore>=2.0.1
+
+========================
+Team and repository tags
+========================
+
+.. image:: https://governance.openstack.org/tc/badges/python-openstackclient.svg
+ :target: https://governance.openstack.org/tc/reference/tags/index.html
+
+.. Change things from this point on
+
+===============
+OpenStackClient
+===============
+
+.. image:: https://img.shields.io/pypi/v/python-openstackclient.svg
+ :target: https://pypi.org/project/python-openstackclient/
+ :alt: Latest Version
+
+OpenStackClient (aka OSC) is a command-line client for OpenStack that brings
+the command set for Compute, Identity, Image, Network, Object Store and Block
+Storage APIs together in a single shell with a uniform command structure.
+
+The primary goal is to provide a unified shell command structure and a common
+language to describe operations in OpenStack.
+
+* `PyPi`_ - package installation
+* `Online Documentation`_
+* `Launchpad project`_ - bugs and feature requests
+* `Blueprints`_ - feature specifications (historical only)
+* `Source`_
+* `Developer`_ - getting started as a developer
+* `Contributing`_ - contributing code
+* `Testing`_ - testing code
+* IRC: #openstack-sdks on OFTC (irc.oftc.net)
+* License: Apache 2.0
+
+.. _PyPi: https://pypi.org/project/python-openstackclient
+.. _Online Documentation: https://docs.openstack.org/python-openstackclient/latest/
+.. _Blueprints: https://blueprints.launchpad.net/python-openstackclient
+.. _`Launchpad project`: https://bugs.launchpad.net/python-openstackclient
+.. _Source: https://opendev.org/openstack/python-openstackclient
+.. _Developer: https://docs.openstack.org/project-team-guide/project-setup/python.html
+.. _Contributing: https://docs.openstack.org/infra/manual/developers.html
+.. _Testing: https://docs.openstack.org/python-openstackclient/latest/contributor/developing.html#testing
+.. _Release Notes: https://docs.openstack.org/releasenotes/python-openstackclient
+
+Getting Started
+===============
+
+OpenStack Client can be installed from PyPI using pip::
+
+ pip install python-openstackclient
+
+There are a few variants on getting help. A list of global options and supported
+commands is shown with ``--help``::
+
+ openstack --help
+
+There is also a ``help`` command that can be used to get help text for a specific
+command::
+
+ openstack help
+ openstack help server create
+
+If you want to make changes to the OpenStackClient for testing and contribution,
+make any changes and then run::
+
+ python setup.py develop
+
+or::
+
+ pip install -e .
+
+Configuration
+=============
+
+The CLI is configured via environment variables and command-line
+options as listed in https://docs.openstack.org/python-openstackclient/latest/cli/authentication.html.
+
+Authentication using username/password is most commonly used:
+
+- For a local user, your configuration will look like the one below::
+
+ export OS_AUTH_URL=<url-to-openstack-identity>
+ export OS_IDENTITY_API_VERSION=3
+ export OS_PROJECT_NAME=<project-name>
+ export OS_PROJECT_DOMAIN_NAME=<project-domain-name>
+ export OS_USERNAME=<username>
+ export OS_USER_DOMAIN_NAME=<user-domain-name>
+ export OS_PASSWORD=<password> # (optional)
+
+ The corresponding command-line options look very similar::
+
+ --os-auth-url <url>
+ --os-identity-api-version 3
+ --os-project-name <project-name>
+ --os-project-domain-name <project-domain-name>
+ --os-username <username>
+ --os-user-domain-name <user-domain-name>
+ [--os-password <password>]
+
+- For a federated user, your configuration will look the so::
+
+ export OS_PROJECT_NAME=<project-name>
+ export OS_PROJECT_DOMAIN_NAME=<project-domain-name>
+ export OS_AUTH_URL=<url-to-openstack-identity>
+ export OS_IDENTITY_API_VERSION=3
+ export OS_AUTH_PLUGIN=openid
+ export OS_AUTH_TYPE=v3oidcpassword
+ export OS_USERNAME=<username-in-idp>
+ export OS_PASSWORD=<password-in-idp>
+ export OS_IDENTITY_PROVIDER=<the-desired-idp-in-keystone>
+ export OS_CLIENT_ID=<the-client-id-configured-in-the-idp>
+ export OS_CLIENT_SECRET=<the-client-secred-configured-in-the-idp>
+ export OS_OPENID_SCOPE=<the-scopes-of-desired-attributes-to-claim-from-idp>
+ export OS_PROTOCOL=<the-protocol-used-in-the-apache2-oidc-proxy>
+ export OS_ACCESS_TOKEN_TYPE=<the-access-token-type-used-by-your-idp>
+ export OS_DISCOVERY_ENDPOINT=<the-well-known-endpoint-of-the-idp>
+
+ The corresponding command-line options look very similar::
+
+ --os-project-name <project-name>
+ --os-project-domain-name <project-domain-name>
+ --os-auth-url <url-to-openstack-identity>
+ --os-identity-api-version 3
+ --os-auth-plugin openid
+ --os-auth-type v3oidcpassword
+ --os-username <username-in-idp>
+ --os-password <password-in-idp>
+ --os-identity-provider <the-desired-idp-in-keystone>
+ --os-client-id <the-client-id-configured-in-the-idp>
+ --os-client-secret <the-client-secred-configured-in-the-idp>
+ --os-openid-scope <the-scopes-of-desired-attributes-to-claim-from-idp>
+ --os-protocol <the-protocol-used-in-the-apache2-oidc-proxy>
+ --os-access-token-type <the-access-token-type-used-by-your-idp>
+ --os-discovery-endpoint <the-well-known-endpoint-of-the-idp>
+
+If a password is not provided above (in plaintext), you will be interactively
+prompted to provide one securely.
+
diff --git a/python_openstackclient.egg-info/SOURCES.txt b/python_openstackclient.egg-info/SOURCES.txt
index 62b5bf9..85e7038 100644
--- a/python_openstackclient.egg-info/SOURCES.txt
+++ b/python_openstackclient.egg-info/SOURCES.txt
@@ -712,6 +712,7 @@ python_openstackclient.egg-info/requires.txt
python_openstackclient.egg-info/top_level.txt
releasenotes/notes/.placeholder
releasenotes/notes/Add-default-security-group-rule-CRUD-2916568f829ea38c.yaml
+releasenotes/notes/Add-trusted-vif-to-the-port-0a0c76d9da8f3da0.yaml
releasenotes/notes/L3-conntrack-helper-bd0d9da041747e84.yaml
releasenotes/notes/Router-flavor-accepts-name-or-id-e9cecafcddf81cb2.yaml
releasenotes/notes/add-auto-and-none-as-nic-parameter-ed23a6e7f99f250d.yaml
@@ -830,6 +831,7 @@ releasenotes/notes/add-tag-support-server-add-port-7e30aa38202d0839.yaml
releasenotes/notes/add-tag-support-server-add-volume-278e79a22dd482f4.yaml
releasenotes/notes/add-trusted-certs-option-server-create-a660488407300f22.yaml
releasenotes/notes/add-virtio-forwarder-vnic-type-bad939c6a868b9e9.yaml
+releasenotes/notes/add-vlan_qinq-to-the-network-3556c094aeedc0de.yaml
releasenotes/notes/add-vol-service-get-set-log-commands-f9420e5061d994b5.yaml
releasenotes/notes/add-volume-attachment-commands-db2974c6460fa3bc.yaml
releasenotes/notes/add-volume-group-commands-b121d6ec7da9779a.yaml
@@ -1191,6 +1193,8 @@ releasenotes/notes/fix-flavor-props-formatting-d21e97745543caa7.yaml
releasenotes/notes/fix-image-create-from-volume-c573e553161605c4.yaml
releasenotes/notes/fix-network-rbac-create-d1f4de77ad2dd421.yaml
releasenotes/notes/fix-openstak-image-save-sdk-port-eb160e8ffc92e514.yaml
+releasenotes/notes/fix-restore-resp-e664a643a723cd2e.yaml
+releasenotes/notes/fix-show-backup-by-name-0759c55396be77a3.yaml
releasenotes/notes/fix-story-2007890-0974f3e69f26801e.yaml
releasenotes/notes/fix-story-2010775-953dbdf03b2b6746.yaml
releasenotes/notes/flavor-add-description-b618abd4a7fb6545.yaml
@@ -1229,9 +1233,11 @@ releasenotes/notes/migrate-agent-commands-1c50ffcb75f91418.yaml
releasenotes/notes/migrate-application-credential-to-sdk-c79d8dfc3c8e1d9f.yaml
releasenotes/notes/migrate-backup-commands-0becc8f18cf9737b.yaml
releasenotes/notes/migrate-create-server-image-to-sdk-e3d8077ffe05bb3d.yaml
+releasenotes/notes/migrate-credential-to-sdk-33a841847fe7d568.yaml
releasenotes/notes/migrate-host-list-show-to-sdk-9b80cd9b4196ab01.yaml
releasenotes/notes/migrate-host-set-438997eb6f81f2b1.yaml
releasenotes/notes/migrate-limits-show-f586c9762dfd7d0c.yaml
+releasenotes/notes/migrate-region-to-sdk-fbd27bceaa1db9dc.yaml
releasenotes/notes/migrate-resource-filter-commands-2a353edb965723d1.yaml
releasenotes/notes/migrate-role-assignment-to-sdk-e6e52bef467b4e4c.yaml
releasenotes/notes/migrate-server-add-network-add-port-to-sdk-7d81b25f59cfbec9.yaml
@@ -1248,7 +1254,9 @@ releasenotes/notes/migrate-server-start-stop-to-sdk-55edd4e1ff5e6ac7.yaml
releasenotes/notes/migrate-server-suspend-resume-to-sdk-fd1709336607b496.yaml
releasenotes/notes/migrate-server-volume-list-update-to-sdk-95b1d3063e46f813.yaml
releasenotes/notes/migrate-service-list-delete-set-to-sdk-920cbe0d210af565.yaml
+releasenotes/notes/migrate-service-provider-to-sdk-74dc48b227f21a05.yaml
releasenotes/notes/migrate-service-to-sdk-6ff62ebf7e41db7c.yaml
+releasenotes/notes/migrate-trust-to-sdk-9397c9cfddcb636a.yaml
releasenotes/notes/migrate-volume-attachment-commands-4309409bca1ca5d4.yaml
releasenotes/notes/migrate-volume-backend-commands-259e553e213c71b0.yaml
releasenotes/notes/migrate-volume-revert-to-sdk-1e399853d80ba5f8.yaml
@@ -1279,6 +1287,7 @@ releasenotes/notes/osc4-volume-470422e5a453310e.yaml
releasenotes/notes/pass_ssh_args-cf26a2ce26ccddaf.yaml
releasenotes/notes/port-device-profile-4a3bf800da21c778.yaml
releasenotes/notes/port-list-security-group-4af5d2e789174ff9.yaml
+releasenotes/notes/port_uplink_status_propagation_updatable-d1e155c19247b666.yaml
releasenotes/notes/project-cleanup-skip-resource-option-4f80db0d8cf36fdb.yaml
releasenotes/notes/properties-with-image-property-field.yaml-c51bf37c3106d6ff.yaml
releasenotes/notes/qos-min-pps-rule-bfe22cea1966c4a0.yaml
@@ -1313,6 +1322,7 @@ releasenotes/notes/router-subnet-469d095ae0bac884.yaml
releasenotes/notes/security-grp-json-fix.yaml-2af1f48a48034d64.yaml
releasenotes/notes/server-add-tag-63f9cd01dbd82d1b.yaml
releasenotes/notes/server-changes-3962541b6ebdbbd8.yaml
+releasenotes/notes/server-create-no-security-group-option-627697bddae429b1.yaml
releasenotes/notes/server-create-server-group-a5b630f2a64de28d.yaml
releasenotes/notes/server-description-ae9618fc09544cac.yaml
releasenotes/notes/server-group-create_rule_option-9f84e52f35e7c3ba.yaml
@@ -1368,6 +1378,7 @@ releasenotes/notes/use_sdk_for_image-f49d2df38e7d9f81.yaml
releasenotes/notes/versions-show-12a2443624c83048.yaml
releasenotes/notes/volume-attachment-create-output-fix-56515b8fcdd260b9.yaml
releasenotes/notes/volume-backend-c5faae0b31556a24.yaml
+releasenotes/notes/volume-backup-created-at-list-v3-47400b31be5143bc.yaml
releasenotes/notes/volume-backup-record-9f5987c45e294dc6.yaml
releasenotes/notes/volume-migrate-command-52cf6edd62fe17a7.yaml
releasenotes/notes/volume-type-extra-specs-22a22fcb6e269832.yaml
diff --git a/python_openstackclient.egg-info/entry_points.txt b/python_openstackclient.egg-info/entry_points.txt
index 630118f..45d6347 100644
--- a/python_openstackclient.egg-info/entry_points.txt
+++ b/python_openstackclient.egg-info/entry_points.txt
@@ -715,4 +715,3 @@ volume_type_set = openstackclient.volume.v3.volume_type:SetVolumeType
volume_type_show = openstackclient.volume.v3.volume_type:ShowVolumeType
volume_type_unset = openstackclient.volume.v3.volume_type:UnsetVolumeType
volume_unset = openstackclient.volume.v3.volume:UnsetVolume
-
diff --git a/python_openstackclient.egg-info/pbr.json b/python_openstackclient.egg-info/pbr.json
index c62adec..4bf5247 100644
--- a/python_openstackclient.egg-info/pbr.json
+++ b/python_openstackclient.egg-info/pbr.json
@@ -1 +1 @@
-{"git_version": "7c6b47b4", "is_release": true} \ No newline at end of file
+{"git_version": "4b7e32ca", "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 b79129e..66146e4 100644
--- a/python_openstackclient.egg-info/requires.txt
+++ b/python_openstackclient.egg-info/requires.txt
@@ -1,11 +1,11 @@
-cliff>=3.5.0
+pbr!=2.1.0,>=2.0.0
cryptography>=2.7
+cliff>=3.5.0
iso8601>=0.1.11
openstacksdk>=3.3.0
osc-lib>=2.3.0
oslo.i18n>=3.15.3
-pbr!=2.1.0,>=2.0.0
-python-cinderclient>=3.3.0
python-keystoneclient>=3.22.0
+python-cinderclient>=3.3.0
requests>=2.27.0
stevedore>=2.0.1
diff --git a/releasenotes/notes/Add-trusted-vif-to-the-port-0a0c76d9da8f3da0.yaml b/releasenotes/notes/Add-trusted-vif-to-the-port-0a0c76d9da8f3da0.yaml
new file mode 100644
index 0000000..ffa9669
--- /dev/null
+++ b/releasenotes/notes/Add-trusted-vif-to-the-port-0a0c76d9da8f3da0.yaml
@@ -0,0 +1,7 @@
+---
+features:
+ - |
+ Add ``trusted`` attribute to the ``port create`` and ``port set`` commands.
+ It can be set to ``true`` with ``--trusted`` and to ``false`` with
+ ``--not-trusted`` CLI arguments passed to the ``port create`` and ``port
+ set`` commands``
diff --git a/releasenotes/notes/add-vlan_qinq-to-the-network-3556c094aeedc0de.yaml b/releasenotes/notes/add-vlan_qinq-to-the-network-3556c094aeedc0de.yaml
new file mode 100644
index 0000000..f89575b
--- /dev/null
+++ b/releasenotes/notes/add-vlan_qinq-to-the-network-3556c094aeedc0de.yaml
@@ -0,0 +1,7 @@
+---
+features:
+ - |
+ Add ``qinq-vlan`` and ``no-qinq-vlan`` arguments to the ``network create``
+ command. It will enable/disable QinQ feature for the created network.
+ This new argument is mutually exclusive with the ``transparent-vlan`` - only
+ one of them can be set to ``True`` for the network.
diff --git a/releasenotes/notes/fix-restore-resp-e664a643a723cd2e.yaml b/releasenotes/notes/fix-restore-resp-e664a643a723cd2e.yaml
new file mode 100644
index 0000000..2ee8f21
--- /dev/null
+++ b/releasenotes/notes/fix-restore-resp-e664a643a723cd2e.yaml
@@ -0,0 +1,4 @@
+---
+fixes:
+ - |
+ Fixed the output of ``volume backup restore`` command.
diff --git a/releasenotes/notes/fix-show-backup-by-name-0759c55396be77a3.yaml b/releasenotes/notes/fix-show-backup-by-name-0759c55396be77a3.yaml
new file mode 100644
index 0000000..7ed9d72
--- /dev/null
+++ b/releasenotes/notes/fix-show-backup-by-name-0759c55396be77a3.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+ - |
+ Fixed the ``openstack volume backup show`` command
+ to show a backup by name.
diff --git a/releasenotes/notes/migrate-credential-to-sdk-33a841847fe7d568.yaml b/releasenotes/notes/migrate-credential-to-sdk-33a841847fe7d568.yaml
new file mode 100644
index 0000000..e830012
--- /dev/null
+++ b/releasenotes/notes/migrate-credential-to-sdk-33a841847fe7d568.yaml
@@ -0,0 +1,10 @@
+---
+upgrade:
+ - |
+ The following commands have been migrated to SDK:
+
+ - ``credential create``
+ - ``credential delete``
+ - ``credential list``
+ - ``credential set``
+ - ``credential show``
diff --git a/releasenotes/notes/migrate-region-to-sdk-fbd27bceaa1db9dc.yaml b/releasenotes/notes/migrate-region-to-sdk-fbd27bceaa1db9dc.yaml
new file mode 100644
index 0000000..31a5e6d
--- /dev/null
+++ b/releasenotes/notes/migrate-region-to-sdk-fbd27bceaa1db9dc.yaml
@@ -0,0 +1,10 @@
+---
+upgrade:
+ - |
+ The following commands have been migrated to SDK:
+
+ - ``region create``
+ - ``region list``
+ - ``region delete``
+ - ``region set``
+ - ``region show``
diff --git a/releasenotes/notes/migrate-service-provider-to-sdk-74dc48b227f21a05.yaml b/releasenotes/notes/migrate-service-provider-to-sdk-74dc48b227f21a05.yaml
new file mode 100644
index 0000000..d9914cf
--- /dev/null
+++ b/releasenotes/notes/migrate-service-provider-to-sdk-74dc48b227f21a05.yaml
@@ -0,0 +1,10 @@
+---
+upgrade:
+ - |
+ The following commands have been migrated to SDK:
+
+ - ``service provider create``
+ - ``service provider delete``
+ - ``service provider set``
+ - ``service provider list``
+ - ``service provider show``
diff --git a/releasenotes/notes/migrate-trust-to-sdk-9397c9cfddcb636a.yaml b/releasenotes/notes/migrate-trust-to-sdk-9397c9cfddcb636a.yaml
new file mode 100644
index 0000000..e45218f
--- /dev/null
+++ b/releasenotes/notes/migrate-trust-to-sdk-9397c9cfddcb636a.yaml
@@ -0,0 +1,9 @@
+---
+upgrade:
+ - |
+ The following commands have been migrated to SDK:
+
+ - ``trust create``
+ - ``trust list``
+ - ``trust delete``
+ - ``trust show``
diff --git a/releasenotes/notes/port_uplink_status_propagation_updatable-d1e155c19247b666.yaml b/releasenotes/notes/port_uplink_status_propagation_updatable-d1e155c19247b666.yaml
new file mode 100644
index 0000000..0e7b776
--- /dev/null
+++ b/releasenotes/notes/port_uplink_status_propagation_updatable-d1e155c19247b666.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ Add ``--enable-uplink-status-propagation`` option and
+ ``--disable-uplink-status-propagation`` option to ``port update`` command.
diff --git a/releasenotes/notes/server-create-no-security-group-option-627697bddae429b1.yaml b/releasenotes/notes/server-create-no-security-group-option-627697bddae429b1.yaml
new file mode 100644
index 0000000..b2169d3
--- /dev/null
+++ b/releasenotes/notes/server-create-no-security-group-option-627697bddae429b1.yaml
@@ -0,0 +1,7 @@
+---
+features:
+ - |
+ The ``server create`` command now supports a ``--no-security-group``
+ option. When provided, no security groups will be associated with ports
+ created and attached to the server during server creation. This does not
+ affect pre-created ports.
diff --git a/releasenotes/notes/volume-backup-created-at-list-v3-47400b31be5143bc.yaml b/releasenotes/notes/volume-backup-created-at-list-v3-47400b31be5143bc.yaml
new file mode 100644
index 0000000..88aa714
--- /dev/null
+++ b/releasenotes/notes/volume-backup-created-at-list-v3-47400b31be5143bc.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ Listing volume backups now shows the created_at column when
+ volume v3 API is used.
diff --git a/releasenotes/source/2023.1.rst b/releasenotes/source/2023.1.rst
index d123847..2c9a36f 100644
--- a/releasenotes/source/2023.1.rst
+++ b/releasenotes/source/2023.1.rst
@@ -3,4 +3,4 @@
===========================
.. release-notes::
- :branch: stable/2023.1
+ :branch: unmaintained/2023.1
diff --git a/test-requirements.txt b/test-requirements.txt
index 275c2ff..c9c1b28 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,7 +1,5 @@
coverage!=4.4,>=4.0 # Apache-2.0
fixtures>=3.0.0 # Apache-2.0/BSD
-oslotest>=3.2.0 # Apache-2.0
-requests>=2.14.2 # Apache-2.0
requests-mock>=1.2.0 # Apache-2.0
stestr>=1.0.0 # Apache-2.0
testtools>=2.2.0 # MIT